From 3b75e5c0b99b29745a84f2b20a23bf15e609286a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Fri, 28 Oct 2011 16:02:47 +0800 Subject: [PATCH] revert android-tegra-2.6.36-honeycomb-mr1-9001adc to v2.6.36 --- Documentation/android.txt | 121 - Documentation/cgroups/cpuacct.txt | 7 - Documentation/cpu-freq/governors.txt | 36 - Documentation/kernel-parameters.txt | 2 +- Documentation/power/runtime_pm.txt | 4 +- Makefile | 2 +- arch/arm/Kconfig | 14 - arch/arm/boot/compressed/.gitignore | 5 +- arch/arm/boot/compressed/head.S | 5 +- arch/arm/boot/compressed/misc.c | 2 +- arch/arm/common/Kconfig | 51 - arch/arm/common/Makefile | 2 - arch/arm/common/fiq_debugger.c | 942 -- arch/arm/common/fiq_debugger_ringbuf.h | 94 - arch/arm/common/fiq_glue.S | 111 - arch/arm/common/fiq_glue_setup.c | 100 - arch/arm/common/gic.c | 133 +- arch/arm/configs/olympus_defconfig | 1675 ---- arch/arm/configs/stingray_defconfig | 427 - arch/arm/configs/tegra_android_defconfig | 307 - arch/arm/configs/tegra_defconfig | 1102 --- arch/arm/include/asm/assembler.h | 2 +- arch/arm/include/asm/cacheflush.h | 2 +- arch/arm/include/asm/delay.h | 4 - arch/arm/include/asm/fiq_debugger.h | 46 - arch/arm/include/asm/fiq_glue.h | 30 - arch/arm/include/asm/hardware/cache-l2x0.h | 5 - arch/arm/include/asm/hardware/gic.h | 12 - arch/arm/include/asm/kgdb.h | 5 +- arch/arm/include/asm/mach/mmc.h | 27 - arch/arm/include/asm/mmu.h | 4 - arch/arm/include/asm/pgtable.h | 3 - arch/arm/include/asm/smp_plat.h | 4 - arch/arm/include/asm/smp_twd.h | 11 - arch/arm/include/asm/system.h | 2 - arch/arm/include/asm/tls.h | 4 +- arch/arm/kernel/debug.S | 2 +- arch/arm/kernel/entry-armv.S | 2 +- arch/arm/kernel/entry-common.S | 6 - arch/arm/kernel/kgdb.c | 2 +- arch/arm/kernel/process.c | 89 +- arch/arm/kernel/signal.c | 9 - arch/arm/kernel/smp_twd.c | 108 +- arch/arm/kernel/traps.c | 6 +- arch/arm/lib/Makefile | 6 +- arch/arm/lib/findbit.S | 6 +- arch/arm/mach-at91/include/mach/at91_mci.h | 2 - .../mach-cns3xxx/include/mach/debug-macro.S | 2 +- arch/arm/mach-cns3xxx/pcie.c | 2 +- arch/arm/mach-realview/realview_pbx.c | 2 +- arch/arm/mach-tegra/Kconfig | 85 +- arch/arm/mach-tegra/Makefile | 68 +- arch/arm/mach-tegra/apbio.c | 151 - arch/arm/mach-tegra/apbio.h | 20 - arch/arm/mach-tegra/arb_sema.c | 242 - arch/arm/mach-tegra/board-harmony-panel.c | 64 - arch/arm/mach-tegra/board-harmony-pinmux.c | 11 +- arch/arm/mach-tegra/board-harmony-sdhci.c | 149 - arch/arm/mach-tegra/board-harmony.c | 98 - arch/arm/mach-tegra/board-harmony.h | 2 - arch/arm/mach-tegra/board-olympus-i2c.c | 372 - arch/arm/mach-tegra/board-olympus-keypad.c | 124 - arch/arm/mach-tegra/board-olympus-panel.c | 63 - arch/arm/mach-tegra/board-olympus-pinmux.c | 145 - arch/arm/mach-tegra/board-olympus-wifi.c | 205 - arch/arm/mach-tegra/board-olympus.c | 375 - arch/arm/mach-tegra/board-olympus.h | 26 - .../arm/mach-tegra/board-stingray-bluetooth.c | 328 - arch/arm/mach-tegra/board-stingray-bootinfo.c | 76 - arch/arm/mach-tegra/board-stingray-gps.c | 84 - arch/arm/mach-tegra/board-stingray-keypad.c | 116 - arch/arm/mach-tegra/board-stingray-memory.c | 832 -- arch/arm/mach-tegra/board-stingray-panel.c | 553 -- arch/arm/mach-tegra/board-stingray-pinmux.c | 219 - arch/arm/mach-tegra/board-stingray-power.c | 786 -- arch/arm/mach-tegra/board-stingray-sensors.c | 450 - arch/arm/mach-tegra/board-stingray-touch.c | 644 -- arch/arm/mach-tegra/board-stingray-usbnet.c | 863 -- arch/arm/mach-tegra/board-stingray-wifi.c | 294 - arch/arm/mach-tegra/board-stingray-wlan_nvs.c | 112 - arch/arm/mach-tegra/board-stingray.c | 1282 --- arch/arm/mach-tegra/board-stingray.h | 74 - arch/arm/mach-tegra/board-ventana-panel.c | 325 - arch/arm/mach-tegra/board-ventana-pinmux.c | 166 - arch/arm/mach-tegra/board-ventana-power.c | 189 - arch/arm/mach-tegra/board-ventana-sdhci.c | 144 - arch/arm/mach-tegra/board-ventana.c | 274 - arch/arm/mach-tegra/board-ventana.h | 25 - arch/arm/mach-tegra/board.h | 18 - arch/arm/mach-tegra/clock.c | 657 +- arch/arm/mach-tegra/clock.h | 130 +- arch/arm/mach-tegra/common.c | 262 +- arch/arm/mach-tegra/cortex-a9.S | 716 -- arch/arm/mach-tegra/cpu-tegra.c | 412 - arch/arm/mach-tegra/cpuidle.c | 714 -- arch/arm/mach-tegra/delay.S | 51 - arch/arm/mach-tegra/devices.c | 844 -- arch/arm/mach-tegra/devices.h | 64 - arch/arm/mach-tegra/dma.c | 865 -- arch/arm/mach-tegra/dvfs.c | 557 -- arch/arm/mach-tegra/dvfs.h | 93 - arch/arm/mach-tegra/fiq.c | 50 - arch/arm/mach-tegra/fuse.c | 116 - arch/arm/mach-tegra/fuse.h | 35 - arch/arm/mach-tegra/gpio.c | 117 +- arch/arm/mach-tegra/headsmp-t2.S | 218 - arch/arm/mach-tegra/headsmp.S | 61 + arch/arm/mach-tegra/hotplug.c | 140 + arch/arm/mach-tegra/include/mach/arb_sema.h | 34 - arch/arm/mach-tegra/include/mach/audio.h | 57 - arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h | 27 - arch/arm/mach-tegra/include/mach/clk.h | 6 - .../arm/mach-tegra/include/mach/cpcap_audio.h | 242 - arch/arm/mach-tegra/include/mach/dc.h | 200 - .../arm/mach-tegra/include/mach/debug-macro.S | 15 +- arch/arm/mach-tegra/include/mach/delay.h | 41 - arch/arm/mach-tegra/include/mach/dma.h | 166 - .../arm/mach-tegra/include/mach/entry-macro.S | 2 +- arch/arm/mach-tegra/include/mach/fb.h | 65 - arch/arm/mach-tegra/include/mach/fiq.h | 25 - arch/arm/mach-tegra/include/mach/gpio.h | 4 +- arch/arm/mach-tegra/include/mach/i2s.h | 316 - arch/arm/mach-tegra/include/mach/io.h | 28 +- arch/arm/mach-tegra/include/mach/iomap.h | 114 +- arch/arm/mach-tegra/include/mach/iovmm.h | 286 - arch/arm/mach-tegra/include/mach/irqs.h | 21 +- arch/arm/mach-tegra/include/mach/kfuse.h | 20 - arch/arm/mach-tegra/include/mach/legacy_irq.h | 36 - arch/arm/mach-tegra/include/mach/mc.h | 100 - arch/arm/mach-tegra/include/mach/memory.h | 5 - arch/arm/mach-tegra/include/mach/nand.h | 54 - arch/arm/mach-tegra/include/mach/nvhost.h | 175 - arch/arm/mach-tegra/include/mach/nvmap.h | 121 - arch/arm/mach-tegra/include/mach/pinmux-t2.h | 184 - arch/arm/mach-tegra/include/mach/pinmux.h | 210 +- arch/arm/mach-tegra/include/mach/powergate.h | 40 - arch/arm/mach-tegra/include/mach/sdhci.h | 36 - arch/arm/mach-tegra/include/mach/smp.h | 1 - arch/arm/mach-tegra/include/mach/spdif.h | 392 - arch/arm/mach-tegra/include/mach/suspend.h | 80 - arch/arm/mach-tegra/include/mach/system.h | 20 +- .../arm/mach-tegra/include/mach/tegra2_fuse.h | 115 - arch/arm/mach-tegra/include/mach/tegra_fb.h | 27 - .../include/mach/tegra_fiq_debugger.h | 30 - .../mach-tegra/include/mach/tegra_hsuart.h | 24 - arch/arm/mach-tegra/include/mach/uncompress.h | 20 +- arch/arm/mach-tegra/include/mach/usb_phy.h | 87 - arch/arm/mach-tegra/include/mach/vmalloc.h | 3 +- arch/arm/mach-tegra/include/mach/w1.h | 84 - arch/arm/mach-tegra/io.c | 38 +- arch/arm/mach-tegra/iovmm-gart.c | 351 - arch/arm/mach-tegra/iovmm.c | 775 -- arch/arm/mach-tegra/irq.c | 293 - arch/arm/mach-tegra/kfuse.c | 88 - arch/arm/mach-tegra/legacy_irq.c | 215 - arch/arm/mach-tegra/localtimer.c | 2 +- arch/arm/mach-tegra/mc.c | 42 - arch/arm/mach-tegra/pinmux-t2-tables.c | 278 - arch/arm/mach-tegra/pinmux.c | 372 +- arch/arm/mach-tegra/platsmp.c | 130 +- arch/arm/mach-tegra/power-macros.S | 57 - arch/arm/mach-tegra/power.h | 63 - arch/arm/mach-tegra/powergate.c | 234 - arch/arm/mach-tegra/pwm.c | 293 - arch/arm/mach-tegra/suspend-t2.c | 413 - arch/arm/mach-tegra/suspend.c | 861 -- arch/arm/mach-tegra/syncpt.c | 100 - arch/arm/mach-tegra/tegra2_clocks.c | 1560 +-- arch/arm/mach-tegra/tegra2_dvfs.c | 298 - arch/arm/mach-tegra/tegra2_emc.c | 251 - arch/arm/mach-tegra/tegra2_emc.h | 38 - arch/arm/mach-tegra/tegra2_fuse.c | 709 -- arch/arm/mach-tegra/tegra2_save.S | 413 - arch/arm/mach-tegra/tegra_fiq_debugger.c | 208 - arch/arm/mach-tegra/tegra_i2s_audio.c | 1963 ---- arch/arm/mach-tegra/tegra_spdif_audio.c | 1186 --- arch/arm/mach-tegra/timer.c | 121 +- arch/arm/mach-tegra/usb_phy.c | 869 -- arch/arm/mach-tegra/wakeups-t2.h | 58 - arch/arm/mm/Kconfig | 7 - arch/arm/mm/cache-l2x0.c | 152 +- arch/arm/mm/cache-v6.S | 46 +- arch/arm/mm/fault-armv.c | 30 +- arch/arm/mm/flush.c | 9 +- arch/arm/mm/init.c | 135 +- arch/arm/mm/mmu.c | 43 +- arch/arm/mm/proc-macros.S | 2 +- arch/arm/mm/proc-v7.S | 8 +- arch/arm/mm/proc-xsc3.S | 2 +- arch/arm/mm/proc-xscale.S | 2 +- arch/arm/plat-omap/dma.c | 50 +- arch/arm/plat-omap/include/plat/dma.h | 4 - arch/arm/vfp/entry.S | 3 +- arch/microblaze/Makefile | 8 +- arch/mips/jz4740/board-qi_lb60.c | 4 +- arch/powerpc/kernel/ppc970-pmu.c | 2 - arch/powerpc/mm/hash_utils_64.c | 2 +- arch/s390/kernel/nmi.c | 10 +- arch/s390/kernel/vtime.c | 19 - arch/s390/lib/delay.c | 14 +- arch/sh/include/asm/syscalls_32.h | 7 +- arch/sparc/include/asm/openprom.h | 2 +- arch/sparc/include/asm/oplib_32.h | 35 +- arch/sparc/include/asm/oplib_64.h | 46 +- arch/sparc/kernel/leon_kernel.c | 4 +- arch/sparc/prom/Makefile | 1 + arch/sparc/prom/console_32.c | 65 +- arch/sparc/prom/console_64.c | 81 +- arch/sparc/prom/devops_32.c | 87 + arch/sparc/prom/devops_64.c | 67 + arch/sparc/prom/misc_64.c | 16 +- arch/sparc/prom/printf.c | 35 +- arch/sparc/prom/tree_32.c | 15 + arch/sparc/prom/tree_64.c | 18 + arch/tile/kernel/process.c | 7 - arch/um/drivers/line.c | 5 +- arch/um/kernel/uml.lds.S | 2 +- arch/um/os-Linux/time.c | 2 +- arch/x86/include/asm/cpufeature.h | 2 +- arch/x86/include/asm/io.h | 1 - arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/include/asm/mrst.h | 2 +- arch/x86/include/asm/processor.h | 23 + arch/x86/include/asm/smp.h | 9 +- arch/x86/kernel/apic/apic.c | 8 - arch/x86/kernel/apic/io_apic.c | 3 - arch/x86/kernel/apic/probe_64.c | 7 + arch/x86/kernel/cpu/amd.c | 3 +- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 1 - arch/x86/kernel/cpu/mtrr/cleanup.c | 2 +- arch/x86/kernel/cpu/perf_event_amd.c | 4 +- arch/x86/kernel/crash_dump_64.c | 3 +- arch/x86/kernel/hw_breakpoint.c | 4 - arch/x86/kernel/microcode_intel.c | 16 +- arch/x86/kernel/olpc.c | 5 +- arch/x86/kernel/reboot.c | 2 +- arch/x86/kernel/smp.c | 15 +- arch/x86/kernel/smpboot.c | 85 +- arch/x86/kernel/traps.c | 1 - arch/x86/kernel/vm86_32.c | 10 +- arch/x86/kernel/xsave.c | 3 +- arch/x86/kvm/svm.c | 43 +- arch/x86/kvm/vmx.c | 24 +- arch/x86/kvm/x86.c | 25 +- arch/x86/kvm/x86.h | 5 - arch/x86/oprofile/op_model_amd.c | 24 +- arch/x86/vdso/Makefile | 4 +- arch/x86/xen/enlighten.c | 4 + arch/x86/xen/smp.c | 6 +- block/blk-core.c | 5 +- block/blk-map.c | 2 - block/blk-merge.c | 6 +- block/blk-settings.c | 27 +- block/blk-sysfs.c | 2 +- block/genhd.c | 23 +- block/scsi_ioctl.c | 34 +- drivers/Kconfig | 2 - drivers/Makefile | 1 - drivers/acpi/acpica/dswexec.c | 19 +- drivers/acpi/battery.c | 38 +- drivers/acpi/bus.c | 7 +- drivers/acpi/debugfs.c | 2 +- drivers/acpi/ec.c | 3 - drivers/ata/ahci.h | 1 - drivers/ata/libahci.c | 18 +- drivers/ata/libata-scsi.c | 5 +- drivers/ata/libata-sff.c | 7 +- drivers/ata/sata_via.c | 9 +- drivers/base/power/main.c | 50 +- drivers/block/xen-blkfront.c | 2 +- drivers/bluetooth/hci_ldisc.c | 7 - drivers/char/Kconfig | 17 - drivers/char/Makefile | 1 - drivers/char/agp/intel-agp.c | 1 - drivers/char/agp/intel-gtt.c | 63 +- drivers/char/dcc_tty.c | 326 - drivers/char/hpet.c | 17 - drivers/char/ipmi/ipmi_si_intf.c | 30 +- drivers/char/mem.c | 17 - drivers/char/n_gsm.c | 6 +- drivers/char/pcmcia/synclink_cs.c | 2 - drivers/char/ramoops.c | 12 +- drivers/char/tty_buffer.c | 14 +- drivers/char/tty_io.c | 13 +- drivers/char/tty_ldisc.c | 51 +- drivers/char/vt_ioctl.c | 11 +- drivers/cpufreq/Kconfig | 16 - drivers/cpufreq/Makefile | 1 - drivers/cpufreq/cpufreq_interactive.c | 711 -- drivers/cpufreq/cpufreq_stats.c | 30 +- drivers/crypto/Kconfig | 9 - drivers/crypto/Makefile | 1 - drivers/crypto/padlock-aes.c | 2 +- drivers/crypto/tegra-aes.c | 1162 --- drivers/crypto/tegra-aes.h | 114 - drivers/dma/mv_xor.c | 2 +- drivers/edac/amd64_edac.c | 2 +- drivers/edac/edac_mc.c | 10 +- drivers/firewire/ohci.c | 107 +- drivers/gpio/cs5535-gpio.c | 27 +- drivers/gpio/rdc321x-gpio.c | 2 +- drivers/gpu/drm/drm_crtc.c | 10 +- drivers/gpu/drm/i915/i915_dma.c | 26 - drivers/gpu/drm/i915/i915_irq.c | 21 +- drivers/gpu/drm/i915/i915_reg.h | 8 - drivers/gpu/drm/i915/i915_suspend.c | 4 +- drivers/gpu/drm/i915/intel_crt.c | 3 +- drivers/gpu/drm/i915/intel_display.c | 11 +- drivers/gpu/drm/i915/intel_dp.c | 37 +- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_overlay.c | 8 - drivers/gpu/drm/i915/intel_sdvo.c | 8 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 6 - drivers/gpu/drm/nouveau/nouveau_irq.c | 1 - drivers/gpu/drm/nouveau/nv50_display.c | 35 +- drivers/gpu/drm/radeon/atom.c | 1 - drivers/gpu/drm/radeon/atombios_crtc.c | 3 +- drivers/gpu/drm/radeon/evergreen.c | 25 +- drivers/gpu/drm/radeon/r100.c | 6 - drivers/gpu/drm/radeon/r100_track.h | 1 - drivers/gpu/drm/radeon/r200.c | 2 - drivers/gpu/drm/radeon/r600.c | 32 +- drivers/gpu/drm/radeon/r600_blit_kms.c | 8 +- drivers/gpu/drm/radeon/r600_cs.c | 4 +- drivers/gpu/drm/radeon/r600_reg.h | 1 - drivers/gpu/drm/radeon/radeon_atombios.c | 16 - drivers/gpu/drm/radeon/radeon_bios.c | 13 +- drivers/gpu/drm/radeon/radeon_combios.c | 15 +- drivers/gpu/drm/radeon/radeon_connectors.c | 34 - drivers/gpu/drm/radeon/radeon_device.c | 9 +- drivers/gpu/drm/radeon/radeon_encoders.c | 36 +- drivers/gpu/drm/radeon/radeon_i2c.c | 1 - drivers/gpu/drm/radeon/radeon_object.c | 4 +- drivers/gpu/drm/radeon/radeon_reg.h | 1 - drivers/gpu/drm/radeon/rv770.c | 9 +- drivers/hid/Kconfig | 7 - drivers/hid/Makefile | 1 - drivers/hid/hid-core.c | 2 - drivers/hid/hid-egalax.c | 16 +- drivers/hid/hid-ids.h | 4 - drivers/hid/hid-magicmouse.c | 330 +- drivers/hid/hid-motorola.c | 177 - drivers/hid/usbhid/hid-quirks.c | 1 + drivers/hwmon/adm1026.c | 20 +- drivers/hwmon/lm85.c | 1 - drivers/i2c/busses/Kconfig | 7 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-pca-platform.c | 2 +- drivers/i2c/busses/i2c-tegra.c | 814 -- drivers/idle/intel_idle.c | 2 +- drivers/infiniband/core/uverbs_cmd.c | 99 +- drivers/input/Kconfig | 9 - drivers/input/Makefile | 1 - drivers/input/evdev.c | 16 +- drivers/input/input.c | 24 - drivers/input/keyreset.c | 239 - drivers/input/misc/Kconfig | 16 - drivers/input/misc/Makefile | 2 - drivers/input/misc/gpio_axis.c | 192 - drivers/input/misc/gpio_event.c | 260 - drivers/input/misc/gpio_input.c | 353 - drivers/input/misc/gpio_matrix.c | 432 - drivers/input/misc/gpio_output.c | 97 - drivers/input/misc/keychord.c | 387 - drivers/input/mouse/synaptics.h | 3 +- drivers/input/serio/i8042-x86ia64io.h | 7 - drivers/input/touchscreen/Kconfig | 28 - drivers/input/touchscreen/Makefile | 3 - drivers/input/touchscreen/panjit_i2c.c | 361 - drivers/input/touchscreen/qtouch_obp_ts.c | 2042 ---- drivers/input/touchscreen/synaptics_i2c_rmi.c | 675 -- drivers/isdn/gigaset/bas-gigaset.c | 89 +- drivers/isdn/gigaset/isocdata.c | 8 +- drivers/leds/Kconfig | 30 - drivers/leds/Makefile | 5 - drivers/leds/led-lm3559.c | 518 - drivers/leds/leds-auo-panel-backlight.c | 128 - drivers/leds/leds-ld-cpcap.c | 271 - drivers/leds/leds-lp8550.c | 494 - drivers/leds/leds-ss4200.c | 1 - drivers/leds/ledtrig-sleep.c | 80 - drivers/md/dm-table.c | 5 + drivers/md/md.c | 21 +- drivers/md/raid1.c | 1 - drivers/md/raid10.c | 2 +- drivers/media/common/saa7146_hlp.c | 8 +- drivers/media/common/saa7146_video.c | 16 +- drivers/media/video/Kconfig | 1 - drivers/media/video/Makefile | 1 - drivers/media/video/cx23885/cx23885-core.c | 1 - drivers/media/video/gspca/gspca.c | 4 +- drivers/media/video/gspca/sonixj.c | 20 +- drivers/media/video/hdpvr/hdpvr-video.c | 1 - drivers/media/video/msp3400-driver.c | 7 +- drivers/media/video/mx2_camera.c | 2 + drivers/media/video/saa7134/saa7134-cards.c | 24 +- drivers/media/video/tegra/Kconfig | 30 - drivers/media/video/tegra/Makefile | 5 - drivers/media/video/tegra/avp/Kconfig | 25 - drivers/media/video/tegra/avp/Makefile | 6 - drivers/media/video/tegra/avp/avp.c | 1736 ---- drivers/media/video/tegra/avp/avp.h | 32 - drivers/media/video/tegra/avp/avp_msg.h | 342 - drivers/media/video/tegra/avp/avp_svc.c | 732 -- drivers/media/video/tegra/avp/headavp.S | 66 - drivers/media/video/tegra/avp/headavp.h | 41 - drivers/media/video/tegra/avp/tegra_rpc.c | 796 -- drivers/media/video/tegra/avp/trpc.h | 80 - drivers/media/video/tegra/avp/trpc_local.c | 333 - drivers/media/video/tegra/avp/trpc_sema.c | 220 - drivers/media/video/tegra/avp/trpc_sema.h | 28 - drivers/media/video/tegra/dw9714l.c | 313 - drivers/media/video/tegra/ov5650.c | 873 -- drivers/media/video/tegra/soc2030.c | 1438 --- drivers/media/video/tegra/tegra_camera.c | 368 - drivers/mfd/Kconfig | 10 +- drivers/mfd/Makefile | 13 - drivers/mfd/cpcap-3mm5.c | 338 - drivers/mfd/cpcap-adc.c | 654 -- drivers/mfd/cpcap-audio-core.c | 1439 --- drivers/mfd/cpcap-core.c | 495 - drivers/mfd/cpcap-irq.c | 652 -- drivers/mfd/cpcap-key.c | 128 - drivers/mfd/cpcap-regacc.c | 385 - drivers/mfd/cpcap-uc.c | 893 -- drivers/mfd/cpcap-whisper.c | 826 -- drivers/mfd/tegra-cpcap-audio.c | 595 -- drivers/mfd/tps6586x.c | 208 +- drivers/mfd/wm831x-core.c | 8 +- drivers/misc/Kconfig | 108 - drivers/misc/Makefile | 16 - drivers/misc/ad525x_dpot-spi.c | 4 +- drivers/misc/akm8975.c | 638 -- drivers/misc/apanic.c | 606 -- drivers/misc/cap_prox.c | 472 - drivers/misc/gps-gpio-brcm4750.c | 227 - drivers/misc/kernel_debugger.c | 89 - drivers/misc/max9635.c | 633 -- drivers/misc/moto_bmp085.c | 915 -- drivers/misc/nct1008.c | 291 - drivers/misc/pmem.c | 1344 --- drivers/misc/radio_ctrl/Kconfig | 27 - drivers/misc/radio_ctrl/Makefile | 7 - drivers/misc/radio_ctrl/mdm6600_ctrl.c | 601 -- drivers/misc/radio_ctrl/radio_class.c | 189 - drivers/misc/radio_ctrl/wrigley_ctrl.c | 391 - drivers/misc/sgi-xp/xpc_partition.c | 25 +- drivers/misc/sgi-xp/xpc_uv.c | 17 - drivers/misc/tegra-cryptodev.c | 343 - drivers/misc/tegra-cryptodev.h | 69 - drivers/misc/ts27010mux/Kconfig | 11 - drivers/misc/ts27010mux/Makefile | 11 - drivers/misc/ts27010mux/ts0710.h | 273 - drivers/misc/ts27010mux/ts27010_ldisc.c | 238 - drivers/misc/ts27010mux/ts27010_mux.c | 1394 --- drivers/misc/ts27010mux/ts27010_mux.h | 74 - drivers/misc/ts27010mux/ts27010_ringbuf.h | 89 - drivers/misc/ts27010mux/ts27010_tty.c | 254 - drivers/misc/uid_stat.c | 156 - drivers/misc/wl127x-rfkill.c | 121 - drivers/mmc/card/Kconfig | 9 - drivers/mmc/card/block.c | 76 +- drivers/mmc/core/Kconfig | 17 - drivers/mmc/core/Makefile | 3 +- drivers/mmc/core/core.c | 99 +- drivers/mmc/core/host.c | 7 +- drivers/mmc/core/mmc_ops.c | 11 - drivers/mmc/core/mmc_ops.h | 1 + drivers/mmc/core/quirks.c | 48 - drivers/mmc/core/sd.c | 86 +- drivers/mmc/core/sdio.c | 158 +- drivers/mmc/core/sdio_bus.c | 13 +- drivers/mmc/core/sdio_io.c | 33 - drivers/mmc/host/Kconfig | 6 - drivers/mmc/host/Makefile | 1 - drivers/mmc/host/at91_mci.c | 13 +- drivers/mmc/host/atmel-mci.c | 18 +- drivers/mmc/host/sdhci-tegra.c | 311 - drivers/mmc/host/sdhci.c | 154 +- drivers/mmc/host/sdhci.h | 84 +- drivers/mtd/devices/Kconfig | 6 - drivers/mtd/devices/Makefile | 1 - drivers/mtd/devices/tegra_nand.c | 1605 ---- drivers/mtd/devices/tegra_nand.h | 147 - drivers/mtd/nand/Kconfig | 10 +- drivers/mtd/nand/nand_base.c | 39 - drivers/net/8139cp.c | 10 +- drivers/net/Kconfig | 17 - drivers/net/Makefile | 2 - drivers/net/benet/be_cmds.c | 2 +- drivers/net/bonding/bonding.h | 4 +- drivers/net/e1000/e1000_main.c | 12 +- drivers/net/ifb.c | 2 - drivers/net/jme.c | 22 +- drivers/net/pcmcia/pcnet_cs.c | 1 - drivers/net/phy/marvell.c | 31 +- drivers/net/ppp_async.c | 25 +- drivers/net/ppp_deflate.c | 5 +- drivers/net/pppoe.c | 2 +- drivers/net/pppolac.c | 449 - drivers/net/pppopns.c | 428 - drivers/net/r6040.c | 22 +- drivers/net/r8169.c | 23 +- drivers/net/tehuti.c | 4 +- drivers/net/usb/Kconfig | 6 - drivers/net/usb/Makefile | 2 +- drivers/net/usb/cdc_ether.c | 38 - drivers/net/usb/qcusbnet/Makefile | 2 - drivers/net/usb/qcusbnet/README | 115 - drivers/net/usb/qcusbnet/qcusbnet.c | 649 -- drivers/net/usb/qcusbnet/qcusbnet.h | 24 - drivers/net/usb/qcusbnet/qmi.c | 358 - drivers/net/usb/qcusbnet/qmi.h | 58 - drivers/net/usb/qcusbnet/qmidevice.c | 1669 ---- drivers/net/usb/qcusbnet/qmidevice.h | 35 - drivers/net/usb/qcusbnet/structs.h | 95 - drivers/net/usb/usbnet.c | 11 - drivers/net/wireless/Kconfig | 1 - drivers/net/wireless/Makefile | 2 - drivers/net/wireless/bcm4329/Kconfig | 27 - drivers/net/wireless/bcm4329/Makefile | 21 - drivers/net/wireless/bcm4329/aiutils.c | 686 -- drivers/net/wireless/bcm4329/bcmpcispi.c | 630 -- drivers/net/wireless/bcm4329/bcmsdh.c | 652 -- drivers/net/wireless/bcm4329/bcmsdh_linux.c | 735 -- drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c | 1304 --- .../net/wireless/bcm4329/bcmsdh_sdmmc_linux.c | 269 - drivers/net/wireless/bcm4329/bcmsdspi.c | 1596 ---- drivers/net/wireless/bcm4329/bcmsdspi_linux.c | 252 - drivers/net/wireless/bcm4329/bcmsdstd.c | 3127 ------ drivers/net/wireless/bcm4329/bcmsdstd_linux.c | 251 - drivers/net/wireless/bcm4329/bcmspibrcm.c | 1726 ---- drivers/net/wireless/bcm4329/bcmutils.c | 1838 ---- drivers/net/wireless/bcm4329/bcmwifi.c | 199 - drivers/net/wireless/bcm4329/dhd.h | 456 - drivers/net/wireless/bcm4329/dhd_bus.h | 93 - drivers/net/wireless/bcm4329/dhd_cdc.c | 522 - drivers/net/wireless/bcm4329/dhd_common.c | 2426 ----- .../net/wireless/bcm4329/dhd_custom_gpio.c | 272 - drivers/net/wireless/bcm4329/dhd_dbg.h | 100 - drivers/net/wireless/bcm4329/dhd_linux.c | 3390 ------- .../net/wireless/bcm4329/dhd_linux_sched.c | 38 - drivers/net/wireless/bcm4329/dhd_proto.h | 102 - drivers/net/wireless/bcm4329/dhd_sdio.c | 5823 ------------ drivers/net/wireless/bcm4329/dngl_stats.h | 43 - drivers/net/wireless/bcm4329/hndpmu.c | 131 - drivers/net/wireless/bcm4329/include/Makefile | 21 - drivers/net/wireless/bcm4329/include/aidmp.h | 368 - drivers/net/wireless/bcm4329/include/bcmcdc.h | 100 - .../net/wireless/bcm4329/include/bcmdefs.h | 114 - .../net/wireless/bcm4329/include/bcmdevs.h | 124 - .../net/wireless/bcm4329/include/bcmendian.h | 205 - .../net/wireless/bcm4329/include/bcmpcispi.h | 205 - .../net/wireless/bcm4329/include/bcmperf.h | 36 - .../net/wireless/bcm4329/include/bcmsdbus.h | 117 - drivers/net/wireless/bcm4329/include/bcmsdh.h | 208 - .../wireless/bcm4329/include/bcmsdh_sdmmc.h | 122 - .../net/wireless/bcm4329/include/bcmsdpcm.h | 263 - .../net/wireless/bcm4329/include/bcmsdspi.h | 131 - .../net/wireless/bcm4329/include/bcmsdstd.h | 223 - drivers/net/wireless/bcm4329/include/bcmspi.h | 36 - .../net/wireless/bcm4329/include/bcmspibrcm.h | 134 - .../net/wireless/bcm4329/include/bcmutils.h | 637 -- .../net/wireless/bcm4329/include/bcmwifi.h | 154 - .../net/wireless/bcm4329/include/dhdioctl.h | 123 - .../net/wireless/bcm4329/include/epivers.h | 48 - drivers/net/wireless/bcm4329/include/hndpmu.h | 34 - .../wireless/bcm4329/include/hndrte_armtrap.h | 88 - .../wireless/bcm4329/include/hndrte_cons.h | 63 - drivers/net/wireless/bcm4329/include/hndsoc.h | 195 - .../net/wireless/bcm4329/include/linux_osl.h | 322 - .../net/wireless/bcm4329/include/linuxver.h | 447 - .../net/wireless/bcm4329/include/miniopt.h | 77 - .../net/wireless/bcm4329/include/msgtrace.h | 72 - drivers/net/wireless/bcm4329/include/osl.h | 55 - .../bcm4329/include/packed_section_end.h | 54 - .../bcm4329/include/packed_section_start.h | 61 - drivers/net/wireless/bcm4329/include/pcicfg.h | 52 - .../wireless/bcm4329/include/proto/802.11.h | 1433 --- .../wireless/bcm4329/include/proto/802.11e.h | 131 - .../wireless/bcm4329/include/proto/802.1d.h | 49 - .../wireless/bcm4329/include/proto/bcmeth.h | 83 - .../wireless/bcm4329/include/proto/bcmevent.h | 212 - .../wireless/bcm4329/include/proto/bcmip.h | 157 - .../wireless/bcm4329/include/proto/eapol.h | 172 - .../wireless/bcm4329/include/proto/ethernet.h | 148 - .../wireless/bcm4329/include/proto/sdspi.h | 71 - .../net/wireless/bcm4329/include/proto/vlan.h | 63 - .../net/wireless/bcm4329/include/proto/wpa.h | 159 - .../net/wireless/bcm4329/include/sbchipc.h | 1026 -- .../net/wireless/bcm4329/include/sbconfig.h | 276 - .../net/wireless/bcm4329/include/sbhnddma.h | 294 - .../net/wireless/bcm4329/include/sbpcmcia.h | 109 - drivers/net/wireless/bcm4329/include/sbsdio.h | 166 - .../net/wireless/bcm4329/include/sbsdpcmdev.h | 288 - .../net/wireless/bcm4329/include/sbsocram.h | 150 - drivers/net/wireless/bcm4329/include/sdio.h | 566 -- drivers/net/wireless/bcm4329/include/sdioh.h | 299 - .../net/wireless/bcm4329/include/sdiovar.h | 58 - .../net/wireless/bcm4329/include/siutils.h | 235 - drivers/net/wireless/bcm4329/include/spid.h | 153 - drivers/net/wireless/bcm4329/include/trxhdr.h | 46 - .../net/wireless/bcm4329/include/typedefs.h | 303 - .../net/wireless/bcm4329/include/wlioctl.h | 1673 ---- drivers/net/wireless/bcm4329/linux_osl.c | 624 -- drivers/net/wireless/bcm4329/miniopt.c | 163 - drivers/net/wireless/bcm4329/sbutils.c | 1004 -- drivers/net/wireless/bcm4329/siutils.c | 1527 --- drivers/net/wireless/bcm4329/siutils_priv.h | 213 - drivers/net/wireless/bcm4329/wl_iw.c | 8441 ----------------- drivers/net/wireless/bcm4329/wl_iw.h | 306 - drivers/net/xen-netfront.c | 4 +- drivers/oprofile/timer_int.c | 13 - drivers/pci/dmar.c | 5 - drivers/pci/pci-sysfs.c | 22 +- drivers/pci/pci.h | 7 +- drivers/pci/proc.c | 2 +- drivers/pci/quirks.c | 23 - drivers/pcmcia/soc_common.c | 1 - drivers/platform/x86/asus-laptop.c | 6 +- drivers/platform/x86/intel_ips.c | 36 +- drivers/platform/x86/intel_ips.h | 21 - drivers/platform/x86/wmi.c | 2 +- drivers/pnp/pnpacpi/core.c | 29 +- drivers/power/Kconfig | 12 - drivers/power/Makefile | 2 - drivers/power/bq24617_charger.c | 308 - drivers/power/ds2781_battery.c | 554 -- drivers/power/olpc_battery.c | 8 +- drivers/power/power_supply_core.c | 29 +- drivers/regulator/Kconfig | 6 - drivers/regulator/Makefile | 1 - drivers/regulator/cpcap-regulator.c | 603 -- drivers/regulator/max8649.c | 103 +- drivers/regulator/tps6586x-regulator.c | 33 +- drivers/rtc/Kconfig | 39 - drivers/rtc/Makefile | 4 - drivers/rtc/alarm-dev.c | 286 - drivers/rtc/alarm.c | 590 -- drivers/rtc/class.c | 13 +- drivers/rtc/rtc-cpcap.c | 483 - drivers/rtc/rtc-rs5c372.c | 2 +- drivers/rtc/rtc-tps6586x.c | 325 - drivers/scsi/gdth.c | 8 - drivers/scsi/libsas/sas_ata.c | 1 - drivers/scsi/pmcraid.h | 1 + drivers/scsi/qla2xxx/qla_gbl.h | 1 - drivers/scsi/qla2xxx/qla_init.c | 5 +- drivers/scsi/qla2xxx/qla_iocb.c | 1 - drivers/scsi/qla2xxx/qla_nx.c | 1 - drivers/scsi/qla2xxx/qla_os.c | 6 - drivers/scsi/qla4xxx/ql4_nx.c | 1 - drivers/scsi/scsi_lib.c | 6 +- drivers/scsi/scsi_sysfs.c | 3 +- drivers/scsi/sd.c | 15 +- drivers/serial/Kconfig | 8 - drivers/serial/Makefile | 1 - drivers/serial/mfd.c | 18 +- drivers/serial/serial_core.c | 3 - drivers/serial/tegra_hsuart.c | 1393 --- drivers/spi/Kconfig | 7 - drivers/spi/Makefile | 1 - drivers/spi/spi_tegra.c | 676 -- drivers/ssb/b43_pci_bridge.c | 1 - drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/android/Kconfig | 95 - drivers/staging/android/Makefile | 6 - drivers/staging/android/binder.c | 3600 ------- drivers/staging/android/binder.h | 330 - drivers/staging/android/logger.c | 616 -- drivers/staging/android/logger.h | 49 - drivers/staging/android/lowmemorykiller.c | 213 - drivers/staging/android/ram_console.c | 418 - drivers/staging/android/timed_gpio.c | 176 - drivers/staging/android/timed_gpio.h | 33 - drivers/staging/android/timed_output.c | 123 - drivers/staging/android/timed_output.h | 37 - drivers/staging/asus_oled/asus_oled.c | 8 +- drivers/staging/batman-adv/soft-interface.c | 4 - drivers/staging/cx25821/cx25821-video.c | 8 +- drivers/staging/cx25821/cx25821-video.h | 2 +- drivers/staging/frontier/tranzport.c | 2 +- drivers/staging/iio/accel/adis16220_core.c | 2 +- drivers/staging/line6/control.c | 204 +- drivers/staging/line6/midi.c | 4 +- drivers/staging/line6/pod.c | 32 +- drivers/staging/line6/toneport.c | 4 +- drivers/staging/line6/variax.c | 12 +- drivers/staging/phison/phison.c | 2 +- drivers/staging/rt2860/usb_main_dev.c | 2 - drivers/staging/rtl8187se/r8185b_init.c | 30 +- .../staging/samsung-laptop/samsung-laptop.c | 2 +- drivers/staging/udlfb/udlfb.c | 2 +- drivers/staging/usbip/usbip_event.c | 16 +- drivers/staging/usbip/vhci_hcd.c | 2 - drivers/switch/Kconfig | 15 - drivers/switch/Makefile | 4 - drivers/switch/switch_class.c | 174 - drivers/switch/switch_gpio.c | 172 - drivers/usb/atm/ueagle-atm.c | 7 +- drivers/usb/core/devio.c | 7 +- drivers/usb/core/driver.c | 14 - drivers/usb/core/hcd.c | 21 +- drivers/usb/core/hub.c | 9 +- drivers/usb/core/message.c | 14 +- drivers/usb/gadget/Kconfig | 57 +- drivers/usb/gadget/Makefile | 11 +- drivers/usb/gadget/android.c | 528 -- drivers/usb/gadget/atmel_usba_udc.c | 3 - drivers/usb/gadget/composite.c | 243 +- drivers/usb/gadget/f_accessory.c | 808 -- drivers/usb/gadget/f_acm.c | 76 +- drivers/usb/gadget/f_adb.c | 655 -- drivers/usb/gadget/f_mass_storage.c | 79 - drivers/usb/gadget/f_mtp.c | 1269 --- drivers/usb/gadget/f_rndis.c | 104 +- drivers/usb/gadget/fsl_tegra_udc.c | 116 - drivers/usb/gadget/fsl_udc_core.c | 457 +- drivers/usb/gadget/fsl_usb2_udc.h | 29 +- drivers/usb/gadget/g_ffs.c | 4 +- drivers/usb/gadget/multi.c | 4 +- drivers/usb/gadget/rndis.c | 23 +- drivers/usb/gadget/storage_common.c | 6 - drivers/usb/gadget/u_ether.c | 1 + drivers/usb/gadget/u_ether.h | 2 +- drivers/usb/gadget/u_serial.c | 2 +- drivers/usb/host/Kconfig | 8 - drivers/usb/host/ehci-dbg.c | 2 +- drivers/usb/host/ehci-hcd.c | 15 +- drivers/usb/host/ehci-hub.c | 1 - drivers/usb/host/ehci-pci.c | 12 - drivers/usb/host/ehci-q.c | 2 - drivers/usb/host/ehci-sched.c | 14 +- drivers/usb/host/ehci-tegra.c | 728 -- drivers/usb/host/ehci.h | 2 - drivers/usb/host/ohci-jz4740.c | 2 +- drivers/usb/host/r8a66597.h | 2 +- drivers/usb/host/xhci-hub.c | 7 - drivers/usb/host/xhci-mem.c | 173 +- drivers/usb/host/xhci-ring.c | 1 + drivers/usb/host/xhci.c | 18 - drivers/usb/host/xhci.h | 32 - drivers/usb/misc/Kconfig | 7 - drivers/usb/misc/Makefile | 1 - drivers/usb/misc/cypress_cy7c63.c | 6 +- drivers/usb/misc/iowarrior.c | 1 - drivers/usb/misc/oob_wake.c | 289 - drivers/usb/misc/sisusbvga/sisusb.c | 1 - drivers/usb/misc/trancevibrator.c | 2 +- drivers/usb/misc/usbled.c | 2 +- drivers/usb/misc/usbsevseg.c | 10 +- drivers/usb/misc/uss720.c | 4 +- drivers/usb/musb/blackfin.c | 7 +- drivers/usb/musb/davinci.c | 2 - drivers/usb/musb/musb_core.c | 5 + drivers/usb/musb/omap2430.c | 1 - drivers/usb/musb/tusb6010.c | 4 - drivers/usb/otg/Kconfig | 26 - drivers/usb/otg/Makefile | 3 - drivers/usb/otg/cpcap-otg.c | 324 - drivers/usb/otg/tegra-otg.c | 393 - drivers/usb/otg/ulpi_viewport.c | 80 - drivers/usb/serial/Kconfig | 14 - drivers/usb/serial/Makefile | 2 - drivers/usb/serial/cp210x.c | 2 - drivers/usb/serial/ftdi_sio.c | 44 +- drivers/usb/serial/ftdi_sio_ids.h | 55 +- drivers/usb/serial/mct_u232.c | 7 +- drivers/usb/serial/mdm6600.c | 1022 -- drivers/usb/serial/moto_flashmdm.c | 143 - drivers/usb/serial/opticon.c | 6 +- drivers/usb/serial/option.c | 25 +- drivers/usb/serial/usb-serial.c | 3 - drivers/usb/serial/visor.c | 11 +- drivers/usb/storage/sierra_ms.c | 2 +- drivers/usb/storage/unusual_devs.h | 7 - drivers/video/Kconfig | 1 - drivers/video/Makefile | 1 - drivers/video/backlight/backlight.c | 12 +- drivers/video/fbmon.c | 93 - drivers/video/modedb.c | 455 +- drivers/video/tegra/Kconfig | 74 - drivers/video/tegra/Makefile | 4 - drivers/video/tegra/dc/Makefile | 5 - drivers/video/tegra/dc/dc.c | 1447 --- drivers/video/tegra/dc/dc_priv.h | 144 - drivers/video/tegra/dc/dc_reg.h | 423 - drivers/video/tegra/dc/edid.c | 278 - drivers/video/tegra/dc/edid.h | 31 - drivers/video/tegra/dc/hdmi.c | 1167 --- drivers/video/tegra/dc/hdmi.h | 189 - drivers/video/tegra/dc/hdmi_reg.h | 448 - drivers/video/tegra/dc/nvhdcp.c | 1246 --- drivers/video/tegra/dc/nvhdcp.h | 29 - drivers/video/tegra/dc/rgb.c | 92 - drivers/video/tegra/fb.c | 838 -- drivers/video/tegra/host/Makefile | 13 - drivers/video/tegra/host/bus.c | 571 -- drivers/video/tegra/host/debug.c | 351 - drivers/video/tegra/host/dev.c | 828 -- drivers/video/tegra/host/dev.h | 53 - drivers/video/tegra/host/nvhost_3dctx.c | 543 -- drivers/video/tegra/host/nvhost_acm.c | 219 - drivers/video/tegra/host/nvhost_acm.h | 76 - drivers/video/tegra/host/nvhost_cdma.c | 648 -- drivers/video/tegra/host/nvhost_cdma.h | 103 - drivers/video/tegra/host/nvhost_channel.c | 250 - drivers/video/tegra/host/nvhost_channel.h | 90 - drivers/video/tegra/host/nvhost_cpuaccess.c | 117 - drivers/video/tegra/host/nvhost_cpuaccess.h | 71 - drivers/video/tegra/host/nvhost_hardware.h | 239 - drivers/video/tegra/host/nvhost_hwctx.h | 88 - drivers/video/tegra/host/nvhost_intr.c | 477 - drivers/video/tegra/host/nvhost_intr.h | 102 - drivers/video/tegra/host/nvhost_mpectx.c | 23 - drivers/video/tegra/host/nvhost_syncpt.c | 316 - drivers/video/tegra/host/nvhost_syncpt.h | 156 - drivers/video/tegra/nvmap/Makefile | 6 - drivers/video/tegra/nvmap/nvmap.c | 776 -- drivers/video/tegra/nvmap/nvmap.h | 238 - drivers/video/tegra/nvmap/nvmap_dev.c | 1278 --- drivers/video/tegra/nvmap/nvmap_handle.c | 518 - drivers/video/tegra/nvmap/nvmap_heap.c | 812 -- drivers/video/tegra/nvmap/nvmap_heap.h | 64 - drivers/video/tegra/nvmap/nvmap_ioctl.c | 630 -- drivers/video/tegra/nvmap/nvmap_ioctl.h | 159 - drivers/video/tegra/nvmap/nvmap_mru.c | 194 - drivers/video/tegra/nvmap/nvmap_mru.h | 84 - drivers/video/via/accel.c | 7 +- drivers/video/via/via_i2c.c | 27 +- drivers/w1/masters/Kconfig | 7 - drivers/w1/masters/Makefile | 1 - drivers/w1/masters/tegra_w1.c | 500 - drivers/w1/slaves/Kconfig | 13 - drivers/w1/slaves/Makefile | 1 - drivers/w1/slaves/w1_ds2781.c | 218 - drivers/w1/slaves/w1_ds2781.h | 105 - drivers/w1/w1.c | 8 +- drivers/w1/w1_family.h | 2 - drivers/watchdog/Kconfig | 17 - drivers/watchdog/Makefile | 1 - drivers/watchdog/rdc321x_wdt.c | 2 +- drivers/watchdog/tegra_wdt.c | 376 - drivers/xen/events.c | 2 +- firmware/Makefile | 1 - firmware/cpcap/firmware_0_2x.HEX | 55 - firmware/cpcap/firmware_1_2x.H16 | 3 - fs/Kconfig | 4 - fs/Makefile | 3 - fs/bio.c | 23 +- fs/cifs/cifsproto.h | 3 +- fs/cifs/dir.c | 12 +- fs/cifs/dns_resolve.c | 2 +- fs/cifs/file.c | 4 +- fs/cifs/inode.c | 12 +- fs/compat.c | 28 +- fs/ecryptfs/inode.c | 11 +- fs/eventpoll.c | 35 +- fs/exec.c | 41 +- fs/ext4/super.c | 61 +- fs/fat/dir.c | 9 - fs/fat/fat.h | 1 - fs/fat/inode.c | 9 - fs/fs-writeback.c | 2 +- fs/fuse/file.c | 82 +- fs/hostfs/hostfs.h | 3 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hostfs/hostfs_user.c | 9 +- fs/nfs/direct.c | 2 +- fs/nfs/file.c | 19 +- fs/nfs/mount_clnt.c | 4 +- fs/nfs/nfs4proc.c | 9 +- fs/nfs/nfs4state.c | 16 +- fs/nfs/pagelist.c | 8 +- fs/nfsd/nfs3xdr.c | 6 +- fs/nfsd/xdr4.h | 21 +- fs/notify/inotify/inotify_user.c | 1 - fs/partitions/Kconfig | 6 - fs/partitions/Makefile | 1 - fs/partitions/check.c | 31 - fs/partitions/check.h | 20 +- fs/partitions/cmdline.c | 194 - fs/partitions/cmdline.h | 23 - fs/partitions/efi.c | 23 +- fs/pipe.c | 16 +- fs/proc/base.c | 40 +- fs/reiserfs/ioctl.c | 7 +- fs/reiserfs/xattr_acl.c | 6 +- fs/select.c | 6 +- fs/splice.c | 24 +- fs/yaffs2/Kconfig | 180 - fs/yaffs2/Makefile | 10 - fs/yaffs2/devextras.h | 196 - fs/yaffs2/moduleconfig.h | 82 - fs/yaffs2/yaffs_checkptrw.c | 401 - fs/yaffs2/yaffs_checkptrw.h | 34 - fs/yaffs2/yaffs_ecc.c | 323 - fs/yaffs2/yaffs_ecc.h | 44 - fs/yaffs2/yaffs_fs.c | 3279 ------- fs/yaffs2/yaffs_getblockinfo.h | 35 - fs/yaffs2/yaffs_guts.c | 8237 ---------------- fs/yaffs2/yaffs_guts.h | 919 -- fs/yaffs2/yaffs_linux.h | 42 - fs/yaffs2/yaffs_mtdif.c | 56 - fs/yaffs2/yaffs_mtdif.h | 27 - fs/yaffs2/yaffs_mtdif1.c | 361 - fs/yaffs2/yaffs_mtdif1.h | 28 - fs/yaffs2/yaffs_mtdif2.c | 257 - fs/yaffs2/yaffs_mtdif2.h | 29 - fs/yaffs2/yaffs_nand.c | 140 - fs/yaffs2/yaffs_nand.h | 44 - fs/yaffs2/yaffs_nandemul2k.h | 39 - fs/yaffs2/yaffs_packedtags1.c | 50 - fs/yaffs2/yaffs_packedtags1.h | 37 - fs/yaffs2/yaffs_packedtags2.c | 198 - fs/yaffs2/yaffs_packedtags2.h | 43 - fs/yaffs2/yaffs_qsort.c | 163 - fs/yaffs2/yaffs_qsort.h | 23 - fs/yaffs2/yaffs_tagscompat.c | 539 -- fs/yaffs2/yaffs_tagscompat.h | 39 - fs/yaffs2/yaffs_tagsvalidity.c | 28 - fs/yaffs2/yaffs_tagsvalidity.h | 24 - fs/yaffs2/yaffs_trace.h | 60 - fs/yaffs2/yaffsinterface.h | 21 - fs/yaffs2/yportenv.h | 169 - include/linux/akm8975.h | 71 - include/linux/amba/mmci.h | 12 - include/linux/android_aid.h | 26 - include/linux/android_alarm.h | 106 - include/linux/android_pmem.h | 93 - include/linux/ashmem.h | 48 - include/linux/binfmts.h | 5 - include/linux/blkdev.h | 13 +- include/linux/bootmem.h | 2 - include/linux/cap_prox.h | 58 - include/linux/cgroup.h | 13 +- include/linux/cpcap_audio.h | 76 - include/linux/cpuacct.h | 43 - include/linux/cpufreq.h | 3 - include/linux/earlysuspend.h | 56 - include/linux/fb.h | 6 - include/linux/fsl_devices.h | 1 - include/linux/genhd.h | 3 - include/linux/gfp.h | 4 +- include/linux/gpio_event.h | 169 - include/linux/gps-gpio-brcm4750.h | 51 - include/linux/i2c-tegra.h | 34 - include/linux/i2c/panjit_ts.h | 30 - include/linux/if_pppolac.h | 35 - include/linux/if_pppopns.h | 34 - include/linux/if_pppox.h | 26 +- include/linux/kernel_debugger.h | 41 - include/linux/keychord.h | 52 - include/linux/keyreset.h | 28 - include/linux/kfifo.h | 7 +- include/linux/led-lm3559.h | 40 - include/linux/leds-auo-panel-backlight.h | 40 - include/linux/leds-ld-cpcap.h | 41 - include/linux/leds-lp8550.h | 43 - include/linux/max9635.h | 41 - include/linux/mfd/tps6586x.h | 35 - include/linux/mfd/wm8994/pdata.h | 2 +- include/linux/mm.h | 1 - include/linux/mmc/card.h | 93 - include/linux/mmc/core.h | 1 - include/linux/mmc/host.h | 34 - include/linux/mmc/pm.h | 1 - include/linux/mmc/sdio_func.h | 10 - include/linux/moto_bmp085.h | 46 - include/linux/msdos_fs.h | 12 - include/linux/nct1008.h | 40 - include/linux/netfilter.h | 2 +- include/linux/pci_ids.h | 1 - include/linux/percpu_counter.h | 10 - include/linux/perf_event.h | 1 - include/linux/pipe_fs_i.h | 1 - include/linux/platform_data/tegra_usb.h | 31 - include/linux/pm_runtime.h | 3 +- include/linux/poll.h | 2 - include/linux/power_supply.h | 4 - include/linux/qtouch_obp_ts.h | 547 -- include/linux/radio_ctrl/mdm6600_ctrl.h | 60 - include/linux/radio_ctrl/radio_class.h | 37 - include/linux/radio_ctrl/wrigley_ctrl.h | 26 - include/linux/radix-tree.h | 36 +- include/linux/sched.h | 6 +- include/linux/serial_core.h | 1 - include/linux/socket.h | 2 +- include/linux/sockios.h | 1 - include/linux/spi/cpcap-regbits.h | 952 -- include/linux/spi/cpcap.h | 801 -- include/linux/switch.h | 53 - include/linux/synaptics_i2c_rmi.h | 55 - include/linux/tegra_audio.h | 57 - include/linux/tegra_avp.h | 41 - include/linux/tegra_rpc.h | 47 - include/linux/tegra_sema.h | 34 - include/linux/tegra_spdif.h | 56 - include/linux/tty.h | 1 - include/linux/uid_stat.h | 29 - include/linux/usb.h | 1 - include/linux/usb/android_composite.h | 106 - include/linux/usb/composite.h | 23 - include/linux/usb/ehci_def.h | 4 +- include/linux/usb/f_accessory.h | 81 - include/linux/usb/f_mtp.h | 53 - include/linux/usb/hcd.h | 16 - include/linux/usb/oob_wake.h | 30 - include/linux/usb/ulpi.h | 5 - include/linux/wakelock.h | 91 - include/linux/wifi_tiwlan.h | 27 - include/linux/wl127x-rfkill.h | 35 - include/linux/wlan_plat.h | 27 - include/media/dw9714l.h | 54 - include/media/ov5650.h | 80 - include/media/saa7146.h | 2 +- include/media/soc2030.h | 100 - include/media/tegra_camera.h | 38 - include/net/activity_stats.h | 25 - include/net/af_unix.h | 2 - include/net/bluetooth/bluetooth.h | 6 - include/net/bluetooth/hci.h | 13 +- include/net/bluetooth/hci_core.h | 12 +- include/net/bluetooth/l2cap.h | 3 - include/net/bluetooth/rfcomm.h | 2 + include/net/bluetooth/sco.h | 4 +- include/net/mac80211.h | 16 - include/net/sock.h | 4 +- include/net/tcp.h | 2 - include/video/nvhdcp.h | 91 - include/video/tegrafb.h | 98 - include/xen/interface/io/ring.h | 11 +- init/Kconfig | 15 - ipc/compat.c | 6 - ipc/compat_mq.c | 5 - ipc/shm.c | 1 - kernel/cgroup.c | 193 +- kernel/cgroup_freezer.c | 8 - kernel/cpuset.c | 7 - kernel/exit.c | 17 - kernel/fork.c | 17 - kernel/futex.c | 31 +- kernel/irq/pm.c | 6 +- kernel/irq/proc.c | 2 +- kernel/latencytop.c | 17 +- kernel/panic.c | 5 +- kernel/perf_event.c | 30 +- kernel/pm_qos_params.c | 4 +- kernel/power/Kconfig | 67 - kernel/power/Makefile | 5 - kernel/power/consoleearlysuspend.c | 78 - kernel/power/earlysuspend.c | 178 - kernel/power/fbearlysuspend.c | 153 - kernel/power/hibernate.c | 22 +- kernel/power/main.c | 20 - kernel/power/power.h | 24 - kernel/power/process.c | 27 +- kernel/power/suspend.c | 8 +- kernel/power/user.c | 4 +- kernel/power/userwakelock.c | 219 - kernel/power/wakelock.c | 607 -- kernel/printk.c | 73 +- kernel/sched.c | 279 +- kernel/sched_fair.c | 20 +- kernel/sysctl.c | 8 - kernel/timer.c | 8 +- kernel/trace/trace.c | 10 +- kernel/user.c | 1 - kernel/watchdog.c | 3 +- lib/Kconfig.debug | 3 +- lib/percpu_counter.c | 1 - lib/radix-tree.c | 83 +- mm/Makefile | 1 - mm/ashmem.c | 743 -- mm/filemap.c | 29 +- mm/hugetlb.c | 8 +- mm/internal.h | 2 +- mm/memblock.c | 4 - mm/memcontrol.c | 62 +- mm/memory_hotplug.c | 2 +- mm/mempolicy.c | 2 +- mm/mmap.c | 16 +- mm/mprotect.c | 2 +- mm/nommu.c | 1 - mm/page_alloc.c | 40 +- mm/shmem.c | 14 +- mm/vmalloc.c | 9 - net/8021q/vlan_core.c | 3 - net/Kconfig | 16 +- net/Makefile | 1 - net/activity_stats.c | 115 - net/ax25/af_ax25.c | 2 +- net/bluetooth/af_bluetooth.c | 38 - net/bluetooth/hci_conn.c | 60 +- net/bluetooth/hci_core.c | 10 +- net/bluetooth/hci_event.c | 7 +- net/bluetooth/l2cap.c | 74 +- net/bluetooth/rfcomm/core.c | 55 + net/bluetooth/sco.c | 55 +- net/bridge/br_multicast.c | 2 +- net/can/bcm.c | 2 +- net/compat.c | 10 +- net/core/dev.c | 16 +- net/core/dst.c | 1 - net/core/filter.c | 83 +- net/core/iovec.c | 20 +- net/core/timestamping.c | 6 +- net/decnet/af_decnet.c | 2 - net/econet/af_econet.c | 99 +- net/ipv4/Makefile | 1 - net/ipv4/af_inet.c | 18 - net/ipv4/devinet.c | 8 +- net/ipv4/sysfs_net_ipv4.c | 88 - net/ipv4/tcp.c | 113 +- net/ipv4/tcp_ipv4.c | 8 +- net/ipv4/tcp_output.c | 42 +- net/ipv6/af_inet6.c | 34 - net/irda/iriap.c | 3 +- net/irda/parameters.c | 4 +- net/l2tp/l2tp_eth.c | 2 +- net/l2tp/l2tp_ip.c | 6 +- net/llc/af_llc.c | 5 +- net/mac80211/cfg.c | 5 +- net/mac80211/ibss.c | 1 - net/mac80211/ieee80211_i.h | 2 - net/mac80211/main.c | 3 +- net/mac80211/mesh_plink.c | 17 +- net/mac80211/mlme.c | 48 +- net/mac80211/offchannel.c | 7 - net/mac80211/rate.c | 3 - net/mac80211/rc80211_minstrel_ht.c | 7 +- net/mac80211/rx.c | 5 +- net/mac80211/status.c | 1 - net/mac80211/tx.c | 21 +- net/netfilter/nf_conntrack_core.c | 3 +- net/netfilter/xt_SECMARK.c | 2 +- net/packet/af_packet.c | 7 +- net/rds/rdma.c | 2 +- net/rfkill/Kconfig | 5 - net/rfkill/core.c | 4 - net/sched/cls_cgroup.c | 2 + net/socket.c | 11 +- net/sunrpc/clnt.c | 2 +- net/sunrpc/svc_xprt.c | 9 +- net/unix/af_unix.c | 37 +- net/unix/garbage.c | 9 +- net/wireless/chan.c | 51 - net/wireless/nl80211.c | 11 +- net/wireless/reg.c | 2 +- net/wireless/scan.c | 12 +- net/x25/x25_facilities.c | 20 +- net/x25/x25_in.c | 2 - net/x25/x25_link.c | 1 - scripts/kconfig/conf.c | 2 +- security/commoncap.c | 10 - security/integrity/ima/ima_policy.c | 2 - sound/core/oss/mixer_oss.c | 12 +- sound/core/oss/pcm_oss.c | 19 +- sound/oss/soundcard.c | 4 +- sound/pci/hda/hda_codec.c | 8 +- sound/pci/hda/hda_codec.h | 1 - sound/pci/hda/hda_eld.c | 20 +- sound/pci/hda/hda_intel.c | 27 +- sound/pci/hda/patch_analog.c | 7 - sound/pci/hda/patch_ca0110.c | 2 +- sound/pci/hda/patch_conexant.c | 5 +- sound/pci/hda/patch_hdmi.c | 1 + sound/pci/hda/patch_realtek.c | 52 +- sound/pci/hda/patch_sigmatel.c | 16 - sound/pci/intel8x0.c | 6 - sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8900.c | 6 + sound/soc/codecs/wm8904.c | 3 +- sound/soc/codecs/wm8955.c | 3 +- sound/soc/codecs/wm8960.c | 3 +- sound/soc/codecs/wm8961.c | 4 +- sound/soc/codecs/wm_hubs.c | 2 +- 1178 files changed, 3991 insertions(+), 195677 deletions(-) delete mode 100644 Documentation/android.txt delete mode 100644 arch/arm/common/fiq_debugger.c delete mode 100644 arch/arm/common/fiq_debugger_ringbuf.h delete mode 100644 arch/arm/common/fiq_glue.S delete mode 100644 arch/arm/common/fiq_glue_setup.c delete mode 100644 arch/arm/configs/olympus_defconfig delete mode 100644 arch/arm/configs/stingray_defconfig delete mode 100644 arch/arm/configs/tegra_android_defconfig delete mode 100644 arch/arm/configs/tegra_defconfig delete mode 100644 arch/arm/include/asm/fiq_debugger.h delete mode 100644 arch/arm/include/asm/fiq_glue.h delete mode 100644 arch/arm/include/asm/mach/mmc.h delete mode 100644 arch/arm/mach-tegra/apbio.c delete mode 100644 arch/arm/mach-tegra/apbio.h delete mode 100644 arch/arm/mach-tegra/arb_sema.c delete mode 100644 arch/arm/mach-tegra/board-harmony-panel.c delete mode 100644 arch/arm/mach-tegra/board-harmony-sdhci.c delete mode 100644 arch/arm/mach-tegra/board-olympus-i2c.c delete mode 100644 arch/arm/mach-tegra/board-olympus-keypad.c delete mode 100644 arch/arm/mach-tegra/board-olympus-panel.c delete mode 100644 arch/arm/mach-tegra/board-olympus-pinmux.c delete mode 100644 arch/arm/mach-tegra/board-olympus-wifi.c delete mode 100644 arch/arm/mach-tegra/board-olympus.c delete mode 100644 arch/arm/mach-tegra/board-olympus.h delete mode 100644 arch/arm/mach-tegra/board-stingray-bluetooth.c delete mode 100644 arch/arm/mach-tegra/board-stingray-bootinfo.c delete mode 100755 arch/arm/mach-tegra/board-stingray-gps.c delete mode 100644 arch/arm/mach-tegra/board-stingray-keypad.c delete mode 100644 arch/arm/mach-tegra/board-stingray-memory.c delete mode 100644 arch/arm/mach-tegra/board-stingray-panel.c delete mode 100755 arch/arm/mach-tegra/board-stingray-pinmux.c delete mode 100644 arch/arm/mach-tegra/board-stingray-power.c delete mode 100755 arch/arm/mach-tegra/board-stingray-sensors.c delete mode 100644 arch/arm/mach-tegra/board-stingray-touch.c delete mode 100644 arch/arm/mach-tegra/board-stingray-usbnet.c delete mode 100644 arch/arm/mach-tegra/board-stingray-wifi.c delete mode 100644 arch/arm/mach-tegra/board-stingray-wlan_nvs.c delete mode 100644 arch/arm/mach-tegra/board-stingray.c delete mode 100644 arch/arm/mach-tegra/board-stingray.h delete mode 100644 arch/arm/mach-tegra/board-ventana-panel.c delete mode 100644 arch/arm/mach-tegra/board-ventana-pinmux.c delete mode 100644 arch/arm/mach-tegra/board-ventana-power.c delete mode 100644 arch/arm/mach-tegra/board-ventana-sdhci.c delete mode 100644 arch/arm/mach-tegra/board-ventana.c delete mode 100644 arch/arm/mach-tegra/board-ventana.h delete mode 100644 arch/arm/mach-tegra/cortex-a9.S delete mode 100644 arch/arm/mach-tegra/cpu-tegra.c delete mode 100644 arch/arm/mach-tegra/cpuidle.c delete mode 100644 arch/arm/mach-tegra/delay.S delete mode 100644 arch/arm/mach-tegra/devices.c delete mode 100644 arch/arm/mach-tegra/devices.h delete mode 100644 arch/arm/mach-tegra/dma.c delete mode 100644 arch/arm/mach-tegra/dvfs.c delete mode 100644 arch/arm/mach-tegra/dvfs.h delete mode 100644 arch/arm/mach-tegra/fiq.c delete mode 100644 arch/arm/mach-tegra/fuse.c delete mode 100644 arch/arm/mach-tegra/fuse.h delete mode 100644 arch/arm/mach-tegra/headsmp-t2.S create mode 100644 arch/arm/mach-tegra/headsmp.S create mode 100644 arch/arm/mach-tegra/hotplug.c delete mode 100644 arch/arm/mach-tegra/include/mach/arb_sema.h delete mode 100644 arch/arm/mach-tegra/include/mach/audio.h delete mode 100644 arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h delete mode 100644 arch/arm/mach-tegra/include/mach/cpcap_audio.h delete mode 100644 arch/arm/mach-tegra/include/mach/dc.h delete mode 100644 arch/arm/mach-tegra/include/mach/delay.h delete mode 100644 arch/arm/mach-tegra/include/mach/dma.h delete mode 100644 arch/arm/mach-tegra/include/mach/fb.h delete mode 100644 arch/arm/mach-tegra/include/mach/fiq.h delete mode 100644 arch/arm/mach-tegra/include/mach/i2s.h delete mode 100644 arch/arm/mach-tegra/include/mach/iovmm.h delete mode 100644 arch/arm/mach-tegra/include/mach/kfuse.h delete mode 100644 arch/arm/mach-tegra/include/mach/legacy_irq.h delete mode 100644 arch/arm/mach-tegra/include/mach/mc.h delete mode 100644 arch/arm/mach-tegra/include/mach/nand.h delete mode 100644 arch/arm/mach-tegra/include/mach/nvhost.h delete mode 100644 arch/arm/mach-tegra/include/mach/nvmap.h delete mode 100644 arch/arm/mach-tegra/include/mach/pinmux-t2.h delete mode 100644 arch/arm/mach-tegra/include/mach/powergate.h delete mode 100644 arch/arm/mach-tegra/include/mach/sdhci.h delete mode 100644 arch/arm/mach-tegra/include/mach/spdif.h delete mode 100644 arch/arm/mach-tegra/include/mach/suspend.h delete mode 100644 arch/arm/mach-tegra/include/mach/tegra2_fuse.h delete mode 100644 arch/arm/mach-tegra/include/mach/tegra_fb.h delete mode 100644 arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h delete mode 100644 arch/arm/mach-tegra/include/mach/tegra_hsuart.h delete mode 100644 arch/arm/mach-tegra/include/mach/usb_phy.h delete mode 100644 arch/arm/mach-tegra/include/mach/w1.h delete mode 100644 arch/arm/mach-tegra/iovmm-gart.c delete mode 100644 arch/arm/mach-tegra/iovmm.c delete mode 100644 arch/arm/mach-tegra/kfuse.c delete mode 100644 arch/arm/mach-tegra/legacy_irq.c delete mode 100644 arch/arm/mach-tegra/mc.c delete mode 100644 arch/arm/mach-tegra/pinmux-t2-tables.c delete mode 100644 arch/arm/mach-tegra/power-macros.S delete mode 100644 arch/arm/mach-tegra/power.h delete mode 100644 arch/arm/mach-tegra/powergate.c delete mode 100644 arch/arm/mach-tegra/pwm.c delete mode 100644 arch/arm/mach-tegra/suspend-t2.c delete mode 100644 arch/arm/mach-tegra/suspend.c delete mode 100644 arch/arm/mach-tegra/syncpt.c delete mode 100644 arch/arm/mach-tegra/tegra2_dvfs.c delete mode 100644 arch/arm/mach-tegra/tegra2_emc.c delete mode 100644 arch/arm/mach-tegra/tegra2_emc.h delete mode 100644 arch/arm/mach-tegra/tegra2_fuse.c delete mode 100644 arch/arm/mach-tegra/tegra2_save.S delete mode 100644 arch/arm/mach-tegra/tegra_fiq_debugger.c delete mode 100644 arch/arm/mach-tegra/tegra_i2s_audio.c delete mode 100644 arch/arm/mach-tegra/tegra_spdif_audio.c delete mode 100644 arch/arm/mach-tegra/usb_phy.c delete mode 100644 arch/arm/mach-tegra/wakeups-t2.h create mode 100644 arch/sparc/prom/devops_32.c create mode 100644 arch/sparc/prom/devops_64.c delete mode 100644 drivers/char/dcc_tty.c delete mode 100644 drivers/cpufreq/cpufreq_interactive.c delete mode 100644 drivers/crypto/tegra-aes.c delete mode 100644 drivers/crypto/tegra-aes.h delete mode 100644 drivers/hid/hid-motorola.c delete mode 100755 drivers/i2c/busses/i2c-tegra.c delete mode 100644 drivers/input/keyreset.c delete mode 100644 drivers/input/misc/gpio_axis.c delete mode 100644 drivers/input/misc/gpio_event.c delete mode 100644 drivers/input/misc/gpio_input.c delete mode 100644 drivers/input/misc/gpio_matrix.c delete mode 100644 drivers/input/misc/gpio_output.c delete mode 100644 drivers/input/misc/keychord.c delete mode 100644 drivers/input/touchscreen/panjit_i2c.c delete mode 100644 drivers/input/touchscreen/qtouch_obp_ts.c delete mode 100644 drivers/input/touchscreen/synaptics_i2c_rmi.c delete mode 100644 drivers/leds/led-lm3559.c delete mode 100755 drivers/leds/leds-auo-panel-backlight.c delete mode 100755 drivers/leds/leds-ld-cpcap.c delete mode 100755 drivers/leds/leds-lp8550.c delete mode 100644 drivers/leds/ledtrig-sleep.c delete mode 100644 drivers/media/video/tegra/Kconfig delete mode 100644 drivers/media/video/tegra/Makefile delete mode 100644 drivers/media/video/tegra/avp/Kconfig delete mode 100644 drivers/media/video/tegra/avp/Makefile delete mode 100644 drivers/media/video/tegra/avp/avp.c delete mode 100644 drivers/media/video/tegra/avp/avp.h delete mode 100644 drivers/media/video/tegra/avp/avp_msg.h delete mode 100644 drivers/media/video/tegra/avp/avp_svc.c delete mode 100644 drivers/media/video/tegra/avp/headavp.S delete mode 100644 drivers/media/video/tegra/avp/headavp.h delete mode 100644 drivers/media/video/tegra/avp/tegra_rpc.c delete mode 100644 drivers/media/video/tegra/avp/trpc.h delete mode 100644 drivers/media/video/tegra/avp/trpc_local.c delete mode 100644 drivers/media/video/tegra/avp/trpc_sema.c delete mode 100644 drivers/media/video/tegra/avp/trpc_sema.h delete mode 100644 drivers/media/video/tegra/dw9714l.c delete mode 100644 drivers/media/video/tegra/ov5650.c delete mode 100644 drivers/media/video/tegra/soc2030.c delete mode 100644 drivers/media/video/tegra/tegra_camera.c delete mode 100644 drivers/mfd/cpcap-3mm5.c delete mode 100644 drivers/mfd/cpcap-adc.c delete mode 100644 drivers/mfd/cpcap-audio-core.c delete mode 100644 drivers/mfd/cpcap-core.c delete mode 100644 drivers/mfd/cpcap-irq.c delete mode 100644 drivers/mfd/cpcap-key.c delete mode 100644 drivers/mfd/cpcap-regacc.c delete mode 100644 drivers/mfd/cpcap-uc.c delete mode 100644 drivers/mfd/cpcap-whisper.c delete mode 100644 drivers/mfd/tegra-cpcap-audio.c delete mode 100644 drivers/misc/akm8975.c delete mode 100644 drivers/misc/apanic.c delete mode 100755 drivers/misc/cap_prox.c delete mode 100755 drivers/misc/gps-gpio-brcm4750.c delete mode 100644 drivers/misc/kernel_debugger.c delete mode 100644 drivers/misc/max9635.c delete mode 100644 drivers/misc/moto_bmp085.c delete mode 100755 drivers/misc/nct1008.c delete mode 100644 drivers/misc/pmem.c delete mode 100644 drivers/misc/radio_ctrl/Kconfig delete mode 100644 drivers/misc/radio_ctrl/Makefile delete mode 100644 drivers/misc/radio_ctrl/mdm6600_ctrl.c delete mode 100644 drivers/misc/radio_ctrl/radio_class.c delete mode 100644 drivers/misc/radio_ctrl/wrigley_ctrl.c delete mode 100644 drivers/misc/tegra-cryptodev.c delete mode 100644 drivers/misc/tegra-cryptodev.h delete mode 100644 drivers/misc/ts27010mux/Kconfig delete mode 100644 drivers/misc/ts27010mux/Makefile delete mode 100644 drivers/misc/ts27010mux/ts0710.h delete mode 100644 drivers/misc/ts27010mux/ts27010_ldisc.c delete mode 100644 drivers/misc/ts27010mux/ts27010_mux.c delete mode 100644 drivers/misc/ts27010mux/ts27010_mux.h delete mode 100644 drivers/misc/ts27010mux/ts27010_ringbuf.h delete mode 100644 drivers/misc/ts27010mux/ts27010_tty.c delete mode 100644 drivers/misc/uid_stat.c delete mode 100644 drivers/misc/wl127x-rfkill.c delete mode 100644 drivers/mmc/core/quirks.c delete mode 100644 drivers/mmc/host/sdhci-tegra.c delete mode 100644 drivers/mtd/devices/tegra_nand.c delete mode 100644 drivers/mtd/devices/tegra_nand.h delete mode 100644 drivers/net/pppolac.c delete mode 100644 drivers/net/pppopns.c delete mode 100644 drivers/net/usb/qcusbnet/Makefile delete mode 100644 drivers/net/usb/qcusbnet/README delete mode 100644 drivers/net/usb/qcusbnet/qcusbnet.c delete mode 100644 drivers/net/usb/qcusbnet/qcusbnet.h delete mode 100644 drivers/net/usb/qcusbnet/qmi.c delete mode 100644 drivers/net/usb/qcusbnet/qmi.h delete mode 100644 drivers/net/usb/qcusbnet/qmidevice.c delete mode 100644 drivers/net/usb/qcusbnet/qmidevice.h delete mode 100644 drivers/net/usb/qcusbnet/structs.h delete mode 100644 drivers/net/wireless/bcm4329/Kconfig delete mode 100755 drivers/net/wireless/bcm4329/Makefile delete mode 100644 drivers/net/wireless/bcm4329/aiutils.c delete mode 100644 drivers/net/wireless/bcm4329/bcmpcispi.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdspi.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdspi_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdstd.c delete mode 100644 drivers/net/wireless/bcm4329/bcmsdstd_linux.c delete mode 100644 drivers/net/wireless/bcm4329/bcmspibrcm.c delete mode 100644 drivers/net/wireless/bcm4329/bcmutils.c delete mode 100644 drivers/net/wireless/bcm4329/bcmwifi.c delete mode 100644 drivers/net/wireless/bcm4329/dhd.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_bus.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_cdc.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_common.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_custom_gpio.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_dbg.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_linux.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_linux_sched.c delete mode 100644 drivers/net/wireless/bcm4329/dhd_proto.h delete mode 100644 drivers/net/wireless/bcm4329/dhd_sdio.c delete mode 100644 drivers/net/wireless/bcm4329/dngl_stats.h delete mode 100644 drivers/net/wireless/bcm4329/hndpmu.c delete mode 100644 drivers/net/wireless/bcm4329/include/Makefile delete mode 100644 drivers/net/wireless/bcm4329/include/aidmp.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmcdc.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmdefs.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmdevs.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmendian.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmpcispi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmperf.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdbus.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdh.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdpcm.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmsdstd.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmspibrcm.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmutils.h delete mode 100644 drivers/net/wireless/bcm4329/include/bcmwifi.h delete mode 100644 drivers/net/wireless/bcm4329/include/dhdioctl.h delete mode 100644 drivers/net/wireless/bcm4329/include/epivers.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndpmu.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndrte_armtrap.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndrte_cons.h delete mode 100644 drivers/net/wireless/bcm4329/include/hndsoc.h delete mode 100644 drivers/net/wireless/bcm4329/include/linux_osl.h delete mode 100644 drivers/net/wireless/bcm4329/include/linuxver.h delete mode 100644 drivers/net/wireless/bcm4329/include/miniopt.h delete mode 100644 drivers/net/wireless/bcm4329/include/msgtrace.h delete mode 100644 drivers/net/wireless/bcm4329/include/osl.h delete mode 100644 drivers/net/wireless/bcm4329/include/packed_section_end.h delete mode 100644 drivers/net/wireless/bcm4329/include/packed_section_start.h delete mode 100644 drivers/net/wireless/bcm4329/include/pcicfg.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.11.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.11e.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/802.1d.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmeth.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmevent.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/bcmip.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/eapol.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/ethernet.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/sdspi.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/vlan.h delete mode 100644 drivers/net/wireless/bcm4329/include/proto/wpa.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbchipc.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbconfig.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbhnddma.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbpcmcia.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsdio.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsdpcmdev.h delete mode 100644 drivers/net/wireless/bcm4329/include/sbsocram.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdio.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdioh.h delete mode 100644 drivers/net/wireless/bcm4329/include/sdiovar.h delete mode 100644 drivers/net/wireless/bcm4329/include/siutils.h delete mode 100644 drivers/net/wireless/bcm4329/include/spid.h delete mode 100644 drivers/net/wireless/bcm4329/include/trxhdr.h delete mode 100644 drivers/net/wireless/bcm4329/include/typedefs.h delete mode 100644 drivers/net/wireless/bcm4329/include/wlioctl.h delete mode 100644 drivers/net/wireless/bcm4329/linux_osl.c delete mode 100644 drivers/net/wireless/bcm4329/miniopt.c delete mode 100644 drivers/net/wireless/bcm4329/sbutils.c delete mode 100644 drivers/net/wireless/bcm4329/siutils.c delete mode 100644 drivers/net/wireless/bcm4329/siutils_priv.h delete mode 100644 drivers/net/wireless/bcm4329/wl_iw.c delete mode 100644 drivers/net/wireless/bcm4329/wl_iw.h delete mode 100644 drivers/platform/x86/intel_ips.h delete mode 100644 drivers/power/bq24617_charger.c delete mode 100644 drivers/power/ds2781_battery.c delete mode 100644 drivers/regulator/cpcap-regulator.c delete mode 100644 drivers/rtc/alarm-dev.c delete mode 100644 drivers/rtc/alarm.c delete mode 100644 drivers/rtc/rtc-cpcap.c delete mode 100644 drivers/rtc/rtc-tps6586x.c delete mode 100644 drivers/serial/tegra_hsuart.c delete mode 100644 drivers/spi/spi_tegra.c delete mode 100644 drivers/staging/android/Kconfig delete mode 100644 drivers/staging/android/Makefile delete mode 100644 drivers/staging/android/binder.c delete mode 100644 drivers/staging/android/binder.h delete mode 100644 drivers/staging/android/logger.c delete mode 100644 drivers/staging/android/logger.h delete mode 100644 drivers/staging/android/lowmemorykiller.c delete mode 100644 drivers/staging/android/ram_console.c delete mode 100755 drivers/staging/android/timed_gpio.c delete mode 100644 drivers/staging/android/timed_gpio.h delete mode 100644 drivers/staging/android/timed_output.c delete mode 100644 drivers/staging/android/timed_output.h delete mode 100644 drivers/switch/Kconfig delete mode 100644 drivers/switch/Makefile delete mode 100644 drivers/switch/switch_class.c delete mode 100644 drivers/switch/switch_gpio.c delete mode 100644 drivers/usb/gadget/android.c delete mode 100644 drivers/usb/gadget/f_accessory.c delete mode 100644 drivers/usb/gadget/f_adb.c delete mode 100644 drivers/usb/gadget/f_mtp.c delete mode 100644 drivers/usb/gadget/fsl_tegra_udc.c delete mode 100644 drivers/usb/host/ehci-tegra.c delete mode 100644 drivers/usb/misc/oob_wake.c delete mode 100644 drivers/usb/otg/cpcap-otg.c delete mode 100644 drivers/usb/otg/tegra-otg.c delete mode 100644 drivers/usb/otg/ulpi_viewport.c delete mode 100644 drivers/usb/serial/mdm6600.c delete mode 100644 drivers/usb/serial/moto_flashmdm.c delete mode 100644 drivers/video/tegra/Kconfig delete mode 100644 drivers/video/tegra/Makefile delete mode 100644 drivers/video/tegra/dc/Makefile delete mode 100644 drivers/video/tegra/dc/dc.c delete mode 100644 drivers/video/tegra/dc/dc_priv.h delete mode 100644 drivers/video/tegra/dc/dc_reg.h delete mode 100644 drivers/video/tegra/dc/edid.c delete mode 100644 drivers/video/tegra/dc/edid.h delete mode 100644 drivers/video/tegra/dc/hdmi.c delete mode 100644 drivers/video/tegra/dc/hdmi.h delete mode 100644 drivers/video/tegra/dc/hdmi_reg.h delete mode 100644 drivers/video/tegra/dc/nvhdcp.c delete mode 100644 drivers/video/tegra/dc/nvhdcp.h delete mode 100644 drivers/video/tegra/dc/rgb.c delete mode 100644 drivers/video/tegra/fb.c delete mode 100644 drivers/video/tegra/host/Makefile delete mode 100644 drivers/video/tegra/host/bus.c delete mode 100644 drivers/video/tegra/host/debug.c delete mode 100644 drivers/video/tegra/host/dev.c delete mode 100644 drivers/video/tegra/host/dev.h delete mode 100644 drivers/video/tegra/host/nvhost_3dctx.c delete mode 100644 drivers/video/tegra/host/nvhost_acm.c delete mode 100644 drivers/video/tegra/host/nvhost_acm.h delete mode 100644 drivers/video/tegra/host/nvhost_cdma.c delete mode 100644 drivers/video/tegra/host/nvhost_cdma.h delete mode 100644 drivers/video/tegra/host/nvhost_channel.c delete mode 100644 drivers/video/tegra/host/nvhost_channel.h delete mode 100644 drivers/video/tegra/host/nvhost_cpuaccess.c delete mode 100644 drivers/video/tegra/host/nvhost_cpuaccess.h delete mode 100644 drivers/video/tegra/host/nvhost_hardware.h delete mode 100644 drivers/video/tegra/host/nvhost_hwctx.h delete mode 100644 drivers/video/tegra/host/nvhost_intr.c delete mode 100644 drivers/video/tegra/host/nvhost_intr.h delete mode 100644 drivers/video/tegra/host/nvhost_mpectx.c delete mode 100644 drivers/video/tegra/host/nvhost_syncpt.c delete mode 100644 drivers/video/tegra/host/nvhost_syncpt.h delete mode 100644 drivers/video/tegra/nvmap/Makefile delete mode 100644 drivers/video/tegra/nvmap/nvmap.c delete mode 100644 drivers/video/tegra/nvmap/nvmap.h delete mode 100644 drivers/video/tegra/nvmap/nvmap_dev.c delete mode 100644 drivers/video/tegra/nvmap/nvmap_handle.c delete mode 100644 drivers/video/tegra/nvmap/nvmap_heap.c delete mode 100644 drivers/video/tegra/nvmap/nvmap_heap.h delete mode 100644 drivers/video/tegra/nvmap/nvmap_ioctl.c delete mode 100644 drivers/video/tegra/nvmap/nvmap_ioctl.h delete mode 100644 drivers/video/tegra/nvmap/nvmap_mru.c delete mode 100644 drivers/video/tegra/nvmap/nvmap_mru.h delete mode 100644 drivers/w1/masters/tegra_w1.c delete mode 100644 drivers/w1/slaves/w1_ds2781.c delete mode 100644 drivers/w1/slaves/w1_ds2781.h delete mode 100644 drivers/watchdog/tegra_wdt.c delete mode 100644 firmware/cpcap/firmware_0_2x.HEX delete mode 100644 firmware/cpcap/firmware_1_2x.H16 delete mode 100644 fs/partitions/cmdline.c delete mode 100644 fs/partitions/cmdline.h delete mode 100644 fs/yaffs2/Kconfig delete mode 100644 fs/yaffs2/Makefile delete mode 100644 fs/yaffs2/devextras.h delete mode 100644 fs/yaffs2/moduleconfig.h delete mode 100644 fs/yaffs2/yaffs_checkptrw.c delete mode 100644 fs/yaffs2/yaffs_checkptrw.h delete mode 100644 fs/yaffs2/yaffs_ecc.c delete mode 100644 fs/yaffs2/yaffs_ecc.h delete mode 100644 fs/yaffs2/yaffs_fs.c delete mode 100644 fs/yaffs2/yaffs_getblockinfo.h delete mode 100644 fs/yaffs2/yaffs_guts.c delete mode 100644 fs/yaffs2/yaffs_guts.h delete mode 100644 fs/yaffs2/yaffs_linux.h delete mode 100644 fs/yaffs2/yaffs_mtdif.c delete mode 100644 fs/yaffs2/yaffs_mtdif.h delete mode 100644 fs/yaffs2/yaffs_mtdif1.c delete mode 100644 fs/yaffs2/yaffs_mtdif1.h delete mode 100644 fs/yaffs2/yaffs_mtdif2.c delete mode 100644 fs/yaffs2/yaffs_mtdif2.h delete mode 100644 fs/yaffs2/yaffs_nand.c delete mode 100644 fs/yaffs2/yaffs_nand.h delete mode 100644 fs/yaffs2/yaffs_nandemul2k.h delete mode 100644 fs/yaffs2/yaffs_packedtags1.c delete mode 100644 fs/yaffs2/yaffs_packedtags1.h delete mode 100644 fs/yaffs2/yaffs_packedtags2.c delete mode 100644 fs/yaffs2/yaffs_packedtags2.h delete mode 100644 fs/yaffs2/yaffs_qsort.c delete mode 100644 fs/yaffs2/yaffs_qsort.h delete mode 100644 fs/yaffs2/yaffs_tagscompat.c delete mode 100644 fs/yaffs2/yaffs_tagscompat.h delete mode 100644 fs/yaffs2/yaffs_tagsvalidity.c delete mode 100644 fs/yaffs2/yaffs_tagsvalidity.h delete mode 100644 fs/yaffs2/yaffs_trace.h delete mode 100644 fs/yaffs2/yaffsinterface.h delete mode 100644 fs/yaffs2/yportenv.h delete mode 100644 include/linux/akm8975.h delete mode 100644 include/linux/android_aid.h delete mode 100644 include/linux/android_alarm.h delete mode 100644 include/linux/android_pmem.h delete mode 100644 include/linux/ashmem.h delete mode 100755 include/linux/cap_prox.h delete mode 100644 include/linux/cpcap_audio.h delete mode 100644 include/linux/cpuacct.h delete mode 100755 include/linux/earlysuspend.h delete mode 100644 include/linux/gpio_event.h delete mode 100755 include/linux/gps-gpio-brcm4750.h delete mode 100644 include/linux/i2c-tegra.h delete mode 100644 include/linux/i2c/panjit_ts.h delete mode 100644 include/linux/if_pppolac.h delete mode 100644 include/linux/if_pppopns.h delete mode 100644 include/linux/kernel_debugger.h delete mode 100644 include/linux/keychord.h delete mode 100644 include/linux/keyreset.h delete mode 100644 include/linux/led-lm3559.h delete mode 100755 include/linux/leds-auo-panel-backlight.h delete mode 100644 include/linux/leds-ld-cpcap.h delete mode 100755 include/linux/leds-lp8550.h delete mode 100644 include/linux/max9635.h delete mode 100644 include/linux/moto_bmp085.h delete mode 100644 include/linux/nct1008.h delete mode 100644 include/linux/platform_data/tegra_usb.h delete mode 100644 include/linux/qtouch_obp_ts.h delete mode 100644 include/linux/radio_ctrl/mdm6600_ctrl.h delete mode 100644 include/linux/radio_ctrl/radio_class.h delete mode 100644 include/linux/radio_ctrl/wrigley_ctrl.h delete mode 100644 include/linux/spi/cpcap-regbits.h delete mode 100644 include/linux/spi/cpcap.h delete mode 100644 include/linux/switch.h delete mode 100644 include/linux/synaptics_i2c_rmi.h delete mode 100644 include/linux/tegra_audio.h delete mode 100644 include/linux/tegra_avp.h delete mode 100644 include/linux/tegra_rpc.h delete mode 100644 include/linux/tegra_sema.h delete mode 100644 include/linux/tegra_spdif.h delete mode 100644 include/linux/uid_stat.h delete mode 100644 include/linux/usb/android_composite.h delete mode 100644 include/linux/usb/f_accessory.h delete mode 100644 include/linux/usb/f_mtp.h delete mode 100644 include/linux/usb/oob_wake.h delete mode 100755 include/linux/wakelock.h delete mode 100644 include/linux/wifi_tiwlan.h delete mode 100644 include/linux/wl127x-rfkill.h delete mode 100644 include/linux/wlan_plat.h delete mode 100644 include/media/dw9714l.h delete mode 100755 include/media/ov5650.h delete mode 100755 include/media/soc2030.h delete mode 100644 include/media/tegra_camera.h delete mode 100644 include/net/activity_stats.h delete mode 100644 include/video/nvhdcp.h delete mode 100644 include/video/tegrafb.h delete mode 100644 kernel/power/consoleearlysuspend.c delete mode 100644 kernel/power/earlysuspend.c delete mode 100644 kernel/power/fbearlysuspend.c delete mode 100644 kernel/power/userwakelock.c delete mode 100644 kernel/power/wakelock.c delete mode 100644 mm/ashmem.c delete mode 100644 net/activity_stats.c delete mode 100644 net/ipv4/sysfs_net_ipv4.c diff --git a/Documentation/android.txt b/Documentation/android.txt deleted file mode 100644 index 72a62afdf202..000000000000 --- a/Documentation/android.txt +++ /dev/null @@ -1,121 +0,0 @@ - ============= - A N D R O I D - ============= - -Copyright (C) 2009 Google, Inc. -Written by Mike Chan - -CONTENTS: ---------- - -1. Android - 1.1 Required enabled config options - 1.2 Required disabled config options - 1.3 Recommended enabled config options -2. Contact - - -1. Android -========== - -Android (www.android.com) is an open source operating system for mobile devices. -This document describes configurations needed to run the Android framework on -top of the Linux kernel. - -To see a working defconfig look at msm_defconfig or goldfish_defconfig -which can be found at http://android.git.kernel.org in kernel/common.git -and kernel/msm.git - - -1.1 Required enabled config options ------------------------------------ -After building a standard defconfig, ensure that these options are enabled in -your .config or defconfig if they are not already. Based off the msm_defconfig. -You should keep the rest of the default options enabled in the defconfig -unless you know what you are doing. - -ANDROID_PARANOID_NETWORK -ASHMEM -CONFIG_FB_MODE_HELPERS -CONFIG_FONT_8x16 -CONFIG_FONT_8x8 -CONFIG_YAFFS_SHORT_NAMES_IN_RAM -DAB -EARLYSUSPEND -FB -FB_CFB_COPYAREA -FB_CFB_FILLRECT -FB_CFB_IMAGEBLIT -FB_DEFERRED_IO -FB_TILEBLITTING -HIGH_RES_TIMERS -INOTIFY -INOTIFY_USER -INPUT_EVDEV -INPUT_GPIO -INPUT_MISC -LEDS_CLASS -LEDS_GPIO -LOCK_KERNEL -LkOGGER -LOW_MEMORY_KILLER -MISC_DEVICES -NEW_LEDS -NO_HZ -POWER_SUPPLY -PREEMPT -RAMFS -RTC_CLASS -RTC_LIB -SWITCH -SWITCH_GPIO -TMPFS -UID_STAT -UID16 -USB_FUNCTION -USB_FUNCTION_ADB -USER_WAKELOCK -VIDEO_OUTPUT_CONTROL -WAKELOCK -YAFFS_AUTO_YAFFS2 -YAFFS_FS -YAFFS_YAFFS1 -YAFFS_YAFFS2 - - -1.2 Required disabled config options ------------------------------------- -CONFIG_YAFFS_DISABLE_LAZY_LOAD -DNOTIFY - - -1.3 Recommended enabled config options ------------------------------- -ANDROID_PMEM -ANDROID_RAM_CONSOLE -ANDROID_RAM_CONSOLE_ERROR_CORRECTION -SCHEDSTATS -DEBUG_PREEMPT -DEBUG_MUTEXES -DEBUG_SPINLOCK_SLEEP -DEBUG_INFO -FRAME_POINTER -CPU_FREQ -CPU_FREQ_TABLE -CPU_FREQ_DEFAULT_GOV_ONDEMAND -CPU_FREQ_GOV_ONDEMAND -CRC_CCITT -EMBEDDED -INPUT_TOUCHSCREEN -I2C -I2C_BOARDINFO -LOG_BUF_SHIFT=17 -SERIAL_CORE -SERIAL_CORE_CONSOLE - - -2. Contact -========== -website: http://android.git.kernel.org - -mailing-lists: android-kernel@googlegroups.com diff --git a/Documentation/cgroups/cpuacct.txt b/Documentation/cgroups/cpuacct.txt index 84e471b612eb..8b930946c52a 100644 --- a/Documentation/cgroups/cpuacct.txt +++ b/Documentation/cgroups/cpuacct.txt @@ -40,13 +40,6 @@ system: Time spent by tasks of the cgroup in kernel mode. user and system are in USER_HZ unit. -cpuacct.cpufreq file gives CPU time (in nanoseconds) spent at each CPU -frequency. Platform hooks must be implemented inorder to properly track -time at each CPU frequency. - -cpuacct.power file gives CPU power consumed (in milliWatt seconds). Platform -must provide and implement power callback functions. - cpuacct controller uses percpu_counter interface to collect user and system times. This has two side effects: diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index b37d805e19ea..737988fca64d 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt @@ -28,7 +28,6 @@ Contents: 2.3 Userspace 2.4 Ondemand 2.5 Conservative -2.6 Interactive 3. The Governor Interface in the CPUfreq Core @@ -183,41 +182,6 @@ governor but for the opposite direction. For example when set to its default value of '20' it means that if the CPU usage needs to be below 20% between samples to have the frequency decreased. - -2.6 Interactive ---------------- - -The CPUfreq governor "interactive" is designed for latency-sensitive, -interactive workloads. This governor sets the CPU speed depending on -usage, similar to "ondemand" and "conservative" governors. However, -the governor is more aggressive about scaling the CPU speed up in -response to CPU-intensive activity. - -Sampling the CPU load every X ms can lead to under-powering the CPU -for X ms, leading to dropped frames, stuttering UI, etc. Instead of -sampling the cpu at a specified rate, the interactive governor will -check whether to scale the cpu frequency up soon after coming out of -idle. When the cpu comes out of idle, a timer is configured to fire -within 1-2 ticks. If the cpu is very busy between exiting idle and -when the timer fires then we assume the cpu is underpowered and ramp -to MAX speed. - -If the cpu was not sufficiently busy to immediately ramp to MAX speed, -then governor evaluates the cpu load since the last speed adjustment, -choosing th highest value between that longer-term load or the -short-term load since idle exit to determine the cpu speed to ramp to. - -The tuneable value for this governor are: - -min_sample_time: The minimum amount of time to spend at the current -frequency before ramping down. This is to ensure that the governor has -seen enough historic cpu load data to determine the appropriate -workload. Default is 80000 uS. - -go_maxspeed_load: The CPU load at which to ramp to max speed. Default -is 85. - - 3. The Governor Interface in the CPUfreq Core ============================================= diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 20ed4ccc2a22..8dd7248508a9 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1745,7 +1745,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 (NMI watchdog). + nowatchdog [KNL] Disable the lockup detector. nowb [ARM] diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 506d9d916e41..55b859b3bc72 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -336,8 +336,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' and its - 'power.disable_depth' field is equal to zero, or false otherwise + - return true if the device's runtime PM status is 'suspended', or false + otherwise void pm_runtime_allow(struct device *dev); - set the power.runtime_auto flag for the device and decrease its usage diff --git a/Makefile b/Makefile index 12bbf67fd532..28a349e91469 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 36 -EXTRAVERSION = .3 +EXTRAVERSION = NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0749858bb362..b449fc4ccbf4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -135,14 +135,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_CPU_IDLE_WAIT - bool - default y - -config ARCH_HAS_DEFAULT_IDLE - bool - default y - config ARCH_HAS_ILOG2_U32 bool @@ -190,9 +182,6 @@ config ARM_L1_CACHE_SHIFT_6 help Setting ARM L1 cache line size to 64 Bytes. -config ARCH_PROVIDES_UDELAY - bool - config VECTORS_BASE hex default 0xffff0000 if MMU || CPU_HIGH_VECTOR @@ -579,9 +568,6 @@ config ARCH_TEGRA select HAVE_CLK select COMMON_CLKDEV select ARCH_HAS_BARRIERS if CACHE_L2X0 - select ARCH_HAS_CPUFREQ - select ARCH_PROVIDES_UDELAY - select FIQ help This enables support for NVIDIA Tegra based systems (Tegra APX, Tegra 6xx and Tegra 2 series). diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index 3e728a6f9649..ab204db594d3 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -1,6 +1,3 @@ font.c -piggy.gzip -piggy.lzo -lib1funcs.S +piggy.gz vmlinux.lds -vmlinux diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 051b179c9135..6825c34646d4 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -21,7 +21,7 @@ #if defined(CONFIG_DEBUG_ICEDCC) -#ifdef defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7) +#ifdef CONFIG_CPU_V6 .macro loadsp, rb, tmp .endm .macro writeb, ch, rb @@ -637,8 +637,6 @@ proc_types: @ b __arm6_mmu_cache_off @ b __armv3_mmu_cache_flush -#if !defined(CONFIG_CPU_V7) - /* This collides with some V7 IDs, preventing correct detection */ .word 0x00000000 @ old ARM ID .word 0x0000f000 mov pc, lr @@ -647,7 +645,6 @@ proc_types: THUMB( nop ) mov pc, lr THUMB( nop ) -#endif .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 253ecc88a7bb..e653a6d3c8d9 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -36,7 +36,7 @@ extern void error(char *x); #ifdef CONFIG_DEBUG_ICEDCC -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7) +#ifdef CONFIG_CPU_V6 static void icedcc_putc(int ch) { diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 2dbc36b05b1d..0a34c8186924 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -41,54 +41,3 @@ config SHARP_SCOOP config COMMON_CLKDEV bool select HAVE_CLK - -config FIQ_GLUE - bool - select FIQ - -config FIQ_DEBUGGER - bool "FIQ Mode Serial Debugger" - select FIQ - select FIQ_GLUE - select KERNEL_DEBUGGER_CORE - default n - help - The FIQ serial debugger can accept commands even when the - kernel is unresponsive due to being stuck with interrupts - disabled. Depends on the kernel debugger core in drivers/misc. - - -config FIQ_DEBUGGER_NO_SLEEP - bool "Keep serial debugger active" - depends on FIQ_DEBUGGER - default n - help - Enables the serial debugger at boot. Passing - fiq_debugger.no_sleep on the kernel commandline will - override this config option. - -config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON - bool "Don't disable wakeup IRQ when debugger is active" - depends on FIQ_DEBUGGER - default n - help - Don't disable the wakeup irq when enabling the uart clock. This will - cause extra interrupts, but it makes the serial debugger usable with - on some MSM radio builds that ignore the uart clock request in power - collapse. - -config FIQ_DEBUGGER_CONSOLE - bool "Console on FIQ Serial Debugger port" - depends on FIQ_DEBUGGER - default n - help - Enables a console so that printk messages are displayed on - the debugger serial port as the occur. - -config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE - bool "Put the FIQ debugger into console mode by default" - depends on FIQ_DEBUGGER_CONSOLE - default n - help - If enabled, this puts the fiq debugger into console mode by default. - Otherwise, the fiq debugger will start out in debug mode. diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index d986c26ee35b..e6e8664a9413 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -17,5 +17,3 @@ 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_FIQ_GLUE) += fiq_glue.o fiq_glue_setup.o -obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger.o diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c deleted file mode 100644 index f172c15f1d3e..000000000000 --- a/arch/arm/common/fiq_debugger.c +++ /dev/null @@ -1,942 +0,0 @@ -/* - * arch/arm/common/fiq_debugger.c - * - * Serial Debugger Interface accessed through an FIQ interrupt. - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include "fiq_debugger_ringbuf.h" - -#define DEBUG_MAX 64 -#define MAX_UNHANDLED_FIQ_COUNT 1000000 - -#define THREAD_INFO(sp) ((struct thread_info *) \ - ((unsigned long)(sp) & ~(THREAD_SIZE - 1))) - -struct fiq_debugger_state { - struct fiq_glue_handler handler; - - int fiq; - int signal_irq; - int wakeup_irq; - bool wakeup_irq_no_set_wake; - struct clk *clk; - struct fiq_debugger_pdata *pdata; - struct platform_device *pdev; - - char debug_cmd[DEBUG_MAX]; - int debug_busy; - int debug_abort; - - char debug_buf[DEBUG_MAX]; - int debug_count; - - bool no_sleep; - bool debug_enable; - bool ignore_next_wakeup_irq; - struct timer_list sleep_timer; - bool uart_clk_enabled; - struct wake_lock debugger_wake_lock; - bool console_enable; - int current_cpu; - atomic_t unhandled_fiq_count; - bool in_fiq; - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - struct console console; - struct tty_driver *tty_driver; - struct tty_struct *tty; - int tty_open_count; - struct fiq_debugger_ringbuf *tty_rbuf; -#endif - - unsigned int last_irqs[NR_IRQS]; - unsigned int last_local_timer_irqs[NR_CPUS]; -}; - -#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP -static bool initial_no_sleep = true; -#else -static bool initial_no_sleep; -#endif - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE -static bool initial_debug_enable = true; -static bool initial_console_enable = true; -#else -static bool initial_debug_enable; -static bool initial_console_enable; -#endif - -module_param_named(no_sleep, initial_no_sleep, bool, 0644); -module_param_named(debug_enable, initial_debug_enable, bool, 0644); -module_param_named(console_enable, initial_console_enable, bool, 0644); - -#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON -static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {} -static inline void disable_wakeup_irq(struct fiq_debugger_state *state) {} -#else -static inline void enable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - enable_irq(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - enable_irq_wake(state->wakeup_irq); -} -static inline void disable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - disable_irq_nosync(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - disable_irq_wake(state->wakeup_irq); -} -#endif - -static void debug_force_irq(struct fiq_debugger_state *state) -{ - unsigned int irq = state->signal_irq; - if (state->pdata->force_irq) - state->pdata->force_irq(state->pdev, irq); - else { - struct irq_chip *chip = get_irq_chip(irq); - if (chip && chip->retrigger) - chip->retrigger(irq); - } -} - -static void debug_uart_flush(struct fiq_debugger_state *state) -{ - if (state->pdata->uart_flush) - state->pdata->uart_flush(state->pdev); -} - -static void debug_puts(struct fiq_debugger_state *state, char *s) -{ - unsigned c; - while ((c = *s++)) { - if (c == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, c); - } -} - -static void debug_prompt(struct fiq_debugger_state *state) -{ - debug_puts(state, "debug> "); -} - -int log_buf_copy(char *dest, int idx, int len); -static void dump_kernel_log(struct fiq_debugger_state *state) -{ - char buf[1024]; - int idx = 0; - int ret; - int saved_oip; - - /* setting oops_in_progress prevents log_buf_copy() - * from trying to take a spinlock which will make it - * very unhappy in some cases... - */ - saved_oip = oops_in_progress; - oops_in_progress = 1; - for (;;) { - ret = log_buf_copy(buf, idx, 1023); - if (ret <= 0) - break; - buf[ret] = 0; - debug_puts(state, buf); - idx += ret; - } - oops_in_progress = saved_oip; -} - -static char *mode_name(unsigned cpsr) -{ - switch (cpsr & MODE_MASK) { - case USR_MODE: return "USR"; - case FIQ_MODE: return "FIQ"; - case IRQ_MODE: return "IRQ"; - case SVC_MODE: return "SVC"; - case ABT_MODE: return "ABT"; - case UND_MODE: return "UND"; - case SYSTEM_MODE: return "SYS"; - default: return "???"; - } -} - -static int debug_printf(void *cookie, const char *fmt, ...) -{ - struct fiq_debugger_state *state = cookie; - char buf[256]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - debug_puts(state, buf); - return state->debug_abort; -} - -/* Safe outside fiq context */ -static int debug_printf_nfiq(void *cookie, const char *fmt, ...) -{ - struct fiq_debugger_state *state = cookie; - char buf[256]; - va_list ap; - unsigned long irq_flags; - - va_start(ap, fmt); - vsnprintf(buf, 128, fmt, ap); - va_end(ap); - - local_irq_save(irq_flags); - debug_puts(state, buf); - debug_uart_flush(state); - local_irq_restore(irq_flags); - return state->debug_abort; -} - -static void dump_regs(struct fiq_debugger_state *state, unsigned *regs) -{ - debug_printf(state, " r0 %08x r1 %08x r2 %08x r3 %08x\n", - regs[0], regs[1], regs[2], regs[3]); - debug_printf(state, " r4 %08x r5 %08x r6 %08x r7 %08x\n", - regs[4], regs[5], regs[6], regs[7]); - debug_printf(state, " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n", - regs[8], regs[9], regs[10], regs[11], - mode_name(regs[16])); - if ((regs[16] & MODE_MASK) == USR_MODE) - debug_printf(state, " ip %08x sp %08x lr %08x pc %08x " - "cpsr %08x\n", regs[12], regs[13], regs[14], - regs[15], regs[16]); - else - debug_printf(state, " ip %08x sp %08x lr %08x pc %08x " - "cpsr %08x spsr %08x\n", regs[12], regs[13], - regs[14], regs[15], regs[16], regs[17]); -} - -struct mode_regs { - unsigned long sp_svc; - unsigned long lr_svc; - unsigned long spsr_svc; - - unsigned long sp_abt; - unsigned long lr_abt; - unsigned long spsr_abt; - - unsigned long sp_und; - unsigned long lr_und; - unsigned long spsr_und; - - unsigned long sp_irq; - unsigned long lr_irq; - unsigned long spsr_irq; - - unsigned long r8_fiq; - unsigned long r9_fiq; - unsigned long r10_fiq; - unsigned long r11_fiq; - unsigned long r12_fiq; - unsigned long sp_fiq; - unsigned long lr_fiq; - unsigned long spsr_fiq; -}; - -void __naked get_mode_regs(struct mode_regs *regs) -{ - asm volatile ( - "mrs r1, cpsr\n" - "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r8 - r14}\n" - "mrs r2, spsr\n" - "stmia r0!, {r2}\n" - "msr cpsr_c, r1\n" - "bx lr\n"); -} - - -static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs) -{ - struct mode_regs mode_regs; - dump_regs(state, regs); - get_mode_regs(&mode_regs); - debug_printf(state, " svc: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc); - debug_printf(state, " abt: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt); - debug_printf(state, " und: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und); - debug_printf(state, " irq: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq); - debug_printf(state, " fiq: r8 %08x r9 %08x r10 %08x r11 %08x " - "r12 %08x\n", - mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq, - mode_regs.r11_fiq, mode_regs.r12_fiq); - debug_printf(state, " fiq: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq); -} - -static void dump_irqs(struct fiq_debugger_state *state) -{ - int n; - unsigned int cpu; - - debug_printf(state, "irqnr total since-last status name\n"); - for (n = 0; n < NR_IRQS; n++) { - struct irqaction *act = irq_desc[n].action; - if (!act && !kstat_irqs(n)) - continue; - debug_printf(state, "%5d: %10u %11u %8x %s\n", n, - kstat_irqs(n), - kstat_irqs(n) - state->last_irqs[n], - irq_desc[n].status, - (act && act->name) ? act->name : "???"); - state->last_irqs[n] = kstat_irqs(n); - } - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - - debug_printf(state, "LOC %d: %10u %11u\n", cpu, - __IRQ_STAT(cpu, local_timer_irqs), - __IRQ_STAT(cpu, local_timer_irqs) - - state->last_local_timer_irqs[cpu]); - state->last_local_timer_irqs[cpu] = - __IRQ_STAT(cpu, local_timer_irqs); - } -} - -struct stacktrace_state { - struct fiq_debugger_state *state; - unsigned int depth; -}; - -static int report_trace(struct stackframe *frame, void *d) -{ - struct stacktrace_state *sts = d; - - if (sts->depth) { - debug_printf(sts->state, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - frame->pc, frame->pc, frame->lr, frame->lr, - frame->sp, frame->fp); - sts->depth--; - return 0; - } - debug_printf(sts->state, " ...\n"); - - return sts->depth == 0; -} - -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail *user_backtrace(struct fiq_debugger_state *state, - struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) { - debug_printf(state, " invalid frame pointer %p\n", tail); - return NULL; - } - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) { - debug_printf(state, - " failed to copy frame pointer %p\n", tail); - return NULL; - } - - debug_printf(state, " %p\n", buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -void dump_stacktrace(struct fiq_debugger_state *state, - struct pt_regs * const regs, unsigned int depth, void *ssp) -{ - struct frame_tail *tail; - struct thread_info *real_thread_info = THREAD_INFO(ssp); - struct stacktrace_state sts; - - sts.depth = depth; - sts.state = state; - *current_thread_info() = *real_thread_info; - - if (!current) - debug_printf(state, "current NULL\n"); - else - debug_printf(state, "pid: %d comm: %s\n", - current->pid, current->comm); - dump_regs(state, (unsigned *)regs); - - if (!user_mode(regs)) { - struct stackframe frame; - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; - debug_printf(state, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr, - regs->ARM_sp, regs->ARM_fp); - walk_stackframe(&frame, report_trace, &sts); - return; - } - - tail = ((struct frame_tail *) regs->ARM_fp) - 1; - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(state, tail); -} - -static void debug_help(struct fiq_debugger_state *state) -{ - debug_printf(state, "FIQ Debugger commands:\n" - " pc PC status\n" - " regs Register dump\n" - " allregs Extended Register dump\n" - " bt Stack trace\n" - " reboot Reboot\n" - " irqs Interupt status\n" - " kmsg Kernel log\n" - " version Kernel version\n"); - debug_printf(state, " sleep Allow sleep while in FIQ\n" - " nosleep Disable sleep while in FIQ\n" - " console Switch terminal to console\n" - " cpu Current CPU\n" - " cpu Switch to CPU\n"); - if (!state->debug_busy) { - strcpy(state->debug_cmd, "help"); - state->debug_busy = 1; - debug_force_irq(state); - } -} - -static void debug_exec(struct fiq_debugger_state *state, - const char *cmd, unsigned *regs, void *svc_sp) -{ - if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) { - debug_help(state); - } else if (!strcmp(cmd, "pc")) { - debug_printf(state, " pc %08x cpsr %08x mode %s\n", - regs[15], regs[16], mode_name(regs[16])); - } else if (!strcmp(cmd, "regs")) { - dump_regs(state, regs); - } else if (!strcmp(cmd, "allregs")) { - dump_allregs(state, regs); - } else if (!strcmp(cmd, "bt")) { - dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp); - } else if (!strcmp(cmd, "reboot")) { - arch_reset(0, 0); - } else if (!strcmp(cmd, "irqs")) { - dump_irqs(state); - } else if (!strcmp(cmd, "kmsg")) { - dump_kernel_log(state); - } else if (!strcmp(cmd, "version")) { - debug_printf(state, "%s\n", linux_banner); - } else if (!strcmp(cmd, "sleep")) { - state->no_sleep = false; - } else if (!strcmp(cmd, "nosleep")) { - state->no_sleep = true; - } else if (!strcmp(cmd, "console")) { - state->console_enable = true; - debug_printf(state, "console mode\n"); - } else if (!strcmp(cmd, "cpu")) { - debug_printf(state, "cpu %d\n", state->current_cpu); - } else if (!strncmp(cmd, "cpu ", 4)) { - unsigned long cpu = 0; - if (strict_strtoul(cmd + 4, 10, &cpu) == 0) - state->current_cpu = cpu; - else - debug_printf(state, "invalid cpu\n"); - debug_printf(state, "cpu %d\n", state->current_cpu); - } else { - if (state->debug_busy) { - debug_printf(state, - "command processor busy. trying to abort.\n"); - state->debug_abort = -1; - } else { - strcpy(state->debug_cmd, cmd); - state->debug_busy = 1; - } - - debug_force_irq(state); - - return; - } - if (!state->console_enable) - debug_prompt(state); -} - -static void sleep_timer_expired(unsigned long data) -{ - struct fiq_debugger_state *state = (struct fiq_debugger_state *)data; - - if (state->uart_clk_enabled && !state->no_sleep) { - if (state->debug_enable) { - state->debug_enable = false; - debug_printf_nfiq(state, "suspending fiq debugger\n"); - } - state->ignore_next_wakeup_irq = true; - if (state->clk) - clk_disable(state->clk); - state->uart_clk_enabled = false; - enable_wakeup_irq(state); - } - wake_unlock(&state->debugger_wake_lock); -} - -static irqreturn_t wakeup_irq_handler(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - - if (!state->no_sleep) - debug_puts(state, "WAKEUP\n"); - if (state->ignore_next_wakeup_irq) - state->ignore_next_wakeup_irq = false; - else if (!state->uart_clk_enabled) { - wake_lock(&state->debugger_wake_lock); - if (state->clk) - clk_enable(state->clk); - state->uart_clk_enabled = true; - disable_wakeup_irq(state); - mod_timer(&state->sleep_timer, jiffies + HZ / 2); - } - return IRQ_HANDLED; -} - -static irqreturn_t debug_irq(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - if (state->pdata->force_irq_ack) - state->pdata->force_irq_ack(state->pdev, state->signal_irq); - - if (!state->no_sleep) { - wake_lock(&state->debugger_wake_lock); - mod_timer(&state->sleep_timer, jiffies + HZ * 5); - } -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - if (state->tty) { - int i; - int count = fiq_debugger_ringbuf_level(state->tty_rbuf); - for (i = 0; i < count; i++) { - int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, i); - tty_insert_flip_char(state->tty, c, TTY_NORMAL); - if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1)) - pr_warn("fiq tty failed to consume byte\n"); - } - tty_flip_buffer_push(state->tty); - } -#endif - if (state->debug_busy) { - struct kdbg_ctxt ctxt; - - ctxt.printf = debug_printf_nfiq; - ctxt.cookie = state; - kernel_debugger(&ctxt, state->debug_cmd); - debug_prompt(state); - - state->debug_busy = 0; - } - return IRQ_HANDLED; -} - -static int debug_getc(struct fiq_debugger_state *state) -{ - return state->pdata->uart_getc(state->pdev); -} - -static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp) -{ - struct fiq_debugger_state *state = - container_of(h, struct fiq_debugger_state, handler); - int c; - static int last_c; - int count = 0; - unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu; - - if (this_cpu != state->current_cpu) { - if (state->in_fiq) - return; - - if (atomic_inc_return(&state->unhandled_fiq_count) != - MAX_UNHANDLED_FIQ_COUNT) - return; - - debug_printf(state, "fiq_debugger: cpu %d not responding, " - "reverting to cpu %d\n", state->current_cpu, - this_cpu); - - atomic_set(&state->unhandled_fiq_count, 0); - state->current_cpu = this_cpu; - return; - } - - state->in_fiq = true; - - while ((c = debug_getc(state)) != FIQ_DEBUGGER_NO_CHAR) { - count++; - if (!state->debug_enable) { - if ((c == 13) || (c == 10)) { - state->debug_enable = true; - state->debug_count = 0; - debug_prompt(state); - } - } else if (c == FIQ_DEBUGGER_BREAK) { - state->console_enable = false; - debug_puts(state, "fiq debugger mode\n"); - state->debug_count = 0; - debug_prompt(state); -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - } else if (state->console_enable && state->tty_rbuf) { - fiq_debugger_ringbuf_push(state->tty_rbuf, c); - debug_force_irq(state); -#endif - } else if ((c >= ' ') && (c < 127)) { - if (state->debug_count < (DEBUG_MAX - 1)) { - state->debug_buf[state->debug_count++] = c; - state->pdata->uart_putc(state->pdev, c); - } - } else if ((c == 8) || (c == 127)) { - if (state->debug_count > 0) { - state->debug_count--; - state->pdata->uart_putc(state->pdev, 8); - state->pdata->uart_putc(state->pdev, ' '); - state->pdata->uart_putc(state->pdev, 8); - } - } else if ((c == 13) || (c == 10)) { - if (c == '\r' || (c == '\n' && last_c != '\r')) { - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, '\n'); - } - if (state->debug_count) { - state->debug_buf[state->debug_count] = 0; - state->debug_count = 0; - debug_exec(state, state->debug_buf, - regs, svc_sp); - } else { - debug_prompt(state); - } - } - last_c = c; - } - debug_uart_flush(state); - if (state->pdata->fiq_ack) - state->pdata->fiq_ack(state->pdev, state->fiq); - - /* poke sleep timer if necessary */ - if (state->debug_enable && !state->no_sleep) - debug_force_irq(state); - - atomic_set(&state->unhandled_fiq_count, 0); - state->in_fiq = false; -} - -static void debug_resume(struct fiq_glue_handler *h) -{ - struct fiq_debugger_state *state = - container_of(h, struct fiq_debugger_state, handler); - if (state->pdata->uart_resume) - state->pdata->uart_resume(state->pdev); -} - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) -struct tty_driver *debug_console_device(struct console *co, int *index) -{ - struct fiq_debugger_state *state; - state = container_of(co, struct fiq_debugger_state, console); - *index = 0; - return state->tty_driver; -} - -static void debug_console_write(struct console *co, - const char *s, unsigned int count) -{ - struct fiq_debugger_state *state; - - state = container_of(co, struct fiq_debugger_state, console); - - if (!state->console_enable) - return; - - while (count--) { - if (*s == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, *s++); - } - debug_uart_flush(state); -} - -static struct console fiq_debugger_console = { - .name = "ttyFIQ", - .device = debug_console_device, - .write = debug_console_write, - .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED, -}; - -int fiq_tty_open(struct tty_struct *tty, struct file *filp) -{ - struct fiq_debugger_state *state = tty->driver->driver_state; - if (state->tty_open_count++) - return 0; - - tty->driver_data = state; - state->tty = tty; - return 0; -} - -void fiq_tty_close(struct tty_struct *tty, struct file *filp) -{ - struct fiq_debugger_state *state = tty->driver_data; - if (--state->tty_open_count) - return; - state->tty = NULL; -} - -int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int i; - struct fiq_debugger_state *state = tty->driver_data; - - if (!state->console_enable) - return count; - - if (state->clk) - clk_enable(state->clk); - for (i = 0; i < count; i++) - state->pdata->uart_putc(state->pdev, *buf++); - if (state->clk) - clk_disable(state->clk); - - return count; -} - -int fiq_tty_write_room(struct tty_struct *tty) -{ - return 1024; -} - -static const struct tty_operations fiq_tty_driver_ops = { - .write = fiq_tty_write, - .write_room = fiq_tty_write_room, - .open = fiq_tty_open, - .close = fiq_tty_close, -}; - -static int fiq_debugger_tty_init(struct fiq_debugger_state *state) -{ - int ret = -EINVAL; - - state->tty_driver = alloc_tty_driver(1); - if (!state->tty_driver) { - pr_err("Failed to allocate fiq debugger tty\n"); - return -ENOMEM; - } - - state->tty_driver->owner = THIS_MODULE; - state->tty_driver->driver_name = "fiq-debugger"; - state->tty_driver->name = "ttyFIQ"; - state->tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - state->tty_driver->subtype = SERIAL_TYPE_NORMAL; - state->tty_driver->init_termios = tty_std_termios; - state->tty_driver->init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL; - state->tty_driver->init_termios.c_ispeed = - state->tty_driver->init_termios.c_ospeed = 115200; - state->tty_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(state->tty_driver, &fiq_tty_driver_ops); - state->tty_driver->driver_state = state; - - ret = tty_register_driver(state->tty_driver); - if (ret) { - pr_err("Failed to register fiq tty: %d\n", ret); - goto err; - } - - state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024); - if (!state->tty_rbuf) { - pr_err("Failed to allocate fiq debugger ringbuf\n"); - ret = -ENOMEM; - goto err; - } - - pr_info("Registered FIQ tty driver %p\n", state->tty_driver); - return 0; - -err: - fiq_debugger_ringbuf_free(state->tty_rbuf); - state->tty_rbuf = NULL; - put_tty_driver(state->tty_driver); - return ret; -} -#endif - -static int fiq_debugger_probe(struct platform_device *pdev) -{ - int ret; - struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev); - struct fiq_debugger_state *state; - - if (!pdata->uart_getc || !pdata->uart_putc || !pdata->fiq_enable) - return -EINVAL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - state->handler.fiq = debug_fiq; - state->handler.resume = debug_resume; - setup_timer(&state->sleep_timer, sleep_timer_expired, - (unsigned long)state); - state->pdata = pdata; - state->pdev = pdev; - state->no_sleep = initial_no_sleep; - state->debug_enable = initial_debug_enable; - state->console_enable = initial_console_enable; - - state->fiq = platform_get_irq_byname(pdev, "fiq"); - state->signal_irq = platform_get_irq_byname(pdev, "signal"); - state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup"); - - if (state->wakeup_irq < 0) - state->no_sleep = true; - state->ignore_next_wakeup_irq = !state->no_sleep; - - wake_lock_init(&state->debugger_wake_lock, - WAKE_LOCK_SUSPEND, "serial-debug"); - - state->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(state->clk)) - state->clk = NULL; - - if (state->clk) - clk_enable(state->clk); - - if (pdata->uart_init) { - ret = pdata->uart_init(pdev); - if (ret) - goto err_uart_init; - } - - debug_printf_nfiq(state, "\n", - state->no_sleep ? "" : "twice "); - - ret = fiq_glue_register_handler(&state->handler); - if (ret) { - pr_err("serial_debugger: could not install fiq handler\n"); - goto err_register_fiq; - } - - pdata->fiq_enable(pdev, state->fiq, 1); - - if (state->clk) - clk_disable(state->clk); - - ret = request_irq(state->signal_irq, debug_irq, - IRQF_TRIGGER_RISING, "debug", state); - if (ret) - pr_err("serial_debugger: could not install signal_irq"); - - if (state->wakeup_irq >= 0) { - ret = request_irq(state->wakeup_irq, wakeup_irq_handler, - IRQF_TRIGGER_FALLING | IRQF_DISABLED, - "debug-wakeup", state); - if (ret) { - pr_err("serial_debugger: " - "could not install wakeup irq\n"); - state->wakeup_irq = -1; - } else { - ret = enable_irq_wake(state->wakeup_irq); - if (ret) { - pr_err("serial_debugger: " - "could not enable wakeup\n"); - state->wakeup_irq_no_set_wake = true; - } - } - } - if (state->no_sleep) - wakeup_irq_handler(state->wakeup_irq, state); - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - state->console = fiq_debugger_console; - register_console(&state->console); - fiq_debugger_tty_init(state); -#endif - return 0; - -err_register_fiq: - if (pdata->uart_free) - pdata->uart_free(pdev); -err_uart_init: - kfree(state); - if (state->clk) - clk_put(state->clk); - return ret; -} - -static struct platform_driver fiq_debugger_driver = { - .probe = fiq_debugger_probe, - .driver.name = "fiq_debugger", -}; - -static int __init fiq_debugger_init(void) -{ - return platform_driver_register(&fiq_debugger_driver); -} - -postcore_initcall(fiq_debugger_init); diff --git a/arch/arm/common/fiq_debugger_ringbuf.h b/arch/arm/common/fiq_debugger_ringbuf.h deleted file mode 100644 index 2649b5581088..000000000000 --- a/arch/arm/common/fiq_debugger_ringbuf.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * arch/arm/common/fiq_debugger_ringbuf.c - * - * simple lockless ringbuffer - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -struct fiq_debugger_ringbuf { - int len; - int head; - int tail; - u8 buf[]; -}; - - -static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len) -{ - struct fiq_debugger_ringbuf *rbuf; - - rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL); - if (rbuf == NULL) - return NULL; - - rbuf->len = len; - rbuf->head = 0; - rbuf->tail = 0; - smp_mb(); - - return rbuf; -} - -static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf) -{ - kfree(rbuf); -} - -static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf) -{ - int level = rbuf->head - rbuf->tail; - - if (level < 0) - level = rbuf->len + level; - - return level; -} - -static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf) -{ - return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1; -} - -static inline u8 -fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i) -{ - return rbuf->buf[(rbuf->tail + i) % rbuf->len]; -} - -static inline int -fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count) -{ - count = min(count, fiq_debugger_ringbuf_level(rbuf)); - - rbuf->tail = (rbuf->tail + count) % rbuf->len; - smp_mb(); - - return count; -} - -static inline int -fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum) -{ - if (fiq_debugger_ringbuf_room(rbuf) == 0) - return 0; - - rbuf->buf[rbuf->head] = datum; - smp_mb(); - rbuf->head = (rbuf->head + 1) % rbuf->len; - smp_mb(); - - return 1; -} diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S deleted file mode 100644 index 9e3455a09f8f..000000000000 --- a/arch/arm/common/fiq_glue.S +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - - .text - - .global fiq_glue_end - - /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */ - -ENTRY(fiq_glue) - /* store pc, cpsr from previous mode */ - mrs r12, spsr - sub r11, lr, #4 - subs r10, #1 - bne nested_fiq - - stmfd sp!, {r11-r12, lr} - - /* store r8-r14 from previous mode */ - sub sp, sp, #(7 * 4) - stmia sp, {r8-r14}^ - nop - - /* store r0-r7 from previous mode */ - stmfd sp!, {r0-r7} - - /* setup func(data,regs) arguments */ - mov r0, r9 - mov r1, sp - mov r3, r8 - - mov r7, sp - - /* Get sp and lr from non-user modes */ - and r4, r12, #MODE_MASK - cmp r4, #USR_MODE - beq fiq_from_usr_mode - - mov r7, sp - orr r4, r4, #(PSR_I_BIT | PSR_F_BIT) - msr cpsr_c, r4 - str sp, [r7, #(4 * 13)] - str lr, [r7, #(4 * 14)] - mrs r5, spsr - str r5, [r7, #(4 * 17)] - - cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - /* use fiq stack if we reenter this mode */ - subne sp, r7, #(4 * 3) - -fiq_from_usr_mode: - msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - mov r2, sp - sub sp, r7, #12 - stmfd sp!, {r2, ip, lr} - /* call func(data,regs) */ - blx r3 - ldmfd sp, {r2, ip, lr} - mov sp, r2 - - /* restore/discard saved state */ - cmp r4, #USR_MODE - beq fiq_from_usr_mode_exit - - msr cpsr_c, r4 - ldr sp, [r7, #(4 * 13)] - ldr lr, [r7, #(4 * 14)] - msr spsr_cxsf, r5 - -fiq_from_usr_mode_exit: - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - - ldmfd sp!, {r0-r7} - add sp, sp, #(7 * 4) - ldmfd sp!, {r11-r12, lr} -exit_fiq: - msr spsr_cxsf, r12 - add r10, #1 - movs pc, r11 - -nested_fiq: - orr r12, r12, #(PSR_F_BIT) - b exit_fiq - -fiq_glue_end: - -ENTRY(fiq_glue_setup) /* func, data, sp */ - mrs r3, cpsr - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - movs r8, r0 - mov r9, r1 - mov sp, r2 - moveq r10, #0 - movne r10, #1 - msr cpsr_c, r3 - bx lr - diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c deleted file mode 100644 index 4044c7db95c8..000000000000 --- a/arch/arm/common/fiq_glue_setup.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include - -extern unsigned char fiq_glue, fiq_glue_end; -extern void fiq_glue_setup(void *func, void *data, void *sp); - -static struct fiq_handler fiq_debbuger_fiq_handler = { - .name = "fiq_glue", -}; -DEFINE_PER_CPU(void *, fiq_stack); -static struct fiq_glue_handler *current_handler; -static DEFINE_MUTEX(fiq_glue_lock); - -static void fiq_glue_setup_helper(void *info) -{ - struct fiq_glue_handler *handler = info; - fiq_glue_setup(handler->fiq, handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); -} - -int fiq_glue_register_handler(struct fiq_glue_handler *handler) -{ - int ret; - int cpu; - - if (!handler || !handler->fiq) - return -EINVAL; - - mutex_lock(&fiq_glue_lock); - if (fiq_stack) { - ret = -EBUSY; - goto err_busy; - } - - for_each_possible_cpu(cpu) { - void *stack; - stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); - if (WARN_ON(!stack)) { - ret = -ENOMEM; - goto err_alloc_fiq_stack; - } - per_cpu(fiq_stack, cpu) = stack; - } - - ret = claim_fiq(&fiq_debbuger_fiq_handler); - if (WARN_ON(ret)) - goto err_claim_fiq; - - current_handler = handler; - on_each_cpu(fiq_glue_setup_helper, handler, true); - set_fiq_handler(&fiq_glue, &fiq_glue_end - &fiq_glue); - - mutex_unlock(&fiq_glue_lock); - return 0; - -err_claim_fiq: -err_alloc_fiq_stack: - for_each_possible_cpu(cpu) { - __free_pages(per_cpu(fiq_stack, cpu), THREAD_SIZE_ORDER); - per_cpu(fiq_stack, cpu) = NULL; - } -err_busy: - mutex_unlock(&fiq_glue_lock); - return ret; -} - -/** - * fiq_glue_resume - Restore fiqs after suspend or low power idle states - * - * This must be called before calling local_fiq_enable after returning from a - * power state where the fiq mode registers were lost. If a driver provided - * a resume hook when it registered the handler it will be called. - */ - -void fiq_glue_resume(void) -{ - if (!current_handler) - return; - fiq_glue_setup(current_handler->fiq, current_handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); - if (current_handler->resume) - current_handler->resume(current_handler); -} - diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 48a70afca283..7dfa9a85bc0c 100755 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -39,13 +39,6 @@ struct gic_chip_data { unsigned int irq_offset; void __iomem *dist_base; void __iomem *cpu_base; -#ifdef CONFIG_PM - u32 saved_enable[DIV_ROUND_UP(1020, 32)]; - u32 saved_conf[DIV_ROUND_UP(1020, 16)]; - u32 saved_pri[DIV_ROUND_UP(1020, 4)]; - u32 saved_target[DIV_ROUND_UP(1020, 4)]; -#endif - unsigned int max_irq; }; #ifndef MAX_GIC_NR @@ -87,7 +80,7 @@ static inline unsigned int gic_irq(unsigned int irq) * our "acknowledge" routine disable the interrupt, then mark it as * complete. */ -void gic_ack_irq(unsigned int irq) +static void gic_ack_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); @@ -97,7 +90,7 @@ void gic_ack_irq(unsigned int irq) spin_unlock(&irq_controller_lock); } -void gic_mask_irq(unsigned int irq) +static void gic_mask_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); @@ -106,7 +99,7 @@ void gic_mask_irq(unsigned int irq) spin_unlock(&irq_controller_lock); } -void gic_unmask_irq(unsigned int irq) +static void gic_unmask_irq(unsigned int irq) { u32 mask = 1 << (irq % 32); @@ -115,7 +108,7 @@ void gic_unmask_irq(unsigned int irq) spin_unlock(&irq_controller_lock); } -int gic_set_type(unsigned int irq, unsigned int type) +static int gic_set_type(unsigned int irq, unsigned int type) { void __iomem *base = gic_dist_base(irq); unsigned int gicirq = gic_irq(irq); @@ -161,7 +154,7 @@ int gic_set_type(unsigned int irq, unsigned int type) } #ifdef CONFIG_SMP -int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val) +static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val) { void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3); unsigned int shift = (irq % 4) * 8; @@ -228,15 +221,21 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) set_irq_chained_handler(irq, gic_handle_cascade_irq); } -static unsigned int _gic_dist_init(unsigned int gic_nr) +void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, + unsigned int irq_start) { unsigned int max_irq, i; - void __iomem *base = gic_data[gic_nr].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); /* @@ -277,96 +276,6 @@ static unsigned int _gic_dist_init(unsigned int gic_nr) for (i = 0; i < max_irq; i += 32) writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); - return max_irq; -} - -static void _gic_dist_exit(unsigned int gic_nr) -{ - writel(0, gic_data[gic_nr].dist_base + GIC_DIST_CTRL); -} - -#ifdef CONFIG_PM -void gic_dist_save(unsigned int gic_nr) -{ - unsigned int max_irq = gic_data[gic_nr].max_irq; - void __iomem *dist_base = gic_data[gic_nr].dist_base; - int i; - - if (gic_nr >= MAX_GIC_NR) - BUG(); - - _gic_dist_exit(gic_nr); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 16); i++) - gic_data[gic_nr].saved_conf[i] = - readl(dist_base + GIC_DIST_CONFIG + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 4); i++) - gic_data[gic_nr].saved_pri[i] = - readl(dist_base + GIC_DIST_PRI + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 4); i++) - gic_data[gic_nr].saved_target[i] = - readl(dist_base + GIC_DIST_TARGET + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 32); i++) - gic_data[gic_nr].saved_enable[i] = - readl(dist_base + GIC_DIST_ENABLE_SET + i * 4); -} - -void gic_dist_restore(unsigned int gic_nr) -{ - unsigned int max_irq; - unsigned int i; - void __iomem *dist_base; - void __iomem *cpu_base; - - if (gic_nr >= MAX_GIC_NR) - BUG(); - - _gic_dist_init(gic_nr); - - max_irq = gic_data[gic_nr].max_irq; - dist_base = gic_data[gic_nr].dist_base; - cpu_base = gic_data[gic_nr].cpu_base; - - for (i = 0; i < DIV_ROUND_UP(max_irq, 16); i++) - writel(gic_data[gic_nr].saved_conf[i], - dist_base + GIC_DIST_CONFIG + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 4); i++) - writel(gic_data[gic_nr].saved_pri[i], - dist_base + GIC_DIST_PRI + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 4); i++) - writel(gic_data[gic_nr].saved_target[i], - dist_base + GIC_DIST_TARGET + i * 4); - - for (i = 0; i < DIV_ROUND_UP(max_irq, 32); i++) - writel(gic_data[gic_nr].saved_enable[i], - dist_base + GIC_DIST_ENABLE_SET + i * 4); - - writel(1, dist_base + GIC_DIST_CTRL); - writel(0xf0, cpu_base + GIC_CPU_PRIMASK); - writel(1, cpu_base + GIC_CPU_CTRL); -} -#endif - -void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, - unsigned int irq_start) -{ - unsigned int max_irq; - unsigned int i; - - if (gic_nr >= MAX_GIC_NR) - BUG(); - - gic_data[gic_nr].dist_base = base; - gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; - - max_irq = _gic_dist_init(gic_nr); - gic_data[gic_nr].max_irq = max_irq; - /* * Setup the Linux IRQ subsystem. */ @@ -380,14 +289,6 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, writel(1, base + GIC_DIST_CTRL); } -void gic_dist_exit(unsigned int gic_nr) -{ - if (gic_nr >= MAX_GIC_NR) - BUG(); - - _gic_dist_exit(gic_nr); -} - void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) { if (gic_nr >= MAX_GIC_NR) @@ -399,14 +300,6 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) writel(1, base + GIC_CPU_CTRL); } -void gic_cpu_exit(unsigned int gic_nr) -{ - if (gic_nr >= MAX_GIC_NR) - BUG(); - - writel(0, gic_data[gic_nr].cpu_base + GIC_CPU_CTRL); -} - #ifdef CONFIG_SMP void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) { diff --git a/arch/arm/configs/olympus_defconfig b/arch/arm/configs/olympus_defconfig deleted file mode 100644 index 2b63a00fc455..000000000000 --- a/arch/arm/configs/olympus_defconfig +++ /dev/null @@ -1,1675 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.34-rc2 -# Tue Mar 30 21:25:33 2010 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_BZIP2 is not set -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_SWAP=y -# CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set -# CONFIG_TINY_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -CONFIG_RCU_FAST_NO_HZ=y -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -# CONFIG_CGROUP_NS is not set -CONFIG_CGROUP_FREEZER=y -# CONFIG_CGROUP_DEVICE is not set -# CONFIG_CPUSETS is not set -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -# CONFIG_CGROUP_MEM_RES_CTLR is not set -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_LZO is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=5 -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_ASHMEM=y -CONFIG_AIO=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -# CONFIG_PERF_EVENTS is not set -# CONFIG_PERF_COUNTERS is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_COMPAT_BRK=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_CLK=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_UNLOCK is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_UNLOCK is not set -# CONFIG_INLINE_READ_UNLOCK_BH is not set -# CONFIG_INLINE_READ_UNLOCK_IRQ is not set -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_UNLOCK is not set -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_STMP3XXX is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_NUC93X is not set -CONFIG_ARCH_TEGRA=y -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P6440 is not set -# CONFIG_ARCH_S5P6442 is not set -# CONFIG_ARCH_S5PC1XX is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP is not set - -# -# NVIDIA Tegra options -# -CONFIG_ARCH_TEGRA_2x_SOC=y -# CONFIG_MACH_HARMONY is not set -CONFIG_MACH_OLYMPUS=y -# CONFIG_TEGRA_DEBUG_UART_NONE is not set -# CONFIG_TEGRA_DEBUG_UARTA is not set -CONFIG_TEGRA_DEBUG_UARTB=y -# CONFIG_TEGRA_DEBUG_UARTC is not set -# CONFIG_TEGRA_DEBUG_UARTD is not set -# CONFIG_TEGRA_DEBUG_UARTE is not set -CONFIG_TEGRA_SYSTEM_DMA=y -CONFIG_WIFI_CONTROL_FUNC=y - -# -# Processor Type -# -CONFIG_CPU_32v6K=y -CONFIG_CPU_V7=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -CONFIG_OUTER_CACHE=y -CONFIG_CACHE_L2X0=y -CONFIG_CACHE_PL310=y -CONFIG_ARM_L1_CACHE_SHIFT=5 -CONFIG_ARCH_HAS_BARRIERS=y -CONFIG_CPU_HAS_PMU=y -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -CONFIG_ARM_GIC=y -CONFIG_COMMON_CLKDEV=y - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_SMP=y -CONFIG_HAVE_ARM_SCU=y -CONFIG_HAVE_ARM_TWD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_NR_CPUS=2 -CONFIG_HOTPLUG_CPU=y -CONFIG_LOCAL_TIMERS=y -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_HZ=100 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -CONFIG_HIGHMEM=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set - -# -# CPU Power Management -# -# CONFIG_CPU_IDLE is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_NEON is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP_SMP=y -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_HAS_WAKELOCK=y -CONFIG_HAS_EARLYSUSPEND=y -CONFIG_WAKELOCK=y -CONFIG_WAKELOCK_STAT=y -CONFIG_USER_WAKELOCK=y -CONFIG_EARLYSUSPEND=y -# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set -# CONFIG_CONSOLE_EARLYSUSPEND is not set -CONFIG_FB_EARLYSUSPEND=y -# CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set -CONFIG_PM_OPS=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set -CONFIG_ANDROID_PARANOID_NETWORK=y -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -# CONFIG_BT_BNEP_MC_FILTER is not set -# CONFIG_BT_BNEP_PROTO_FILTER is not set -CONFIG_BT_HIDP=y - -# -# Bluetooth device drivers -# -# CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_BCSP is not set -CONFIG_BT_HCIUART_LL=y -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_MRVL is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -# CONFIG_LIB80211 is not set - -# -# CFG80211 needs to be enabled for MAC80211 -# -# CONFIG_WIMAX is not set -CONFIG_RFKILL=y -# CONFIG_RFKILL_PM is not set -# CONFIG_RFKILL_INPUT is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -# CONFIG_DEVTMPFS is not set -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -CONFIG_MTD_NAND_TEGRA=y -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_ANDROID_PMEM is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_KERNEL_DEBUGGER_CORE=y -# CONFIG_ISL29003 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_AKM8973 is not set -CONFIG_SENSORS_AKM8973_AKMD=y -# CONFIG_SENSORS_LIS331DLH is not set -# CONFIG_WL127X_RFKILL is not set -# CONFIG_DS1682 is not set -CONFIG_UID_STAT=y -CONFIG_APANIC=y -CONFIG_APANIC_PLABEL="crashdata" -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_IWMC3200TOP is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM=y -CONFIG_DM_DEBUG=y -CONFIG_DM_CRYPT=y -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -CONFIG_DM_UEVENT=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -CONFIG_SMC91X=y -# CONFIG_DM9000 is not set -# CONFIG_ETHOC is not set -# CONFIG_SMC911X is not set -# CONFIG_SMSC911X is not set -# CONFIG_DNET is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_B44 is not set -# CONFIG_KS8842 is not set -# CONFIG_KS8851_MLL is not set -CONFIG_NETDEV_1000=y -CONFIG_NETDEV_10000=y -CONFIG_WLAN=y -# CONFIG_HOSTAP is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_MPPE=y -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y -# CONFIG_SLIP is not set -CONFIG_SLHC=y -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set -CONFIG_INPUT_KEYRESET=y - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_AD7879_I2C is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set -CONFIG_TOUCHSCREEN_QUANTUM_OBP=y -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -CONFIG_INPUT_KEYCHORD=y -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_UINPUT=y -CONFIG_INPUT_GPIO=y -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVMEM=y -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_TEGRA=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_TIMBERDALE is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_DCC_TTY is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -# CONFIG_I2C_CHARDEV is not set -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set -CONFIG_I2C_TEGRA=y -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_SPI is not set - -# -# PPS support -# -# CONFIG_PPS is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_IT8761E is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_ADP5588 is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# - -# -# AC97 GPIO expanders: -# -CONFIG_W1=y - -# -# 1-wire Bus Masters -# -CONFIG_W1_MASTER_DS2482=y -# CONFIG_W1_MASTER_DS1WM is not set -# CONFIG_W1_MASTER_GPIO is not set - -# -# 1-wire Slaves -# -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -# CONFIG_W1_SLAVE_BQ27000 is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -CONFIG_PDA_POWER=y -# CONFIG_BATTERY_DS2760 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_BQ27x00 is not set -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_TPS65010 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_AB3100_CORE is not set -CONFIG_REGULATOR=y -CONFIG_REGULATOR_DEBUG=y -# CONFIG_REGULATOR_DUMMY is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_LP3971 is not set -CONFIG_REGULATOR_TPS65023=y -# CONFIG_REGULATOR_TPS6507X is not set -CONFIG_MEDIA_SUPPORT=y - -# -# Multimedia core support -# -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -# CONFIG_VIDEO_ALLOW_V4L1 is not set -CONFIG_VIDEO_V4L1_COMPAT=y -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=y - -# -# Multimedia drivers -# -CONFIG_IR_CORE=y -CONFIG_VIDEO_IR=y -# CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=y -# CONFIG_MEDIA_TUNER_CUSTOMISE is not set -CONFIG_MEDIA_TUNER_SIMPLE=y -CONFIG_MEDIA_TUNER_TDA8290=y -CONFIG_MEDIA_TUNER_TDA9887=y -CONFIG_MEDIA_TUNER_TEA5761=y -CONFIG_MEDIA_TUNER_TEA5767=y -CONFIG_MEDIA_TUNER_MT20XX=y -CONFIG_MEDIA_TUNER_XC2028=y -CONFIG_MEDIA_TUNER_XC5000=y -CONFIG_MEDIA_TUNER_MC44S803=y -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -CONFIG_VIDEO_IR_I2C=y -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_SOC_CAMERA is not set -CONFIG_RADIO_ADAPTERS=y -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_RADIO_SI470X is not set -# CONFIG_RADIO_TEA5764 is not set -# CONFIG_RADIO_SAA7706H is not set -# CONFIG_RADIO_TEF6862 is not set -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_TEGRA=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_LOGO is not set -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HIDRAW is not set -# CONFIG_HID_PID is not set - -# -# Special HID drivers -# -# CONFIG_HID_APPLE is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_WACOM is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_GADGET_MUSB_HDRC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=500 -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AT91 is not set -# CONFIG_USB_GADGET_ATMEL_USBA is not set -CONFIG_USB_GADGET_FSL_USB2=y -CONFIG_USB_FSL_USB2=y -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_PXA25X is not set -# CONFIG_USB_GADGET_R8A66597 is not set -# CONFIG_USB_GADGET_PXA27X is not set -# CONFIG_USB_GADGET_S3C_HSOTG is not set -# CONFIG_USB_GADGET_IMX is not set -# CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_AMD5536UDC is not set -# CONFIG_USB_GADGET_FSL_QE is not set -# CONFIG_USB_GADGET_CI13XXX is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LANGWELL is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -CONFIG_USB_ANDROID=y -CONFIG_USB_ANDROID_ACM=y -CONFIG_USB_ANDROID_ADB=y -CONFIG_USB_ANDROID_MASS_STORAGE=y -CONFIG_USB_ANDROID_RNDIS=y -# CONFIG_USB_ANDROID_RNDIS_WCEIS is not set -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_G_NOKIA is not set -# CONFIG_USB_G_MULTI is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ULPI is not set -# CONFIG_NOP_USB_XCEIV is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_EMBEDDED_SDIO=y -CONFIG_MMC_PARANOID_SD_INIT=y - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -# CONFIG_MMC_BLOCK_BOUNCE is not set -CONFIG_MMC_BLOCK_DEFERRED_RESUME=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PLTFM is not set -CONFIG_MMC_SDHCI_TEGRA=y -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -CONFIG_SWITCH=y -# CONFIG_SWITCH_GPIO is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -# CONFIG_RTC_INTF_SYSFS is not set -# CONFIG_RTC_INTF_PROC is not set -# CONFIG_RTC_INTF_DEV is not set -CONFIG_RTC_INTF_ALARM=y -CONFIG_RTC_INTF_ALARM_DEV=y -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# TI VLYNQ -# -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -# CONFIG_ECHO is not set - -# -# Android -# -CONFIG_ANDROID=y -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ANDROID_LOGGER=y -CONFIG_ANDROID_RAM_CONSOLE=y -CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128 -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16 -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8 -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d -# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set -CONFIG_ANDROID_TIMED_OUTPUT=y -# CONFIG_ANDROID_TIMED_GPIO is not set -CONFIG_ANDROID_LOW_MEMORY_KILLER=y - -# -# Qualcomm MSM Camera And Video -# - -# -# Camera Sensor Selection -# -# CONFIG_POHMELFS is not set - -# -# RAR Register Driver -# -# CONFIG_RAR_REGISTER is not set -# CONFIG_IIO is not set -# CONFIG_RAMZSWAP is not set -# CONFIG_BATMAN_ADV is not set -# CONFIG_STRIP is not set -# CONFIG_FB_SM7XX is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -# CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_YAFFS_FS=y -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -CONFIG_YAFFS2_TAG_NO_ECC=y -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y -# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_CMDLINE_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SLAB_LEAK is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_DEBUG_SG=y -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_PAGE_POISONING is not set -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_BOOT_TRACER is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_KMEMTRACE is not set -# CONFIG_WORKQUEUE_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_OC_ETM is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SECURITY_SMACK is not set -# CONFIG_DEFAULT_SECURITY_TOMOYO is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_REED_SOLOMON=y -CONFIG_REED_SOLOMON_ENC8=y -CONFIG_REED_SOLOMON_DEC8=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y diff --git a/arch/arm/configs/stingray_defconfig b/arch/arm/configs/stingray_defconfig deleted file mode 100644 index 88749e7cc6cf..000000000000 --- a/arch/arm/configs/stingray_defconfig +++ /dev/null @@ -1,427 +0,0 @@ -CONFIG_EXPERIMENTAL=y -CONFIG_CROSS_COMPILE="arm-eabi-" -# CONFIG_SWAP is not set -CONFIG_RCU_FAST_NO_HZ=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_PANIC_TIMEOUT=5 -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_ELF_CORE is not set -CONFIG_ASHMEM=y -# CONFIG_PERF_EVENTS is not set -CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_TEGRA=y -CONFIG_MACH_HARMONY=y -CONFIG_MACH_OLYMPUS=y -CONFIG_MACH_STINGRAY=y -CONFIG_TEGRA_DEBUG_UARTB=y -CONFIG_WIFI_CONTROL_FUNC=y -CONFIG_TEGRA_EMC_SCALING_ENABLE=y -CONFIG_ARM_ERRATA_742231=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_743622=y -CONFIG_FIQ_DEBUGGER_NO_SLEEP=y -CONFIG_FIQ_DEBUGGER_CONSOLE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PREEMPT=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="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_INTERACTIVE=y -CONFIG_CPU_IDLE=y -CONFIG_VFP=y -CONFIG_PM=y -CONFIG_WAKELOCK=y -CONFIG_PM_RUNTIME=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -CONFIG_NF_CONNTRACK_SIP=y -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -CONFIG_NETFILTER_XT_MATCH_OWNER=y -CONFIG_NETFILTER_XT_MATCH_POLICY=y -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_ADDRTYPE=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_NF_NAT=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_U32=y -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -CONFIG_NET_ACT_GACT=y -CONFIG_NET_ACT_MIRRED=y -# CONFIG_RPS is not set -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_HIDP=y -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_LL=y -CONFIG_RFKILL=y -# CONFIG_RFKILL_PM 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_TEGRA=y -CONFIG_MTD_NAND_IDS=y -CONFIG_BLK_DEV_LOOP=y -# CONFIG_ANDROID_PMEM is not set -CONFIG_SENSORS_AK8975=y -CONFIG_SENSORS_CAP_PROX=y -CONFIG_SENSORS_KXTF9=y -CONFIG_SENSORS_L3G4200D=y -CONFIG_SENSORS_MAX9635=y -CONFIG_SENSORS_NCT1008=y -CONFIG_SENSORS_MOTO_BMP085=y -CONFIG_UID_STAT=y -CONFIG_APANIC=y -CONFIG_APANIC_PLABEL="crashdata" -CONFIG_TEGRA_CRYPTO_DEV=y -CONFIG_TS27010MUX=y -CONFIG_MDM6600_CTRL=y -CONFIG_WRIGLEY_CTRL=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_MD=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_DEBUG=y -CONFIG_DM_CRYPT=y -CONFIG_DM_UEVENT=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_BCM4329=m -CONFIG_BCM4329_FW_PATH="/vendor/firmware/fw_bcm4329.bin" -CONFIG_BCM4329_NVRAM_PATH="/system/etc/wifi/bcm4329.cal" -CONFIG_USB_USBNET=y -CONFIG_USB_NET_GOBI=y -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -CONFIG_PPP=y -CONFIG_PPP_ASYNC=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_MPPE=y -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_KEYRESET=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_QUANTUM_OBP=y -CONFIG_INPUT_MISC=y -CONFIG_INPUT_KEYCHORD=y -CONFIG_INPUT_JOYSTICK=y -CONFIG_INPUT_UINPUT=y -CONFIG_INPUT_GPIO=y -# CONFIG_SERIO is not set -# CONFIG_VT is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_TEGRA=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_TEGRA=y -CONFIG_SPI=y -CONFIG_SPI_TEGRA=y -CONFIG_GPIO_SYSFS=y -CONFIG_W1_MASTER_TEGRA=y -CONFIG_POWER_SUPPLY=y -CONFIG_BATTERY_DS2781=y -CONFIG_CHARGER_BQ24617=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_TEGRA_WATCHDOG=y -CONFIG_TEGRA_WATCHDOG_ENABLE_ON_PROBE=y -CONFIG_MFD_CPCAP=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_DEBUG=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_MAX8649=y -CONFIG_REGULATOR_TPS65023=y -CONFIG_REGULATOR_CPCAP=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_VIDEO_DEV=y -# CONFIG_VIDEO_ALLOW_V4L1 is not set -# CONFIG_IR_CORE is not set -# CONFIG_MEDIA_TUNER_SIMPLE is not set -# CONFIG_MEDIA_TUNER_TDA8290 is not set -# CONFIG_MEDIA_TUNER_TDA827X is not set -# CONFIG_MEDIA_TUNER_TDA18271 is not set -# CONFIG_MEDIA_TUNER_TDA9887 is not set -# CONFIG_MEDIA_TUNER_TEA5761 is not set -# CONFIG_MEDIA_TUNER_TEA5767 is not set -# CONFIG_MEDIA_TUNER_MT20XX is not set -# CONFIG_MEDIA_TUNER_MT2060 is not set -# CONFIG_MEDIA_TUNER_MT2266 is not set -# CONFIG_MEDIA_TUNER_MT2131 is not set -# CONFIG_MEDIA_TUNER_QT1010 is not set -# CONFIG_MEDIA_TUNER_XC2028 is not set -# CONFIG_MEDIA_TUNER_XC5000 is not set -# CONFIG_MEDIA_TUNER_MXL5005S is not set -# CONFIG_MEDIA_TUNER_MXL5007T is not set -# CONFIG_MEDIA_TUNER_MC44S803 is not set -# CONFIG_MEDIA_TUNER_MAX2165 is not set -CONFIG_VIDEO_OV5650=y -CONFIG_VIDEO_SOC2030=y -CONFIG_VIDEO_DW9714L=y -# CONFIG_V4L_USB_DRIVERS is not set -# CONFIG_RADIO_ADAPTERS is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -CONFIG_FB=y -CONFIG_TEGRA_GRHOST=y -CONFIG_TEGRA_DC=y -# CONFIG_NVMAP_ALLOW_SYSMEM is not set -CONFIG_NVMAP_HIGHMEM_ONLY=y -CONFIG_NVMAP_CARVEOUT_KILLER=y -CONFIG_HIDRAW=y -CONFIG_HID_3M_PCT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CANDO=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_DRAGONRISE=y -CONFIG_HID_EGALAX=y -CONFIG_HID_EZKEY=y -CONFIG_HID_KYE=y -CONFIG_HID_GYRATION=y -CONFIG_HID_TWINHAN=y -CONFIG_HID_KENSINGTON=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MAGICMOUSE=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MOSART=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_MOTOROLA=y -CONFIG_HID_NTRIG=y -CONFIG_HID_ORTEK=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_PICOLCD=y -CONFIG_HID_QUANTA=y -CONFIG_HID_ROCCAT_KONE=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_STANTUM=y -CONFIG_HID_SUNPLUS=y -CONFIG_HID_GREENASIA=y -CONFIG_HID_SMARTJOYPLUS=y -CONFIG_HID_TOPSEED=y -CONFIG_HID_THRUSTMASTER=y -CONFIG_HID_WACOM=y -CONFIG_HID_ZEROPLUS=y -CONFIG_HID_ZYDACRON=y -CONFIG_JOYSTICK_XPAD=y -CONFIG_JOYSTICK_XPAD_FF=y -CONFIG_JOYSTICK_XPAD_LEDS=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_SUSPEND=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_TEGRA=y -CONFIG_USB_ACM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_MDM6600=y -CONFIG_USB_SERIAL_MOTO_FLASH_MODEM=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=500 -CONFIG_USB_ANDROID=y -CONFIG_USB_ANDROID_ACM=y -CONFIG_USB_ANDROID_ADB=y -CONFIG_USB_ANDROID_MTP=y -CONFIG_USB_ANDROID_RNDIS=y -CONFIG_USB_ANDROID_RNDIS_WCEIS=y -CONFIG_USB_ANDROID_ACCESSORY=y -CONFIG_USB_CPCAP_OTG=y -CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_EMBEDDED_SDIO=y -CONFIG_MMC_PARANOID_SD_INIT=y -# CONFIG_MMC_BLOCK_BOUNCE is not set -CONFIG_MMC_BLOCK_DEFERRED_RESUME=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_TEGRA=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_AUO_PANEL=y -CONFIG_LEDS_CPCAP=y -CONFIG_LEDS_LP8550=y -CONFIG_LEDS_LM3559=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_SWITCH=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_INTF_SYSFS is not set -# CONFIG_RTC_INTF_PROC is not set -# CONFIG_RTC_INTF_DEV is not set -CONFIG_RTC_DRV_CPCAP=y -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -CONFIG_ANDROID=y -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ANDROID_LOGGER=y -CONFIG_ANDROID_RAM_CONSOLE=y -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y -CONFIG_ANDROID_LOW_MEMORY_KILLER=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_DEBUG=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_PRINTK_TIME=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_STACKTRACE is not set -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y -CONFIG_DEBUG_LIST=y -CONFIG_DEBUG_SG=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_TWOFISH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_TEGRA_AES=y diff --git a/arch/arm/configs/tegra_android_defconfig b/arch/arm/configs/tegra_android_defconfig deleted file mode 100644 index 55367029c677..000000000000 --- a/arch/arm/configs/tegra_android_defconfig +++ /dev/null @@ -1,307 +0,0 @@ -CONFIG_EXPERIMENTAL=y -CONFIG_CROSS_COMPILE="arm-eabi-" -# CONFIG_SWAP is not set -CONFIG_RCU_FAST_NO_HZ=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_PANIC_TIMEOUT=10 -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_ELF_CORE is not set -CONFIG_ASHMEM=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_TEGRA=y -CONFIG_MACH_HARMONY=y -CONFIG_MACH_VENTANA=y -CONFIG_TEGRA_DEBUG_UARTD=y -CONFIG_TEGRA_PWM=y -CONFIG_TEGRA_NVRM=y -CONFIG_TEGRA_NVOS=y -CONFIG_FIQ_DEBUGGER=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PREEMPT=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="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_IDLE=y -CONFIG_VFP=y -CONFIG_PM=y -CONFIG_WAKELOCK=y -CONFIG_PM_RUNTIME=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -CONFIG_NF_CONNTRACK_SIP=y -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -CONFIG_NETFILTER_XT_MATCH_OWNER=y -CONFIG_NETFILTER_XT_MATCH_POLICY=y -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_ADDRTYPE=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_NF_NAT=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_U32=y -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -CONFIG_NET_ACT_GACT=y -CONFIG_NET_ACT_MIRRED=y -# CONFIG_RPS is not set -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_HIDP=y -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_LL=y -CONFIG_RFKILL=y -# CONFIG_FIRMWARE_IN_KERNEL 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_TEGRA=y -CONFIG_MTD_NAND=y -CONFIG_BLK_DEV_LOOP=y -# CONFIG_ANDROID_PMEM is not set -CONFIG_SENSORS_AK8975=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_MD=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_CRYPT=y -CONFIG_DM_UEVENT=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=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_PPP_MPPE=y -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_KEYRESET=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_PANJIT_I2C=y -CONFIG_INPUT_MISC=y -CONFIG_INPUT_UINPUT=y -CONFIG_INPUT_GPIO=y -# CONFIG_SERIO is not set -# CONFIG_VT is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_TEGRA=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_TEGRA=y -CONFIG_SPI=y -CONFIG_SPI_TEGRA=y -CONFIG_GPIO_SYSFS=y -CONFIG_POWER_SUPPLY=y -CONFIG_PDA_POWER=y -CONFIG_WATCHDOG=y -CONFIG_TEGRA_WATCHDOG=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_TPS6586X=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_VIDEO_DEV=y -# CONFIG_VIDEO_ALLOW_V4L1 is not set -# CONFIG_RC_MAP is not set -# CONFIG_IR_NEC_DECODER is not set -# CONFIG_IR_RC5_DECODER is not set -# CONFIG_IR_RC6_DECODER is not set -# CONFIG_IR_JVC_DECODER is not set -# CONFIG_IR_SONY_DECODER is not set -# CONFIG_MEDIA_TUNER_CUSTOMISE is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -CONFIG_USB_VIDEO_CLASS=y -# CONFIG_USB_GSPCA is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -CONFIG_FB=y -CONFIG_TEGRA_GRHOST=y -CONFIG_TEGRA_DC=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_BACKLIGHT_PWM=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_SUSPEND=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -CONFIG_USB_TEGRA_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y -CONFIG_USB_SERIAL=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=500 -CONFIG_USB_ANDROID=y -CONFIG_USB_ANDROID_ADB=y -CONFIG_USB_ANDROID_MTP=y -CONFIG_USB_TEGRA_OTG=y -CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_EMBEDDED_SDIO=y -CONFIG_MMC_PARANOID_SD_INIT=y -# CONFIG_MMC_BLOCK_BOUNCE is not set -CONFIG_MMC_BLOCK_DEFERRED_RESUME=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_TEGRA=y -CONFIG_SWITCH=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_TPS6586X=y -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -CONFIG_ANDROID=y -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ANDROID_LOGGER=y -CONFIG_ANDROID_RAM_CONSOLE=y -CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y -CONFIG_ANDROID_LOW_MEMORY_KILLER=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_PRINTK_TIME=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_TWOFISH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig deleted file mode 100644 index 3d730a772a2b..000000000000 --- a/arch/arm/configs/tegra_defconfig +++ /dev/null @@ -1,1102 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.35-rc2 -# Tue Jun 8 17:11:49 2010 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -# CONFIG_ARCH_USES_GETTIMEOFFSET is not set -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_BZIP2 is not set -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_SWAP=y -# CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set -# CONFIG_TINY_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -# CONFIG_CGROUP_NS is not set -CONFIG_CGROUP_FREEZER=y -# CONFIG_CGROUP_DEVICE is not set -# CONFIG_CPUSETS is not set -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -# CONFIG_CGROUP_MEM_RES_CTLR is not set -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -# CONFIG_BLK_CGROUP is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_LZO is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -# CONFIG_PERF_EVENTS is not set -# CONFIG_PERF_COUNTERS is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_COMPAT_BRK=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_CLK=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_UNLOCK is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_UNLOCK is not set -# CONFIG_INLINE_READ_UNLOCK_BH is not set -# CONFIG_INLINE_READ_UNLOCK_IRQ is not set -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_UNLOCK is not set -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_STMP3XXX is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_NUC93X is not set -CONFIG_ARCH_TEGRA=y -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P6440 is not set -# CONFIG_ARCH_S5P6442 is not set -# CONFIG_ARCH_S5PC100 is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_PLAT_SPEAR is not set - -# -# NVIDIA Tegra options -# -CONFIG_ARCH_TEGRA_2x_SOC=y - -# -# Tegra board type -# -CONFIG_MACH_HARMONY=y -# CONFIG_TEGRA_DEBUG_UART_NONE is not set -# CONFIG_TEGRA_DEBUG_UARTA is not set -# CONFIG_TEGRA_DEBUG_UARTB is not set -# CONFIG_TEGRA_DEBUG_UARTC is not set -CONFIG_TEGRA_DEBUG_UARTD=y -# CONFIG_TEGRA_DEBUG_UARTE is not set - -# -# Processor Type -# -CONFIG_CPU_32v6K=y -CONFIG_CPU_V7=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_CACHE_L2X0=y -CONFIG_ARM_L1_CACHE_SHIFT=5 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARCH_HAS_BARRIERS=y -CONFIG_CPU_HAS_PMU=y -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -CONFIG_ARM_GIC=y -CONFIG_COMMON_CLKDEV=y - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_SMP=y -CONFIG_HAVE_ARM_SCU=y -CONFIG_HAVE_ARM_TWD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_NR_CPUS=2 -CONFIG_HOTPLUG_CPU=y -CONFIG_LOCAL_TIMERS=y -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_HZ=100 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -CONFIG_HIGHMEM=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" -# CONFIG_CMDLINE_FORCE is not set -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set - -# -# CPU Power Management -# -# CONFIG_CPU_IDLE is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_NEON is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP_SMP=y -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -# CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set -CONFIG_PM_OPS=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set -CONFIG_RPS=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -# CONFIG_DEVTMPFS is not set -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -CONFIG_MISC_DEVICES=y -# CONFIG_ANDROID_PMEM is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_NET_ETHERNET is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_WLAN is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_DEVKMEM is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_RAMOOPS is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set - -# -# PPS support -# -# CONFIG_PPS is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_IT8761E is not set - -# -# I2C GPIO expanders: -# - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -# CONFIG_MFD_SUPPORT is not set -CONFIG_REGULATOR=y -# CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_DUMMY=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_VIRTUAL_CONSUMER=y -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_TEGRA=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_LOGO is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -# CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SLAB_LEAK is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_DEBUG_SG=y -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_LKDTM is not set -# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_PAGE_POISONING is not set -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_BOOT_TRACER is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_KMEMTRACE is not set -# CONFIG_WORKQUEUE_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_OC_ETM is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SECURITY_SMACK is not set -# CONFIG_DEFAULT_SECURITY_TOMOYO is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index d7575554e407..6e8f05c8a1c8 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -215,7 +215,7 @@ @ Slightly optimised to avoid incrementing the pointer twice usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort .if \rept == 2 - usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort + usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort .endif add\cond \ptr, #\rept * \inc diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 5078dc6c50d8..4656a24058d2 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -336,7 +336,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr * Harvard caches are synchronised for the user space address range. * This is used for the ARM private sys_cacheflush system call. */ -#define flush_cache_user_range(start,end) \ +#define flush_cache_user_range(vma,start,end) \ __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) /* diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index 57f1fa0e983b..b2deda181549 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -8,9 +8,6 @@ #include /* HZ */ -#ifdef CONFIG_ARCH_PROVIDES_UDELAY -#include -#else extern void __delay(int loops); /* @@ -43,6 +40,5 @@ extern void __const_udelay(unsigned long); __const_udelay((n) * ((2199023U*HZ)>>11))) : \ __udelay(n)) -#endif /* defined(ARCH_PROVIDES_UDELAY) */ #endif /* defined(_ARM_DELAY_H) */ diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h deleted file mode 100644 index e711b57b22f1..000000000000 --- a/arch/arm/include/asm/fiq_debugger.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * arch/arm/include/asm/fiq_debugger.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ -#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ - -#include - -#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR -#define FIQ_DEBUGGER_BREAK 0x00ff0100 - -#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq" -#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal" -#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup" - -struct fiq_debugger_pdata { - int (*uart_init)(struct platform_device *pdev); - void (*uart_free)(struct platform_device *pdev); - int (*uart_resume)(struct platform_device *pdev); - int (*uart_getc)(struct platform_device *pdev); - void (*uart_putc)(struct platform_device *pdev, unsigned int c); - void (*uart_flush)(struct platform_device *pdev); - - void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq, - bool enable); - void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq); - - void (*force_irq)(struct platform_device *pdev, unsigned int irq); - void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq); -}; - -#endif diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h deleted file mode 100644 index d54c29db97a8..000000000000 --- a/arch/arm/include/asm/fiq_glue.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_FIQ_GLUE_H -#define __ASM_FIQ_GLUE_H - -struct fiq_glue_handler { - void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp); - void (*resume)(struct fiq_glue_handler *h); -}; - -int fiq_glue_register_handler(struct fiq_glue_handler *handler); - -#ifdef CONFIG_FIQ_GLUE -void fiq_glue_resume(void); -#else -static inline void fiq_glue_resume(void) {} -#endif - -#endif diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index d62847df3df5..6bcba48800fe 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -53,14 +53,9 @@ #define L2X0_LINE_DATA 0xF10 #define L2X0_LINE_TAG 0xF30 #define L2X0_DEBUG_CTRL 0xF40 -#define L2X0_PREFETCH_OFFSET 0xF60 -#define L2X0_PWR_CTRL 0xF80 #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); -extern void l2x0_shutdown(void); -extern void l2x0_restart(void); -extern bool l2x0_disabled; #endif #endif diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 5fd0ff2bb821..7f34333bb545 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -34,21 +34,9 @@ #ifndef __ASSEMBLY__ void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); -void gic_dist_save(unsigned int gic_nr); -void gic_dist_restore(unsigned int gic_nr); -void gic_dist_exit(unsigned int gic_nr); void gic_cpu_init(unsigned int gic_nr, void __iomem *base); -void gic_cpu_exit(unsigned int gic_nr); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); - -void gic_ack_irq(unsigned int irq); -void gic_mask_irq(unsigned int irq); -void gic_unmask_irq(unsigned int irq); -int gic_set_type(unsigned int irq, unsigned int type); -#ifdef CONFIG_SMP -int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val); -#endif #endif #endif diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 48066ce9ea34..08265993227f 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -70,8 +70,7 @@ extern int kgdb_fault_expected; #define _GP_REGS 16 #define _FP_REGS 8 #define _EXTRA_REGS 2 -#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) -#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) +#define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) #define KGDB_MAX_NO_CPUS 1 #define BUFMAX 400 @@ -94,7 +93,7 @@ extern int kgdb_fault_expected; #define _SPT 13 #define _LR 14 #define _PC 15 -#define _CPSR (GDB_MAX_REGS - 1) +#define _CPSR (DBG_MAX_REG_NUM - 1) /* * So that we can denote the end of a frame for tracing, diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h deleted file mode 100644 index f8d391ad9203..000000000000 --- a/arch/arm/include/asm/mach/mmc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/include/asm/mach/mmc.h - */ -#ifndef ASMARM_MACH_MMC_H -#define ASMARM_MACH_MMC_H - -#include -#include -#include - -struct embedded_sdio_data { - struct sdio_cis cis; - struct sdio_cccr cccr; - struct sdio_embedded_func *funcs; - int num_funcs; -}; - -struct mmc_platform_data { - unsigned int ocr_mask; /* available voltages */ - int built_in; /* built-in device flag */ - u32 (*translate_vdd)(struct device *, unsigned int); - unsigned int (*status)(struct device *); - struct embedded_sdio_data *embedded_sdio; - int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id); -}; - -#endif diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index b4ffe9d5b526..68870c776671 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -13,10 +13,6 @@ typedef struct { #ifdef CONFIG_CPU_HAS_ASID #define ASID(mm) ((mm)->context.id & 255) - -/* init_mm.context.id_lock should be initialized. */ -#define INIT_MM_CONTEXT(name) \ - .context.id_lock = __SPIN_LOCK_UNLOCKED(name.context.id_lock), #else #define ASID(mm) (0) #endif diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 73ee18b1a054..e90b167ea848 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -184,7 +184,6 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #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_INNER_WB (0x05 << 2) /* 0101 (armv6, armv7) */ #define L_PTE_MT_MASK (0x0f << 2) #ifndef __ASSEMBLY__ @@ -326,8 +325,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) #endif -#define pgprot_inner_writeback(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_INNER_WB) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_present(pmd) (pmd_val(pmd)) diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index 963a338d567b..e6215305544a 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h @@ -13,13 +13,9 @@ static inline int tlb_ops_need_broadcast(void) return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; } -#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7 -#define cache_ops_need_broadcast() 0 -#else static inline int cache_ops_need_broadcast(void) { return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; } -#endif #endif diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index ce0a8b95da39..634f357be6bb 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -17,7 +17,6 @@ #define TWD_TIMER_CONTROL_ONESHOT (0 << 1) #define TWD_TIMER_CONTROL_PERIODIC (1 << 1) #define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) -#define TWD_TIMER_CONTROL_PRESCALE_MASK (0xFF << 8) struct clock_event_device; @@ -27,14 +26,4 @@ void twd_timer_stop(void); int twd_timer_ack(void); void twd_timer_setup(struct clock_event_device *); -/* - * Use this setup function on systems where the cpu clock frequency may - * change. periphclk_prescaler is the fixed divider value between the cpu - * clock and the PERIPHCLK clock that feeds the TWD. target_rate should be - * low enough that the prescaler can accurately reach the target rate from the - * lowest cpu frequency. - */ -void twd_timer_setup_scalable(struct clock_event_device *, - unsigned long target_rate, unsigned int periphclk_prescaler); - #endif diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 549c9786e0f9..8ba1ccf82a02 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -97,8 +97,6 @@ extern void __show_regs(struct pt_regs *); extern int cpu_architecture(void); extern void cpu_init(void); -extern void cpu_idle_wait(void); -extern void default_idle(void); void arm_machine_restart(char mode, const char *cmd); extern void (*arm_pm_restart)(char str, const char *cmd); diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h index 80f749368e4f..e71d6ff8d104 100644 --- a/arch/arm/include/asm/tls.h +++ b/arch/arm/include/asm/tls.h @@ -7,8 +7,6 @@ .macro set_tls_v6k, tp, tmp1, tmp2 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register - mov \tmp1, #0xffff0fff - str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0 .endm .macro set_tls_v6, tp, tmp1, tmp2 @@ -17,7 +15,7 @@ mov \tmp2, #0xffff0fff tst \tmp1, #HWCAP_TLS @ hardware TLS available? mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register - str \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 + streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 .endm .macro set_tls_software, tp, tmp1, tmp2 diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 90ecfa32a226..a38b4879441d 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -22,7 +22,7 @@ #if defined(CONFIG_DEBUG_ICEDCC) @@ debug using ARM EmbeddedICE DCC channel -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7) +#if defined(CONFIG_CPU_V6) .macro addruart, rx, tmp .endm diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 44cb9db8dd50..bb8e93a76407 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -506,7 +506,7 @@ __und_usr: blo __und_usr_unknown 3: ldrht r0, [r4] add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 - orr r0, r0, r5, lsl #16 + orr r0, r0, r5, lsl #16 #else b __und_usr_unknown #endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index ba5a2cdd4822..571b4ec71f6b 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -30,9 +30,6 @@ ENTRY(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 @@ -69,9 +66,6 @@ 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 diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index 778c2f7024ff..d6e8b4d2e60d 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) return; /* Initialize to zero */ - for (regno = 0; regno < GDB_MAX_REGS; regno++) + for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) gdb_regs[regno] = 0; /* Otherwise, we have only some registers from switch_to() */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3161faf3d2e8..401e38be1f78 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -140,13 +140,12 @@ EXPORT_SYMBOL_GPL(arm_pm_restart); * This is our default idle handler. We need to disable * interrupts here to ensure we don't miss a wakeup call. */ -void default_idle(void) +static void default_idle(void) { if (!need_resched()) arch_idle(); local_irq_enable(); } -EXPORT_SYMBOL(default_idle); void (*pm_idle)(void) = default_idle; EXPORT_SYMBOL(pm_idle); @@ -196,19 +195,6 @@ void cpu_idle(void) } } -#if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT) -static void do_nothing(void *unused) -{ -} - -void cpu_idle_wait(void) -{ - smp_mb(); - smp_call_function(do_nothing, NULL, 1); -} -#endif - - static char reboot_mode = 'h'; int __init reboot_setup(char *str) @@ -245,77 +231,6 @@ void machine_restart(char *cmd) arm_pm_restart(reboot_mode, cmd); } -/* - * dump a block of kernel memory from around the given address - */ -static void show_data(unsigned long addr, int nbytes, const char *name) -{ - int i, j; - int nlines; - u32 *p; - - /* - * don't attempt to dump non-kernel addresses or - * values that are probably just small negative numbers - */ - if (addr < PAGE_OFFSET || addr > -256UL) - return; - - printk("\n%s: %#lx:\n", name, addr); - - /* - * round address down to a 32 bit boundary - * and always dump a multiple of 32 bytes - */ - p = (u32 *)(addr & ~(sizeof(u32) - 1)); - nbytes += (addr & (sizeof(u32) - 1)); - nlines = (nbytes + 31) / 32; - - - for (i = 0; i < nlines; i++) { - /* - * just display low 16 bits of address to keep - * each line of the dump < 80 characters - */ - printk("%04lx ", (unsigned long)p & 0xffff); - for (j = 0; j < 8; j++) { - u32 data; - if (probe_kernel_address(p, data)) { - printk(" ********"); - } else { - printk(" %08x", data); - } - ++p; - } - printk("\n"); - } -} - -static void show_extra_register_data(struct pt_regs *regs, int nbytes) -{ - mm_segment_t fs; - - fs = get_fs(); - set_fs(KERNEL_DS); - show_data(regs->ARM_pc - nbytes, nbytes * 2, "PC"); - show_data(regs->ARM_lr - nbytes, nbytes * 2, "LR"); - show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP"); - show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP"); - show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP"); - show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0"); - show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1"); - show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2"); - show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3"); - show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4"); - show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5"); - show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6"); - show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7"); - show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8"); - show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9"); - show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10"); - set_fs(fs); -} - void __show_regs(struct pt_regs *regs) { unsigned long flags; @@ -375,8 +290,6 @@ void __show_regs(struct pt_regs *regs) printk("Control: %08x%s\n", ctrl, buf); } #endif - - show_extra_register_data(regs, 128); } void show_regs(struct pt_regs * regs) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 15c46d27ca27..907d5a620bca 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -602,14 +602,6 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, static inline void setup_syscall_restart(struct pt_regs *regs) { - if (regs->ARM_ORIG_r0 == -ERESTARTNOHAND || - regs->ARM_ORIG_r0 == -ERESTARTSYS || - regs->ARM_ORIG_r0 == -ERESTARTNOINTR || - regs->ARM_ORIG_r0 == -ERESTART_RESTARTBLOCK) { - /* the syscall cannot be safely restarted, return -EINTR instead */ - regs->ARM_r0 = -EINTR; - return; - } regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; } @@ -742,7 +734,6 @@ static void do_signal(struct pt_regs *regs, int syscall) */ if (syscall) { if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { - regs->ARM_r0 = -EAGAIN; /* prevent multiple restarts */ if (thumb_mode(regs)) { regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; regs->ARM_pc -= 2; diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 3dc62ee45639..35882fbf37f9 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -26,29 +25,26 @@ void __iomem *twd_base; static unsigned long twd_timer_rate; -static unsigned long twd_periphclk_prescaler; -static unsigned long twd_cpu_rate; static void twd_set_mode(enum clock_event_mode mode, struct clock_event_device *clk) { - unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); - ctrl &= TWD_TIMER_CONTROL_PRESCALE_MASK; + unsigned long ctrl; switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* timer load already set up */ - ctrl |= TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE + ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_PERIODIC; break; case CLOCK_EVT_MODE_ONESHOT: /* period set, and timer enabled in 'next_event' hook */ - ctrl |= TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT; + ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT; break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: default: - break; + ctrl = 0; } __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); @@ -83,63 +79,7 @@ int twd_timer_ack(void) return 0; } -/* - * Recalculate the twd prescaler value when the cpu frequency changes. To - * prevent early timer interrupts, must be called before changing the cpu - * frequency if the frequency is increasing, or after if the frequency is - * decreasing. - */ -static void twd_update_prescaler(void *data) -{ - u32 ctrl; - int prescaler; - unsigned long periphclk_rate; - - BUG_ON(twd_periphclk_prescaler == 0 || twd_timer_rate == 0); - - periphclk_rate = twd_cpu_rate / twd_periphclk_prescaler; - - prescaler = DIV_ROUND_UP(periphclk_rate, twd_timer_rate); - prescaler = clamp(prescaler - 1, 0, 0xFF); - - ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); - ctrl &= ~TWD_TIMER_CONTROL_PRESCALE_MASK; - ctrl |= prescaler << 8; - __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); -} - -static int twd_cpufreq_transition(struct notifier_block *nb, - unsigned long state, void *data) -{ - struct cpufreq_freqs *freqs = data; - if (((freqs->new > freqs->old) && state == CPUFREQ_PRECHANGE) || - ((freqs->old > freqs->new) && state == CPUFREQ_POSTCHANGE)) { - /* freqs->new is in kHz, twd_cpu_rate is in Hz */ - twd_cpu_rate = freqs->new * 1000; - - smp_call_function_single(freqs->cpu, twd_update_prescaler, - NULL, 1); - } - - return NOTIFY_OK; -} - -static struct notifier_block twd_cpufreq_nb = { - .notifier_call = twd_cpufreq_transition, -}; - -static int twd_cpufreq_init(void) -{ - if (twd_cpu_rate) - return cpufreq_register_notifier(&twd_cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - - return 0; -} -core_initcall(twd_cpufreq_init); - -static void __cpuinit twd_calibrate_rate(unsigned long target_rate, - unsigned int periphclk_prescaler) +static void __cpuinit twd_calibrate_rate(void) { unsigned long load, count; u64 waitjiffies; @@ -173,28 +113,8 @@ static void __cpuinit twd_calibrate_rate(unsigned long target_rate, twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); - /* - * If a target rate has been requested, adjust the TWD prescaler - * to get the closest lower frequency. - */ - if (target_rate) { - twd_periphclk_prescaler = periphclk_prescaler; - - printk("%lu.%02luMHz, setting to ", - twd_timer_rate / 1000000, - (twd_timer_rate / 10000) % 100); - twd_cpu_rate = twd_timer_rate * periphclk_prescaler; - twd_timer_rate = target_rate; - twd_update_prescaler(NULL); - } - printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, - (twd_timer_rate / 10000) % 100); - } else { - if (target_rate) { - BUG_ON(target_rate != twd_timer_rate); - twd_update_prescaler(NULL); - } + (twd_timer_rate / 100000) % 100); } load = twd_timer_rate / HZ; @@ -205,12 +125,11 @@ static void __cpuinit twd_calibrate_rate(unsigned long target_rate, /* * Setup the local clock events for a CPU. */ -static void __cpuinit __twd_timer_setup(struct clock_event_device *clk, - unsigned long target_rate, unsigned int periphclk_prescaler) +void __cpuinit twd_timer_setup(struct clock_event_device *clk) { unsigned long flags; - twd_calibrate_rate(target_rate, periphclk_prescaler); + twd_calibrate_rate(); clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | @@ -232,17 +151,6 @@ static void __cpuinit __twd_timer_setup(struct clock_event_device *clk, clockevents_register_device(clk); } -void __cpuinit twd_timer_setup_scalable(struct clock_event_device *clk, - unsigned long target_rate, unsigned int periphclk_prescaler) -{ - __twd_timer_setup(clk, target_rate, periphclk_prescaler); -} - -void __cpuinit twd_timer_setup(struct clock_event_device *clk) -{ - __twd_timer_setup(clk, 0, 0); -} - #ifdef CONFIG_HOTPLUG_CPU /* * take a local timer down diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 17c5649340ad..cda78d59aa31 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -454,9 +454,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags) if (end > vma->vm_end) end = vma->vm_end; - up_read(&mm->mmap_sem); - flush_cache_user_range(start, end); - return; + flush_cache_user_range(vma, start, end); } up_read(&mm->mmap_sem); } @@ -526,7 +524,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) if (has_tls_reg) { asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0)); - } /*else*/ { + } else { /* * User space must never try to access this directly. * Expect your app to break eventually if you do so. diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 68b10b684e83..59ff42ddf0ae 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -6,7 +6,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ - findbit.o memchr.o memcpy.o \ + delay.o findbit.o memchr.o memcpy.o \ memmove.o memset.o memzero.o setbit.o \ strncpy_from_user.o strnlen_user.o \ strchr.o strrchr.o \ @@ -17,10 +17,6 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ mmu-y := clear_user.o copy_page.o getuser.o putuser.o -ifneq ($(CONFIG_ARCH_PROVIDES_UDELAY),y) - lib-y += delay.o -endif - # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only ifeq ($(CONFIG_PREEMPT),y) diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 64f6bc1a9132..1e4cbd4e7be9 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S @@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be) */ .L_found: #if __LINUX_ARM_ARCH__ >= 5 - rsb r0, r3, #0 - and r3, r3, r0 + rsb r1, r3, #0 + and r3, r3, r1 clz r3, r3 rsb r3, r3, #31 add r0, r2, r3 @@ -190,7 +190,5 @@ ENDPROC(_find_next_bit_be) addeq r2, r2, #1 mov r0, r2 #endif - cmp r1, r0 @ Clamp to maxbit - movlo r0, r1 mov pc, lr diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h index 27ac6f550fe3..57f8ee154943 100644 --- a/arch/arm/mach-at91/include/mach/at91_mci.h +++ b/arch/arm/mach-at91/include/mach/at91_mci.h @@ -74,8 +74,6 @@ #define AT91_MCI_TRTYP_BLOCK (0 << 19) #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) #define AT91_MCI_TRTYP_STREAM (2 << 19) -#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) -#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) #define AT91_MCI_BLKR 0x18 /* Block Register */ #define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S index 9b50442d4b9b..d16ce7eb00e9 100644 --- a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S +++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S @@ -10,7 +10,7 @@ * published by the Free Software Foundation. */ - .macro addruart,rx,rtmp + .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? moveq \rx, #0x10000000 diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 78defd71a829..38088c36936c 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, 0, + hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, "imprecise external abort"); for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) { diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index af13eb6e553c..9428eff0b116 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -382,7 +382,7 @@ static void __init realview_pbx_init(void) int i; #ifdef CONFIG_CACHE_L2X0 - if (!l2x0_disabled && core_tile_pbxa9mp()) { + if (core_tile_pbxa9mp()) { void __iomem *l2x0_base = __io_address(REALVIEW_PBX_TILE_L220_BASE); diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index e7f944d07fb5..a57713c1954a 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -10,10 +10,6 @@ config ARCH_TEGRA_2x_SOC select CPU_V7 select ARM_GIC select ARCH_REQUIRE_GPIOLIB - select ARM_ERRATA_742230 - select USB_ARCH_HAS_EHCI if USB_SUPPORT - select USB_ULPI if USB_SUPPORT - select USB_ULPI_VIEWPORT if USB_SUPPORT help Support for NVIDIA Tegra AP20 and T20 processors, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller @@ -24,26 +20,8 @@ comment "Tegra board type" config MACH_HARMONY bool "Harmony board" - select TEGRA_DEBUG_UARTD help - Support for NVIDIA Harmony development platform - -config MACH_VENTANA - bool "Ventana board" - help - Support for NVIDIA Ventana development platform - -config MACH_OLYMPUS - bool "Olympus board" - select TEGRA_DEBUG_UARTB - help - Support for Olympus development platform - -config MACH_STINGRAY - bool "Stingray board" - select TEGRA_DEBUG_UARTB - help - Support for Stingray development platform + Support for nVidia Harmony development platform choice prompt "Low-level debug console UART" @@ -69,65 +47,4 @@ config TEGRA_DEBUG_UARTE endchoice -config TEGRA_SYSTEM_DMA - bool "Enable system DMA driver for NVIDIA Tegra SoCs" - default y - help - Adds system DMA functionality for NVIDIA Tegra SoCs, used by - several Tegra device drivers - -config TEGRA_PWM - tristate "Enable PWM driver" - select HAVE_PWM - help - Enable support for the Tegra PWM controller(s). - -config TEGRA_FIQ_DEBUGGER - bool "Enable the FIQ serial debugger on Tegra" - default y - select FIQ_DEBUGGER - help - Enables the FIQ serial debugger on Tegra" - -config WIFI_CONTROL_FUNC - bool "Enable WiFi control function abstraction" - help - Enables Power/Reset/Carddetect function abstraction - endif - -config TEGRA_EMC_SCALING_ENABLE - bool "Enable scaling the memory frequency" - default n - -config TEGRA_CPU_DVFS - bool "Enable voltage scaling on Tegra CPU" - default y - -config TEGRA_CORE_DVFS - bool "Enable voltage scaling on Tegra core" - depends on TEGRA_CPU_DVFS - default y - -config TEGRA_IOVMM_GART - bool "Enable I/O virtual memory manager for GART" - depends on ARCH_TEGRA_2x_SOC - default y - select TEGRA_IOVMM - help - Enables support for remapping discontiguous physical memory - shared with the operating system into contiguous I/O virtual - space through the GART hardware included on Tegra SoCs - -config TEGRA_IOVMM - bool - -config TEGRA_ARB_SEMAPHORE - bool - -config TEGRA_THERMAL_THROTTLE - bool "Enable throttling of CPU speed on overtemp" - depends on CPU_FREQ - default y - help - Also requires enabling a temperature sensor such as NCT1008. diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 3d13786352a2..51e9370eed99 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,76 +1,14 @@ obj-y += common.o -obj-y += apbio.o obj-y += io.o -obj-y += irq.o legacy_irq.o -obj-y += syncpt.o +obj-y += irq.o obj-y += clock.o -obj-y += dvfs.o obj-y += timer.o obj-y += gpio.o obj-y += pinmux.o -obj-y += devices.o -obj-y += delay.o -obj-y += powergate.o -obj-y += suspend.o -obj-y += fuse.o -obj-y += kfuse.o -obj-y += tegra_i2s_audio.o -obj-y += tegra_spdif_audio.o -obj-y += mc.o -obj-$(CONFIG_USB_SUPPORT) += usb_phy.o -obj-$(CONFIG_FIQ) += fiq.o -obj-$(CONFIG_TEGRA_FIQ_DEBUGGER) += tegra_fiq_debugger.o -obj-$(CONFIG_TEGRA_PWM) += pwm.o -obj-$(CONFIG_TEGRA_ARB_SEMAPHORE) += arb_sema.o - obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_dvfs.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_fuse.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += suspend-t2.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_save.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o -obj-$(CONFIG_CPU_V7) += cortex-a9.o - -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o -obj-$(CONFIG_SMP) += localtimer.o -obj-$(CONFIG_SMP) += platsmp.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += headsmp-t2.o -obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o -obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_TEGRA_IOVMM) += iovmm.o -obj-$(CONFIG_TEGRA_IOVMM_GART) += iovmm-gart.o +obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-${CONFIG_MACH_HARMONY} += board-harmony.o obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-panel.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-sdhci.o - -obj-${CONFIG_MACH_VENTANA} += board-ventana.o -obj-${CONFIG_MACH_VENTANA} += board-ventana-pinmux.o -obj-${CONFIG_MACH_VENTANA} += board-ventana-sdhci.o -obj-${CONFIG_MACH_VENTANA} += board-ventana-power.o -obj-${CONFIG_MACH_VENTANA} += board-ventana-panel.o - -obj-${CONFIG_MACH_OLYMPUS} += board-olympus.o -obj-${CONFIG_MACH_OLYMPUS} += board-olympus-pinmux.o -obj-${CONFIG_MACH_OLYMPUS} += board-olympus-panel.o -obj-${CONFIG_MACH_OLYMPUS} += board-olympus-i2c.o -obj-${CONFIG_MACH_OLYMPUS} += board-olympus-keypad.o -obj-${CONFIG_MACH_OLYMPUS} += board-olympus-wifi.o - -obj-${CONFIG_MACH_STINGRAY} += board-stingray.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-pinmux.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-panel.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-keypad.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-wifi.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-sensors.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-wlan_nvs.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-touch.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-power.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-bluetooth.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-gps.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-usbnet.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-bootinfo.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-memory.o diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c deleted file mode 100644 index d6e08c966e72..000000000000 --- a/arch/arm/mach-tegra/apbio.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * arch/arm/mach-tegra/apbio.c - * - * Copyright (C) 2010 NVIDIA Corporation. - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "apbio.h" - -static DEFINE_MUTEX(tegra_apb_dma_lock); - -#ifdef CONFIG_TEGRA_SYSTEM_DMA -static struct tegra_dma_channel *tegra_apb_dma; -static u32 *tegra_apb_bb; -static dma_addr_t tegra_apb_bb_phys; -static DECLARE_COMPLETION(tegra_apb_wait); - -static void apb_dma_complete(struct tegra_dma_req *req) -{ - complete(&tegra_apb_wait); -} - -static inline u32 apb_readl(unsigned long offset) -{ - struct tegra_dma_req req; - int ret; - - if (!tegra_apb_dma) - return readl(IO_TO_VIRT(offset)); - - mutex_lock(&tegra_apb_dma_lock); - req.complete = apb_dma_complete; - req.to_memory = 1; - req.dest_addr = tegra_apb_bb_phys; - req.dest_bus_width = 32; - req.dest_wrap = 1; - req.source_addr = offset; - req.source_bus_width = 32; - req.source_wrap = 4; - req.req_sel = 0; - req.size = 4; - - INIT_COMPLETION(tegra_apb_wait); - - tegra_dma_enqueue_req(tegra_apb_dma, &req); - - ret = wait_for_completion_timeout(&tegra_apb_wait, - msecs_to_jiffies(50)); - - if (WARN(ret == 0, "apb read dma timed out")) - *(u32 *)tegra_apb_bb = 0; - - mutex_unlock(&tegra_apb_dma_lock); - return *((u32 *)tegra_apb_bb); -} - -static inline void apb_writel(u32 value, unsigned long offset) -{ - struct tegra_dma_req req; - int ret; - - if (!tegra_apb_dma) { - writel(value, IO_TO_VIRT(offset)); - return; - } - - mutex_lock(&tegra_apb_dma_lock); - *((u32 *)tegra_apb_bb) = value; - req.complete = apb_dma_complete; - req.to_memory = 0; - req.dest_addr = offset; - req.dest_wrap = 4; - req.dest_bus_width = 32; - req.source_addr = tegra_apb_bb_phys; - req.source_bus_width = 32; - req.source_wrap = 1; - req.req_sel = 0; - req.size = 4; - - INIT_COMPLETION(tegra_apb_wait); - - tegra_dma_enqueue_req(tegra_apb_dma, &req); - - ret = wait_for_completion_timeout(&tegra_apb_wait, - msecs_to_jiffies(50)); - - mutex_unlock(&tegra_apb_dma_lock); -} -#else -static inline u32 apb_readl(unsigned long offset) -{ - return readl(IO_TO_VIRT(offset)); -} - -static inline void apb_writel(u32 value, unsigned long offset) -{ - writel(value, IO_TO_VIRT(offset)); -} -#endif - -u32 tegra_apb_readl(unsigned long offset) -{ - return apb_readl(offset); -} - -void tegra_apb_writel(u32 value, unsigned long offset) -{ - apb_writel(value, offset); -} - -void tegra_init_apb_dma(void) -{ -#ifdef CONFIG_TEGRA_SYSTEM_DMA - tegra_apb_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT | - TEGRA_DMA_SHARED); - if (!tegra_apb_dma) { - pr_err("%s: can not allocate dma channel\n", __func__); - return; - } - - tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32), - &tegra_apb_bb_phys, GFP_KERNEL); - if (!tegra_apb_bb) { - pr_err("%s: can not allocate bounce buffer\n", __func__); - tegra_dma_free_channel(tegra_apb_dma); - tegra_apb_dma = NULL; - return; - } -#endif -} diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h deleted file mode 100644 index a8b8250c891a..000000000000 --- a/arch/arm/mach-tegra/apbio.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-tegra/apbio.h - * - * Copyright (C) 2010 NVIDIA Corporation. - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -u32 tegra_apb_readl(unsigned long offset); -void tegra_apb_writel(u32 value, unsigned long offset); -void tegra_init_apb_dma(void); diff --git a/arch/arm/mach-tegra/arb_sema.c b/arch/arm/mach-tegra/arb_sema.c deleted file mode 100644 index 55af15e935f2..000000000000 --- a/arch/arm/mach-tegra/arb_sema.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2010, NVIDIA Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define TEGRA_RPC_MAX_SEM 32 - -/* arb_gnt ictrl */ -#define ARB_CPU_INT_EN 0x4 - -/* arb_sema */ -#define ARB_GRANT_STATUS 0x0 -#define ARB_GRANT_REQUEST 0x4 -#define ARB_GRANT_RELEASE 0x8 - -struct tegra_arb_dev { - void __iomem *sema_base; - void __iomem *gnt_base; - spinlock_t lock; - struct completion arb_gnt_complete[TEGRA_RPC_MAX_SEM]; - struct mutex mutexes[TEGRA_RPC_MAX_SEM]; - int irq; - int status; - bool suspended; -}; - -static struct tegra_arb_dev *arb; - -static inline u32 arb_sema_read(u32 offset) -{ - return readl(arb->sema_base + offset); -} - -static inline void arb_sema_write(u32 value, u32 offset) -{ - writel(value, arb->sema_base + offset); -} - -static inline u32 arb_gnt_read(u32 offset) -{ - return readl(arb->gnt_base + offset); -} - -static inline void arb_gnt_write(u32 value, u32 offset) -{ - writel(value, arb->gnt_base + offset); -} - -static void request_arb_sem(enum tegra_arb_module lock) -{ - unsigned long flags; - u32 value; - - spin_lock_irqsave(&arb->lock, flags); - - arb_sema_write(1 << lock, ARB_GRANT_REQUEST); - value = arb_gnt_read(ARB_CPU_INT_EN); - value |= (1 << lock); - arb_gnt_write(value, ARB_CPU_INT_EN); - - spin_unlock_irqrestore(&arb->lock, flags); -} - -static void cancel_arb_sem(enum tegra_arb_module lock) -{ - unsigned long flags; - u32 value; - - spin_lock_irqsave(&arb->lock, flags); - - arb_sema_write(1 << lock, ARB_GRANT_RELEASE); - value = arb_gnt_read(ARB_CPU_INT_EN); - value &= ~(1 << lock); - arb_gnt_write(value, ARB_CPU_INT_EN); - - spin_unlock_irqrestore(&arb->lock, flags); -} - -int tegra_arb_mutex_lock_timeout(enum tegra_arb_module lock, int msecs) -{ - int ret; - - if (!arb) - return -ENODEV; - - if (arb->suspended) { - pr_err("device in suspend\n"); - return -ETIMEDOUT; - } - - mutex_lock(&arb->mutexes[lock]); - INIT_COMPLETION(arb->arb_gnt_complete[lock]); - request_arb_sem(lock); - ret = wait_for_completion_timeout(&arb->arb_gnt_complete[lock], msecs_to_jiffies(msecs)); - if (ret == 0) { - pr_err("timed out.\n"); - cancel_arb_sem(lock); - mutex_unlock(&arb->mutexes[lock]); - return -ETIMEDOUT; - } - - return 0; -} -EXPORT_SYMBOL(tegra_arb_mutex_lock_timeout); - -int tegra_arb_mutex_unlock(enum tegra_arb_module lock) -{ - if (!arb) - return -ENODEV; - - if (arb->suspended) { - pr_err("device in suspend\n"); - return -ETIMEDOUT; - } - - cancel_arb_sem(lock); - mutex_unlock(&arb->mutexes[lock]); - return 0; -} -EXPORT_SYMBOL(tegra_arb_mutex_unlock); - -static irqreturn_t arb_gnt_isr(int irq, void *dev_id) -{ - struct tegra_arb_dev *dev = dev_id; - unsigned long status; - u32 cpu_int_en; - unsigned int bit; - unsigned long flags; - - spin_lock_irqsave(&arb->lock, flags); - - status = arb_sema_read(ARB_GRANT_STATUS); - pr_debug("%s: 0x%lx\n", __func__, status); - - /* disable the arb semaphores which were signalled */ - cpu_int_en = arb_gnt_read(ARB_CPU_INT_EN); - arb_gnt_write((cpu_int_en & ~(status & cpu_int_en)), - ARB_CPU_INT_EN); - - status &= cpu_int_en; - for_each_set_bit(bit, &status, BITS_PER_LONG) - complete(&dev->arb_gnt_complete[bit]); - - spin_unlock_irqrestore(&arb->lock, flags); - return IRQ_HANDLED; -} - -int tegra_arb_suspend(void) -{ - unsigned long status = arb_sema_read(ARB_GRANT_STATUS); - - if (WARN_ON(status != 0)) { - pr_err("%s: suspending while holding arbitration " - "semaphore: %08lx\n", __func__, status); - } - arb->suspended = true; - - return status ? -EBUSY : 0; -} - -int tegra_arb_resume(void) -{ - arb->suspended = false; - return 0; -} - -static int __init tegra_arb_init(void) -{ - struct tegra_arb_dev *dev = NULL; - int err, i; - - dev = kzalloc(sizeof(struct tegra_arb_dev), GFP_KERNEL); - if (dev == NULL) { - pr_err("%s: unable to alloc data struct.\n", __func__); - return -ENOMEM; - } - - for (i = 0; i < TEGRA_RPC_MAX_SEM; i++) { - mutex_init(&dev->mutexes[i]); - init_completion(&dev->arb_gnt_complete[i]); - } - - dev->sema_base = IO_ADDRESS(TEGRA_ARB_SEMA_BASE); - if (!dev->sema_base) { - pr_err("%s: can't get arb sema_base\n", __func__); - err = -ENOMEM; - goto out; - } - - dev->gnt_base = IO_ADDRESS(TEGRA_ARBGNT_ICTLR_BASE); - if (!dev->gnt_base) { - pr_err("%s: can't ioremap gnt_base\n", __func__); - err = -ENOMEM; - goto out; - } - - dev->irq = INT_GNT_1; - err = request_irq(dev->irq, arb_gnt_isr, 0, "rpc-arbsema", dev); - if (err) { - pr_err("%s: request_irq(%d) failed(%d)\n", __func__, - dev->irq, err); - goto out; - } - - spin_lock_init(&dev->lock); - arb = dev; - - pr_info("%s: initialized\n", __func__); - return 0; - -out: - kfree(dev); - pr_err("%s: initialization failed.\n", __func__); - return err; -} -subsys_initcall(tegra_arb_init); - -MODULE_LICENSE("GPLv2"); diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c deleted file mode 100644 index 309d72e4b490..000000000000 --- a/arch/arm/mach-tegra/board-harmony-panel.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/arm/mach-tegra/board-harmony-panel.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -/* Framebuffer */ -static struct resource fb_resource[] = { - [0] = { - .start = INT_DISPLAY_GENERAL, - .end = INT_DISPLAY_GENERAL, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 0x1c012000, - .end = 0x1c012000 + 0x500000 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_fb_lcd_data tegra_fb_lcd_platform_data = { - .lcd_xres = 1024, - .lcd_yres = 600, - .fb_xres = 1024, - .fb_yres = 600, - .bits_per_pixel = 16, -}; - -static struct platform_device tegra_fb_device = { - .name = "tegrafb", - .id = 0, - .resource = fb_resource, - .num_resources = ARRAY_SIZE(fb_resource), - .dev = { - .platform_data = &tegra_fb_lcd_platform_data, - }, -}; - -int __init harmony_panel_init(void) { - return platform_device_register(&tegra_fb_device); -} - diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c index 78980e48970f..50b15d500cac 100644 --- a/arch/arm/mach-tegra/board-harmony-pinmux.c +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c @@ -15,12 +15,11 @@ */ #include -#include #include #include "board-harmony.h" -static __initdata struct tegra_pingroup_config harmony_pinmux[] = { +static struct tegra_pingroup_config harmony_pinmux[] = { {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, @@ -35,10 +34,10 @@ static __initdata struct tegra_pingroup_config harmony_pinmux[] = { {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, @@ -139,7 +138,7 @@ static __initdata struct tegra_pingroup_config harmony_pinmux[] = { {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, }; -void __init harmony_pinmux_init(void) +void harmony_pinmux_init(void) { tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); } diff --git a/arch/arm/mach-tegra/board-harmony-sdhci.c b/arch/arm/mach-tegra/board-harmony-sdhci.c deleted file mode 100644 index 9c4d1e072968..000000000000 --- a/arch/arm/mach-tegra/board-harmony-sdhci.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * arch/arm/mach-tegra/board-harmony-sdhci.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "gpio-names.h" - -static struct resource sdhci_resource1[] = { - [0] = { - .start = INT_SDMMC1, - .end = INT_SDMMC1, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC1_BASE, - .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource2[] = { - [0] = { - .start = INT_SDMMC2, - .end = INT_SDMMC2, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC2_BASE, - .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource4[] = { - [0] = { - .start = INT_SDMMC4, - .end = INT_SDMMC4, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC4_BASE, - .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = { - .clk_id = NULL, - .force_hs = 1, - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = { - .clk_id = NULL, - .force_hs = 1, - .cd_gpio = TEGRA_GPIO_PI5, - .wp_gpio = TEGRA_GPIO_PH1, - .power_gpio = TEGRA_GPIO_PT3, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data4 = { - .clk_id = NULL, - .force_hs = 0, - .cd_gpio = TEGRA_GPIO_PH2, - .wp_gpio = TEGRA_GPIO_PH3, - .power_gpio = TEGRA_GPIO_PI6, -}; - -static struct platform_device tegra_sdhci_device1 = { - .name = "sdhci-tegra", - .id = 0, - .resource = sdhci_resource1, - .num_resources = ARRAY_SIZE(sdhci_resource1), - .dev = { - .platform_data = &tegra_sdhci_platform_data1, - }, -}; - -static struct platform_device tegra_sdhci_device2 = { - .name = "sdhci-tegra", - .id = 1, - .resource = sdhci_resource2, - .num_resources = ARRAY_SIZE(sdhci_resource2), - .dev = { - .platform_data = &tegra_sdhci_platform_data2, - }, -}; - -static struct platform_device tegra_sdhci_device4 = { - .name = "sdhci-tegra", - .id = 3, - .resource = sdhci_resource4, - .num_resources = ARRAY_SIZE(sdhci_resource4), - .dev = { - .platform_data = &tegra_sdhci_platform_data4, - }, -}; - -int __init harmony_sdhci_init(void) -{ - gpio_request(tegra_sdhci_platform_data2.power_gpio, "sdhci2_power"); - gpio_request(tegra_sdhci_platform_data2.cd_gpio, "sdhci2_cd"); - gpio_request(tegra_sdhci_platform_data2.wp_gpio, "sdhci2_wp"); - - tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data2.cd_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data2.wp_gpio); - - gpio_request(tegra_sdhci_platform_data4.power_gpio, "sdhci4_power"); - gpio_request(tegra_sdhci_platform_data4.cd_gpio, "sdhci4_cd"); - gpio_request(tegra_sdhci_platform_data4.wp_gpio, "sdhci4_wp"); - - tegra_gpio_enable(tegra_sdhci_platform_data4.power_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data4.cd_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data4.wp_gpio); - - gpio_direction_output(tegra_sdhci_platform_data2.power_gpio, 1); - gpio_direction_output(tegra_sdhci_platform_data4.power_gpio, 1); - - platform_device_register(&tegra_sdhci_device1); - platform_device_register(&tegra_sdhci_device2); - platform_device_register(&tegra_sdhci_device4); - - return 0; -} diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index ee01dd0ae7cd..9e305de56be9 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -19,12 +19,9 @@ #include #include #include -#include -#include #include #include #include -#include #include #include @@ -33,14 +30,10 @@ #include #include -#include -#include -#include "clock.h" #include "board.h" #include "board-harmony.h" #include "clock.h" -#include "devices.h" /* NVidia bootloader tags */ #define ATAG_NVIDIA 0x41000801 @@ -67,69 +60,6 @@ static int __init parse_tag_nvidia(const struct tag *tag) } __tagtable(ATAG_NVIDIA, parse_tag_nvidia); -static struct tegra_nand_chip_parms nand_chip_parms[] = { - /* Samsung K5E2G1GACM */ - [0] = { - .vendor_id = 0xEC, - .device_id = 0xAA, - .capacity = 256, - .timing = { - .trp = 21, - .trh = 15, - .twp = 21, - .twh = 15, - .tcs = 31, - .twhr = 60, - .tcr_tar_trr = 20, - .twb = 100, - .trp_resp = 30, - .tadl = 100, - }, - }, - /* Hynix H5PS1GB3EFR */ - [1] = { - .vendor_id = 0xAD, - .device_id = 0xDC, - .capacity = 512, - .timing = { - .trp = 12, - .trh = 10, - .twp = 12, - .twh = 10, - .tcs = 20, - .twhr = 80, - .tcr_tar_trr = 20, - .twb = 100, - .trp_resp = 20, - .tadl = 70, - }, - }, -}; - -struct tegra_nand_platform harmony_nand_data = { - .max_chips = 8, - .chip_parms = nand_chip_parms, - .nr_chip_parms = ARRAY_SIZE(nand_chip_parms), -}; - -static struct resource resources_nand[] = { - [0] = { - .start = INT_NANDFLASH, - .end = INT_NANDFLASH, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device tegra_nand_device = { - .name = "tegra_nand", - .id = -1, - .num_resources = ARRAY_SIZE(resources_nand), - .resource = resources_nand, - .dev = { - .platform_data = &harmony_nand_data, - }, -}; - static struct plat_serial8250_port debug_uart_platform_data[] = { { .membase = IO_ADDRESS(TEGRA_UARTD_BASE), @@ -152,33 +82,8 @@ static struct platform_device debug_uart = { }, }; -/* PDA power */ -static struct pda_power_pdata pda_power_pdata = { -}; - -static struct platform_device pda_power_device = { - .name = "pda_power", - .id = -1, - .dev = { - .platform_data = &pda_power_pdata, - }, -}; - static struct platform_device *harmony_devices[] __initdata = { &debug_uart, - &pmu_device, - &tegra_nand_device, - &tegra_udc_device, - &pda_power_device, - &tegra_i2c_device1, - &tegra_i2c_device2, - &tegra_i2c_device3, - &tegra_i2c_device4, - &tegra_spi_device1, - &tegra_spi_device2, - &tegra_spi_device3, - &tegra_spi_device4, - &tegra_gart_device, }; static void __init tegra_harmony_fixup(struct machine_desc *desc, @@ -206,9 +111,6 @@ static void __init tegra_harmony_init(void) harmony_pinmux_init(); platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); - - harmony_panel_init(); - harmony_sdhci_init(); } MACHINE_START(HARMONY, "harmony") diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h index 3b2c469206cc..09ca7755dd55 100644 --- a/arch/arm/mach-tegra/board-harmony.h +++ b/arch/arm/mach-tegra/board-harmony.h @@ -18,7 +18,5 @@ #define _MACH_TEGRA_BOARD_HARMONY_H void harmony_pinmux_init(void); -int harmony_panel_init(void); -int harmony_sdhci_init(void); #endif diff --git a/arch/arm/mach-tegra/board-olympus-i2c.c b/arch/arm/mach-tegra/board-olympus-i2c.c deleted file mode 100644 index 9a56299b8b8c..000000000000 --- a/arch/arm/mach-tegra/board-olympus-i2c.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus-i2c.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "board-olympus.h" -#include "gpio-names.h" - -#define XMEGAT_BL_I2C_ADDR 0x24 -#define OLYMPUS_TOUCH_IRQ_GPIO TEGRA_GPIO_PF5 -#define OLYMPUS_TOUCH_RESET_GPIO TEGRA_GPIO_PF4 -#define OLYMPUS_COMPASS_IRQ_GPIO TEGRA_GPIO_PE2 - - -static int olympus_touch_reset(void) -{ - gpio_set_value(OLYMPUS_TOUCH_RESET_GPIO, 0); - msleep(10); - gpio_set_value(OLYMPUS_TOUCH_RESET_GPIO, 1); - msleep(100); - - return 0; -} - -static struct vkey sholes_touch_vkeys[] = { - { - .code = KEY_BACK, - }, - { - .code = KEY_MENU, - }, - { - .code = KEY_HOME, - }, - { - .code = KEY_SEARCH, - }, -}; - -static struct qtm_touch_keyarray_cfg sholes_key_array_data[] = { - { - .ctrl = 0, - .x_origin = 0, - .y_origin = 0, - .x_size = 0, - .y_size = 0, - .aks_cfg = 0, - .burst_len = 0, - .tch_det_thr = 0, - .tch_det_int = 0, - .reserve9 = 0, - .reserve10 = 0, - }, - { - .ctrl = 0, - .x_origin = 0, - .y_origin = 0, - .x_size = 0, - .y_size = 0, - .aks_cfg = 0, - .burst_len = 0, - .tch_det_thr = 0, - .tch_det_int = 0, - .reserve9 = 0, - .reserve10 = 0, - }, -}; - -struct qtouch_ts_platform_data olympus_touch_data = { - - .flags = (QTOUCH_SWAP_XY | - QTOUCH_USE_MULTITOUCH | - QTOUCH_CFG_BACKUPNV | - QTOUCH_EEPROM_CHECKSUM), - .irqflags = (IRQF_TRIGGER_LOW), - .abs_min_x = 0, - .abs_max_x = 1023, - .abs_min_y = 0, - .abs_max_y = 1023, - .abs_min_p = 0, - .abs_max_p = 255, - .abs_min_w = 0, - .abs_max_w = 15, - .x_delta = 400, - .y_delta = 250, - .nv_checksum = 0xc240, - .fuzz_x = 0, - .fuzz_y = 0, - .fuzz_p = 2, - .fuzz_w = 2, - .boot_i2c_addr = XMEGAT_BL_I2C_ADDR, - .hw_reset = olympus_touch_reset, - .key_array = { - .cfg = NULL, - .keys = NULL, - .num_keys = 0, - }, - .power_cfg = { - .idle_acq_int = 0xff, - .active_acq_int = 0xff, - .active_idle_to = 0x01, - }, - .acquire_cfg = { - .charge_time = 0x06, - .reserve1 = 0x00, - .touch_drift = 0x0a, - .drift_susp = 0x05, - .touch_autocal = 0x00, - .reserve5 = 0, - .atch_cal_suspend_time = 0, - .atch_cal_suspend_thres = 0, - }, - .multi_touch_cfg = { - .ctrl = 0x0b, - .x_origin = 0, - .y_origin = 0, - .x_size = 0x13, - .y_size = 0x0b, - .aks_cfg = 0, - .burst_len = 0x41, - .tch_det_thr = 0x14, - .tch_det_int = 0x2, - .orient = 4, - .mrg_to = 0x19, - .mov_hyst_init = 0x05, - .mov_hyst_next = 0x05, - .mov_filter = 0, - .num_touch = 0x02, - .merge_hyst = 0x05, - .merge_thresh = 0x05, - .amp_hyst = 0, - .x_res = 0x0000, - .y_res = 0x0000, - .x_low_clip = 0x00, - .x_high_clip = 0x00, - .y_low_clip = 0x00, - .y_high_clip = 0x00, - .x_edge_ctrl = 0, - .x_edge_dist = 0, - .y_edge_ctrl = 0, - .y_edge_dist = 0, - .jump_limit = 0, - }, - .linear_tbl_cfg = { - .ctrl = 0x00, - .x_offset = 0x0000, - .x_segment = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - .y_offset = 0x0000, - .y_segment = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - }, - .comms_config_cfg = { - .ctrl = 0, - .command = 0, - }, - .gpio_pwm_cfg = { - .ctrl = 0, - .report_mask = 0, - .pin_direction = 0, - .internal_pullup = 0, - .output_value = 0, - .wake_on_change = 0, - .pwm_enable = 0, - .pwm_period = 0, - .duty_cycle_0 = 0, - .duty_cycle_1 = 0, - .duty_cycle_2 = 0, - .duty_cycle_3 = 0, - .trigger_0 = 0, - .trigger_1 = 0, - .trigger_2 = 0, - .trigger_3 = 0, - }, - .grip_face_suppression_cfg = { - .ctrl = 0x00, - .xlogrip = 0x00, - .xhigrip = 0x00, - .ylogrip = 0x00, - .yhigrip = 0x00, - .maxtchs = 0x00, - .reserve6 = 0x00, - .szthr1 = 0x00, - .szthr2 = 0x00, - .shpthr1 = 0x00, - .shpthr2 = 0x00, - .supextto = 0x00, - }, - .noise_suppression_cfg = { - .ctrl = 0, - .reserve1 = 0, - .reserve2 = 0, - .reserve3 = 0, - .reserve4 = 0, - .reserve5 = 0, - .reserve6 = 0, - .reserve7 = 0, - .noise_thres = 0, - .reserve9 = 0, - .freq_hop_scale = 0, - .burst_freq_0 = 0, - .burst_freq_1 = 0, - .burst_freq_2 = 0, - .burst_freq_3 = 0, - .burst_freq_4 = 0, - .reserve16 = 0, - }, - .touch_proximity_cfg = { - .ctrl = 0, - .x_origin = 0, - .y_origin = 0, - .x_size = 0, - .y_size = 0, - .reserve5 = 0, - .blen = 0, - .tch_thresh = 0, - .tch_detect_int = 0, - .average = 0, - .move_null_rate = 0, - .move_det_tresh = 0, - }, - .one_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .gesture_enable = 0, - .pres_proc = 0, - .tap_time_out = 0, - .flick_time_out = 0, - .drag_time_out = 0, - .short_press_time_out = 0, - .long_press_time_out = 0, - .repeat_press_time_out = 0, - .flick_threshold = 0, - .drag_threshold = 0, - .tap_threshold = 0, - .throw_threshold = 0, - }, - .self_test_cfg = { - .ctrl = 0, - .command = 0, - .high_signal_limit_0 = 0, - .low_signal_limit_0 = 0, - .high_signal_limit_1 = 0, - .low_signal_limit_1 = 0, - .high_signal_limit_2 = 0, - .low_signal_limit_2 = 0, - }, - .two_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .reserve2 = 0, - .gesture_enable = 0, - .rotate_threshold = 0, - .zoom_threshold = 0, - }, - .cte_config_cfg = { - .ctrl = 1, - .command = 0, - .reserve2 = 3, - .idle_gcaf_depth = 4, - .active_gcaf_depth = 8, - .voltage = 0, - }, - .noise1_suppression_cfg = { - .ctrl = 0x01, - .version = 0x01, - .atch_thr = 0x64, - .duty_cycle = 0x08, - .drift_thr = 0x00, - .clamp_thr = 0x00, - .diff_thr = 0x00, - .adjustment = 0x00, - .average = 0x0000, - .temp = 0x00, - .offset = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - .bad_chan = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 - }, - .x_short = 0x00, - }, - .vkeys = { - .count = 0, - .keys = NULL, - }, -}; - -static struct i2c_board_info __initdata sholes_i2c_bus1_board_info[] = { - { - I2C_BOARD_INFO(QTOUCH_TS_NAME, 0x4a), - .platform_data = &olympus_touch_data, - .irq = TEGRA_GPIO_TO_IRQ(OLYMPUS_TOUCH_IRQ_GPIO), - }, -}; - -static struct i2c_board_info __initdata olympus_i2c_bus4_board_info[] = { - { - I2C_BOARD_INFO("akm8973", 0x0C), - .irq = TEGRA_GPIO_TO_IRQ(OLYMPUS_COMPASS_IRQ_GPIO), - }, -}; - -void __init olympus_i2c_init(void) -{ - tegra_gpio_enable(OLYMPUS_TOUCH_IRQ_GPIO); - gpio_request(OLYMPUS_TOUCH_IRQ_GPIO, "touch_irq"); - gpio_direction_input(OLYMPUS_TOUCH_IRQ_GPIO); - - tegra_gpio_enable(OLYMPUS_TOUCH_RESET_GPIO); - gpio_request(OLYMPUS_TOUCH_RESET_GPIO, "touch_reset"); - gpio_direction_output(OLYMPUS_TOUCH_RESET_GPIO, 1); - - - i2c_register_board_info(0, sholes_i2c_bus1_board_info, 1); - - i2c_register_board_info(3, olympus_i2c_bus4_board_info, 1); -} - diff --git a/arch/arm/mach-tegra/board-olympus-keypad.c b/arch/arm/mach-tegra/board-olympus-keypad.c deleted file mode 100644 index 9271c84c524f..000000000000 --- a/arch/arm/mach-tegra/board-olympus-keypad.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus-keypad.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include "gpio-names.h" - -static unsigned int olympus_row_gpios[] = { - TEGRA_GPIO_PR0, - TEGRA_GPIO_PR1, - TEGRA_GPIO_PR2 -}; -static unsigned int olympus_col_gpios[] = { - TEGRA_GPIO_PQ0, - TEGRA_GPIO_PQ1, - TEGRA_GPIO_PQ2 -}; - -#define KEYMAP_INDEX(col, row) ((col)*ARRAY_SIZE(olympus_row_gpios) + (row)) - -static const unsigned short olympus_p3_keymap[ARRAY_SIZE(olympus_col_gpios) * - ARRAY_SIZE(olympus_row_gpios)] = { - [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP, - [KEYMAP_INDEX(1, 0)] = KEY_CAMERA_FOCUS, - [KEYMAP_INDEX(2, 0)] = KEY_MENU, - [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN, - [KEYMAP_INDEX(1, 1)] = KEY_CAMERA, - [KEYMAP_INDEX(2, 1)] = KEY_HOME, - [KEYMAP_INDEX(0, 2)] = KEY_AUX, - [KEYMAP_INDEX(1, 2)] = KEY_SEARCH, - [KEYMAP_INDEX(2, 2)] = KEY_BACK, -}; - -static struct gpio_event_matrix_info olympus_keypad_matrix_info = { - .info.func = gpio_event_matrix_func, - .keymap = olympus_p3_keymap, - .output_gpios = olympus_col_gpios, - .input_gpios = olympus_row_gpios, - .noutputs = ARRAY_SIZE(olympus_col_gpios), - .ninputs = ARRAY_SIZE(olympus_row_gpios), - .settle_time.tv.nsec = 40 * NSEC_PER_USEC, - .poll_time.tv.nsec = 20 * NSEC_PER_MSEC, - .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_REMOVE_PHANTOM_KEYS | - GPIOKPF_PRINT_UNMAPPED_KEYS /*| GPIOKPF_PRINT_MAPPED_KEYS*/ -}; - -static struct gpio_event_direct_entry olympus_keypad_switch_map[] = { -}; - -static struct gpio_event_input_info olympus_keypad_switch_info = { - .info.func = gpio_event_input_func, - .flags = 0, - .type = EV_SW, - .keymap = olympus_keypad_switch_map, - .keymap_size = ARRAY_SIZE(olympus_keypad_switch_map) -}; - -static struct gpio_event_info *olympus_keypad_info[] = { - &olympus_keypad_matrix_info.info, - &olympus_keypad_switch_info.info, -}; - -static struct gpio_event_platform_data olympus_keypad_data = { - .name = "olympus-keypad", - .info = olympus_keypad_info, - .info_count = ARRAY_SIZE(olympus_keypad_info) -}; - -static struct platform_device olympus_keypad_device = { - .name = GPIO_EVENT_DEV_NAME, - .id = 0, - .dev = { - .platform_data = &olympus_keypad_data, - }, -}; - -static int olympus_reset_keys_up[] = { - BTN_MOUSE, /* XXX */ - 0 -}; - -static struct keyreset_platform_data olympus_reset_keys_pdata = { - .keys_up = olympus_reset_keys_up, - .keys_down = { - KEY_LEFTSHIFT, - KEY_LEFTALT, - KEY_BACKSPACE, - 0 - }, -}; - -static struct platform_device olympus_reset_keys_device = { - .name = KEYRESET_NAME, - .dev.platform_data = &olympus_reset_keys_pdata, -}; - -int __init olympus_keypad_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PR0); - tegra_gpio_enable(TEGRA_GPIO_PR1); - tegra_gpio_enable(TEGRA_GPIO_PR2); - tegra_gpio_enable(TEGRA_GPIO_PQ0); - tegra_gpio_enable(TEGRA_GPIO_PQ1); - tegra_gpio_enable(TEGRA_GPIO_PQ2); - platform_device_register(&olympus_reset_keys_device); - return platform_device_register(&olympus_keypad_device); -} diff --git a/arch/arm/mach-tegra/board-olympus-panel.c b/arch/arm/mach-tegra/board-olympus-panel.c deleted file mode 100644 index 25b2e92776a5..000000000000 --- a/arch/arm/mach-tegra/board-olympus-panel.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus-panel.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -/* Framebuffer */ -static struct resource fb_resource[] = { - [0] = { - .start = INT_DISPLAY_GENERAL, - .end = INT_DISPLAY_GENERAL, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 0x1c03a000, - .end = 0x1c03a000 + 0x500000 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_fb_lcd_data tegra_fb_lcd_platform_data = { - .lcd_xres = 480, - .lcd_yres = 854, - .fb_xres = 480, - .fb_yres = 854, - .bits_per_pixel = 16, -}; - -static struct platform_device tegra_fb_device = { - .name = "tegrafb", - .id = 0, - .resource = fb_resource, - .num_resources = ARRAY_SIZE(fb_resource), - .dev = { - .platform_data = &tegra_fb_lcd_platform_data, - }, -}; - -int __init olympus_panel_init(void) { - return platform_device_register(&tegra_fb_device); -} diff --git a/arch/arm/mach-tegra/board-olympus-pinmux.c b/arch/arm/mach-tegra/board-olympus-pinmux.c deleted file mode 100644 index f4500649bfa8..000000000000 --- a/arch/arm/mach-tegra/board-olympus-pinmux.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus-pinmux.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -#include "board-olympus.h" - -static __initdata struct tegra_pingroup_config olympus_pinmux[] = { - {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_TRI_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_TRI_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LM0, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPW0, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPW2, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSC1, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_TRI_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_TRI_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAA, TEGRA_MUX_MIPI_HS, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UAB, TEGRA_MUX_MIPI_HS, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UAC, TEGRA_MUX_OWR, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UDA, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, -}; - -void __init olympus_pinmux_init(void) -{ - tegra_pinmux_config_table(olympus_pinmux, ARRAY_SIZE(olympus_pinmux)); -} diff --git a/arch/arm/mach-tegra/board-olympus-wifi.c b/arch/arm/mach-tegra/board-olympus-wifi.c deleted file mode 100644 index af0200f71012..000000000000 --- a/arch/arm/mach-tegra/board-olympus-wifi.c +++ /dev/null @@ -1,205 +0,0 @@ -/* linux/arch/arm/mach-msm/board-olympus-wifi.c -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "board-olympus.h" -#include "gpio-names.h" - -#define OLYMPUS_WLAN_IRQ TEGRA_GPIO_PU5 -#define OLYMPUS_WLAN_PWR TEGRA_GPIO_PU3 -#define OLYMPUS_WLAN_RST TEGRA_GPIO_PU2 - -#define PREALLOC_WLAN_NUMBER_OF_SECTIONS 4 -#define PREALLOC_WLAN_NUMBER_OF_BUFFERS 160 -#define PREALLOC_WLAN_SECTION_HEADER 24 - -#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128) -#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128) -#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 512) -#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 1024) - -#define WLAN_SKB_BUF_NUM 16 - -static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; - -typedef struct wifi_mem_prealloc_struct { - void *mem_ptr; - unsigned long size; -} wifi_mem_prealloc_t; - -static wifi_mem_prealloc_t wifi_mem_array[PREALLOC_WLAN_NUMBER_OF_SECTIONS] = { - { NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER) } -}; - -static void *olympus_wifi_mem_prealloc(int section, unsigned long size) -{ - if (section == PREALLOC_WLAN_NUMBER_OF_SECTIONS) - return wlan_static_skb; - if ((section < 0) || (section > PREALLOC_WLAN_NUMBER_OF_SECTIONS)) - return NULL; - if (wifi_mem_array[section].size < size) - return NULL; - return wifi_mem_array[section].mem_ptr; -} - -int __init olympus_init_wifi_mem(void) -{ - int i; - - for(i=0;( i < WLAN_SKB_BUF_NUM );i++) { - if (i < (WLAN_SKB_BUF_NUM/2)) - wlan_static_skb[i] = dev_alloc_skb(4096); - else - wlan_static_skb[i] = dev_alloc_skb(8192); - } - for(i=0;( i < PREALLOC_WLAN_NUMBER_OF_SECTIONS );i++) { - wifi_mem_array[i].mem_ptr = kmalloc(wifi_mem_array[i].size, - GFP_KERNEL); - if (wifi_mem_array[i].mem_ptr == NULL) - return -ENOMEM; - } - return 0; -} - -static struct resource olympus_wifi_resources[] = { - [0] = { - .name = "bcm4329_wlan_irq", - .start = TEGRA_GPIO_TO_IRQ(OLYMPUS_WLAN_IRQ), - .end = TEGRA_GPIO_TO_IRQ(OLYMPUS_WLAN_IRQ), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, - }, -}; - -/* BCM4329 returns wrong sdio_vsn(1) when we read cccr, - * we use predefined value (sdio_vsn=2) here to initial sdio driver well - */ -static struct embedded_sdio_data olympus_wifi_emb_data = { - .cccr = { - .sdio_vsn = 2, - .multi_block = 1, - .low_speed = 0, - .wide_bus = 0, - .high_power = 1, - .high_speed = 1, - }, -}; - -static int olympus_wifi_cd = 0; /* WIFI virtual 'card detect' status */ -static void (*wifi_status_cb)(int card_present, void *dev_id); -static void *wifi_status_cb_devid; - -static int olympus_wifi_status_register( - void (*callback)(int card_present, void *dev_id), - void *dev_id) -{ - if (wifi_status_cb) - return -EAGAIN; - wifi_status_cb = callback; - wifi_status_cb_devid = dev_id; - return 0; -} - -static unsigned int olympus_wifi_status(struct device *dev) -{ - return olympus_wifi_cd; -} - -struct tegra_sdhci_platform_data olympus_wifi_data = { - .clk_id = NULL, - .force_hs = 0, - .mmc_data = { - .ocr_mask = MMC_VDD_165_195, - .status = olympus_wifi_status, - .register_status_notify = olympus_wifi_status_register, - .embedded_sdio = &olympus_wifi_emb_data, - } -}; - -int olympus_wifi_set_carddetect(int val) -{ - pr_debug("%s: %d\n", __func__, val); - olympus_wifi_cd = val; - if (wifi_status_cb) { - wifi_status_cb(val, wifi_status_cb_devid); - } else - pr_warning("%s: Nobody to notify\n", __func__); - return 0; -} - -static int olympus_wifi_power_state; - -int olympus_wifi_power(int on) -{ - pr_debug("%s: %d\n", __func__, on); - - mdelay(100); - gpio_set_value(OLYMPUS_WLAN_PWR, on); - mdelay(100); - gpio_set_value(OLYMPUS_WLAN_RST, on); - mdelay(200); - - olympus_wifi_power_state = on; - return 0; -} - -static int olympus_wifi_reset_state; - -int olympus_wifi_reset(int on) -{ - pr_debug("%s: do nothing\n", __func__); - olympus_wifi_reset_state = on; - return 0; -} - -static struct wifi_platform_data olympus_wifi_control = { - .set_power = olympus_wifi_power, - .set_reset = olympus_wifi_reset, - .set_carddetect = olympus_wifi_set_carddetect, - .mem_prealloc = olympus_wifi_mem_prealloc, -}; - -static struct platform_device olympus_wifi_device = { - .name = "bcm4329_wlan", - .id = 1, - .num_resources = ARRAY_SIZE(olympus_wifi_resources), - .resource = olympus_wifi_resources, - .dev = { - .platform_data = &olympus_wifi_control, - }, -}; - -static void __init olympus_wlan_gpio(void) -{ - tegra_gpio_enable(OLYMPUS_WLAN_PWR); - gpio_request(OLYMPUS_WLAN_PWR, "wlan_pwr"); - gpio_direction_output(OLYMPUS_WLAN_PWR, 0); - - tegra_gpio_enable(OLYMPUS_WLAN_RST); - gpio_request(OLYMPUS_WLAN_RST, "wlan_rst"); - gpio_direction_output(OLYMPUS_WLAN_RST, 0); - - tegra_gpio_enable(OLYMPUS_WLAN_IRQ); - gpio_request(OLYMPUS_WLAN_IRQ, "wlan_irq"); - gpio_direction_input(OLYMPUS_WLAN_IRQ); -} - -int __init olympus_wlan_init(void) -{ - pr_debug("%s: start\n", __func__); - olympus_wlan_gpio(); - olympus_init_wifi_mem(); - return platform_device_register(&olympus_wifi_device); -} diff --git a/arch/arm/mach-tegra/board-olympus.c b/arch/arm/mach-tegra/board-olympus.c deleted file mode 100644 index 40470c6dcb3f..000000000000 --- a/arch/arm/mach-tegra/board-olympus.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "board.h" -#include "board-olympus.h" -#include "clock.h" -#include "gpio-names.h" -#include "devices.h" - -/* NVidia bootloader tags */ -#define ATAG_NVIDIA 0x41000801 - -#define ATAG_NVIDIA_RM 0x1 -#define ATAG_NVIDIA_DISPLAY 0x2 -#define ATAG_NVIDIA_FRAMEBUFFER 0x3 -#define ATAG_NVIDIA_CHIPSHMOO 0x4 -#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5 -#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000 -#define ATAG_NVIDIA_PRESERVED_MEM_N 2 -#define ATAG_NVIDIA_FORCE_32 0x7fffffff - -struct tag_tegra { - __u32 bootarg_key; - __u32 bootarg_len; - char bootarg[1]; -}; - -static int __init parse_tag_nvidia(const struct tag *tag) -{ - - return 0; -} -__tagtable(ATAG_NVIDIA, parse_tag_nvidia); - -static struct plat_serial8250_port debug_uart_platform_data[] = { - { - .membase = IO_ADDRESS(TEGRA_UARTB_BASE), - .mapbase = TEGRA_UARTB_BASE, - .irq = INT_UARTB, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 0, /* filled in by tegra_olympus_init */ - }, { - .flags = 0 - } -}; - -static struct platform_device debug_uart = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = debug_uart_platform_data, - }, -}; - -/* OTG gadget device */ -static u64 tegra_otg_dmamask = DMA_BIT_MASK(32); - - -static struct resource tegra_otg_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB, - .end = INT_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct fsl_usb2_platform_data tegra_otg_pdata = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - -static struct platform_device tegra_otg = { - .name = "fsl-tegra-udc", - .id = -1, - .dev = { - .dma_mask = &tegra_otg_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &tegra_otg_pdata, - }, - .resource = tegra_otg_resources, - .num_resources = ARRAY_SIZE(tegra_otg_resources), -}; - -static char *usb_functions[] = { "usb_mass_storage" }; -static char *usb_functions_adb[] = { "usb_mass_storage", "adb" }; - -static struct android_usb_product usb_products[] = { - { - .product_id = 0xDEAD, - .num_functions = ARRAY_SIZE(usb_functions), - .functions = usb_functions, - }, - { - .product_id = 0xBEEF, - .num_functions = ARRAY_SIZE(usb_functions_adb), - .functions = usb_functions_adb, - }, -}; - -/* standard android USB platform data */ -static struct android_usb_platform_data andusb_plat = { - .vendor_id = 0x18d1, - .product_id = 0x0002, - .manufacturer_name = "Google", - .product_name = "Olympus!", - .serial_number = "0000", - .num_products = ARRAY_SIZE(usb_products), - .products = usb_products, - .num_functions = ARRAY_SIZE(usb_functions_adb), - .functions = usb_functions_adb, -}; - - -static struct platform_device androidusb_device = { - .name = "android_usb", - .id = -1, - .dev = { - .platform_data = &andusb_plat, - }, -}; - -/* PDA power */ -static struct pda_power_pdata pda_power_pdata = { -}; - -static struct platform_device pda_power_device = { - .name = "pda_power", - .id = -1, - .dev = { - .platform_data = &pda_power_pdata, - }, -}; - - -static struct resource tegra_gart_resources[] = { - { - .name = "mc", - .flags = IORESOURCE_MEM, - .start = TEGRA_MC_BASE, - .end = TEGRA_MC_BASE + TEGRA_MC_SIZE - 1, - }, - { - .name = "gart", - .flags = IORESOURCE_MEM, - .start = 0x58000000, - .end = 0x58000000 - 1 + 32 * 1024 * 1024, - } -}; - - -static struct platform_device tegra_gart_dev = { - .name = "tegra_gart", - .id = -1, - .num_resources = ARRAY_SIZE(tegra_gart_resources), - .resource = tegra_gart_resources -}; - -static struct resource tegra_grhost_resources[] = { - { - .start = TEGRA_HOST1X_BASE, - .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_DISPLAY2_BASE, - .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_VI_BASE, - .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_ISP_BASE, - .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_MPE_BASE, - .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SYNCPT_THRESH_BASE, - .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1, - .flags = IORESOURCE_IRQ, - }, - { - .start = INT_HOST1X_MPCORE_GENERAL, - .end = INT_HOST1X_MPCORE_GENERAL, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tegra_grhost_dev = { - .name = "tegra_grhost", - .id = -1, - .resource = tegra_grhost_resources, - .num_resources = ARRAY_SIZE(tegra_grhost_resources), -}; - -static struct platform_device *olympus_devices[] __initdata = { - &debug_uart, - &tegra_otg, - &androidusb_device, - &pda_power_device, - &tegra_uartd_device, - &tegra_i2c_device1, - &tegra_i2c_device2, - &tegra_i2c_device3, - &tegra_i2c_device4, - &tegra_spi_device1, - &tegra_spi_device2, - &tegra_spi_device3, - &tegra_spi_device4, - &tegra_gart_dev, - &tegra_grhost_dev, -}; - -extern struct tegra_sdhci_platform_data olympus_wifi_data; /* sdhci1 */ - -static struct tegra_sdhci_platform_data olympus_sdhci_platform_data3 = { - .clk_id = NULL, - .force_hs = 0, -}; - -static struct tegra_sdhci_platform_data olympus_sdhci_platform_data4 = { - .clk_id = NULL, - .force_hs = 0, - .cd_gpio = TEGRA_GPIO_PH2, - .wp_gpio = TEGRA_GPIO_PH3, - .power_gpio = TEGRA_GPIO_PI6, -}; - -static __initdata struct tegra_clk_init_table olympus_clk_init_table[] = { - /* name parent rate enabled */ - { "uartb", "clk_m", 26000000, true}, - { "host1x", "pll_p", 108000000, true}, - { "2d", "pll_m", 50000000, true}, - { "epp", "pll_m", 50000000, true}, - { "vi", "pll_m", 50000000, true}, - { NULL, NULL, 0, 0}, -}; - - -static void olympus_sdhci_init(void) -{ - /* TODO: setup GPIOs for cd, wd, and power */ - tegra_sdhci_device1.dev.platform_data = &olympus_wifi_data; - tegra_sdhci_device3.dev.platform_data = &olympus_sdhci_platform_data3; - tegra_sdhci_device4.dev.platform_data = &olympus_sdhci_platform_data4; - - platform_device_register(&tegra_sdhci_device1); - platform_device_register(&tegra_sdhci_device3); - platform_device_register(&tegra_sdhci_device4); -} - -static void __init tegra_olympus_fixup(struct machine_desc *desc, struct tag *tags, - char **cmdline, struct meminfo *mi) -{ - mi->nr_banks = 2; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = 448 * SZ_1M; - mi->bank[1].start = SZ_512M; - mi->bank[1].size = SZ_512M; -} - -static void __init tegra_olympus_init(void) -{ - struct clk *clk; - - tegra_common_init(); - - /* Olympus has a USB switch that disconnects the usb port from the AP20 - unless a factory cable is used, the factory jumper is set, or the - usb_data_en gpio is set. - */ - tegra_gpio_enable(TEGRA_GPIO_PV6); - gpio_request(TEGRA_GPIO_PV6, "usb_data_en"); - gpio_direction_output(TEGRA_GPIO_PV6, 1); - - olympus_pinmux_init(); - - tegra_clk_init_from_table(olympus_clk_init_table); - - clk = tegra_get_clock_by_name("uartb"); - debug_uart_platform_data[0].uartclk = clk_get_rate(clk); - - clk = clk_get_sys("dsi", NULL); - clk_enable(clk); - clk_put(clk); - - clk = clk_get_sys("3d", NULL); - tegra_periph_reset_assert(clk); - writel(0x101, IO_ADDRESS(TEGRA_PMC_BASE) + 0x30); - clk_enable(clk); - udelay(10); - writel(1 << 1, IO_ADDRESS(TEGRA_PMC_BASE) + 0x34); - tegra_periph_reset_deassert(clk); - clk_put(clk); - - - platform_add_devices(olympus_devices, ARRAY_SIZE(olympus_devices)); - - olympus_keypad_init(); - olympus_i2c_init(); - olympus_panel_init(); - olympus_sdhci_init(); - olympus_wlan_init(); -} - -MACHINE_START(OLYMPUS, "olympus") - .boot_params = 0x00000100, - .phys_io = IO_APB_PHYS, - .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc, - .fixup = tegra_olympus_fixup, - .init_irq = tegra_init_irq, - .init_machine = tegra_olympus_init, - .map_io = tegra_map_common_io, - .timer = &tegra_timer, -MACHINE_END diff --git a/arch/arm/mach-tegra/board-olympus.h b/arch/arm/mach-tegra/board-olympus.h deleted file mode 100644 index 0201b56cbb6c..000000000000 --- a/arch/arm/mach-tegra/board-olympus.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-tegra/board-olympus.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_TEGRA_BOARD_OLYMPUS_H -#define _MACH_TEGRA_BOARD_OLYMPUS_H - -void olympus_pinmux_init(void); -int olympus_keypad_init(void); -void olympus_i2c_init(void); -int olympus_panel_init(void); -int olympus_wlan_init(void); - -#endif diff --git a/arch/arm/mach-tegra/board-stingray-bluetooth.c b/arch/arm/mach-tegra/board-stingray-bluetooth.c deleted file mode 100644 index f4419c3874bb..000000000000 --- a/arch/arm/mach-tegra/board-stingray-bluetooth.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Bluetooth Broadcomm and low power control via GPIO - * - * Copyright (C) 2010 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gpio-names.h" - -#define BT_SHUTDOWN_GPIO TEGRA_GPIO_PI7 -#define BT_RESET_GPIO TEGRA_GPIO_PU0 - -#define BT_WAKE_GPIO TEGRA_GPIO_PU1 -#define BT_HOST_WAKE_GPIO TEGRA_GPIO_PU6 - -extern void change_power_brcm_4329(bool); -static struct rfkill *bt_rfkill; - -struct bcm_bt_lpm { - int wake; - int host_wake; - bool rx_wake_lock_taken; - - struct hrtimer enter_lpm_timer; - ktime_t enter_lpm_delay; - - struct uart_port *uport; - - struct wake_lock wake_lock; - char wake_lock_name[100]; -} bt_lpm; - -static int bcm4329_bt_rfkill_set_power(void *data, bool blocked) -{ - // rfkill_ops callback. Turn transmitter on when blocked is false - if (!blocked) { - change_power_brcm_4329(true); - gpio_direction_output(BT_RESET_GPIO, 1); - gpio_direction_output(BT_SHUTDOWN_GPIO, 0); - } else { - change_power_brcm_4329(false); - gpio_direction_output(BT_SHUTDOWN_GPIO, 0); - gpio_direction_output(BT_RESET_GPIO, 0); - } - - return 0; -} - -static const struct rfkill_ops bcm4329_bt_rfkill_ops = { - .set_block = bcm4329_bt_rfkill_set_power, -}; - -static void set_wake_locked(int wake) -{ - bt_lpm.wake = wake; - - if (!wake) - wake_unlock(&bt_lpm.wake_lock); - - gpio_set_value(BT_WAKE_GPIO, wake); -} - -static enum hrtimer_restart enter_lpm(struct hrtimer *timer) { - unsigned long flags; - spin_lock_irqsave(&bt_lpm.uport->lock, flags); - set_wake_locked(0); - spin_unlock_irqrestore(&bt_lpm.uport->lock, flags); - - return HRTIMER_NORESTART; -} - -void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport) { - bt_lpm.uport = uport; - - hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer); - - set_wake_locked(1); - - hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay, - HRTIMER_MODE_REL); -} -EXPORT_SYMBOL(bcm_bt_lpm_exit_lpm_locked); - -void bcm_bt_rx_done_locked(struct uart_port *uport) { - if (bt_lpm.host_wake) { - // Release wake in 500 ms so that higher layers can take it. - wake_lock_timeout(&bt_lpm.wake_lock, HZ/2); - bt_lpm.rx_wake_lock_taken = true; - } -} -EXPORT_SYMBOL(bcm_bt_rx_done_locked); - -static void update_host_wake_locked(int host_wake) -{ - if (host_wake == bt_lpm.host_wake) - return; - - bt_lpm.host_wake = host_wake; - - if (host_wake) { - bt_lpm.rx_wake_lock_taken = false; - wake_lock(&bt_lpm.wake_lock); - } else if (!bt_lpm.rx_wake_lock_taken) { - // Failsafe timeout of wakelock. - // If the host wake pin is asserted and no data is sent, - // when its deasserted we will enter this path - wake_lock_timeout(&bt_lpm.wake_lock, HZ/2); - } - -} - -static irqreturn_t host_wake_isr(int irq, void *dev) -{ - int host_wake; - unsigned long flags; - - host_wake = gpio_get_value(BT_HOST_WAKE_GPIO); - set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); - - if (!bt_lpm.uport) { - bt_lpm.host_wake = host_wake; - return IRQ_HANDLED; - } - - spin_lock_irqsave(&bt_lpm.uport->lock, flags); - update_host_wake_locked(host_wake); - spin_unlock_irqrestore(&bt_lpm.uport->lock, flags); - - return IRQ_HANDLED; -} - -static int bcm_bt_lpm_init(struct platform_device *pdev) -{ - int irq; - int ret; - int rc; - - tegra_gpio_enable(BT_WAKE_GPIO); - rc = gpio_request(BT_WAKE_GPIO, "bcm4329_wake_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_WAKE_GPIO); - return rc; - } - - tegra_gpio_enable(BT_HOST_WAKE_GPIO); - rc = gpio_request(BT_HOST_WAKE_GPIO, "bcm4329_host_wake_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - gpio_free(BT_WAKE_GPIO); - return rc; - } - - hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - bt_lpm.enter_lpm_delay = ktime_set(1, 0); /* 1 sec */ - bt_lpm.enter_lpm_timer.function = enter_lpm; - - bt_lpm.host_wake = 0; - - irq = gpio_to_irq(BT_HOST_WAKE_GPIO); - ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH, - "bt host_wake", NULL); - if (ret) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - return ret; - } - - ret = set_irq_wake(irq, 1); - if (ret) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - return ret; - } - - gpio_direction_output(BT_WAKE_GPIO, 0); - gpio_direction_input(BT_HOST_WAKE_GPIO); - - snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name), - "BTLowPower"); - wake_lock_init(&bt_lpm.wake_lock, WAKE_LOCK_SUSPEND, - bt_lpm.wake_lock_name); - return 0; -} - -static int bcm4329_bluetooth_probe(struct platform_device *pdev) -{ - int rc = 0; - int ret = 0; - - tegra_gpio_enable(BT_RESET_GPIO); - rc = gpio_request(BT_RESET_GPIO, "bcm4329_nreset_gpip"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_RESET_GPIO); - return rc; - } - - tegra_gpio_enable(BT_SHUTDOWN_GPIO); - rc = gpio_request(BT_SHUTDOWN_GPIO, "bcm4329_nshutdown_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - gpio_free(BT_RESET_GPIO); - return rc; - } - - - bcm4329_bt_rfkill_set_power(NULL, true); - - bt_rfkill = rfkill_alloc("bcm4329 Bluetooth", &pdev->dev, - RFKILL_TYPE_BLUETOOTH, &bcm4329_bt_rfkill_ops, - NULL); - - if (unlikely(!bt_rfkill)) { - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - return -ENOMEM; - } - - rfkill_set_states(bt_rfkill, true, false); - - rc = rfkill_register(bt_rfkill); - - if (unlikely(rc)) { - rfkill_destroy(bt_rfkill); - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - return -1; - } - - ret = bcm_bt_lpm_init(pdev); - if (ret) { - rfkill_unregister(bt_rfkill); - rfkill_destroy(bt_rfkill); - - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - } - - return ret; -} - -static int bcm4329_bluetooth_remove(struct platform_device *pdev) -{ - rfkill_unregister(bt_rfkill); - rfkill_destroy(bt_rfkill); - - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_SHUTDOWN_GPIO); - gpio_free(BT_RESET_GPIO); - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - - wake_lock_destroy(&bt_lpm.wake_lock); - return 0; -} - -static struct platform_driver bcm4329_bluetooth_platform_driver = { - .probe = bcm4329_bluetooth_probe, - .remove = bcm4329_bluetooth_remove, - .driver = { - .name = "bcm4329_bluetooth", - .owner = THIS_MODULE, - }, -}; - -static int __init bcm4329_bluetooth_init(void) -{ - return platform_driver_register(&bcm4329_bluetooth_platform_driver); -} - -static void __exit bcm4329_bluetooth_exit(void) -{ - platform_driver_unregister(&bcm4329_bluetooth_platform_driver); -} - - -module_init(bcm4329_bluetooth_init); -module_exit(bcm4329_bluetooth_exit); - -MODULE_ALIAS("platform:bcm4329"); -MODULE_DESCRIPTION("bcm4329_bluetooth"); -MODULE_AUTHOR("Jaikumar Ganesh "); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-tegra/board-stingray-bootinfo.c b/arch/arm/mach-tegra/board-stingray-bootinfo.c deleted file mode 100644 index 55642dec3164..000000000000 --- a/arch/arm/mach-tegra/board-stingray-bootinfo.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * bootinfo.c: This code provides boot information via /proc/bootinfo. - * The information currently includes: - * - the powerup reason - * - the hardware revision - * All new user-space consumers of the powerup reason should use - * the /proc/bootinfo interface; all kernel-space consumers of the - * powerup reason should use the stingray_powerup_reason interface. - * - * Copyright (C) 2009 Motorola, 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 - * - * Revision History: - * - * Date Author Comment - * ---------- -------- ----------- - * 30/06/2009 Motorola Initialize version - * 25/10/2010 Motorola Modified for stingray - * 30/10/2010 Motorola Converted to seq_file interface - */ - -#include -#include -#include -#include -#include -#include "board-stingray.h" - -static int bootinfo_show(struct seq_file *m, void *v) -{ - seq_printf(m, "POWERUPREASON : 0x%08x\n", - stingray_powerup_reason()); - - seq_printf(m, "BOARDREVISION : 0x%08x\n", - stingray_revision()); - - return 0; -} - -static int bootinfo_open(struct inode *inode, struct file *file) -{ - return single_open(file, bootinfo_show, NULL); -} - -static const struct file_operations bootinfo_operations = { - .open = bootinfo_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -int __init bootinfo_init(void) -{ - struct proc_dir_entry *pe; - - pe = proc_create("bootinfo", S_IRUGO, NULL, &bootinfo_operations); - if (!pe) - return -ENOMEM; - - return 0; -} - -device_initcall(bootinfo_init); diff --git a/arch/arm/mach-tegra/board-stingray-gps.c b/arch/arm/mach-tegra/board-stingray-gps.c deleted file mode 100755 index 597bf92069fb..000000000000 --- a/arch/arm/mach-tegra/board-stingray-gps.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include "board-stingray.h" -#include "gpio-names.h" - -#define STINGRAY_GPS_RESET TEGRA_GPIO_PH0 -#define STINGRAY_GPS_STANDBY TEGRA_GPIO_PH1 -#define STINGRAY_GPS_UART_CTS TEGRA_GPIO_PY6 - -static void stingray_gps_reset_gpio(unsigned int gpio_val) -{ - pr_info("%s: setting GPS Reset GPIO to %d\n", __func__, gpio_val); - gpio_set_value(STINGRAY_GPS_RESET, gpio_val); -} - -static void stingray_gps_standby_gpio(unsigned int gpio_val) -{ - pr_info("%s: setting GPS standby GPIO to %d\n", __func__, gpio_val); - gpio_set_value(STINGRAY_GPS_STANDBY, gpio_val); -} - -static void stingray_gps_gpio_release(void) -{ - gpio_free(STINGRAY_GPS_RESET); - gpio_free(STINGRAY_GPS_STANDBY); -} - -static void stingray_gps_gpio_init(void) -{ - tegra_gpio_enable(STINGRAY_GPS_RESET); - gpio_request(STINGRAY_GPS_RESET, "gps_rst"); - gpio_direction_output(STINGRAY_GPS_RESET, 0); - - tegra_gpio_enable(STINGRAY_GPS_STANDBY); - gpio_request(STINGRAY_GPS_STANDBY, "gps_stdby"); - gpio_direction_output(STINGRAY_GPS_STANDBY, 0); - - if (stingray_revision() < STINGRAY_REVISION_P3) { - tegra_gpio_enable(STINGRAY_GPS_UART_CTS); - gpio_request(STINGRAY_GPS_UART_CTS, "uarte_cts"); - gpio_direction_output(STINGRAY_GPS_UART_CTS, 0); - gpio_set_value(STINGRAY_GPS_UART_CTS, 0); - } -} - -struct gps_gpio_brcm4750_platform_data stingray_gps_gpio_data = { - .set_reset_gpio = stingray_gps_reset_gpio, - .set_standby_gpio = stingray_gps_standby_gpio, - .free_gpio = stingray_gps_gpio_release, -}; - -static struct platform_device stingray_gps_device = { - .name = GPS_GPIO_DRIVER_NAME, - .id = -1, - .dev = { - .platform_data = &stingray_gps_gpio_data, - }, -}; - -void __init stingray_gps_init(void) -{ - stingray_gps_gpio_init(); - platform_device_register(&stingray_gps_device); -} diff --git a/arch/arm/mach-tegra/board-stingray-keypad.c b/arch/arm/mach-tegra/board-stingray-keypad.c deleted file mode 100644 index 3fd5c9ea0965..000000000000 --- a/arch/arm/mach-tegra/board-stingray-keypad.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray-keypad.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "board-stingray.h" -#include "gpio-names.h" - -static unsigned int stingray_row_gpios[] = { - TEGRA_GPIO_PR0, - TEGRA_GPIO_PR1 -}; -static unsigned int stingray_col_gpios[] = { - TEGRA_GPIO_PQ0 -}; - -#define KEYMAP_INDEX(col, row) ((col)*ARRAY_SIZE(stingray_row_gpios) + (row)) - -static const unsigned short stingray_p3_keymap[ARRAY_SIZE(stingray_col_gpios) * - ARRAY_SIZE(stingray_row_gpios)] = { - [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP, - [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN -}; - -static struct gpio_event_matrix_info stingray_keypad_matrix_info = { - .info.func = gpio_event_matrix_func, - .keymap = stingray_p3_keymap, - .output_gpios = stingray_col_gpios, - .input_gpios = stingray_row_gpios, - .noutputs = ARRAY_SIZE(stingray_col_gpios), - .ninputs = ARRAY_SIZE(stingray_row_gpios), - .settle_time.tv.nsec = 40 * NSEC_PER_USEC, - .poll_time.tv.nsec = 20 * NSEC_PER_MSEC, - .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_REMOVE_PHANTOM_KEYS | - GPIOKPF_PRINT_UNMAPPED_KEYS /*| GPIOKPF_PRINT_MAPPED_KEYS*/ -}; - -static struct gpio_event_direct_entry stingray_keypad_switch_map[] = { -}; - -static struct gpio_event_input_info stingray_keypad_switch_info = { - .info.func = gpio_event_input_func, - .flags = 0, - .type = EV_SW, - .keymap = stingray_keypad_switch_map, - .keymap_size = ARRAY_SIZE(stingray_keypad_switch_map) -}; - -static struct gpio_event_info *stingray_keypad_info[] = { - &stingray_keypad_matrix_info.info, - &stingray_keypad_switch_info.info, -}; - -static struct gpio_event_platform_data stingray_keypad_data = { - .name = "stingray-keypad", - .info = stingray_keypad_info, - .info_count = ARRAY_SIZE(stingray_keypad_info) -}; - -static struct platform_device stingray_keypad_device = { - .name = GPIO_EVENT_DEV_NAME, - .id = 0, - .dev = { - .platform_data = &stingray_keypad_data, - }, -}; - -int stingray_log_reset(void) -{ - pr_warn("Hard reset buttons pushed\n"); - return 0; -} - -static struct keyreset_platform_data stingray_reset_keys_pdata = { - .reset_fn = stingray_log_reset, - .keys_down = { - KEY_END, - KEY_VOLUMEUP, - 0 - }, -}; - -struct platform_device stingray_keyreset_device = { - .name = KEYRESET_NAME, - .dev = { - .platform_data = &stingray_reset_keys_pdata, - }, -}; - - -int __init stingray_keypad_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PR0); - tegra_gpio_enable(TEGRA_GPIO_PR1); - tegra_gpio_enable(TEGRA_GPIO_PQ0); - platform_device_register(&stingray_keyreset_device); - return platform_device_register(&stingray_keypad_device); -} diff --git a/arch/arm/mach-tegra/board-stingray-memory.c b/arch/arm/mach-tegra/board-stingray-memory.c deleted file mode 100644 index d163ecab95b9..000000000000 --- a/arch/arm/mach-tegra/board-stingray-memory.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include - -#include "board-stingray.h" -#include "tegra2_emc.h" - - -static const struct tegra_emc_table stingray_emc_tables_samsung[] = { - { - .rate = 25000, /* SDRAM frequency */ - .regs = { - 0x00000002, /* RC */ - 0x00000006, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000004, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000004d, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000004, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000068, /* TREFBW */ - 0x00000003, /* QUSE_EXTRA */ - 0x00000003, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa09404ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000003, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 50000, /* SDRAM frequency */ - .regs = { - 0x00000003, /* RC */ - 0x00000007, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000009f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000007, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000000d0, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa09404ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000005, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 75000, /* SDRAM frequency */ - .regs = { - 0x00000005, /* RC */ - 0x0000000a, /* RFC */ - 0x00000004, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x000000ff, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x0000000b, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000138, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa09404ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000007, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 150000, /* SDRAM frequency */ - .regs = { - 0x00000009, /* RC */ - 0x00000014, /* RFC */ - 0x00000007, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000021f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000015, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000270, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000001, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa06804ae, /* CFG_DIG_DLL */ - 0x007e0010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000000e, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 300000, /* SDRAM frequency */ - .regs = { - 0x00000012, /* RC */ - 0x00000027, /* RFC */ - 0x0000000d, /* RAS */ - 0x00000006, /* RP */ - 0x00000007, /* R2W */ - 0x00000005, /* W2R */ - 0x00000003, /* R2P */ - 0x00000009, /* W2P */ - 0x00000006, /* RD_RCD */ - 0x00000006, /* WR_RCD */ - 0x00000003, /* RRD */ - 0x00000003, /* REXT */ - 0x00000002, /* WDV */ - 0x00000006, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000009, /* QSAFE */ - 0x0000000c, /* RDV */ - 0x0000045f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000004, /* PDEX2WR */ - 0x00000004, /* PDEX2RD */ - 0x00000006, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000e, /* RW2PDEN */ - 0x0000002a, /* TXSR */ - 0x00000003, /* TCKE */ - 0x0000000f, /* TFAW */ - 0x00000007, /* TRPAB */ - 0x00000005, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000004e0, /* TREFBW */ - 0x00000005, /* QUSE_EXTRA */ - 0x00000002, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000282, /* FBIO_CFG5 */ - 0xe04e048b, /* CFG_DIG_DLL */ - 0x007e0010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000001b, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - } -}; - -static const struct tegra_emc_table stingray_emc_tables_elpida_50nm[] = { - { - .rate = 25000, /* SDRAM frequency */ - .regs = { - 0x00000002, /* RC */ - 0x00000006, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000004, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000004d, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000004, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000068, /* TREFBW */ - 0x00000003, /* QUSE_EXTRA */ - 0x00000003, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa06a04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000003, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 50000, /* SDRAM frequency */ - .regs = { - 0x00000003, /* RC */ - 0x00000007, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000009f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000007, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000000d0, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa06a04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000005, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 75000, /* SDRAM frequency */ - .regs = { - 0x00000005, /* RC */ - 0x0000000a, /* RFC */ - 0x00000004, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x000000ff, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x0000000b, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000138, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa06a04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000007, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 150000, /* SDRAM frequency */ - .regs = { - 0x00000009, /* RC */ - 0x00000014, /* RFC */ - 0x00000007, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000021f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000015, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000270, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000001, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa04c04ae, /* CFG_DIG_DLL */ - 0x007e0010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000000e, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 300000, /* SDRAM frequency */ - .regs = { - 0x00000012, /* RC */ - 0x00000027, /* RFC */ - 0x0000000d, /* RAS */ - 0x00000006, /* RP */ - 0x00000007, /* R2W */ - 0x00000005, /* W2R */ - 0x00000003, /* R2P */ - 0x00000009, /* W2P */ - 0x00000006, /* RD_RCD */ - 0x00000006, /* WR_RCD */ - 0x00000003, /* RRD */ - 0x00000003, /* REXT */ - 0x00000002, /* WDV */ - 0x00000006, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000009, /* QSAFE */ - 0x0000000c, /* RDV */ - 0x0000045f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000004, /* PDEX2WR */ - 0x00000004, /* PDEX2RD */ - 0x00000006, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000e, /* RW2PDEN */ - 0x0000002a, /* TXSR */ - 0x00000003, /* TCKE */ - 0x0000000f, /* TFAW */ - 0x00000007, /* TRPAB */ - 0x00000005, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000004e0, /* TREFBW */ - 0x00000005, /* QUSE_EXTRA */ - 0x00000002, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000282, /* FBIO_CFG5 */ - 0xe03c048b, /* CFG_DIG_DLL */ - 0x007e0010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000001b, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - } -}; - -static const struct tegra_emc_table stingray_emc_tables_elpida_40nm[] = { - { - .rate = 25000, /* SDRAM frequency */ - .regs = { - 0x00000002, /* RC */ - 0x00000006, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000004, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000004d, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000004, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000068, /* TREFBW */ - 0x00000003, /* QUSE_EXTRA */ - 0x00000003, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa0ae04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000003, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 50000, /* SDRAM frequency */ - .regs = { - 0x00000003, /* RC */ - 0x00000007, /* RFC */ - 0x00000003, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000009f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000007, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000000d0, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa0ae04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000005, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 75000, /* SDRAM frequency */ - .regs = { - 0x00000005, /* RC */ - 0x0000000a, /* RFC */ - 0x00000004, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x000000ff, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x0000000b, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000138, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000000, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa0ae04ae, /* CFG_DIG_DLL */ - 0x00070000, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x00000007, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 150000, /* SDRAM frequency */ - .regs = { - 0x00000009, /* RC */ - 0x00000014, /* RFC */ - 0x00000007, /* RAS */ - 0x00000003, /* RP */ - 0x00000006, /* R2W */ - 0x00000004, /* W2R */ - 0x00000002, /* R2P */ - 0x00000009, /* W2P */ - 0x00000003, /* RD_RCD */ - 0x00000003, /* WR_RCD */ - 0x00000002, /* RRD */ - 0x00000002, /* REXT */ - 0x00000002, /* WDV */ - 0x00000005, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000008, /* QSAFE */ - 0x0000000b, /* RDV */ - 0x0000021f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000003, /* PDEX2WR */ - 0x00000003, /* PDEX2RD */ - 0x00000003, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000a, /* RW2PDEN */ - 0x00000015, /* TXSR */ - 0x00000003, /* TCKE */ - 0x00000008, /* TFAW */ - 0x00000004, /* TRPAB */ - 0x00000006, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x00000270, /* TREFBW */ - 0x00000004, /* QUSE_EXTRA */ - 0x00000001, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000082, /* FBIO_CFG5 */ - 0xa07c04ae, /* CFG_DIG_DLL */ - 0x007de010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000000e, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - }, - { - .rate = 300000, /* SDRAM frequency */ - .regs = { - 0x00000012, /* RC */ - 0x00000027, /* RFC */ - 0x0000000d, /* RAS */ - 0x00000006, /* RP */ - 0x00000007, /* R2W */ - 0x00000005, /* W2R */ - 0x00000003, /* R2P */ - 0x00000009, /* W2P */ - 0x00000006, /* RD_RCD */ - 0x00000006, /* WR_RCD */ - 0x00000003, /* RRD */ - 0x00000003, /* REXT */ - 0x00000002, /* WDV */ - 0x00000006, /* QUSE */ - 0x00000003, /* QRST */ - 0x00000009, /* QSAFE */ - 0x0000000c, /* RDV */ - 0x0000045f, /* REFRESH */ - 0x00000000, /* BURST_REFRESH_NUM */ - 0x00000004, /* PDEX2WR */ - 0x00000004, /* PDEX2RD */ - 0x00000006, /* PCHG2PDEN */ - 0x00000008, /* ACT2PDEN */ - 0x00000001, /* AR2PDEN */ - 0x0000000e, /* RW2PDEN */ - 0x0000002a, /* TXSR */ - 0x00000003, /* TCKE */ - 0x0000000f, /* TFAW */ - 0x00000007, /* TRPAB */ - 0x00000005, /* TCLKSTABLE */ - 0x00000002, /* TCLKSTOP */ - 0x000004e0, /* TREFBW */ - 0x00000005, /* QUSE_EXTRA */ - 0x00000002, /* FBIO_CFG6 */ - 0x00000000, /* ODT_WRITE */ - 0x00000000, /* ODT_READ */ - 0x00000282, /* FBIO_CFG5 */ - 0xe059048b, /* CFG_DIG_DLL */ - 0x007e4010, /* DLL_XFORM_DQS */ - 0x00000000, /* DLL_XFORM_QUSE */ - 0x00000000, /* ZCAL_REF_CNT */ - 0x0000001b, /* ZCAL_WAIT_CNT */ - 0x00000000, /* AUTO_CAL_INTERVAL */ - 0x00000000, /* CFG_CLKTRIM_0 */ - 0x00000000, /* CFG_CLKTRIM_1 */ - 0x00000000, /* CFG_CLKTRIM_2 */ - } - } -}; - -struct tegra_emc_chip stingray_emc_chips[] = { - { - .description = "Samsung", - .mem_manufacturer_id = 0x0101, - .mem_revision_id1 = -1, - .mem_revision_id2 = -1, - .mem_pid = 0x5454, - .table = stingray_emc_tables_samsung, - .table_size = ARRAY_SIZE(stingray_emc_tables_samsung) - }, - { - .description = "Elpida 40nm", - .mem_manufacturer_id = 0x0303, - .mem_revision_id1 = 0x0101, - .mem_revision_id2 = -1, - .mem_pid = 0x5454, - .table = stingray_emc_tables_elpida_40nm, - .table_size = ARRAY_SIZE(stingray_emc_tables_elpida_40nm) - }, - { - .description = "Elpida 50nm", - .mem_manufacturer_id = 0x0303, - .mem_revision_id1 = -1, - .mem_revision_id2 = -1, - .mem_pid = 0x5454, - .table = stingray_emc_tables_elpida_50nm, - .table_size = ARRAY_SIZE(stingray_emc_tables_elpida_50nm) - }, -}; - -void stingray_init_emc(void) -{ - tegra_init_emc(stingray_emc_chips, ARRAY_SIZE(stingray_emc_chips)); -} diff --git a/arch/arm/mach-tegra/board-stingray-panel.c b/arch/arm/mach-tegra/board-stingray-panel.c deleted file mode 100644 index bf06c700b634..000000000000 --- a/arch/arm/mach-tegra/board-stingray-panel.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray-panel.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "board.h" -#include "board-stingray.h" -#include "gpio-names.h" - -#define STINGRAY_AUO_DISP_BL TEGRA_GPIO_PD0 -#define STINGRAY_LVDS_SHDN_B TEGRA_GPIO_PB2 -#define STINGRAY_HDMI_5V_EN TEGRA_GPIO_PC4 -#define STINGRAY_HDMI_HPD TEGRA_GPIO_PN7 - -/* Display Controller */ -static struct resource stingray_disp1_resources[] = { - { - .name = "irq", - .start = INT_DISPLAY_GENERAL, - .end = INT_DISPLAY_GENERAL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "regs", - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, - .flags = IORESOURCE_MEM, - }, - { - .name = "fbmem", - /* .start and .end to be filled in later */ - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource stingray_disp2_resources[] = { - { - .name = "irq", - .start = INT_DISPLAY_B_GENERAL, - .end = INT_DISPLAY_B_GENERAL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "regs", - .start = TEGRA_DISPLAY2_BASE, - .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE-1, - .flags = IORESOURCE_MEM, - }, - { - .name = "fbmem", - /* .start and .end to be filled in later */ - .flags = IORESOURCE_MEM, - }, - { - .name = "hdmi_regs", - .start = TEGRA_HDMI_BASE, - .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_dc_mode stingray_panel_modes_p0[] = { - { - .pclk = 62200000, - .h_ref_to_sync = 11, - .v_ref_to_sync = 1, - .h_sync_width = 42, - .v_sync_width = 6, - .h_back_porch = 43, - .v_back_porch = 5, - .h_active = 1280, - .v_active = 720, - .h_front_porch = 43, - .v_front_porch = 5, - }, -}; - -static struct tegra_dc_mode stingray_panel_modes[] = { - { - .pclk = 65000000, - .h_ref_to_sync = 11, - .v_ref_to_sync = 1, - .h_sync_width = 26, - .v_sync_width = 6, - .h_back_porch = 12, - .v_back_porch = 3, - .h_active = 1280, - .v_active = 800, - .h_front_porch = 45, - .v_front_porch = 3, - }, -}; - -static struct tegra_fb_data stingray_fb_data_p0 = { - .win = 0, - .xres = 1280, - .yres = 720, - .bits_per_pixel = -1, - .flags = TEGRA_FB_FLIP_ON_PROBE, -}; - -static struct tegra_fb_data stingray_fb_data = { - .win = 0, - .xres = 1280, - .yres = 800, - .bits_per_pixel = -1, - .flags = TEGRA_FB_FLIP_ON_PROBE, -}; - -#define LCD_MANFID_MAX_LEN 3 -static char lcd_manfid[LCD_MANFID_MAX_LEN + 1]; -int __init board_lcd_manfid_init(char *s) -{ - strncpy(lcd_manfid, s, LCD_MANFID_MAX_LEN); - lcd_manfid[LCD_MANFID_MAX_LEN] = '\0'; - printk(KERN_INFO "lcd_manfid=%s\n", lcd_manfid); - return 1; -} -__setup("lcd_manfid=", board_lcd_manfid_init); - -/* Disgusting hack to deal with the fact that there are a set of pull down - * resistors on the panel end of the i2c bus. These cause a voltage - * divider on the i2c bus which can cause these devices to fail to recognize - * their addresses when power to the display is cut. This creates a dependency - * between these devices and the power to the panel. - */ -static struct regulator_consumer_supply stingray_panel_reg_consumer_supply[] = { - { .supply = "vdd_panel", .dev_name = NULL, }, - { .supply = "vio", .dev_name = "0-0077" /* barometer */}, - { .supply = "vio", .dev_name = "0-002c" /* lighting */}, - { .supply = "vio", .dev_name = "0-005b" /* touch */}, - { .supply = "vio", .dev_name = "0-004b" /* als */}, -}; - -static struct regulator_init_data stingray_panel_reg_initdata = { - .consumer_supplies = stingray_panel_reg_consumer_supply, - .num_consumer_supplies = ARRAY_SIZE(stingray_panel_reg_consumer_supply), - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, -}; - -static struct fixed_voltage_config stingray_panel_reg_config = { - .supply_name = "stingray_panel_reg", - .microvolts = 5000000, - .gpio = STINGRAY_LVDS_SHDN_B, - .startup_delay = 200000, - .enable_high = 1, - .enabled_at_boot = 1, - .init_data = &stingray_panel_reg_initdata, -}; - -static struct platform_device stingray_panel_reg_device = { - .name = "reg-fixed-voltage", - .id = 0, - .dev = { - .platform_data = &stingray_panel_reg_config, - }, -}; - -static struct regulator *stingray_panel_regulator = NULL; -static int stingray_panel_enable(void) -{ - if (IS_ERR_OR_NULL(stingray_panel_regulator)) { - stingray_panel_regulator = regulator_get(NULL, "vdd_panel"); - if (IS_ERR_OR_NULL(stingray_panel_regulator)) { - pr_err("%s: Could not get panel regulator\n", __func__); - return PTR_ERR(stingray_panel_regulator); - } - } - - return regulator_enable(stingray_panel_regulator); -} - -static int stingray_panel_disable(void) -{ - if (!IS_ERR_OR_NULL(stingray_panel_regulator)) - regulator_disable(stingray_panel_regulator); - return 0; -} - -static void stingray_panel_early_reg_disable(struct work_struct *work) -{ - stingray_panel_disable(); -} - -static DECLARE_DELAYED_WORK(stingray_panel_early_reg_disable_work, - stingray_panel_early_reg_disable); - -static void stingray_panel_early_reg_enable(struct work_struct *work) -{ - /* - * If the regulator was previously enabled, the work function to - * disable the work will be pending, cancel_delayed_work_sync - * will return true, and the regulator will not get enabled again. - */ - if (!cancel_delayed_work_sync(&stingray_panel_early_reg_disable_work)) - stingray_panel_enable(); - - /* - * After the cancel_delay_work_sync, there is no outstanding work - * to disable the regulator, so queue the disable in 1 second. - * If no other driver calls regulator_enable on stingray_panel_regulator - * before 1 second has elapsed, the bridge chip will power down. - */ - queue_delayed_work(system_nrt_wq, - &stingray_panel_early_reg_disable_work, - msecs_to_jiffies(1000)); -} - -static DECLARE_WORK(stingray_panel_early_reg_enable_work, - stingray_panel_early_reg_enable); -static bool stingray_panel_early_reg_in_resume; - -static int stingray_panel_early_reg_resume_noirq(struct device *dev) -{ - stingray_panel_early_reg_in_resume = true; - smp_wmb(); - return 0; -} - -static void stingray_panel_early_reg_resume_complete(struct device *dev) -{ - stingray_panel_early_reg_in_resume = false; - smp_wmb(); -} - -static int stingray_panel_early_reg_suspend(struct device *dev) -{ - cancel_work_sync(&stingray_panel_early_reg_enable_work); - flush_delayed_work(&stingray_panel_early_reg_disable_work); - - return 0; -} - -/* - * If the power button key event is detected during the resume process, - * the screen will get turned on later. Immediately start the LVDS bridge chip - * turning on to reduce time spent waiting for it later in resume. - */ -static int stingray_panel_early_reg_power(void) -{ - smp_rmb(); - if (stingray_panel_early_reg_in_resume) - queue_work(system_nrt_wq, &stingray_panel_early_reg_enable_work); - - return 0; -} - -static struct dev_pm_ops stingray_panel_early_reg_pm_ops = { - .resume_noirq = stingray_panel_early_reg_resume_noirq, - .complete = stingray_panel_early_reg_resume_complete, - .suspend = stingray_panel_early_reg_suspend, -}; - -static struct keyreset_platform_data stingray_panel_early_reg_keyreset = { - .reset_fn = stingray_panel_early_reg_power, - .keys_down = { - KEY_END, - 0 - }, -}; - -struct platform_device stingray_panel_early_reg_keyreset_device = { - .name = KEYRESET_NAME, - .id = -1, - .dev = { - .platform_data = &stingray_panel_early_reg_keyreset, - }, -}; - -static struct platform_driver stingray_panel_early_reg_driver = { - .driver = { - .name = "stingray-panel-early-reg", - .owner = THIS_MODULE, - .pm = &stingray_panel_early_reg_pm_ops, - } -}; - -static struct platform_device stingray_panel_early_reg_device = { - .name = "stingray-panel-early-reg", -}; - -static struct tegra_dc_out stingray_disp1_out = { - .type = TEGRA_DC_OUT_RGB, - - .align = TEGRA_DC_ALIGN_MSB, - .order = TEGRA_DC_ORDER_RED_BLUE, - .depth = 24, - - .height = 136, /* mm */ - .width = 217, /* mm */ - - .modes = stingray_panel_modes, - .n_modes = ARRAY_SIZE(stingray_panel_modes), - - .enable = stingray_panel_enable, - .disable = stingray_panel_disable, -}; - -static struct tegra_dc_platform_data stingray_disp1_pdata = { - .flags = TEGRA_DC_FLAG_ENABLED, - .emc_clk_rate = 300000000, - .default_out = &stingray_disp1_out, - .fb = &stingray_fb_data, -}; - -static struct nvhost_device stingray_disp1_device = { - .name = "tegradc", - .id = 0, - .resource = stingray_disp1_resources, - .num_resources = ARRAY_SIZE(stingray_disp1_resources), - .dev = { - .platform_data = &stingray_disp1_pdata, - }, -}; - -static int stingray_hdmi_init(void) -{ - tegra_gpio_enable(STINGRAY_HDMI_5V_EN); - gpio_request(STINGRAY_HDMI_5V_EN, "hdmi_5v_en"); - gpio_direction_output(STINGRAY_HDMI_5V_EN, 1); - - tegra_gpio_enable(STINGRAY_HDMI_HPD); - gpio_request(STINGRAY_HDMI_HPD, "hdmi_hpd"); - gpio_direction_input(STINGRAY_HDMI_HPD); - - - return 0; -} - -static struct tegra_dc_out stingray_disp2_out = { - .type = TEGRA_DC_OUT_HDMI, - .flags = TEGRA_DC_OUT_HOTPLUG_HIGH, - - .dcc_bus = 1, - .hotplug_gpio = STINGRAY_HDMI_HPD, - - .align = TEGRA_DC_ALIGN_MSB, - .order = TEGRA_DC_ORDER_RED_BLUE, -}; - -static struct tegra_fb_data stingray_disp2_fb_data = { - .win = 0, - .xres = 1280, - .yres = 720, - .bits_per_pixel = 32, -}; - -static struct tegra_dc_platform_data stingray_disp2_pdata = { - .flags = 0, - .emc_clk_rate = ULONG_MAX, - .default_out = &stingray_disp2_out, - .fb = &stingray_disp2_fb_data, -}; - -static struct nvhost_device stingray_disp2_device = { - .name = "tegradc", - .id = 1, - .resource = stingray_disp2_resources, - .num_resources = ARRAY_SIZE(stingray_disp2_resources), - .dev = { - .platform_data = &stingray_disp2_pdata, - }, -}; - - -static void stingray_backlight_enable(void) -{ - gpio_set_value(STINGRAY_AUO_DISP_BL, 1); -} - -static void stingray_backlight_disable(void) -{ - gpio_set_value(STINGRAY_AUO_DISP_BL, 0); -} - -struct auo_panel_bl_platform_data stingray_auo_backlight_data = { - .bl_enable = stingray_backlight_enable, - .bl_disable = stingray_backlight_disable, - .pwm_enable = NULL, - .pwm_disable = NULL, -}; - -static struct platform_device stingray_panel_bl_driver = { - .name = LD_AUO_PANEL_BL_NAME, - .id = -1, - .dev = { - .platform_data = &stingray_auo_backlight_data, - }, -}; - -struct lp8550_eeprom_data stingray_lp8550_eeprom_data[] = { - /* Set the backlight current to 19mA each step is .12mA */ - {0xa1}, - /* Boost freq 312khz, PWM controled w/constant current, - thermal deration disabled, brightness slope 500mS */ - {0x67}, - /* Adaptive mode for light loads, advanced slope enabled, 50% mode selected, - Adaptive mode enabled, Boost is enabled, Boost Imax is 2.5A */ - {0xbf}, - /* UVLO is disabled, phase shift PWM enabled, PWM Freq 19232 */ - {0x3f}, - /* LED current resistor disabled, LED Fault = 3.3V */ - {0x08}, - /* Vsync is enabled, Dither enabled, Boost voltage 20V */ - {0xea}, - /* PLL 13-bit counter */ - {0x64}, - /* 1-bit hysteresis w/10 bit resolution, PWM output freq is set with - PWM_FREQ EEPROM bits */ - {0x2a}, -}; - -struct lp8550_platform_data stingray_lp8550_backlight_data = { - .power_up_brightness = 0x80, - .dev_ctrl_config = 0x04, - .brightness_control = 0x80, - .dev_id = 0xfc, - .direct_ctrl = 0x01, - .eeprom_table = stingray_lp8550_eeprom_data, - .eeprom_tbl_sz = ARRAY_SIZE(stingray_lp8550_eeprom_data), - .scaling_factor = 690, /* For SHP and default */ -}; - -static int stingray_lp8550_init(void) -{ - struct lp8550_platform_data *pdata = - &stingray_lp8550_backlight_data; - if (!strncmp(lcd_manfid, "AUO", 3)) - pdata->scaling_factor = 726; - - return 0; -} - -static struct i2c_board_info __initdata stingray_i2c_bus1_led_info[] = { - { - I2C_BOARD_INFO(LD_LP8550_NAME, 0x2c), - .platform_data = &stingray_lp8550_backlight_data, - }, -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -/* put early_suspend/late_resume handlers here for the display in order - * to keep the code out of the display driver, keeping it closer to upstream - */ -struct early_suspend stingray_panel_early_suspender; - -static void stingray_panel_early_suspend(struct early_suspend *h) -{ - if (num_registered_fb > 0) - fb_blank(registered_fb[0], FB_BLANK_POWERDOWN); -} - -static void stingray_panel_late_resume(struct early_suspend *h) -{ - if (num_registered_fb > 0) - fb_blank(registered_fb[0], FB_BLANK_UNBLANK); -} -#endif - -static struct regulator *stingray_csi_reg; - -int __init stingray_panel_init(void) -{ - struct resource *res; - - if (stingray_revision() < STINGRAY_REVISION_P1) { - tegra_gpio_enable(STINGRAY_AUO_DISP_BL); - gpio_request(STINGRAY_AUO_DISP_BL, "auo_disp_bl"); - gpio_direction_output(STINGRAY_AUO_DISP_BL, 1); - platform_device_register(&stingray_panel_bl_driver); - stingray_disp1_pdata.fb = &stingray_fb_data_p0; - stingray_disp1_out.modes = stingray_panel_modes_p0; - } else { - if (stingray_revision() >= STINGRAY_REVISION_P3) - stingray_lp8550_backlight_data.dev_ctrl_config = 0x02; - i2c_register_board_info(0, stingray_i2c_bus1_led_info, - ARRAY_SIZE(stingray_i2c_bus1_led_info)); - } - - platform_device_register(&stingray_panel_reg_device); - - platform_driver_register(&stingray_panel_early_reg_driver); - platform_device_register(&stingray_panel_early_reg_device); - platform_device_register(&stingray_panel_early_reg_keyreset_device); - - stingray_hdmi_init(); - stingray_lp8550_init(); - - stingray_csi_reg = regulator_get(NULL, "vcsi"); - if (IS_ERR(stingray_csi_reg)) { - pr_err("hdmi: couldn't get regulator vcsi"); - } else { - regulator_enable(stingray_csi_reg); - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - stingray_panel_early_suspender.suspend = stingray_panel_early_suspend; - stingray_panel_early_suspender.resume = stingray_panel_late_resume; - stingray_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - register_early_suspend(&stingray_panel_early_suspender); -#endif - - - res = nvhost_get_resource_byname(&stingray_disp1_device, - IORESOURCE_MEM, "fbmem"); - res->start = tegra_fb_start; - res->end = tegra_fb_start + tegra_fb_size - 1; - - res = nvhost_get_resource_byname(&stingray_disp2_device, - IORESOURCE_MEM, "fbmem"); - res->start = tegra_fb2_start; - res->end = tegra_fb2_start + tegra_fb2_size - 1; - - tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start, - min(tegra_fb_size, tegra_bootloader_fb_size)); - - nvhost_device_register(&stingray_disp1_device); - return nvhost_device_register(&stingray_disp2_device); -} - diff --git a/arch/arm/mach-tegra/board-stingray-pinmux.c b/arch/arm/mach-tegra/board-stingray-pinmux.c deleted file mode 100755 index 845ac2a28129..000000000000 --- a/arch/arm/mach-tegra/board-stingray-pinmux.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray-pinmux.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -#include "gpio-names.h" - -#include "board-stingray.h" - -static __initdata struct tegra_pingroup_config stingray_pinmux[] = { - {TEGRA_PINGROUP_ATA, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATC, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATD, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATE, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTA, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTB, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMB, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMD, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPV, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCE, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCF, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LCSN, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LDC, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LM0, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LM1, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPW0, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPW1, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPW2, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSC1, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSCK, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSDA, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSDI, TEGRA_MUX_SPI3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LVP0, TEGRA_MUX_SAFE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PTA, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_RM, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_UARTE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXA, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPDI, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPDO, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAC, TEGRA_MUX_SAFE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, -}; - -static __initdata struct tegra_drive_pingroup_config stingray_drive_pinmux[] = { - {TEGRA_DRIVE_PINGROUP_AO1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_2, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_AO2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_AT1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_AT2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_CDEV1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_CDEV2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_CSUS, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_DAP1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_0, TEGRA_PULL_0, TEGRA_SLEW_FASTEST, TEGRA_SLEW_FASTEST}, - {TEGRA_DRIVE_PINGROUP_DAP2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_8, TEGRA_PULL_0, TEGRA_PULL_0, TEGRA_SLEW_FASTEST, TEGRA_SLEW_FASTEST}, - {TEGRA_DRIVE_PINGROUP_DAP3, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_8, TEGRA_PULL_0, TEGRA_PULL_0, TEGRA_SLEW_FASTEST, TEGRA_SLEW_FASTEST}, - {TEGRA_DRIVE_PINGROUP_DAP4, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_DBG, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_2, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_LCD1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_LCD2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_SDMMC2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_SDMMC3, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_SPI, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_UAA, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_UAB, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_UART2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_UART3, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_18, TEGRA_PULL_22, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_VI1, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_VI2, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_SLOWEST}, - {TEGRA_DRIVE_PINGROUP_XM2A, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_8, TEGRA_PULL_28, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_FAST}, - {TEGRA_DRIVE_PINGROUP_XM2C, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_FAST}, - {TEGRA_DRIVE_PINGROUP_XM2D, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_1, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_FAST}, - {TEGRA_DRIVE_PINGROUP_XM2CLK, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_DISABLE, TEGRA_DRIVE_DIV_8, TEGRA_PULL_28, TEGRA_PULL_31, TEGRA_SLEW_SLOWEST, TEGRA_SLEW_FAST}, - {TEGRA_DRIVE_PINGROUP_MEMCOMP, TEGRA_HSM_DISABLE, TEGRA_SCHMITT_ENABLE, TEGRA_DRIVE_DIV_8, TEGRA_PULL_31, TEGRA_PULL_31, TEGRA_SLEW_FASTEST, TEGRA_SLEW_FASTEST}, -}; - -void __init stingray_pinmux_init(void) -{ - tegra_pinmux_config_table(stingray_pinmux, ARRAY_SIZE(stingray_pinmux)); - tegra_drive_pinmux_config_table(stingray_drive_pinmux, - ARRAY_SIZE(stingray_drive_pinmux)); - - if (!stingray_hw_has_cdma() && !stingray_hw_has_umts()) { - /* Keep the pins from floating and creating excessive - * current drain. */ - tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_GMC, - TEGRA_PUPD_PULL_UP); - tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_UDA, - TEGRA_PUPD_PULL_UP); - } - - tegra_gpio_disable(TEGRA_GPIO_PE0); - tegra_gpio_disable(TEGRA_GPIO_PE1); - tegra_gpio_disable(TEGRA_GPIO_PE2); - tegra_gpio_disable(TEGRA_GPIO_PE3); - tegra_gpio_disable(TEGRA_GPIO_PE4); - tegra_gpio_disable(TEGRA_GPIO_PE5); - tegra_gpio_disable(TEGRA_GPIO_PE6); - tegra_gpio_disable(TEGRA_GPIO_PE7); - tegra_gpio_disable(TEGRA_GPIO_PF0); - tegra_gpio_disable(TEGRA_GPIO_PF1); - tegra_gpio_disable(TEGRA_GPIO_PF2); - tegra_gpio_disable(TEGRA_GPIO_PF3); - tegra_gpio_disable(TEGRA_GPIO_PF4); - tegra_gpio_disable(TEGRA_GPIO_PF5); - tegra_gpio_disable(TEGRA_GPIO_PF6); - tegra_gpio_disable(TEGRA_GPIO_PF7); - tegra_gpio_disable(TEGRA_GPIO_PM0); - tegra_gpio_disable(TEGRA_GPIO_PM1); - tegra_gpio_disable(TEGRA_GPIO_PM2); - tegra_gpio_disable(TEGRA_GPIO_PM3); - tegra_gpio_disable(TEGRA_GPIO_PM4); - tegra_gpio_disable(TEGRA_GPIO_PM5); - tegra_gpio_disable(TEGRA_GPIO_PM6); - tegra_gpio_disable(TEGRA_GPIO_PM7); - tegra_gpio_disable(TEGRA_GPIO_PN7); - - tegra_gpio_disable(TEGRA_GPIO_PK5); - tegra_gpio_disable(TEGRA_GPIO_PK6); -} diff --git a/arch/arm/mach-tegra/board-stingray-power.c b/arch/arm/mach-tegra/board-stingray-power.c deleted file mode 100644 index 57ceaa6b5347..000000000000 --- a/arch/arm/mach-tegra/board-stingray-power.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "board-stingray.h" -#include "gpio-names.h" - -/* For the PWR + VOL UP reset, CPCAP can perform a hard or a soft reset. A hard - * reset will reset the entire system, where a soft reset will reset only the - * T20. Uncomment this line to use soft resets (should not be enabled on - * production builds). */ -/* #define ENABLE_SOFT_RESET_DEBUGGING */ - -static struct cpcap_device *cpcap_di; - -static int cpcap_validity_reboot(struct notifier_block *this, - unsigned long code, void *cmd) -{ - int ret = -1; - int result = NOTIFY_DONE; - char *mode = cmd; - - dev_info(&(cpcap_di->spi->dev), "Saving power down reason.\n"); - - if (code == SYS_RESTART) { - if (mode != NULL && !strncmp("outofcharge", mode, 12)) { - /* Set the outofcharge bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - CPCAP_BIT_OUT_CHARGE_ONLY, - CPCAP_BIT_OUT_CHARGE_ONLY); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "outofcharge cpcap set failure.\n"); - result = NOTIFY_BAD; - } - /* Set the soft reset bit in the cpcap */ - cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - CPCAP_BIT_SOFT_RESET, - CPCAP_BIT_SOFT_RESET); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "reset cpcap set failure.\n"); - result = NOTIFY_BAD; - } - } - - /* Check if we are starting recovery mode */ - if (mode != NULL && !strncmp("recovery", mode, 9)) { - /* Set the fota (recovery mode) bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - CPCAP_BIT_FOTA_MODE, CPCAP_BIT_FOTA_MODE); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "Recovery cpcap set failure.\n"); - result = NOTIFY_BAD; - } - } else { - /* Set the fota (recovery mode) bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, 0, - CPCAP_BIT_FOTA_MODE); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "Recovery cpcap clear failure.\n"); - result = NOTIFY_BAD; - } - } - /* Check if we are going into fast boot mode */ - if (mode != NULL && !strncmp("bootloader", mode, 11)) { - /* Set the bootmode bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - CPCAP_BIT_BOOT_MODE, CPCAP_BIT_BOOT_MODE); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "Boot mode cpcap set failure.\n"); - result = NOTIFY_BAD; - } - } - } else { - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - 0, - CPCAP_BIT_OUT_CHARGE_ONLY); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "outofcharge cpcap set failure.\n"); - result = NOTIFY_BAD; - } - - /* Clear the soft reset bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, 0, - CPCAP_BIT_SOFT_RESET); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "SW Reset cpcap set failure.\n"); - result = NOTIFY_BAD; - } - /* Clear the fota (recovery mode) bit in the cpcap */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, 0, - CPCAP_BIT_FOTA_MODE); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "Recovery cpcap clear failure.\n"); - result = NOTIFY_BAD; - } - } - - /* Always clear the kpanic bit */ - ret = cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - 0, CPCAP_BIT_AP_KERNEL_PANIC); - if (ret) { - dev_err(&(cpcap_di->spi->dev), - "Clear kernel panic bit failure.\n"); - result = NOTIFY_BAD; - } - - return result; -} -static struct notifier_block validity_reboot_notifier = { - .notifier_call = cpcap_validity_reboot, -}; - -static int cpcap_validity_probe(struct platform_device *pdev) -{ - int err; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - cpcap_di = pdev->dev.platform_data; - - cpcap_regacc_write(cpcap_di, CPCAP_REG_VAL1, - (CPCAP_BIT_AP_KERNEL_PANIC | CPCAP_BIT_SOFT_RESET), - (CPCAP_BIT_AP_KERNEL_PANIC | CPCAP_BIT_SOFT_RESET)); - - register_reboot_notifier(&validity_reboot_notifier); - - /* CORE_PWR_REQ is only properly connected on P1 hardware and later */ - if (stingray_revision() >= STINGRAY_REVISION_P1) { - err = cpcap_uc_start(cpcap_di, CPCAP_MACRO_14); - dev_info(&pdev->dev, "Started macro 14: %d\n", err); - } else - dev_info(&pdev->dev, "Not starting macro 14 (no hw support)\n"); - - /* Enable workaround to allow soft resets to work */ - cpcap_regacc_write(cpcap_di, CPCAP_REG_PGC, - CPCAP_BIT_SYS_RST_MODE, CPCAP_BIT_SYS_RST_MODE); - err = cpcap_uc_start(cpcap_di, CPCAP_MACRO_15); - dev_info(&pdev->dev, "Started macro 15: %d\n", err); - - return 0; -} - -static int cpcap_validity_remove(struct platform_device *pdev) -{ - unregister_reboot_notifier(&validity_reboot_notifier); - cpcap_di = NULL; - - return 0; -} - -static struct platform_driver cpcap_validity_driver = { - .probe = cpcap_validity_probe, - .remove = cpcap_validity_remove, - .driver = { - .name = "cpcap_validity", - .owner = THIS_MODULE, - }, -}; - -static struct platform_device cpcap_validity_device = { - .name = "cpcap_validity", - .id = -1, - .dev = { - .platform_data = NULL, - }, -}; - -static struct platform_device cpcap_3mm5_device = { - .name = "cpcap_3mm5", - .id = -1, - .dev = { - .platform_data = NULL, - }, -}; - -static struct cpcap_whisper_pdata whisper_pdata = { - .data_gpio = TEGRA_GPIO_PV4, - .pwr_gpio = TEGRA_GPIO_PT2, - .uartmux = 1, -}; - -static struct platform_device cpcap_whisper_device = { - .name = "cpcap_whisper", - .id = -1, - .dev = { - .platform_data = &whisper_pdata, - }, -}; - -static struct cpcap_led stingray_privacy_led ={ - .blink_able = 0, - .cpcap_register = CPCAP_REG_BLEDC, - .cpcap_reg_mask = 0x03FF, - .cpcap_reg_period = 0x0000, - .cpcap_reg_duty_cycle = 0x0038, - .cpcap_reg_current = 0x0002, - .class_name = LD_PRIVACY_LED_DEV, - .led_regulator = "sw5_led2", -}; - -static struct platform_device cpcap_privacy_led = { - .name = LD_CPCAP_LED_DRV, - .id = 2, - .dev = { - .platform_data = &stingray_privacy_led, - }, -}; - -static struct cpcap_led stingray_notification_led ={ - .blink_able = 1, - .cpcap_register = CPCAP_REG_ADLC, - .cpcap_reg_mask = 0x7FFF, - .cpcap_reg_period = 0x0000, - .cpcap_reg_duty_cycle = 0x03F0, - .cpcap_reg_current = 0x0008, - .class_name = LD_NOTIF_LED_DEV, - .led_regulator = "sw5_led3", -}; - -static struct platform_device cpcap_notification_led = { - .name = LD_CPCAP_LED_DRV, - .id = 3, - .dev = { - .platform_data = &stingray_notification_led, - }, -}; - -static struct platform_device *cpcap_devices[] = { - &cpcap_validity_device, - &cpcap_notification_led, - &cpcap_privacy_led, - &cpcap_3mm5_device, -}; - -struct cpcap_spi_init_data stingray_cpcap_spi_init[] = { - {CPCAP_REG_S1C1, 0x0000}, - {CPCAP_REG_S1C2, 0x0000}, - {CPCAP_REG_S2C1, 0x4830}, - {CPCAP_REG_S2C2, 0x3030}, - {CPCAP_REG_S3C, 0x0439}, - {CPCAP_REG_S4C1, 0x4930}, - {CPCAP_REG_S4C2, 0x301C}, - {CPCAP_REG_S5C, 0x0000}, - {CPCAP_REG_S6C, 0x0000}, - {CPCAP_REG_VRF1C, 0x0000}, - {CPCAP_REG_VRF2C, 0x0000}, - {CPCAP_REG_VRFREFC, 0x0000}, - {CPCAP_REG_VAUDIOC, 0x0065}, - {CPCAP_REG_ADCC1, 0x9000}, - {CPCAP_REG_ADCC2, 0x4136}, - {CPCAP_REG_USBC1, 0x1201}, - {CPCAP_REG_USBC3, 0x7DFB}, - {CPCAP_REG_OWDC, 0x0003}, - {CPCAP_REG_ADLC, 0x0000}, -}; - -unsigned short cpcap_regulator_mode_values[CPCAP_NUM_REGULATORS] = { - [CPCAP_SW2] = 0x0800, - [CPCAP_SW4] = 0x0900, - [CPCAP_SW5] = 0x0022, - [CPCAP_VCAM] = 0x0007, - [CPCAP_VCSI] = 0x0007, - [CPCAP_VDAC] = 0x0003, - [CPCAP_VDIG] = 0x0005, - [CPCAP_VFUSE] = 0x0080, - [CPCAP_VHVIO] = 0x0002, - [CPCAP_VSDIO] = 0x0002, - [CPCAP_VPLL] = 0x0001, - [CPCAP_VRF1] = 0x000C, - [CPCAP_VRF2] = 0x0003, - [CPCAP_VRFREF] = 0x0003, - [CPCAP_VWLAN1] = 0x0005, - [CPCAP_VWLAN2] = 0x0008, - [CPCAP_VSIM] = 0x0003, - [CPCAP_VSIMCARD] = 0x1E00, - [CPCAP_VVIB] = 0x0001, - [CPCAP_VUSB] = 0x000C, - [CPCAP_VAUDIO] = 0x0004, -}; - -unsigned short cpcap_regulator_off_mode_values[CPCAP_NUM_REGULATORS] = { - [CPCAP_SW2] = 0x0000, - [CPCAP_SW4] = 0x0000, - [CPCAP_SW5] = 0x0000, - [CPCAP_VCAM] = 0x0000, - [CPCAP_VCSI] = 0x0000, - [CPCAP_VDAC] = 0x0000, - [CPCAP_VDIG] = 0x0000, - [CPCAP_VFUSE] = 0x0000, - [CPCAP_VHVIO] = 0x0000, - [CPCAP_VSDIO] = 0x0000, - [CPCAP_VPLL] = 0x0000, - [CPCAP_VRF1] = 0x0000, - [CPCAP_VRF2] = 0x0000, - [CPCAP_VRFREF] = 0x0000, - [CPCAP_VWLAN1] = 0x0000, - [CPCAP_VWLAN2] = 0x0000, - [CPCAP_VSIM] = 0x0000, - [CPCAP_VSIMCARD] = 0x0000, - [CPCAP_VVIB] = 0x0000, - [CPCAP_VUSB] = 0x0000, - [CPCAP_VAUDIO] = 0x0000, -}; - -#define REGULATOR_CONSUMER(name, device) { .supply = name, .dev_name = device, } -#define REGULATOR_CONSUMER_BY_DEVICE(name, device) \ - { .supply = name, .dev = device, } - -struct regulator_consumer_supply cpcap_sw2_consumers[] = { - REGULATOR_CONSUMER("sw2", NULL), - REGULATOR_CONSUMER("vdd_core", NULL), -}; - -struct regulator_consumer_supply cpcap_sw4_consumers[] = { - REGULATOR_CONSUMER("sw4", NULL), - REGULATOR_CONSUMER("vdd_aon", NULL), -}; - -struct regulator_consumer_supply cpcap_sw5_consumers[] = { - REGULATOR_CONSUMER_BY_DEVICE("sw5_led2", &cpcap_privacy_led.dev), - REGULATOR_CONSUMER_BY_DEVICE("sw5_led3", &cpcap_notification_led.dev), -}; - -struct regulator_consumer_supply cpcap_vcam_consumers[] = { - REGULATOR_CONSUMER("vcc", "2-000c" /* focuser */), -}; - -struct regulator_consumer_supply cpcap_vhvio_consumers[] = { - REGULATOR_CONSUMER("vhvio", NULL /* lighting_driver */), - REGULATOR_CONSUMER("vcc", "2-0068" /* gyro*/), - REGULATOR_CONSUMER("vcc", "3-000c" /* magnetometer */), - REGULATOR_CONSUMER("vcc", "0-0077" /* barometer */), - REGULATOR_CONSUMER("vcc", "3-000f" /* accelerometer */), -}; - -struct regulator_consumer_supply cpcap_vcsi_consumers[] = { - REGULATOR_CONSUMER("vcsi", "tegra_camera"), -}; - -struct regulator_consumer_supply cpcap_vusb_consumers[] = { - REGULATOR_CONSUMER_BY_DEVICE("vusb", &cpcap_whisper_device.dev), -}; - -struct regulator_consumer_supply cpcap_vaudio_consumers[] = { - REGULATOR_CONSUMER("vaudio", NULL /* mic opamp */), -}; - -struct regulator_consumer_supply cpcap_vdig_consumers[] = { - REGULATOR_CONSUMER("vdig", NULL /* gps */), -}; -static struct regulator_init_data cpcap_regulator[CPCAP_NUM_REGULATORS] = { - [CPCAP_SW2] = { - .constraints = { - .min_uV = 1000000, - .max_uV = 1200000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .always_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_sw2_consumers), - .consumer_supplies = cpcap_sw2_consumers, - }, - [CPCAP_SW4] = { - .constraints = { - .min_uV = 1000000, - .max_uV = 1200000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .always_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_sw4_consumers), - .consumer_supplies = cpcap_sw4_consumers, - }, - [CPCAP_SW5] = { - .constraints = { - .min_uV = 5050000, - .max_uV = 5050000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_sw5_consumers), - .consumer_supplies = cpcap_sw5_consumers, - }, - [CPCAP_VCAM] = { - .constraints = { - .min_uV = 2900000, - .max_uV = 2900000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .apply_uV = 1, - - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vcam_consumers), - .consumer_supplies = cpcap_vcam_consumers, - }, - [CPCAP_VCSI] = { - .constraints = { - .min_uV = 1200000, - .max_uV = 1200000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .boot_on = 1, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vcsi_consumers), - .consumer_supplies = cpcap_vcsi_consumers, - }, - [CPCAP_VDAC] = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .apply_uV = 1, - }, - }, - [CPCAP_VDIG] = { - .constraints = { - .min_uV = 1875000, - .max_uV = 1875000, - .valid_ops_mask = 0, - .always_on = 1, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vdig_consumers), - .consumer_supplies = cpcap_vdig_consumers, - }, - [CPCAP_VFUSE] = { - .constraints = { - .min_uV = 1500000, - .max_uV = 3150000, - .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS), - }, - }, - [CPCAP_VHVIO] = { - .constraints = { - .min_uV = 2775000, - .max_uV = 2775000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .always_on = 1, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vhvio_consumers), - .consumer_supplies = cpcap_vhvio_consumers, - }, - [CPCAP_VSDIO] = { - .constraints = { - .min_uV = 3000000, - .max_uV = 3000000, - .valid_ops_mask = 0, - .always_on = 1, - .apply_uV = 1, - }, - }, - [CPCAP_VPLL] = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .valid_ops_mask = 0, - .always_on = 1, - .apply_uV = 1, - }, - }, - [CPCAP_VRF1] = { - .constraints = { - .min_uV = 2500000, - .max_uV = 2775000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VRF2] = { - .constraints = { - .min_uV = 2775000, - .max_uV = 2775000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VRFREF] = { - .constraints = { - .min_uV = 2500000, - .max_uV = 2775000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VWLAN1] = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1900000, - .valid_ops_mask = 0, - .always_on = 1, - }, - }, - [CPCAP_VWLAN2] = { - .constraints = { - .min_uV = 3300000, - .max_uV = 3300000, - .valid_ops_mask = 0, - .always_on = 1, - .apply_uV = 1, - }, - }, - [CPCAP_VSIM] = { - .constraints = { - .min_uV = 1800000, - .max_uV = 2900000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VSIMCARD] = { - .constraints = { - .min_uV = 1800000, - .max_uV = 2900000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VVIB] = { - .constraints = { - .min_uV = 1300000, - .max_uV = 3000000, - .valid_ops_mask = 0, - }, - }, - [CPCAP_VUSB] = { - .constraints = { - .min_uV = 3300000, - .max_uV = 3300000, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vusb_consumers), - .consumer_supplies = cpcap_vusb_consumers, - }, - [CPCAP_VAUDIO] = { - .constraints = { - .min_uV = 2775000, - .max_uV = 2775000, - .valid_modes_mask = (REGULATOR_MODE_NORMAL | - REGULATOR_MODE_STANDBY), - .valid_ops_mask = REGULATOR_CHANGE_MODE, - .always_on = 1, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cpcap_vaudio_consumers), - .consumer_supplies = cpcap_vaudio_consumers, - }, -}; - -static struct cpcap_adc_ato stingray_cpcap_adc_ato = { - .ato_in = 0x0480, - .atox_in = 0, - .adc_ps_factor_in = 0x0200, - .atox_ps_factor_in = 0, - .ato_out = 0, - .atox_out = 0, - .adc_ps_factor_out = 0, - .atox_ps_factor_out = 0, -}; - -static struct cpcap_platform_data stingray_cpcap_data = { - .init = stingray_cpcap_spi_init, - .init_len = ARRAY_SIZE(stingray_cpcap_spi_init), - .regulator_mode_values = cpcap_regulator_mode_values, - .regulator_off_mode_values = cpcap_regulator_off_mode_values, - .regulator_init = cpcap_regulator, - .adc_ato = &stingray_cpcap_adc_ato, - .ac_changed = NULL, - .batt_changed = NULL, - .usb_changed = NULL, - .hwcfg = { - (CPCAP_HWCFG0_SEC_STBY_SW3 | - CPCAP_HWCFG0_SEC_STBY_SW4 | - CPCAP_HWCFG0_SEC_STBY_VAUDIO | - CPCAP_HWCFG0_SEC_STBY_VCAM | - CPCAP_HWCFG0_SEC_STBY_VCSI | - CPCAP_HWCFG0_SEC_STBY_VHVIO | - CPCAP_HWCFG0_SEC_STBY_VPLL | - CPCAP_HWCFG0_SEC_STBY_VSDIO), - (CPCAP_HWCFG1_SEC_STBY_VWLAN1 | - CPCAP_HWCFG1_SEC_STBY_VWLAN2)} -}; - -static struct spi_board_info stingray_spi_board_info[] __initdata = { - { - .modalias = "cpcap", - .bus_num = 1, - .chip_select = 0, - .mode = SPI_MODE_0, - .max_speed_hz = 10000000, - .controller_data = &stingray_cpcap_data, - .irq = INT_EXTERNAL_PMU, - }, -}; - -struct regulator_consumer_supply max8649_consumers[] = { - REGULATOR_CONSUMER("vdd_cpu", NULL /* cpu */), -}; - -struct regulator_init_data max8649_regulator_init_data[] = { - { - .constraints = { - .min_uV = 770000, - .max_uV = 1100000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .always_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(max8649_consumers), - .consumer_supplies = max8649_consumers, - }, -}; - -struct max8649_platform_data stingray_max8649_pdata = { - .regulator = max8649_regulator_init_data, - .mode = 1, - .extclk = 0, - .ramp_timing = MAX8649_RAMP_32MV, - .ramp_down = 0, -}; - -static struct i2c_board_info __initdata stingray_i2c_bus4_power_info[] = { - { - I2C_BOARD_INFO("max8649", 0x60), - .platform_data = &stingray_max8649_pdata, - }, -}; - -static struct mdm_ctrl_platform_data mdm_ctrl_platform_data = { - .gpios[MDM_CTRL_GPIO_AP_STATUS_0] = { - TEGRA_GPIO_PC1, MDM_GPIO_DIRECTION_OUT, 0, 0, "mdm_ap_status0"}, - .gpios[MDM_CTRL_GPIO_AP_STATUS_1] = { - TEGRA_GPIO_PC6, MDM_GPIO_DIRECTION_OUT, 0, 0, "mdm_ap_status1"}, - .gpios[MDM_CTRL_GPIO_AP_STATUS_2] = { - TEGRA_GPIO_PQ3, MDM_GPIO_DIRECTION_OUT, 0, 0, "mdm_ap_status2"}, - .gpios[MDM_CTRL_GPIO_BP_STATUS_0] = { - TEGRA_GPIO_PK3, MDM_GPIO_DIRECTION_IN, 0, 0, "mdm_bp_status0"}, - .gpios[MDM_CTRL_GPIO_BP_STATUS_1] = { - TEGRA_GPIO_PK4, MDM_GPIO_DIRECTION_IN, 0, 0, "mdm_bp_status1"}, - .gpios[MDM_CTRL_GPIO_BP_STATUS_2] = { - TEGRA_GPIO_PK2, MDM_GPIO_DIRECTION_IN, 0, 0, "mdm_bp_status2"}, - .gpios[MDM_CTRL_GPIO_BP_RESOUT] = { - TEGRA_GPIO_PS4, MDM_GPIO_DIRECTION_IN, 0, 0, "mdm_bp_resout"}, - .gpios[MDM_CTRL_GPIO_BP_RESIN] = { - TEGRA_GPIO_PZ1, MDM_GPIO_DIRECTION_OUT, 0, 0, "mdm_bp_resin"}, - .gpios[MDM_CTRL_GPIO_BP_PWRON] = { - TEGRA_GPIO_PS6, MDM_GPIO_DIRECTION_OUT, 0, 0, "mdm_bp_pwr_on"}, - .cmd_gpios = {TEGRA_GPIO_PQ5, TEGRA_GPIO_PS5}, -}; - -static struct platform_device mdm_ctrl_platform_device = { - .name = MDM_CTRL_MODULE_NAME, - .id = -1, - .dev = { - .platform_data = &mdm_ctrl_platform_data, - }, -}; - -static struct wrigley_ctrl_platform_data wrigley_ctrl_pdata = { - .gpio_disable = TEGRA_GPIO_PG0, - .gpio_reset = TEGRA_GPIO_PI6, - .gpio_force_flash = TEGRA_GPIO_PT5, -}; - -static struct platform_device wrigley_ctrl_pdev = { - .name = "wrigley", - .id = -1, - .dev = { - .platform_data = &wrigley_ctrl_pdata, - }, -}; - -static void mdm_ctrl_register(void) -{ - int i; - - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) - tegra_gpio_enable(mdm_ctrl_platform_data.gpios[i].number); - - if (stingray_qbp_usb_hw_bypass_enabled()) { - /* The default AP status is "no bypass", so we must override it */ - mdm_ctrl_platform_data.gpios[MDM_CTRL_GPIO_AP_STATUS_0]. \ - default_value = 1; - mdm_ctrl_platform_data.gpios[MDM_CTRL_GPIO_AP_STATUS_1]. \ - default_value = 0; - mdm_ctrl_platform_data.gpios[MDM_CTRL_GPIO_AP_STATUS_2]. \ - default_value = 0; - } - - platform_device_register(&mdm_ctrl_platform_device); -} - -static void wrigley_ctrl_register(void) -{ - tegra_gpio_enable(wrigley_ctrl_pdata.gpio_reset); - tegra_gpio_enable(wrigley_ctrl_pdata.gpio_disable); - tegra_gpio_enable(wrigley_ctrl_pdata.gpio_force_flash); - platform_device_register(&wrigley_ctrl_pdev); -} - -int __init stingray_power_init(void) -{ - int i; - unsigned long pmc_cntrl_0; - - /* Enable CORE_PWR_REQ signal from T20. The signal must be enabled - * before the CPCAP uC firmware is started. */ - pmc_cntrl_0 = readl(IO_ADDRESS(TEGRA_PMC_BASE)); - pmc_cntrl_0 |= 0x00000200; - writel(pmc_cntrl_0, IO_ADDRESS(TEGRA_PMC_BASE)); - - if (stingray_revision() <= STINGRAY_REVISION_M1) - stingray_max8649_pdata.mode = 3; - -#ifdef ENABLE_SOFT_RESET_DEBUGGING - /* Only P3 and later hardware supports CPCAP resetting the T20. */ - if (stingray_revision() >= STINGRAY_REVISION_P3) - stingray_cpcap_data.hwcfg[1] |= CPCAP_HWCFG1_SOFT_RESET_HOST; -#endif - - tegra_gpio_enable(TEGRA_GPIO_PT2); - gpio_request(TEGRA_GPIO_PT2, "usb_host_pwr_en"); - gpio_direction_output(TEGRA_GPIO_PT2, 0); - - spi_register_board_info(stingray_spi_board_info, - ARRAY_SIZE(stingray_spi_board_info)); - - for (i = 0; i < ARRAY_SIZE(cpcap_devices); i++) - cpcap_device_register(cpcap_devices[i]); - - if (!stingray_qbp_usb_hw_bypass_enabled()) - cpcap_device_register(&cpcap_whisper_device); - - (void) cpcap_driver_register(&cpcap_validity_driver); - - i2c_register_board_info(3, stingray_i2c_bus4_power_info, - ARRAY_SIZE(stingray_i2c_bus4_power_info)); - - if (stingray_hw_has_cdma()) { - mdm_ctrl_register(); - wrigley_ctrl_register(); - } - - return 0; -} diff --git a/arch/arm/mach-tegra/board-stingray-sensors.c b/arch/arm/mach-tegra/board-stingray-sensors.c deleted file mode 100755 index 92faeb5b4df8..000000000000 --- a/arch/arm/mach-tegra/board-stingray-sensors.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2010, Motorola, 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 3 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, see . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "board-stingray.h" -#include "gpio-names.h" - -#define KXTF9_IRQ_GPIO TEGRA_GPIO_PV3 -#define MAX9635_IRQ_GPIO TEGRA_GPIO_PV1 -#define BMP085_IRQ_GPIO TEGRA_GPIO_PW0 -#define L3G4200D_DRDY_GPIO TEGRA_GPIO_PH3 -#define AKM8975_IRQ_GPIO TEGRA_GPIO_PQ2 -#define LM3559_RESETN_GPIO TEGRA_GPIO_PT4 -#define OV5650_RESETN_GPIO TEGRA_GPIO_PD2 -#define OV5650_PWRDN_GPIO TEGRA_GPIO_PBB1 -#define SOC2030_RESETN_GPIO TEGRA_GPIO_PD5 -#define SOC2030_PWRDN_GPIO TEGRA_GPIO_PBB5 -#define CAP_PROX_IRQ_GPIO TEGRA_GPIO_PZ3 -#define NCT1008_THERM2_GPIO TEGRA_GPIO_PQ7 - -extern void tegra_throttling_enable(bool enable); - -static int stingray_ov5650_power_on(void) -{ - msleep(20); - - gpio_direction_output(OV5650_PWRDN_GPIO, 0); - msleep(10); - - gpio_direction_output(OV5650_RESETN_GPIO, 1); - msleep(5); - gpio_direction_output(OV5650_RESETN_GPIO, 0); - msleep(5); - gpio_direction_output(OV5650_RESETN_GPIO, 1); - msleep(5); - - return 0; -} - -static int stingray_ov5650_power_off(void) -{ - gpio_direction_output(OV5650_PWRDN_GPIO, 1); - gpio_direction_output(OV5650_RESETN_GPIO, 0); - - return 0; -} - -struct ov5650_platform_data stingray_ov5650_data = { - .power_on = stingray_ov5650_power_on, - .power_off = stingray_ov5650_power_off, - .ignore_otp = false -}; - -static int stingray_ov5650_init(void) -{ - tegra_gpio_enable(OV5650_RESETN_GPIO); - gpio_request(OV5650_RESETN_GPIO, "ov5650_reset"); - gpio_direction_output(OV5650_RESETN_GPIO, 0); - gpio_export(OV5650_RESETN_GPIO, false); - - tegra_gpio_enable(OV5650_PWRDN_GPIO); - gpio_request(OV5650_PWRDN_GPIO, "ov5650_pwrdn"); - gpio_direction_output(OV5650_PWRDN_GPIO, 1); - gpio_export(OV5650_PWRDN_GPIO, false); - - if (stingray_revision() <= STINGRAY_REVISION_P1) { - stingray_ov5650_data.ignore_otp = true; - pr_info("running on old hardware, ignoring OTP data\n"); - } - - pr_info("initialize the ov5650 sensor\n"); - - return 0; -} - -static int stingray_soc2030_init(void) -{ - tegra_gpio_enable(SOC2030_RESETN_GPIO); - gpio_request(SOC2030_RESETN_GPIO, "soc2030_reset"); - gpio_direction_output(SOC2030_RESETN_GPIO, 0); - gpio_export(SOC2030_RESETN_GPIO, false); - - tegra_gpio_enable(SOC2030_PWRDN_GPIO); - gpio_request(SOC2030_PWRDN_GPIO, "soc2030_pwrdn"); - gpio_direction_output(SOC2030_PWRDN_GPIO, 1); - gpio_export(SOC2030_PWRDN_GPIO, false); - - pr_info("initialize the soc2030 sensor\n"); - - return 0; -} - -static int stingray_soc2030_power_on(void) -{ - gpio_direction_output(SOC2030_PWRDN_GPIO, 0); - msleep(10); - - gpio_direction_output(SOC2030_RESETN_GPIO, 1); - msleep(5); - gpio_direction_output(SOC2030_RESETN_GPIO, 0); - msleep(5); - gpio_direction_output(SOC2030_RESETN_GPIO, 1); - msleep(5); - - return 0; -} - -static int stingray_soc2030_power_off(void) -{ - gpio_direction_output(SOC2030_RESETN_GPIO, 0); - gpio_direction_output(SOC2030_PWRDN_GPIO, 1); - return 0; -} - -struct soc2030_platform_data stingray_soc2030_data = { - .power_on = stingray_soc2030_power_on, - .power_off = stingray_soc2030_power_off, -}; - -static int stingray_bmp085_init(void) -{ - /*struct regulator *reg;*/ - - tegra_gpio_enable(BMP085_IRQ_GPIO); - gpio_request(BMP085_IRQ_GPIO, "bmp085_irq"); - gpio_direction_input(BMP085_IRQ_GPIO); - - return 0; -} - -struct bmp085_platform_data stingray_barom_pdata = { - .poll_interval = 200, - .min_interval = 20, - .min_p = 95000, - .max_p = 125000, - .fuzz = 5, - .flat = 5, -}; - -static int stingray_kxtf9_gpio_level(void) -{ - return gpio_get_value(KXTF9_IRQ_GPIO); -} - - -struct kxtf9_platform_data stingray_kxtf9_pdata = { - .min_interval = 2, - .poll_interval = 200, - - .g_range = KXTF9_G_2G, - - .axis_map_x = 0, - .axis_map_y = 1, - .axis_map_z = 2, - - .negate_x = 0, - .negate_y = 0, - .negate_z = 0, - - - .data_odr_init = ODR100, - .ctrl_reg1_init = RES_12BIT | KXTF9_G_2G | WUFE, - .int_ctrl_init = IEA | IEN, - .tilt_timer_init = 0x03, - .engine_odr_init = OTP12_5 | OWUF50 | OTDT400, - .wuf_timer_init = 0x0A, - .wuf_thresh_init = 0x20, - .tdt_timer_init = 0x78, - .tdt_h_thresh_init = 0xB6, - .tdt_l_thresh_init = 0x1A, - .tdt_tap_timer_init = 0xA2, - .tdt_total_timer_init = 0x24, - .tdt_latency_timer_init = 0x28, - .tdt_window_timer_init = 0xA0, - - .gpio = stingray_kxtf9_gpio_level, - .gesture = 0, - .sensitivity_low = { - 0x50, 0xFF, 0xB8, 0x32, 0x09, 0x0A, 0xA0, - }, - .sensitivity_medium = { - 0x50, 0xFF, 0x68, 0x32, 0x09, 0x0A, 0xA0, - }, - .sensitivity_high = { - 0x78, 0xB6, 0x1A, 0xA2, 0x24, 0x28, 0xA0, - }, -}; -static void stingray_kxtf9_init(void) -{ - tegra_gpio_enable(KXTF9_IRQ_GPIO); - gpio_request(KXTF9_IRQ_GPIO, "kxtf9_irq"); - gpio_direction_input(KXTF9_IRQ_GPIO); -} - -struct cap_prox_platform_data stingray_cap_prox_pdata = { - .poll_interval = 10000, - .min_poll_interval = 200, - .key1_ref_drift_thres_l = 5, - .key3_ref_drift_thres_l = 5, - .key1_ref_drift_thres_h = 30, - .key3_ref_drift_thres_h = 30, - .ref_drift_diff_thres = 9, - .key1_save_drift_thres = 125, - .key3_save_drift_thres = 165, - .save_drift_diff_thres = 90, - .key1_failsafe_thres = 170, - .key3_failsafe_thres = 100, - .key2_signal_thres = 1700, - .key4_signal_thres = 2200, - .plat_cap_prox_cfg = { - .lp_mode = 0x00, - .address_ptr = 0x10, - .reset = 0x20, - .key_enable_mask = 0x3F, - .data_integration = 0x40, - .neg_drift_rate = 0x50, - .pos_drift_rate = 0x60, - .force_detect = 0x75, - .calibrate = 0x80, - .thres_key1 = 0x92, - .ref_backup = 0xaa, - .thres_key2 = 0xb2, - .reserved12 = 0xc0, - .drift_hold_time = 0xd0, - .reserved14 = 0xe0, - .reserved15 = 0xf0, - }, -}; - -static void stingray_cap_prox_init(void) -{ - tegra_gpio_enable(CAP_PROX_IRQ_GPIO); - gpio_request(CAP_PROX_IRQ_GPIO, "cap_prox_irq"); - gpio_direction_input(CAP_PROX_IRQ_GPIO); -} - -struct max9635_platform_data stingray_max9635_pdata = { - .configure = 0x80, - .threshold_timer = 0x04, /* 400mS interrupt delay */ - .def_low_threshold = 0xFE, - .def_high_threshold = 0xFF, - .lens_coeff = 20, -}; - -static int stingray_max9635_init(void) -{ - tegra_gpio_enable(MAX9635_IRQ_GPIO); - gpio_request(MAX9635_IRQ_GPIO, "max9635_irq"); - gpio_direction_input(MAX9635_IRQ_GPIO); - return 0; -} - -static int stingray_l3g4200d_init(void) -{ - tegra_gpio_enable(L3G4200D_DRDY_GPIO); - gpio_request(L3G4200D_DRDY_GPIO, "l3g4200d_irq"); - gpio_direction_input(L3G4200D_DRDY_GPIO); - return 0; -} - -struct l3g4200d_platform_data stingray_gyro_pdata = { - .poll_interval = 10, - .gpio_drdy = L3G4200D_DRDY_GPIO, - - .ctrl_reg1 = 0x1f, /* ODR100 */ - .ctrl_reg2 = 0x00, - .ctrl_reg3 = 0x08, /* Enable DRDY interrupt */ - .ctrl_reg4 = 0xA0, /* BDU enable, 2000 dps */ - .ctrl_reg5 = 0x00, - .reference = 0x00, - .fifo_ctrl_reg = 0x00, - .int1_cfg = 0x00, - .int1_tsh_xh = 0x00, - .int1_tsh_xl = 0x00, - .int1_tsh_yh = 0x00, - .int1_tsh_yl = 0x00, - .int1_tsh_zh = 0x00, - .int1_tsh_zl = 0x00, - .int1_duration = 0x00, -}; - -static int stingray_akm8975_init(void) -{ - tegra_gpio_enable(AKM8975_IRQ_GPIO); - gpio_request(AKM8975_IRQ_GPIO, "akm8975"); - gpio_direction_input(AKM8975_IRQ_GPIO); - return 0; -} - -struct lm3559_platform_data stingray_lm3559_data = { - .flags = 0, - .flash_duration_def = 0x04, /* 160ms timeout */ - .vin_monitor_def = 0xC0, -}; - -static void stingray_lm3559_init(void) -{ - tegra_gpio_enable(LM3559_RESETN_GPIO); - gpio_request(LM3559_RESETN_GPIO, "lm3559_hwenable"); - gpio_direction_output(LM3559_RESETN_GPIO, 1); - gpio_export(LM3559_RESETN_GPIO, false); - - /* define LM3559_STROBE_GPIO for debug, usually controlled by VGP3 */ - #ifdef LM3559_STROBE_GPIO - tegra_gpio_enable(LM3559_STROBE_GPIO); - gpio_request(LM3559_STROBE_GPIO, "lm3559_strobe"); - gpio_direction_output(LM3559_STROBE_GPIO, 0); - gpio_export(LM3559_STROBE_GPIO, false); - #endif -} - -static struct nct1008_platform_data stingray_nct1008_data = { - .supported_hwrev = true, - .ext_range = true, - .conv_rate = 0x08, - .offset = 6, - .hysteresis = 5, - .shutdown_ext_limit = 115, - .shutdown_local_limit = 120, - .throttling_ext_limit = 90, - .alarm_fn = tegra_throttling_enable, -}; - -static int stingray_nct1008_init(void) -{ - if (stingray_revision() >= STINGRAY_REVISION_P2) { - tegra_gpio_enable(NCT1008_THERM2_GPIO); - gpio_request(NCT1008_THERM2_GPIO, "nct1008_therm2"); - gpio_direction_input(NCT1008_THERM2_GPIO); - } else { - stingray_nct1008_data.supported_hwrev = false; - } - return 0; -} - -static struct i2c_board_info __initdata stingray_i2c_bus4_sensor_info[] = { - { - I2C_BOARD_INFO("akm8975", 0x0C), - .irq = TEGRA_GPIO_TO_IRQ(AKM8975_IRQ_GPIO), - }, - { - I2C_BOARD_INFO("kxtf9", 0x0F), - .platform_data = &stingray_kxtf9_pdata, - .irq = TEGRA_GPIO_TO_IRQ(KXTF9_IRQ_GPIO), - }, - { - I2C_BOARD_INFO("nct1008", 0x4C), - .platform_data = &stingray_nct1008_data, - .irq = TEGRA_GPIO_TO_IRQ(NCT1008_THERM2_GPIO), - }, - { - I2C_BOARD_INFO("cap-prox", 0x12), - .platform_data = &stingray_cap_prox_pdata, - .irq = TEGRA_GPIO_TO_IRQ(CAP_PROX_IRQ_GPIO), - }, -}; - -static struct i2c_board_info __initdata stingray_i2c_bus1_sensor_info[] = { - { - I2C_BOARD_INFO(BMP085_NAME, 0x77), - .platform_data = &stingray_barom_pdata, - .irq = TEGRA_GPIO_TO_IRQ(BMP085_IRQ_GPIO), - }, - { - I2C_BOARD_INFO(MAX9635_NAME, 0x4b), - .platform_data = &stingray_max9635_pdata, - .irq = TEGRA_GPIO_TO_IRQ(MAX9635_IRQ_GPIO), - }, -}; - -static struct i2c_board_info __initdata stingray_i2c_bus3_sensor_info[] = { - { - I2C_BOARD_INFO(L3G4200D_NAME, 0x68), - .platform_data = &stingray_gyro_pdata, - .irq = TEGRA_GPIO_TO_IRQ(L3G4200D_DRDY_GPIO), - }, - - { - I2C_BOARD_INFO(LM3559_NAME, 0x53), - .platform_data = &stingray_lm3559_data, - }, - - { - I2C_BOARD_INFO("ov5650", 0x36), - .platform_data = &stingray_ov5650_data, - }, - - { - I2C_BOARD_INFO("dw9714l", 0x0C), - }, - - { - I2C_BOARD_INFO("soc2030", 0x3c), - .platform_data = &stingray_soc2030_data, - }, -}; - -int __init stingray_sensors_init(void) -{ - stingray_bmp085_init(); - stingray_kxtf9_init(); - stingray_max9635_init(); - stingray_l3g4200d_init(); - stingray_akm8975_init(); - stingray_lm3559_init(); - stingray_ov5650_init(); - stingray_soc2030_init(); - stingray_cap_prox_init(); - stingray_nct1008_init(); - - i2c_register_board_info(3, stingray_i2c_bus4_sensor_info, - ARRAY_SIZE(stingray_i2c_bus4_sensor_info)); - i2c_register_board_info(2, stingray_i2c_bus3_sensor_info, - ARRAY_SIZE(stingray_i2c_bus3_sensor_info)); - return i2c_register_board_info(0, stingray_i2c_bus1_sensor_info, - ARRAY_SIZE(stingray_i2c_bus1_sensor_info)); -} diff --git a/arch/arm/mach-tegra/board-stingray-touch.c b/arch/arm/mach-tegra/board-stingray-touch.c deleted file mode 100644 index 92de67d607b0..000000000000 --- a/arch/arm/mach-tegra/board-stingray-touch.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray-touch.c - * - * Copyright (C) 2010 Motorola, Inc. - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "board-stingray.h" -#include "gpio-names.h" - -#define XMEGAT_BL_I2C_ADDR 0x35 -#define STINGRAY_TOUCH_RESET_N_GPIO TEGRA_GPIO_PR4 -#define STINGRAY_TOUCH_INT_N_GPIO TEGRA_GPIO_PV2 -#define STINGRAY_TOUCH_WAKE_N_GPIO TEGRA_GPIO_PJ2 - -#define STINGRAY_TOUCH_INT_N_GPIO_P2 TEGRA_GPIO_PZ2 - -static int stingray_touch_reset(void) -{ - gpio_set_value(STINGRAY_TOUCH_RESET_N_GPIO, 0); - msleep(10); - gpio_set_value(STINGRAY_TOUCH_RESET_N_GPIO, 1); - msleep(100); /* value from moto */ - return 0; -} - -static int stingray_touch_suspend(int enable) -{ - gpio_set_value(STINGRAY_TOUCH_WAKE_N_GPIO, enable); - msleep(80); - return 0; -} - -/* mortable M1 */ -struct qtouch_ts_platform_data stingray_touch_data_m1 = { - - .flags = (QTOUCH_USE_MULTITOUCH | - QTOUCH_CFG_BACKUPNV), - .irqflags = (IRQF_TRIGGER_LOW), - .abs_min_x = 0, - .abs_max_x = 4095, - .abs_min_y = 0, - .abs_max_y = 4095, - .abs_min_p = 0, - .abs_max_p = 255, - .abs_min_w = 0, - .abs_max_w = 15, - .x_delta = 400, - .y_delta = 250, - .nv_checksum = 0x2c30, - .fuzz_x = 0, - .fuzz_y = 0, - .fuzz_p = 2, - .fuzz_w = 2, - .boot_i2c_addr = XMEGAT_BL_I2C_ADDR, - .hw_reset = stingray_touch_reset, - .key_array = { - .cfg = NULL, - .keys = NULL, - .num_keys = 0, - }, - .touch_fw_cfg = { - .fw_name = "mXT1386_08_E1.bin", - .family_id = 0xA0, - .variant_id = 0x00, - .fw_version = 0x08, - .fw_build = 0xE1, - .boot_version = 0x20, - .base_fw_version = 0x00, - }, - .power_cfg = { - .idle_acq_int = 0xff, - .active_acq_int = 0xff, - .active_idle_to = 0x00, - }, - .acquire_cfg = { - .charge_time = 0x0A, - .reserve1 = 0, - .touch_drift = 0x14, - .drift_susp = 0x14, - .touch_autocal = 0x00, - .reserve5 = 0, - .atch_cal_suspend_time = 0, - .atch_cal_suspend_thres = 0, - .atch_cal_force_thres = 0x10, - .atch_cal_force_ratio = 0, - }, - .multi_touch_cfg = { - .ctrl = 0x83, - .x_origin = 0, - .y_origin = 0, - .x_size = 0x1b, - .y_size = 0x2a, - .aks_cfg = 0, - .burst_len = 0x10, - .tch_det_thr = 45, - .tch_det_int = 0x3, - .orient = 7, - .mrg_to = 0x00, - .mov_hyst_init = 0x05, - .mov_hyst_next = 0x02, - .mov_filter = 0x20, - .num_touch = 0x01, - .merge_hyst = 0x0A, - .merge_thresh = 0x0A, - .amp_hyst = 0x0A, - .x_res = 0x0FFF, - .y_res = 0x0FFF, - .x_low_clip = 0x00, - .x_high_clip = 0x00, - .y_low_clip = 0x00, - .y_high_clip = 0x00, - .x_edge_ctrl = 0, - .x_edge_dist = 0, - .y_edge_ctrl = 0, - .y_edge_dist = 0, - .jump_limit = 0, - }, - .comms_config_cfg = { - .ctrl = 0, - .command = 0, - }, - .noise_suppression_cfg = { - .ctrl = 0, - .reserve1 = 0, - .reserve2 = 0, - .reserve3 = 0, - .reserve4 = 0, - .reserve5 = 0, - .reserve6 = 0, - .reserve7 = 0, - .noise_thres = 0, - .reserve9 = 0, - .freq_hop_scale = 0, - .burst_freq_0 = 0, - .burst_freq_1 = 0, - .burst_freq_2 = 0, - .burst_freq_3 = 0, - .burst_freq_4 = 0, - .reserve16 = 0, - }, - .one_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .gesture_enable = 0, - .pres_proc = 0, - .tap_time_out = 0, - .flick_time_out = 0, - .drag_time_out = 0, - .short_press_time_out = 0, - .long_press_time_out = 0, - .repeat_press_time_out = 0, - .flick_threshold = 0, - .drag_threshold = 0, - .tap_threshold = 0, - .throw_threshold = 0, - }, - .self_test_cfg = { - .ctrl = 0, - .command = 0, - .high_signal_limit_0 = 0, - .low_signal_limit_0 = 0, - .high_signal_limit_1 = 0, - .low_signal_limit_1 = 0, - .high_signal_limit_2 = 0, - .low_signal_limit_2 = 0, - }, - .two_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .reserve2 = 0, - .gesture_enable = 0, - .rotate_threshold = 0, - .zoom_threshold = 0, - }, - .cte_config_cfg = { - .ctrl = 0, - .command = 0, - .reserve2 = 0, - .idle_gcaf_depth = 16, - .active_gcaf_depth = 16, - .voltage = 60, - }, - .gripsuppression_t40_cfg = { - .ctrl = 0, - .xlo_grip = 0, - .xhi_grip = 0, - .ylo_grip = 0, - .yhi_grip = 0, - }, - .palm_suppression_cfg = { - .ctrl = 0, - .small_obj_thr = 0, - .sig_spread_thr = 0, - .large_obj_thr = 0, - .distance_thr = 0, - .sup_ext_to = 0, - }, - .spt_digitizer_cfg = { - .ctrl = 0, - .hid_idlerate = 0, - .xlength = 0, - .ylength = 0, - }, - - .vkeys = { - .count = 0, - .keys = NULL, - }, -}; - -/* Portable P0 */ -struct qtouch_ts_platform_data stingray_touch_data_p0 = { - - .flags = (QTOUCH_USE_MULTITOUCH | - QTOUCH_CFG_BACKUPNV), - .irqflags = (IRQF_TRIGGER_LOW), - .abs_min_x = 10, - .abs_max_x = 2569, - .abs_min_y = 15, - .abs_max_y = 1614, - .abs_min_p = 0, - .abs_max_p = 255, - .abs_min_w = 0, - .abs_max_w = 15, - .x_delta = 400, - .y_delta = 250, - .nv_checksum = 0x3fa414, - .fuzz_x = 0, - .fuzz_y = 0, - .fuzz_p = 2, - .fuzz_w = 2, - .boot_i2c_addr = XMEGAT_BL_I2C_ADDR, - .hw_reset = stingray_touch_reset, - .hw_suspend = stingray_touch_suspend, - .key_array = { - .cfg = NULL, - .keys = NULL, - .num_keys = 0, - }, - .touch_fw_cfg = { - .fw_name = "mXT1386_10_FF.bin", - .family_id = 0xA0, - .variant_id = 0x00, - .fw_version = 0x10, - .fw_build = 0xFF, - .boot_version = 0x20, - .base_fw_version = 0x00, - }, - .power_cfg = { - .idle_acq_int = 0x12, - .active_acq_int = 0xFF, - .active_idle_to = 0x0A, - }, - .acquire_cfg = { - .charge_time = 0x0A, - .reserve1 = 0, - .touch_drift = 0x14, - .drift_susp = 0x14, - .touch_autocal = 0x4B, - .reserve5 = 0, - .atch_cal_suspend_time = 0, - .atch_cal_suspend_thres = 0, - .atch_cal_force_thres = 0x10, - .atch_cal_force_ratio = 0x10, - }, - .multi_touch_cfg = { - .ctrl = 0x83, - .x_origin = 0, - .y_origin = 0, - .x_size = 0x21, - .y_size = 0x2a, - .aks_cfg = 0, - .burst_len = 0x20, - .tch_det_thr = 0x2d, - .tch_det_int = 0x2, - .orient = 1, - .mrg_to = 0x0A, - .mov_hyst_init = 0x16, - .mov_hyst_next = 0x0B, - .mov_filter = 0x30, - .num_touch = 0x0A, - .merge_hyst = 0x10, - .merge_thresh = 0x23, - .amp_hyst = 0x0A, - .x_res = 0x065E, - .y_res = 0x0A14, - .x_low_clip = 0x0C, - .x_high_clip = 0x0C, - .y_low_clip = 0x05, - .y_high_clip = 0x05, - .x_edge_ctrl = 0xC3, - .x_edge_dist = 0x22, - .y_edge_ctrl = 0x82, - .y_edge_dist = 0x3C, - .jump_limit = 0x20, - .tch_thres_hyst = 0, - .xpitch = 0x2D, - .ypitch = 0x2D, - }, - .comms_config_cfg = { - .ctrl = 0, - .command = 0, - }, - .noise_suppression_cfg = { - .ctrl = 5, - .reserve1 = 0, - .reserve2 = 0, - .reserve3 = 0, - .reserve4 = 0, - .reserve5 = 0, - .reserve6 = 0, - .reserve7 = 0, - .noise_thres = 32, - .reserve9 = 0, - .freq_hop_scale = 0, - .burst_freq_0 = 10, - .burst_freq_1 = 15, - .burst_freq_2 = 19, - .burst_freq_3 = 25, - .burst_freq_4 = 30, - .reserve16 = 0, - }, - .one_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .gesture_enable = 0, - .pres_proc = 0, - .tap_time_out = 0, - .flick_time_out = 0, - .drag_time_out = 0, - .short_press_time_out = 0, - .long_press_time_out = 0, - .repeat_press_time_out = 0, - .flick_threshold = 0, - .drag_threshold = 0, - .tap_threshold = 0, - .throw_threshold = 0, - }, - .self_test_cfg = { - .ctrl = 0, - .command = 0, - .high_signal_limit_0 = 0, - .low_signal_limit_0 = 0, - .high_signal_limit_1 = 0, - .low_signal_limit_1 = 0, - .high_signal_limit_2 = 0, - .low_signal_limit_2 = 0, - }, - .two_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .reserve2 = 0, - .gesture_enable = 0, - .rotate_threshold = 0, - .zoom_threshold = 0, - }, - .cte_config_cfg = { - .ctrl = 0, - .command = 0, - .reserve2 = 0, - .idle_gcaf_depth = 20, - .active_gcaf_depth = 20, - .voltage = 60, - }, - .gripsuppression_t40_cfg = { - .ctrl = 0, - .xlo_grip = 0, - .xhi_grip = 0, - .ylo_grip = 0, - .yhi_grip = 0, - }, - .palm_suppression_cfg = { - .ctrl = 1, - .small_obj_thr = 0, - .sig_spread_thr = 0, - .large_obj_thr = 0xD3, - .distance_thr = 0x05, - .sup_ext_to = 0x05, - .strength = 0xDC, - }, - .spt_digitizer_cfg = { - .ctrl = 0, - .hid_idlerate = 0, - .xlength = 0, - .ylength = 0, - }, - - .vkeys = { - .count = 0, - .keys = NULL, - }, -}; - -/* Portable P1 and later versions */ -struct qtouch_ts_platform_data stingray_touch_data_p1_or_later = { - - .flags = (QTOUCH_USE_MULTITOUCH | - QTOUCH_CFG_BACKUPNV), - .irqflags = (IRQF_TRIGGER_LOW), - .abs_min_x = 10, - .abs_max_x = 2569, - .abs_min_y = 15, - .abs_max_y = 1614, - .abs_min_p = 0, - .abs_max_p = 255, - .abs_min_w = 0, - .abs_max_w = 15, - .x_delta = 400, - .y_delta = 250, - .nv_checksum = 0x3fa414, - .fuzz_x = 0, - .fuzz_y = 0, - .fuzz_p = 2, - .fuzz_w = 2, - .boot_i2c_addr = XMEGAT_BL_I2C_ADDR, - .hw_reset = stingray_touch_reset, - .hw_suspend = stingray_touch_suspend, - .key_array = { - .cfg = NULL, - .keys = NULL, - .num_keys = 0, - }, - .touch_fw_cfg = { - .fw_name = "mXT1386_10_FF.bin", - .family_id = 0xA0, - .variant_id = 0x00, - .fw_version = 0x10, - .fw_build = 0xFF, - .boot_version = 0x20, - .base_fw_version = 0x00, - }, - .power_cfg = { - .idle_acq_int = 0x12, - .active_acq_int = 0xFF, - .active_idle_to = 0x0A, - }, - .acquire_cfg = { - .charge_time = 0x0A, - .reserve1 = 0, - .touch_drift = 0x14, - .drift_susp = 0x14, - .touch_autocal = 0x4B, - .reserve5 = 0, - .atch_cal_suspend_time = 0, - .atch_cal_suspend_thres = 0, - .atch_cal_force_thres = 0x10, - .atch_cal_force_ratio = 0x10, - }, - .multi_touch_cfg = { - .ctrl = 0x83, - .x_origin = 0, - .y_origin = 0, - .x_size = 0x21, - .y_size = 0x2a, - .aks_cfg = 0, - .burst_len = 0x20, - .tch_det_thr = 0x2d, - .tch_det_int = 0x2, - .orient = 1, - .mrg_to = 0x0A, - .mov_hyst_init = 0x16, - .mov_hyst_next = 0x0B, - .mov_filter = 0x30, - .num_touch = 0x0A, - .merge_hyst = 0x10, - .merge_thresh = 0x23, - .amp_hyst = 0x0A, - .x_res = 0x065E, - .y_res = 0x0A14, - .x_low_clip = 0x0C, - .x_high_clip = 0x0C, - .y_low_clip = 0x05, - .y_high_clip = 0x05, - .x_edge_ctrl = 0xC3, - .x_edge_dist = 0x22, - .y_edge_ctrl = 0x82, - .y_edge_dist = 0x3C, - .jump_limit = 0x20, - .tch_thres_hyst = 0, - .xpitch = 0x2D, - .ypitch = 0x2D, - }, - .comms_config_cfg = { - .ctrl = 0, - .command = 0, - }, - .noise_suppression_cfg = { - .ctrl = 5, - .reserve1 = 0, - .reserve2 = 0, - .reserve3 = 0, - .reserve4 = 0, - .reserve5 = 0, - .reserve6 = 0, - .reserve7 = 0, - .noise_thres = 32, - .reserve9 = 0, - .freq_hop_scale = 0, - .burst_freq_0 = 10, - .burst_freq_1 = 15, - .burst_freq_2 = 19, - .burst_freq_3 = 25, - .burst_freq_4 = 30, - .reserve16 = 0, - }, - .one_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .gesture_enable = 0, - .pres_proc = 0, - .tap_time_out = 0, - .flick_time_out = 0, - .drag_time_out = 0, - .short_press_time_out = 0, - .long_press_time_out = 0, - .repeat_press_time_out = 0, - .flick_threshold = 0, - .drag_threshold = 0, - .tap_threshold = 0, - .throw_threshold = 0, - }, - .self_test_cfg = { - .ctrl = 0, - .command = 0, - .high_signal_limit_0 = 0, - .low_signal_limit_0 = 0, - .high_signal_limit_1 = 0, - .low_signal_limit_1 = 0, - .high_signal_limit_2 = 0, - .low_signal_limit_2 = 0, - }, - .two_touch_gesture_proc_cfg = { - .ctrl = 0, - .num_gestures = 0, - .reserve2 = 0, - .gesture_enable = 0, - .rotate_threshold = 0, - .zoom_threshold = 0, - }, - .cte_config_cfg = { - .ctrl = 0, - .command = 0, - .reserve2 = 0, - .idle_gcaf_depth = 20, - .active_gcaf_depth = 20, - .voltage = 60, - }, - .gripsuppression_t40_cfg = { - .ctrl = 0, - .xlo_grip = 0, - .xhi_grip = 0, - .ylo_grip = 0, - .yhi_grip = 0, - }, - .palm_suppression_cfg = { - .ctrl = 1, - .small_obj_thr = 0, - .sig_spread_thr = 0, - .large_obj_thr = 0xD3, - .distance_thr = 0x05, - .sup_ext_to = 0x05, - .strength = 0xDC, - }, - .spt_digitizer_cfg = { - .ctrl = 0, - .hid_idlerate = 0, - .xlength = 0, - .ylength = 0, - }, - - .vkeys = { - .count = 0, - .keys = NULL, - }, -}; - -static struct i2c_board_info __initdata stingray_i2c_bus1_touch_info[] = { - { - I2C_BOARD_INFO(QTOUCH_TS_NAME, 0x5B), - }, -}; - -int __init stingray_touch_init(void) -{ - unsigned touch_int_gpio; - - if (stingray_revision() == STINGRAY_REVISION_P2) - touch_int_gpio = STINGRAY_TOUCH_INT_N_GPIO_P2; - else - touch_int_gpio = STINGRAY_TOUCH_INT_N_GPIO; - - tegra_gpio_enable(touch_int_gpio); - gpio_request(touch_int_gpio, "touch_irq"); - gpio_direction_input(touch_int_gpio); - - tegra_gpio_enable(STINGRAY_TOUCH_WAKE_N_GPIO); - gpio_request(STINGRAY_TOUCH_WAKE_N_GPIO, "touch_wake"); - gpio_direction_output(STINGRAY_TOUCH_WAKE_N_GPIO, 0); - - tegra_gpio_enable(STINGRAY_TOUCH_RESET_N_GPIO); - gpio_request(STINGRAY_TOUCH_RESET_N_GPIO, "touch_reset"); - gpio_direction_output(STINGRAY_TOUCH_RESET_N_GPIO, 1); - - stingray_i2c_bus1_touch_info[0].irq = - TEGRA_GPIO_TO_IRQ(touch_int_gpio); - - if ((stingray_revision() == STINGRAY_REVISION_P1) || - (stingray_revision() == STINGRAY_REVISION_P2) || - (stingray_revision() == STINGRAY_REVISION_P3)) - stingray_i2c_bus1_touch_info[0].platform_data = - &stingray_touch_data_p1_or_later; - else if (stingray_revision() == STINGRAY_REVISION_P0) - stingray_i2c_bus1_touch_info[0].platform_data = &stingray_touch_data_p0; - else - stingray_i2c_bus1_touch_info[0].platform_data = &stingray_touch_data_m1; - - i2c_register_board_info(0, stingray_i2c_bus1_touch_info, 1); - - return 0; -} diff --git a/arch/arm/mach-tegra/board-stingray-usbnet.c b/arch/arm/mach-tegra/board-stingray-usbnet.c deleted file mode 100644 index cb0d1e03689f..000000000000 --- a/arch/arm/mach-tegra/board-stingray-usbnet.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - * Gadget Driver for Motorola USBNet - * - * Copyright (C) 2009 Motorola, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -/* - * Macro Defines - */ - -#define EP0_BUFSIZE 256 - - -/* Vendor Request to config IP */ -#define USBNET_SET_IP_ADDRESS 0x05 -#define USBNET_SET_SUBNET_MASK 0x06 -#define USBNET_SET_HOST_IP 0x07 - -/* Linux Network Interface */ -#define USB_MTU 1536 -#define MAX_BULK_TX_REQ_NUM 8 -#define MAX_BULK_RX_REQ_NUM 8 -#define MAX_INTR_RX_REQ_NUM 8 -#define STRING_INTERFACE 0 - -struct usbnet_context { - spinlock_t lock; /* For RX/TX list */ - struct net_device *dev; - - struct usb_gadget *gadget; - - struct usb_ep *bulk_in; - struct usb_ep *bulk_out; - struct usb_ep *intr_out; - u16 config; /* current USB config w_value */ - - struct list_head rx_reqs; - struct list_head tx_reqs; - - struct net_device_stats stats; - struct work_struct usbnet_config_wq; - u32 ip_addr; - u32 subnet_mask; - u32 router_ip; - u32 iff_flag; -}; - - -struct usbnet_device { - struct usb_function function; - struct usb_composite_dev *cdev; - struct usbnet_context *net_ctxt; -}; - -/* static strings, in UTF-8 */ -static struct usb_string usbnet_string_defs[] = { - [STRING_INTERFACE].s = "Motorola Test Command", - { /* ZEROES END LIST */ }, -}; - -static struct usb_gadget_strings usbnet_string_table = { - .language = 0x0409, /* en-us */ - .strings = usbnet_string_defs, -}; - -static struct usb_gadget_strings *usbnet_strings[] = { - &usbnet_string_table, - NULL, -}; - - - -/* There is only one interface. */ - -static struct usb_interface_descriptor intf_desc = { - .bLength = sizeof intf_desc, - .bDescriptorType = USB_DT_INTERFACE, - - .bNumEndpoints = 3, - .bInterfaceClass = 0x02, - .bInterfaceSubClass = 0x0a, - .bInterfaceProtocol = 0x01, -}; - - -static struct usb_endpoint_descriptor fs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor fs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor fs_intr_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .bInterval = 1, -}; - -static struct usb_descriptor_header *fs_function[] = { - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &fs_bulk_in_desc, - (struct usb_descriptor_header *) &fs_bulk_out_desc, - (struct usb_descriptor_header *) &fs_intr_out_desc, - NULL, -}; - -static struct usb_endpoint_descriptor hs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), - .bInterval = 0, -}; - -static struct usb_endpoint_descriptor hs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), - .bInterval = 0, -}; - -static struct usb_endpoint_descriptor hs_intr_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = __constant_cpu_to_le16(64), - .bInterval = 1, -}; - -static struct usb_descriptor_header *hs_function[] = { - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &hs_bulk_in_desc, - (struct usb_descriptor_header *) &hs_bulk_out_desc, - (struct usb_descriptor_header *) &hs_intr_out_desc, - NULL, -}; - -#define DO_NOT_STOP_QUEUE 0 -#define STOP_QUEUE 1 - -#define USBNETDBG(context, fmt, args...) \ - if (context && context->gadget) \ - dev_dbg(&(context->gadget->dev) , fmt , ## args) - -static const char *usb_description = "Motorola BLAN Interface"; - -static ssize_t usbnet_desc_show(struct device *dev, - struct device_attribute *attr, char *buff) -{ - ssize_t status = 0; - status = sprintf(buff, "%s\n", usb_description); - return status; -} - -static DEVICE_ATTR(description, S_IRUGO, usbnet_desc_show, NULL); - -static inline struct usbnet_device *func_to_dev(struct usb_function *f) -{ - return container_of(f, struct usbnet_device, function); -} - - -static int ether_queue_out(struct usb_request *req , - struct usbnet_context *context) -{ - unsigned long flags; - struct sk_buff *skb; - int ret; - - skb = alloc_skb(USB_MTU + NET_IP_ALIGN, GFP_ATOMIC); - if (!skb) { - USBNETDBG(context, "%s: failed to alloc skb\n", __func__); - ret = -ENOMEM; - goto fail; - } - - skb_reserve(skb, NET_IP_ALIGN); - - req->buf = skb->data; - req->length = USB_MTU; - req->context = skb; - - ret = usb_ep_queue(context->bulk_out, req, GFP_KERNEL); - if (ret == 0) - return 0; - else - kfree_skb(skb); -fail: - spin_lock_irqsave(&context->lock, flags); - list_add_tail(&req->list, &context->rx_reqs); - spin_unlock_irqrestore(&context->lock, flags); - - return ret; -} - -struct usb_request *usb_get_recv_request(struct usbnet_context *context) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&context->lock, flags); - if (list_empty(&context->rx_reqs)) { - req = NULL; - } else { - req = list_first_entry(&context->rx_reqs, - struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&context->lock, flags); - - return req; -} - -struct usb_request *usb_get_xmit_request(int stop_flag, struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&context->lock, flags); - if (list_empty(&context->tx_reqs)) { - req = NULL; - } else { - req = list_first_entry(&context->tx_reqs, - struct usb_request, list); - list_del(&req->list); - if (stop_flag == STOP_QUEUE && - list_empty(&context->tx_reqs)) - netif_stop_queue(dev); - } - spin_unlock_irqrestore(&context->lock, flags); - return req; -} - -static int usb_ether_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - struct usb_request *req; - unsigned long flags; - unsigned len; - int rc; - - req = usb_get_xmit_request(STOP_QUEUE, dev); - - if (!req) { - USBNETDBG(context, "%s: could not obtain tx request\n", - __func__); - return 1; - } - - /* Add 4 bytes CRC */ - skb->len += 4; - - /* ensure that we end with a short packet */ - len = skb->len; - if (!(len & 63) || !(len & 511)) - len++; - - req->context = skb; - req->buf = skb->data; - req->length = len; - - rc = usb_ep_queue(context->bulk_in, req, GFP_KERNEL); - if (rc != 0) { - spin_lock_irqsave(&context->lock, flags); - list_add_tail(&req->list, &context->tx_reqs); - spin_unlock_irqrestore(&context->lock, flags); - - dev_kfree_skb_any(skb); - context->stats.tx_dropped++; - - USBNETDBG(context, - "%s: could not queue tx request\n", __func__); - } - - return 0; -} - -static int usb_ether_open(struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - USBNETDBG(context, "%s\n", __func__); - return 0; -} - -static int usb_ether_stop(struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - USBNETDBG(context, "%s\n", __func__); - return 0; -} - -static struct net_device_stats *usb_ether_get_stats(struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - USBNETDBG(context, "%s\n", __func__); - return &context->stats; -} - -static void usbnet_if_config(struct work_struct *work) -{ - struct ifreq ifr; - mm_segment_t saved_fs; - unsigned err; - struct sockaddr_in *sin; - struct usbnet_context *context = container_of(work, - struct usbnet_context, usbnet_config_wq); - - memset(&ifr, 0, sizeof(ifr)); - sin = (void *) &(ifr.ifr_ifru.ifru_addr); - strncpy(ifr.ifr_ifrn.ifrn_name, context->dev->name, - sizeof(ifr.ifr_ifrn.ifrn_name)); - sin->sin_family = AF_INET; - - sin->sin_addr.s_addr = context->ip_addr; - saved_fs = get_fs(); - set_fs(get_ds()); - err = devinet_ioctl(dev_net(context->dev), SIOCSIFADDR, &ifr); - if (err) - USBNETDBG(context, "%s: Error in SIOCSIFADDR\n", __func__); - - sin->sin_addr.s_addr = context->subnet_mask; - err = devinet_ioctl(dev_net(context->dev), SIOCSIFNETMASK, &ifr); - if (err) - USBNETDBG(context, "%s: Error in SIOCSIFNETMASK\n", __func__); - - sin->sin_addr.s_addr = context->ip_addr | ~(context->subnet_mask); - err = devinet_ioctl(dev_net(context->dev), SIOCSIFBRDADDR, &ifr); - if (err) - USBNETDBG(context, "%s: Error in SIOCSIFBRDADDR\n", __func__); - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_ifrn.ifrn_name, context->dev->name, - sizeof(ifr.ifr_ifrn.ifrn_name)); - ifr.ifr_flags = ((context->dev->flags) | context->iff_flag); - err = devinet_ioctl(dev_net(context->dev), SIOCSIFFLAGS, &ifr); - if (err) - USBNETDBG(context, "%s: Error in SIOCSIFFLAGS\n", __func__); - - set_fs(saved_fs); -} - -static const struct net_device_ops eth_netdev_ops = { - .ndo_open = usb_ether_open, - .ndo_stop = usb_ether_stop, - .ndo_start_xmit = usb_ether_xmit, - .ndo_get_stats = usb_ether_get_stats, -}; - -static void usb_ether_setup(struct net_device *dev) -{ - struct usbnet_context *context = netdev_priv(dev); - INIT_LIST_HEAD(&context->rx_reqs); - INIT_LIST_HEAD(&context->tx_reqs); - - spin_lock_init(&context->lock); - context->dev = dev; - - dev->netdev_ops = ð_netdev_ops; - dev->watchdog_timeo = 20; - - ether_setup(dev); - - random_ether_addr(dev->dev_addr); -} - -/*-------------------------------------------------------------------------*/ -static void usbnet_cleanup(struct usbnet_device *dev) -{ - struct usbnet_context *context = dev->net_ctxt; - if (context) { - device_remove_file(&(context->dev->dev), &dev_attr_description); - unregister_netdev(context->dev); - free_netdev(context->dev); - dev->net_ctxt = NULL; - } -} - -static void usbnet_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usb_composite_dev *cdev = c->cdev; - struct usbnet_context *context = dev->net_ctxt; - struct usb_request *req; - - dev->cdev = cdev; - - usb_ep_disable(context->bulk_in); - usb_ep_disable(context->bulk_out); - - /* Free BULK OUT Requests */ - while ((req = usb_get_recv_request(context))) - usb_ep_free_request(context->bulk_out, req); - - /* Free BULK IN Requests */ - while ((req = usb_get_xmit_request(DO_NOT_STOP_QUEUE, - context->dev))) { - usb_ep_free_request(context->bulk_in, req); - } - - context->config = 0; - - usbnet_cleanup(dev); -} - -static void ether_out_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct sk_buff *skb = req->context; - struct usbnet_context *context = ep->driver_data; - - if (req->status == 0) { - skb_put(skb, req->actual); - skb->protocol = eth_type_trans(skb, context->dev); - context->stats.rx_packets++; - context->stats.rx_bytes += req->actual; - netif_rx(skb); - } else { - dev_kfree_skb_any(skb); - context->stats.rx_errors++; - } - - /* don't bother requeuing if we just went offline */ - if ((req->status == -ENODEV) || (req->status == -ESHUTDOWN)) { - unsigned long flags; - spin_lock_irqsave(&context->lock, flags); - list_add_tail(&req->list, &context->rx_reqs); - spin_unlock_irqrestore(&context->lock, flags); - } else { - if (ether_queue_out(req, context)) - USBNETDBG(context, "ether_out: cannot requeue\n"); - } -} - -static void ether_in_complete(struct usb_ep *ep, struct usb_request *req) -{ - unsigned long flags; - struct sk_buff *skb = req->context; - struct usbnet_context *context = ep->driver_data; - - if (req->status == 0) { - context->stats.tx_packets++; - context->stats.tx_bytes += req->actual; - } else { - context->stats.tx_errors++; - } - - dev_kfree_skb_any(skb); - - spin_lock_irqsave(&context->lock, flags); - if (list_empty(&context->tx_reqs)) - netif_start_queue(context->dev); - - list_add_tail(&req->list, &context->tx_reqs); - spin_unlock_irqrestore(&context->lock, flags); -} - -static int usbnet_bind(struct usb_configuration *c, - struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - int n, rc, id; - struct usb_ep *ep; - struct usb_request *req; - unsigned long flags; - - dev->cdev = cdev; - - id = usb_interface_id(c, f); - if (id < 0) - return id; - intf_desc.bInterfaceNumber = id; - context->gadget = cdev->gadget; - - /* Find all the endpoints we will use */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_in_desc); - if (!ep) { - USBNETDBG(context, "%s auto-configure hs_bulk_in_desc error\n", - __func__); - goto autoconf_fail; - } - ep->driver_data = context; - context->bulk_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_out_desc); - if (!ep) { - USBNETDBG(context, "%s auto-configure hs_bulk_out_desc error\n", - __func__); - goto autoconf_fail; - } - ep->driver_data = context; - context->bulk_out = ep; - - - ep = usb_ep_autoconfig(cdev->gadget, &fs_intr_out_desc); - if (!ep) { - USBNETDBG(context, "%s auto-configure hs_intr_out_desc error\n", - __func__); - goto autoconf_fail; - } - ep->driver_data = context; - context->intr_out = ep; - - if (gadget_is_dualspeed(cdev->gadget)) { - - /* Assume endpoint addresses are the same for both speeds */ - hs_bulk_in_desc.bEndpointAddress = - fs_bulk_in_desc.bEndpointAddress; - hs_bulk_out_desc.bEndpointAddress = - fs_bulk_out_desc.bEndpointAddress; - hs_intr_out_desc.bEndpointAddress = - fs_intr_out_desc.bEndpointAddress; - } - - - rc = -ENOMEM; - - for (n = 0; n < MAX_BULK_RX_REQ_NUM; n++) { - req = usb_ep_alloc_request(context->bulk_out, - GFP_KERNEL); - if (!req) { - USBNETDBG(context, "%s: alloc request bulk_out fail\n", - __func__); - break; - } - req->complete = ether_out_complete; - spin_lock_irqsave(&context->lock, flags); - list_add_tail(&req->list, &context->rx_reqs); - spin_unlock_irqrestore(&context->lock, flags); - } - for (n = 0; n < MAX_BULK_TX_REQ_NUM; n++) { - req = usb_ep_alloc_request(context->bulk_in, - GFP_KERNEL); - if (!req) { - USBNETDBG(context, "%s: alloc request bulk_in fail\n", - __func__); - break; - } - req->complete = ether_in_complete; - spin_lock_irqsave(&context->lock, flags); - list_add_tail(&req->list, &context->tx_reqs); - spin_unlock_irqrestore(&context->lock, flags); - } - - return 0; - -autoconf_fail: - rc = -ENOTSUPP; - usbnet_unbind(c, f); - return rc; -} - - - - -static void do_set_config(struct usb_function *f, u16 new_config) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - int result = 0; - struct usb_request *req; - int high_speed_flag = 0; - - if (context->config == new_config) /* Config did not change */ - return; - - context->config = new_config; - - if (new_config == 1) { /* Enable End points */ - if (gadget_is_dualspeed(context->gadget) - && context->gadget->speed == USB_SPEED_HIGH) - high_speed_flag = 1; - - if (high_speed_flag) - result = usb_ep_enable(context->bulk_in, - &hs_bulk_in_desc); - else - result = usb_ep_enable(context->bulk_in, - &fs_bulk_in_desc); - - if (result != 0) { - USBNETDBG(context, - "%s: failed to enable BULK_IN EP ret=%d\n", - __func__, result); - } - - context->bulk_in->driver_data = context; - - if (high_speed_flag) - result = usb_ep_enable(context->bulk_out, - &hs_bulk_out_desc); - else - result = usb_ep_enable(context->bulk_out, - &fs_bulk_out_desc); - - if (result != 0) { - USBNETDBG(context, - "%s: failed to enable BULK_OUT EP ret = %d\n", - __func__, result); - } - - context->bulk_out->driver_data = context; - - if (high_speed_flag) - result = usb_ep_enable(context->intr_out, - &hs_intr_out_desc); - else - result = usb_ep_enable(context->intr_out, - &fs_intr_out_desc); - - if (result != 0) { - USBNETDBG(context, - "%s: failed to enable INTR_OUT EP ret = %d\n", - __func__, result); - } - - context->intr_out->driver_data = context; - - /* we're online -- get all rx requests queued */ - while ((req = usb_get_recv_request(context))) { - if (ether_queue_out(req, context)) { - USBNETDBG(context, - "%s: ether_queue_out failed\n", - __func__); - break; - } - } - - } else {/* Disable Endpoints */ - if (context->bulk_in) - usb_ep_disable(context->bulk_in); - if (context->bulk_out) - usb_ep_disable(context->bulk_out); - } -} - - -static int usbnet_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - USBNETDBG(context, "usbnet_set_alt intf: %d alt: %d\n", intf, alt); - do_set_config(f, 1); - return 0; -} - -static int usbnet_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - int rc = -EOPNOTSUPP; - int wIndex = le16_to_cpu(ctrl->wIndex); - int wValue = le16_to_cpu(ctrl->wValue); - int wLength = le16_to_cpu(ctrl->wLength); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - - if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { - switch (ctrl->bRequest) { - case USBNET_SET_IP_ADDRESS: - context->ip_addr = (wValue << 16) | wIndex; - rc = 0; - break; - case USBNET_SET_SUBNET_MASK: - context->subnet_mask = (wValue << 16) | wIndex; - rc = 0; - break; - case USBNET_SET_HOST_IP: - context->router_ip = (wValue << 16) | wIndex; - rc = 0; - break; - default: - break; - } - - if (context->ip_addr && context->subnet_mask - && context->router_ip) { - context->iff_flag = IFF_UP; - /* schedule a work queue to do this because we - need to be able to sleep */ - queue_work(system_nrt_wq, &context->usbnet_config_wq); - } - } - - /* respond with data transfer or status phase? */ - if (rc >= 0) { - req->zero = rc < wLength; - req->length = rc; - rc = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (rc < 0) - USBNETDBG(context, "usbnet setup response error\n"); - } - - return rc; -} - -static void usbnet_disable(struct usb_function *f) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - USBNETDBG(context, "%s\n", __func__); - do_set_config(f, 0); -} - -static void usbnet_suspend(struct usb_function *f) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - USBNETDBG(context, "%s\n", __func__); -} - -static void usbnet_resume(struct usb_function *f) -{ - struct usbnet_device *dev = func_to_dev(f); - struct usbnet_context *context = dev->net_ctxt; - USBNETDBG(context, "%s\n", __func__); -} - -int usbnet_bind_config(struct usb_configuration *c) -{ - struct usbnet_device *dev; - struct usbnet_context *context; - struct net_device *net_dev; - int ret, status; - - pr_debug("usbnet_bind_config\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - net_dev = alloc_netdev(sizeof(struct usbnet_context), - "usb%d", usb_ether_setup); - if (!net_dev) { - pr_err("%s: alloc_netdev error\n", __func__); - return -EINVAL; - } - - ret = register_netdev(net_dev); - if (ret) { - pr_err("%s: register_netdev error\n", __func__); - free_netdev(net_dev); - return -EINVAL; - } - - ret = device_create_file(&net_dev->dev, &dev_attr_description); - if (ret < 0) { - pr_err("%s: sys file creation error\n", __func__); - unregister_netdev(net_dev); - free_netdev(net_dev); - return -EINVAL; - } - - context = netdev_priv(net_dev); - INIT_WORK(&context->usbnet_config_wq, usbnet_if_config); - - status = usb_string_id(c->cdev); - if (status >= 0) { - usbnet_string_defs[STRING_INTERFACE].id = status; - intf_desc.iInterface = status; - } - - context->config = 0; - dev->net_ctxt = context; - dev->cdev = c->cdev; - dev->function.name = "usbnet"; - dev->function.descriptors = fs_function; - dev->function.hs_descriptors = hs_function; - dev->function.bind = usbnet_bind; - dev->function.unbind = usbnet_unbind; - dev->function.set_alt = usbnet_set_alt; - dev->function.disable = usbnet_disable; - dev->function.setup = usbnet_setup; - dev->function.suspend = usbnet_suspend; - dev->function.resume = usbnet_resume; - dev->function.strings = usbnet_strings; - - ret = usb_add_function(c, &dev->function); - if (ret) - goto err1; - - return 0; - -err1: - pr_err("usbnet gadget driver failed to initialize\n"); - usbnet_cleanup(dev); - kfree(dev); - return ret; -} - -static struct android_usb_function usbnet_function = { - .name = "usbnet", - .bind_config = usbnet_bind_config, -}; - -static int usbnet_probe(struct platform_device *pdev) -{ - pr_info("usbnet_probe\n"); - /* do not register our function unless our platform device was registered */ - android_register_function(&usbnet_function); - return 0; -} - -static struct platform_driver usbnet_platform_driver = { - .driver = { .name = "usbnet", }, - .probe = usbnet_probe, -}; - -static int __init init(void) -{ - pr_info("usbnet init\n"); - platform_driver_register(&usbnet_platform_driver); - return 0; -} -module_init(init); diff --git a/arch/arm/mach-tegra/board-stingray-wifi.c b/arch/arm/mach-tegra/board-stingray-wifi.c deleted file mode 100644 index 755e044f5d41..000000000000 --- a/arch/arm/mach-tegra/board-stingray-wifi.c +++ /dev/null @@ -1,294 +0,0 @@ -/* linux/arch/arm/mach-msm/board-stingray-wifi.c -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "board-stingray.h" -#include "gpio-names.h" - -#define STINGRAY_WLAN_IRQ TEGRA_GPIO_PU5 -#define STINGRAY_WLAN_RST TEGRA_GPIO_PU2 - -#define ATAG_STINGRAY_MAC 0x57464d41 -#define ATAG_STINGRAY_MAC_DEBUG - -#define PREALLOC_WLAN_NUMBER_OF_SECTIONS 4 -#define PREALLOC_WLAN_NUMBER_OF_BUFFERS 160 -#define PREALLOC_WLAN_SECTION_HEADER 24 - -#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128) -#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128) -#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 512) -#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 1024) - -#define WLAN_SKB_BUF_NUM 16 - -static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; - -typedef struct wifi_mem_prealloc_struct { - void *mem_ptr; - unsigned long size; -} wifi_mem_prealloc_t; - -static wifi_mem_prealloc_t wifi_mem_array[PREALLOC_WLAN_NUMBER_OF_SECTIONS] = { - { NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER) }, - { NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER) } -}; - -static void *stingray_wifi_mem_prealloc(int section, unsigned long size) -{ - if (section == PREALLOC_WLAN_NUMBER_OF_SECTIONS) - return wlan_static_skb; - if ((section < 0) || (section > PREALLOC_WLAN_NUMBER_OF_SECTIONS)) - return NULL; - if (wifi_mem_array[section].size < size) - return NULL; - return wifi_mem_array[section].mem_ptr; -} - -int __init stingray_init_wifi_mem(void) -{ - int i; - - for(i=0;( i < WLAN_SKB_BUF_NUM );i++) { - if (i < (WLAN_SKB_BUF_NUM/2)) - wlan_static_skb[i] = dev_alloc_skb(4096); - else - wlan_static_skb[i] = dev_alloc_skb(8192); - } - for(i=0;( i < PREALLOC_WLAN_NUMBER_OF_SECTIONS );i++) { - wifi_mem_array[i].mem_ptr = kmalloc(wifi_mem_array[i].size, - GFP_KERNEL); - if (wifi_mem_array[i].mem_ptr == NULL) - return -ENOMEM; - } - return 0; -} - -static struct resource stingray_wifi_resources[] = { - [0] = { - .name = "bcm4329_wlan_irq", - .start = TEGRA_GPIO_TO_IRQ(STINGRAY_WLAN_IRQ), - .end = TEGRA_GPIO_TO_IRQ(STINGRAY_WLAN_IRQ), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE, - }, -}; - -/* BCM4329 returns wrong sdio_vsn(1) when we read cccr, - * we use predefined value (sdio_vsn=2) here to initial sdio driver well - */ -static struct embedded_sdio_data stingray_wifi_emb_data = { - .cccr = { - .sdio_vsn = 2, - .multi_block = 1, - .low_speed = 0, - .wide_bus = 0, - .high_power = 1, - .high_speed = 1, - }, -}; - -static int stingray_wifi_cd = 0; /* WIFI virtual 'card detect' status */ -static void (*wifi_status_cb)(int card_present, void *dev_id); -static void *wifi_status_cb_devid; - -static int stingray_wifi_status_register( - void (*callback)(int card_present, void *dev_id), - void *dev_id) -{ - if (wifi_status_cb) - return -EAGAIN; - wifi_status_cb = callback; - wifi_status_cb_devid = dev_id; - return 0; -} - -static unsigned int stingray_wifi_status(struct device *dev) -{ - return stingray_wifi_cd; -} - -struct tegra_sdhci_platform_data stingray_wifi_data = { - .clk_id = NULL, - .force_hs = 0, - .mmc_data = { - .ocr_mask = MMC_VDD_165_195, - .built_in = 1, - .status = stingray_wifi_status, - .register_status_notify = stingray_wifi_status_register, - .embedded_sdio = &stingray_wifi_emb_data, - }, - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static int stingray_wifi_set_carddetect(int val) -{ - pr_debug("%s: %d\n", __func__, val); - stingray_wifi_cd = val; - if (wifi_status_cb) { - wifi_status_cb(val, wifi_status_cb_devid); - } else - pr_warning("%s: Nobody to notify\n", __func__); - return 0; -} - -static int stingray_wifi_power_state; - -static int stingray_wifi_power(int on) -{ - pr_debug("%s: %d\n", __func__, on); - - mdelay(100); - change_power_brcm_4329(on); - mdelay(100); - gpio_set_value(STINGRAY_WLAN_RST, on); - mdelay(200); - - stingray_wifi_power_state = on; - return 0; -} - -static int stingray_wifi_reset_state; - -static int stingray_wifi_reset(int on) -{ - pr_debug("%s: do nothing\n", __func__); - stingray_wifi_reset_state = on; - return 0; -} - -static unsigned char stingray_mac_addr[IFHWADDRLEN] = { 0,0x90,0x4c,0,0,0 }; - -static int __init parse_tag_wlan_mac(const struct tag *tag) -{ - unsigned char *dptr = (unsigned char *)(&tag->u); - unsigned size; -#ifdef ATAG_STINGRAY_MAC_DEBUG - unsigned i; -#endif - - size = min((tag->hdr.size - 2) * sizeof(__u32), (unsigned)IFHWADDRLEN); -#ifdef ATAG_STINGRAY_MAC_DEBUG - printk("WiFi MAC Addr [%d] = 0x%x\n", tag->hdr.size, tag->hdr.tag); - for(i=0;(i < size);i++) { - printk(" %02x", dptr[i]); - } - printk("\n"); -#endif - memcpy(stingray_mac_addr, dptr, size); - return 0; -} - -__tagtable(ATAG_STINGRAY_MAC, parse_tag_wlan_mac); - -static int stingray_wifi_get_mac_addr(unsigned char *buf) -{ - uint rand_mac; - - if (!buf) - return -EINVAL; - - if ((stingray_mac_addr[4] == 0) && (stingray_mac_addr[5] == 0)) { - srandom32((uint)jiffies); - rand_mac = random32(); - stingray_mac_addr[3] = (unsigned char)rand_mac; - stingray_mac_addr[4] = (unsigned char)(rand_mac >> 8); - stingray_mac_addr[5] = (unsigned char)(rand_mac >> 16); - } - memcpy(buf, stingray_mac_addr, IFHWADDRLEN); - return 0; -} - -/* Customized Locale table : OPTIONAL feature */ -#define WLC_CNTRY_BUF_SZ 4 -typedef struct cntry_locales_custom { - char iso_abbrev[WLC_CNTRY_BUF_SZ]; - char custom_locale[WLC_CNTRY_BUF_SZ]; - int custom_locale_rev; -} cntry_locales_custom_t; - -static cntry_locales_custom_t stingray_wifi_translate_custom_table[] = { -/* Table should be filled out based on custom platform regulatory requirement */ - {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ - {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ - {"EU", "EU", 5}, /* input ISO "EU" to : EU regrev 05 */ - {"FR", "EU", 5}, - {"DE", "EU", 5}, - {"IR", "EU", 5}, - {"UK", "EU", 5}, /* input ISO "UK" to : EU regrev 05 */ - {"KR", "XY", 3}, - {"AU", "XY", 3}, - {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ - {"TW", "XY", 3}, - {"AR", "XY", 3}, -}; - -static void *stingray_wifi_get_country_code(char *ccode) -{ - int size = ARRAY_SIZE(stingray_wifi_translate_custom_table); - int i; - - if (!ccode) - return NULL; - - for (i = 0; i < size; i++) - if (strcmp(ccode, stingray_wifi_translate_custom_table[i].iso_abbrev) == 0) - return &stingray_wifi_translate_custom_table[i]; - return NULL; -} - -static struct wifi_platform_data stingray_wifi_control = { - .set_power = stingray_wifi_power, - .set_reset = stingray_wifi_reset, - .set_carddetect = stingray_wifi_set_carddetect, - .mem_prealloc = stingray_wifi_mem_prealloc, - .get_mac_addr = stingray_wifi_get_mac_addr, - .get_country_code = stingray_wifi_get_country_code, -}; - -static struct platform_device stingray_wifi_device = { - .name = "bcm4329_wlan", - .id = 1, - .num_resources = ARRAY_SIZE(stingray_wifi_resources), - .resource = stingray_wifi_resources, - .dev = { - .platform_data = &stingray_wifi_control, - }, -}; - -static void __init stingray_wlan_gpio(void) -{ - tegra_gpio_enable(STINGRAY_WLAN_RST); - gpio_request(STINGRAY_WLAN_RST, "wlan_rst"); - gpio_direction_output(STINGRAY_WLAN_RST, 0); - - tegra_gpio_enable(STINGRAY_WLAN_IRQ); - gpio_request(STINGRAY_WLAN_IRQ, "wlan_irq"); - gpio_direction_input(STINGRAY_WLAN_IRQ); -} - -int __init stingray_wlan_init(void) -{ - pr_debug("%s: start\n", __func__); - stingray_wlan_gpio(); - stingray_init_wifi_mem(); - return platform_device_register(&stingray_wifi_device); -} diff --git a/arch/arm/mach-tegra/board-stingray-wlan_nvs.c b/arch/arm/mach-tegra/board-stingray-wlan_nvs.c deleted file mode 100644 index 197a4cffd020..000000000000 --- a/arch/arm/mach-tegra/board-stingray-wlan_nvs.c +++ /dev/null @@ -1,112 +0,0 @@ -/* arch/arm/mach-tegra/board-stingray-wlan_nvs.c - * - * Code to extract WiFi calibration information from ATAG set up - * by the bootloader. - * - * Copyright (C) 2008 Google, Inc. - * Author: Dmitry Shmidt - * - * 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 -#include -#include -#include - -#include - -/* configuration tags specific to msm */ -#define ATAG_WLAN_NVS 0x57494649 /* Wlan ATAG */ - -#define NVS_MAX_SIZE 0x800U -#define NVS_LEN_OFFSET 0x0C -/* #define NVS_DATA_OFFSET 0x40*/ -#define NVS_DATA_OFFSET 0x0 - -static unsigned char wifi_nvs_ram[NVS_MAX_SIZE]; -static unsigned wifi_nvs_size = 0; -static struct proc_dir_entry *wifi_calibration; - -unsigned char *get_wifi_nvs_ram( void ) -{ - return wifi_nvs_ram; -} -EXPORT_SYMBOL(get_wifi_nvs_ram); - -static int __init parse_tag_wlan_nvs(const struct tag *tag) -{ - unsigned char *dptr = (unsigned char *)(&tag->u); - unsigned size; -#ifdef ATAG_WLAN_NVS_DEBUG - unsigned i; -#endif - - size = min((tag->hdr.size - 2) * sizeof(__u32), NVS_MAX_SIZE); -#ifdef ATAG_WLAN_NVS_DEBUG - printk("WiFi Data size = %d , 0x%x\n", tag->hdr.size, tag->hdr.tag); - for(i=0;( i < size );i++) { - printk("%02x ", *dptr++); - } -#endif - memcpy(wifi_nvs_ram, dptr, size); - wifi_nvs_size = size; - return 0; -} - -__tagtable(ATAG_WLAN_NVS, parse_tag_wlan_nvs); - -static unsigned wifi_get_nvs_size( void ) -{ -#if 0 - unsigned char *ptr; - unsigned len; - - ptr = get_wifi_nvs_ram(); - /* Size in format LE assumed */ - memcpy(&len, ptr + NVS_LEN_OFFSET, sizeof(len)); - len = min(len, (NVS_MAX_SIZE - NVS_DATA_OFFSET)); - return len; -#endif - return wifi_nvs_size; -} - -int wifi_calibration_size_set(void) -{ - if (wifi_calibration != NULL) - wifi_calibration->size = wifi_get_nvs_size(); - return 0; -} - -static int wifi_calibration_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - unsigned char *ptr; - unsigned len; - - ptr = get_wifi_nvs_ram(); - len = min(wifi_get_nvs_size(), (unsigned)count); - memcpy(page, ptr + NVS_DATA_OFFSET, len); - return len; -} - -static int __init wifi_nvs_init(void) -{ - wifi_calibration = create_proc_entry("calibration", 0444, NULL); - if (wifi_calibration != NULL) { - wifi_calibration->size = wifi_get_nvs_size(); - wifi_calibration->read_proc = wifi_calibration_read_proc; - wifi_calibration->write_proc = NULL; - } - return 0; -} - -device_initcall(wifi_nvs_init); diff --git a/arch/arm/mach-tegra/board-stingray.c b/arch/arm/mach-tegra/board-stingray.c deleted file mode 100644 index 4ae0721d6956..000000000000 --- a/arch/arm/mach-tegra/board-stingray.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "board.h" -#include "board-stingray.h" -#include "clock.h" -#include "gpio-names.h" -#include "devices.h" - -/* NVidia bootloader tags */ -#define ATAG_NVIDIA 0x41000801 - -#define ATAG_NVIDIA_RM 0x1 -#define ATAG_NVIDIA_DISPLAY 0x2 -#define ATAG_NVIDIA_FRAMEBUFFER 0x3 -#define ATAG_NVIDIA_CHIPSHMOO 0x4 -#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5 -#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000 -#define ATAG_NVIDIA_PRESERVED_MEM_N 2 -#define ATAG_NVIDIA_FORCE_32 0x7fffffff - -#define USB_MANUFACTURER_NAME "Motorola" -#define USB_PRODUCT_NAME "MZ600" -#define USB_PRODUCT_NAME_LTE "MZ602" -#define USB_PRODUCT_NAME_WIFI_ONLY "MZ604" -#define USB_PRODUCT_ID_BLAN 0x70A3 -#define USB_PRODUCT_ID_MTP 0x70A8 -#define USB_PRODUCT_ID_MTP_ADB 0x70A9 -#define USB_PRODUCT_ID_RNDIS 0x70AE -#define USB_PRODUCT_ID_RNDIS_ADB 0x70AF -#define USB_PRODUCT_ID_BP 0x70B0 -#define USB_PRODUCT_ID_BP_ADB 0x70B1 -#define USB_PRODUCT_ID_RNDIS_BP 0x70B2 -#define USB_PRODUCT_ID_RNDIS_BP_ADB 0x70B3 -#define USB_VENDOR_ID 0x22b8 - -struct tag_tegra { - __u32 bootarg_key; - __u32 bootarg_len; - char bootarg[1]; -}; - -static int __init parse_tag_nvidia(const struct tag *tag) -{ - - return 0; -} -__tagtable(ATAG_NVIDIA, parse_tag_nvidia); - -static unsigned long ramconsole_start = SZ_512M - SZ_1M; -static unsigned long ramconsole_size = SZ_1M; - -static struct resource mdm6600_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6), - }, -}; - -static struct platform_device mdm6600_modem = { - .name = "mdm6600_modem", - .id = -1, - .resource = mdm6600_resources, - .num_resources = ARRAY_SIZE(mdm6600_resources), -}; - -/* OTG gadget device */ -static struct tegra_utmip_config udc_phy_config = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_lsfslew = 1, - .xcvr_lsrslew = 1, -}; - -static struct fsl_usb2_platform_data tegra_udc_pdata = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, - .phy_config = &udc_phy_config, -}; - -/* OTG transceiver */ -static struct resource cpcap_otg_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device cpcap_otg = { - .name = "cpcap-otg", - .id = -1, - .resource = cpcap_otg_resources, - .num_resources = ARRAY_SIZE(cpcap_otg_resources), - .dev = { - .platform_data = &tegra_ehci1_device, - }, -}; - -static struct cpcap_audio_state stingray_cpcap_audio_state = { - .cpcap = NULL, - .mode = CPCAP_AUDIO_MODE_NORMAL, - .codec_mode = CPCAP_AUDIO_CODEC_OFF, - .codec_rate = CPCAP_AUDIO_CODEC_RATE_8000_HZ, - .codec_mute = CPCAP_AUDIO_CODEC_MUTE, - .stdac_mode = CPCAP_AUDIO_STDAC_OFF, - .stdac_rate = CPCAP_AUDIO_STDAC_RATE_44100_HZ, - .stdac_mute = CPCAP_AUDIO_STDAC_MUTE, - .analog_source = CPCAP_AUDIO_ANALOG_SOURCE_OFF, - .codec_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .codec_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - .stdac_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .stdac_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - .ext_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .ext_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - .codec_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - .stdac_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - .ext_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - .output_gain = 7, - .microphone = CPCAP_AUDIO_IN_NONE, - .input_gain = 31, - .rat_type = CPCAP_AUDIO_RAT_NONE -}; - -/* CPCAP is i2s master; tegra_audio_pdata.master == false */ -static void init_dac2(bool bluetooth); -static struct cpcap_audio_platform_data cpcap_audio_pdata = { - .master = true, - .regulator = "vaudio", - .state = &stingray_cpcap_audio_state, - .speaker_gpio = TEGRA_GPIO_PR3, - .headset_gpio = -1, - .spdif_gpio = TEGRA_GPIO_PD4, - .bluetooth_bypass = init_dac2, -}; - -static struct platform_device cpcap_audio_device = { - .name = "cpcap_audio", - .id = -1, - .dev = { - .platform_data = &cpcap_audio_pdata, - }, -}; - -/* This is the CPCAP Stereo DAC interface. */ -static struct tegra_audio_platform_data tegra_audio_pdata = { - .i2s_master = false, /* CPCAP Stereo DAC */ - .dsp_master = false, /* Don't care */ - .dma_on = true, /* use dma by default */ - .i2s_clk_rate = 24000000, - .dap_clk = "clk_dev1", - .audio_sync_clk = "audio_2x", - .mode = I2S_BIT_FORMAT_I2S, - .fifo_fmt = I2S_FIFO_PACKED, - .bit_size = I2S_BIT_SIZE_16, - .i2s_bus_width = 32, /* Using Packed 16 bit data, the dma is 32 bit. */ - .dsp_bus_width = 16, /* When using DSP mode (unused), this should be 16 bit. */ - .mask = TEGRA_AUDIO_ENABLE_TX, -}; - -/* Connected to CPCAP CODEC - Switchable to Bluetooth Audio. */ -static struct tegra_audio_platform_data tegra_audio2_pdata = { - .i2s_master = false, /* CPCAP CODEC */ - .dsp_master = true, /* Bluetooth */ - .dsp_master_clk = 8000, /* Bluetooth audio speed */ - .dma_on = true, /* use dma by default */ - .i2s_clk_rate = 2000000, /* BCM4329 max bitclock is 2048000 Hz */ - .dap_clk = "clk_dev1", - .audio_sync_clk = "audio_2x", - .mode = I2S_BIT_FORMAT_DSP, /* Using COCEC in network mode */ - .fifo_fmt = I2S_FIFO_16_LSB, - .bit_size = I2S_BIT_SIZE_16, - .i2s_bus_width = 16, /* Capturing a single timeslot, mono 16 bits */ - .dsp_bus_width = 16, - .mask = TEGRA_AUDIO_ENABLE_TX | TEGRA_AUDIO_ENABLE_RX, -}; - -static struct tegra_audio_platform_data tegra_spdif_pdata = { - .dma_on = true, /* use dma by default */ - .i2s_clk_rate = 5644800, - .mode = SPDIF_BIT_MODE_MODE16BIT, - .fifo_fmt = 1, -}; - - -static char *usb_functions_mtp[] = { "mtp" }; -static char *usb_functions_mtp_adb[] = { "mtp", "adb" }; -#ifdef CONFIG_USB_ANDROID_ACCESSORY -static char *usb_functions_accessory[] = { "accessory" }; -static char *usb_functions_accessory_adb[] = { "accessory", "adb" }; -#endif -#ifdef CONFIG_USB_ANDROID_RNDIS -static char *usb_functions_rndis[] = { "rndis" }; -static char *usb_functions_rndis_adb[] = { "rndis", "adb" }; -#endif -static char *usb_functions_all[] = { -#ifdef CONFIG_USB_ANDROID_RNDIS - "rndis", -#endif -#ifdef CONFIG_USB_ANDROID_ACCESSORY - "accessory", -#endif - "mtp", - "adb" -}; - -static struct android_usb_product usb_products[] = { - { - .product_id = USB_PRODUCT_ID_MTP, - .num_functions = ARRAY_SIZE(usb_functions_mtp), - .functions = usb_functions_mtp, - }, - { - .product_id = USB_PRODUCT_ID_MTP_ADB, - .num_functions = ARRAY_SIZE(usb_functions_mtp_adb), - .functions = usb_functions_mtp_adb, - }, -#ifdef CONFIG_USB_ANDROID_ACCESSORY - { - .vendor_id = USB_ACCESSORY_VENDOR_ID, - .product_id = USB_ACCESSORY_PRODUCT_ID, - .num_functions = ARRAY_SIZE(usb_functions_accessory), - .functions = usb_functions_accessory, - }, - { - .vendor_id = USB_ACCESSORY_VENDOR_ID, - .product_id = USB_ACCESSORY_ADB_PRODUCT_ID, - .num_functions = ARRAY_SIZE(usb_functions_accessory_adb), - .functions = usb_functions_accessory_adb, - }, -#endif -#ifdef CONFIG_USB_ANDROID_RNDIS - { - .product_id = USB_PRODUCT_ID_RNDIS, - .num_functions = ARRAY_SIZE(usb_functions_rndis), - .functions = usb_functions_rndis, - }, - { - .product_id = USB_PRODUCT_ID_RNDIS_ADB, - .num_functions = ARRAY_SIZE(usb_functions_rndis_adb), - .functions = usb_functions_rndis_adb, - }, -#endif -}; - -/* standard android USB platform data */ -static struct android_usb_platform_data andusb_plat = { - .vendor_id = USB_VENDOR_ID, - .product_id = USB_PRODUCT_ID_MTP_ADB, - .manufacturer_name = USB_MANUFACTURER_NAME, - .product_name = USB_PRODUCT_NAME, - .serial_number = "0000", - .num_products = ARRAY_SIZE(usb_products), - .products = usb_products, - .num_functions = ARRAY_SIZE(usb_functions_all), - .functions = usb_functions_all, -}; - -static struct platform_device androidusb_device = { - .name = "android_usb", - .id = -1, - .dev = { - .platform_data = &andusb_plat, - }, -}; - -static char *factory_usb_functions[] = { - "usbnet" -}; - -static struct android_usb_product factory_usb_products[] = { - { - .product_id = USB_PRODUCT_ID_BLAN, - .num_functions = ARRAY_SIZE(factory_usb_functions), - .functions = factory_usb_functions, - }, -}; - -/* android USB platform data for factory test mode*/ -static struct android_usb_platform_data andusb_plat_factory = { - .vendor_id = USB_VENDOR_ID, - .product_id = USB_PRODUCT_ID_BLAN, - .manufacturer_name = USB_MANUFACTURER_NAME, - .product_name = USB_PRODUCT_NAME, - .serial_number = "000000000", - .num_products = ARRAY_SIZE(factory_usb_products), - .products = factory_usb_products, - .num_functions = ARRAY_SIZE(factory_usb_functions), - .functions = factory_usb_functions, -}; - -static char *bp_usb_functions_bp[] = { - "acm", "usbnet"}; -static char *bp_usb_functions_bp_adb[] = { - "acm", "usbnet", "adb"}; -static char *bp_usb_functions_rndis_bp[] = { - "rndis", "acm", "usbnet"}; -static char *bp_usb_functions_all[] = { - "rndis", "acm", "usbnet", "adb"}; - -static struct android_usb_product bp_usb_products[] = { - { - .product_id = USB_PRODUCT_ID_BP, - .num_functions = ARRAY_SIZE(bp_usb_functions_bp), - .functions = bp_usb_functions_bp, - }, - { - .product_id = USB_PRODUCT_ID_BP_ADB, - .num_functions = ARRAY_SIZE(bp_usb_functions_bp_adb), - .functions = bp_usb_functions_bp_adb, - }, - { - .product_id = USB_PRODUCT_ID_RNDIS_BP, - .num_functions = ARRAY_SIZE(bp_usb_functions_rndis_bp), - .functions = bp_usb_functions_rndis_bp, - }, - { - .product_id = USB_PRODUCT_ID_RNDIS_BP_ADB, - .num_functions = ARRAY_SIZE(bp_usb_functions_all), - .functions = bp_usb_functions_all, - }, -}; - -static struct android_usb_platform_data andusb_plat_bp = { - .vendor_id = USB_VENDOR_ID, - .product_id = USB_PRODUCT_ID_BP_ADB, - .manufacturer_name = USB_MANUFACTURER_NAME, - .product_name = USB_PRODUCT_NAME, - .serial_number = "0000", - .num_products = ARRAY_SIZE(bp_usb_products), - .products = bp_usb_products, - .num_functions = ARRAY_SIZE(bp_usb_functions_all), - .functions = bp_usb_functions_all, -}; - -static struct platform_device usbnet_device = { - .name = "usbnet", -}; - -#ifdef CONFIG_USB_ANDROID_RNDIS -static struct usb_ether_platform_data rndis_pdata = { - /* ethaddr is filled by board_serialno_setup */ - .vendorID = USB_VENDOR_ID, - .vendorDescr = USB_MANUFACTURER_NAME, -}; - -static struct platform_device rndis_device = { - .name = "rndis", - .id = -1, - .dev = { - .platform_data = &rndis_pdata, - }, -}; -#endif - -static struct acm_platform_data acm_pdata = { - /* Modify num_inst at runtime depending on boot_mode */ - .num_inst = 1, -}; - -static struct platform_device acm_device = { - .name = "acm", - .id = -1, - .dev = { - .platform_data = &acm_pdata, - }, -}; - -static struct tegra_utmip_config utmi_phy_config[] = { - [0] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 15, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, - [1] = { - .hssync_start_delay = 0, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 8, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static struct tegra_ulpi_config ulpi_phy_config = { - .reset_gpio = TEGRA_GPIO_PG2, - .clk = "clk_dev2", -}; - -static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { - [0] = { - .phy_config = &utmi_phy_config[0], - .operating_mode = TEGRA_USB_OTG, - .power_down_on_bus_suspend = 0, - }, - [1] = { - .phy_config = &ulpi_phy_config, - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - }, - [2] = { - .phy_config = &utmi_phy_config[1], - .operating_mode = TEGRA_USB_HOST, - .power_down_on_bus_suspend = 1, - }, -}; - -/* bq24617 charger */ -static struct resource bq24617_resources[] = { - [0] = { - .name = "stat1", - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV5), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV5), - }, - [1] = { - .name = "stat2", - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PD1), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PD1), - }, - [2] = { - .name = "detect", - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - }, -}; - -static struct resource bq24617_resources_m1_p0[] = { - [0] = { - .name = "stat1", - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV5), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV5), - }, - [1] = { - .name = "stat2", - .flags = IORESOURCE_IRQ, - .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - }, -}; - -static struct platform_device bq24617_device = { - .name = "bq24617", - .id = -1, - .resource = bq24617_resources, - .num_resources = ARRAY_SIZE(bq24617_resources), -}; - -static struct resource tegra_gart_resources[] = { - { - .name = "mc", - .flags = IORESOURCE_MEM, - .start = TEGRA_MC_BASE, - .end = TEGRA_MC_BASE + TEGRA_MC_SIZE - 1, - }, - { - .name = "gart", - .flags = IORESOURCE_MEM, - .start = 0x58000000, - .end = 0x58000000 - 1 + 32 * 1024 * 1024, - } -}; - - -static struct platform_device tegra_gart_dev = { - .name = "tegra_gart", - .id = -1, - .num_resources = ARRAY_SIZE(tegra_gart_resources), - .resource = tegra_gart_resources -}; - -static struct platform_device bcm4329_bluetooth_device = { - .name = "bcm4329_bluetooth", - .id = -1, -}; - -static struct platform_device tegra_camera = { - .name = "tegra_camera", - .id = -1, -}; - -static struct tegra_w1_timings tegra_w1_platform_timings = { - .tsu = 0x1, - .trelease = 0xf, - .trdv = 0xf, - .tlow0 = 0x3c, - .tlow1 = 0x1, - .tslot = 0x78, - - .tpdl = 0x3c, - .tpdh = 0x1e, - .trstl = 0x1ea, - .trsth = 0x1df, - - .rdsclk = 0x7, - .psclk = 0x50, -}; - -static struct tegra_w1_platform_data tegra_w1_pdata = { - .clk_id = NULL, - .timings = &tegra_w1_platform_timings, -}; - -static struct resource ram_console_resources[] = { - { - /* .start and .end filled in later */ - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device ram_console_device = { - .name = "ram_console", - .id = -1, - .num_resources = ARRAY_SIZE(ram_console_resources), - .resource = ram_console_resources, -}; - -static struct nvmap_platform_carveout stingray_carveouts[] = { - [0] = { - .name = "iram", - .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM, - .base = TEGRA_IRAM_BASE, - .size = TEGRA_IRAM_SIZE, - .buddy_size = 0, - }, - [1] = { - .name = "generic-0", - .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC, - /* .base and .size to be filled in later */ - .buddy_size = SZ_32K, - }, -}; - -static struct nvmap_platform_data stingray_nvmap_data = { - .carveouts = stingray_carveouts, - .nr_carveouts = ARRAY_SIZE(stingray_carveouts), -}; - -static struct platform_device stingray_nvmap_device = { - .name = "tegra-nvmap", - .id = -1, - .dev = { - .platform_data = &stingray_nvmap_data, - }, -}; - -static struct tegra_hsuart_platform_data tegra_uartc_pdata = { - .exit_lpm_cb = bcm_bt_lpm_exit_lpm_locked, - .rx_done_cb = bcm_bt_rx_done_locked, -}; - -static struct platform_device *stingray_devices[] __initdata = { - &cpcap_otg, - &bq24617_device, - &bcm4329_bluetooth_device, - &tegra_uarta_device, - &tegra_uartc_device, - &tegra_uartd_device, - &tegra_uarte_device, - &tegra_spi_device1, - &tegra_spi_device2, - &tegra_spi_device3, - &tegra_spi_device4, - &tegra_gart_dev, - &stingray_nvmap_device, - &tegra_grhost_device, - &ram_console_device, - &tegra_camera, - &tegra_i2s_device1, - &tegra_i2s_device2, - &mdm6600_modem, - &tegra_spdif_device, - &tegra_avp_device, - &pmu_device, - &tegra_aes_device, - &tegra_wdt_device, -}; - -extern struct tegra_sdhci_platform_data stingray_wifi_data; /* sdhci2 */ - -static struct tegra_sdhci_platform_data stingray_sdhci_sdcard_platform_data = { - .clk_id = NULL, - .force_hs = 0, - .cd_gpio = TEGRA_GPIO_PI5, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static struct tegra_sdhci_platform_data stingray_sdhci_platform_data4 = { - .clk_id = NULL, - .force_hs = 0, - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static struct tegra_i2c_platform_data stingray_i2c1_platform_data = { - .adapter_nr = 0, - .bus_count = 1, - .bus_clk_rate = { 400000 }, -}; - -static struct tegra_i2c_platform_data stingray_i2c2_platform_data = { - .adapter_nr = 1, - .bus_count = 1, -}; - -static struct tegra_i2c_platform_data stingray_i2c3_platform_data = { - .adapter_nr = 2, - .bus_count = 1, - .bus_clk_rate = { 400000 }, -}; - -static struct tegra_i2c_platform_data stingray_i2c4_platform_data = { - .adapter_nr = 3, - .bus_count = 1, - .bus_clk_rate = { 400000 }, - .is_dvc = true, -}; - -static __initdata struct tegra_clk_init_table stingray_clk_init_table[] = { - /* name parent rate enabled */ - { "uartb", "clk_m", 26000000, true}, - { "uartc", "pll_m", 600000000, false}, - /*{ "emc", "pll_p", 0, true}, - { "emc", "pll_m", 600000000, false},*/ - { "pll_m", NULL, 600000000, true}, - { "mpe", "pll_m", 250000000, false}, - { "pll_a", NULL, 56448000, false}, - { "pll_a_out0", NULL, 11289600, false}, - { "i2s1", "pll_p", 24000000, false}, - { "i2s2", "pll_p", 2000000, false}, - { "sdmmc2", "pll_m", 48000000, false}, - { "spdif_out", "pll_a_out0", 5644800, false}, - { NULL, NULL, 0, 0}, -}; - -static void stingray_i2c_init(void) -{ - tegra_i2c_device1.dev.platform_data = &stingray_i2c1_platform_data; - tegra_i2c_device2.dev.platform_data = &stingray_i2c2_platform_data; - tegra_i2c_device3.dev.platform_data = &stingray_i2c3_platform_data; - tegra_i2c_device4.dev.platform_data = &stingray_i2c4_platform_data; - - platform_device_register(&tegra_i2c_device1); - platform_device_register(&tegra_i2c_device2); - platform_device_register(&tegra_i2c_device3); - platform_device_register(&tegra_i2c_device4); -} - -static void stingray_sdhci_init(void) -{ - /* TODO: setup GPIOs for cd, wd, and power */ - tegra_sdhci_device2.dev.platform_data = &stingray_wifi_data; - tegra_sdhci_device3.dev.platform_data = &stingray_sdhci_sdcard_platform_data; - tegra_sdhci_device4.dev.platform_data = &stingray_sdhci_platform_data4; - - platform_device_register(&tegra_sdhci_device2); - platform_device_register(&tegra_sdhci_device3); - platform_device_register(&tegra_sdhci_device4); -} -#define ATAG_BDADDR 0x43294329 /* stingray bluetooth address tag */ -#define ATAG_BDADDR_SIZE 4 -#define BDADDR_STR_SIZE 18 - -static char bdaddr[BDADDR_STR_SIZE]; - -module_param_string(bdaddr, bdaddr, sizeof(bdaddr), 0400); -MODULE_PARM_DESC(bdaddr, "bluetooth address"); - -static int __init parse_tag_bdaddr(const struct tag *tag) -{ - unsigned char *b = (unsigned char *)&tag->u; - - if (tag->hdr.size != ATAG_BDADDR_SIZE) - return -EINVAL; - - snprintf(bdaddr, BDADDR_STR_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", - b[0], b[1], b[2], b[3], b[4], b[5]); - - return 0; -} -__tagtable(ATAG_BDADDR, parse_tag_bdaddr); - -static DEFINE_SPINLOCK(brcm_4329_enable_lock); -static int brcm_4329_enable_count; - -static void stingray_w1_init(void) -{ - tegra_w1_device.dev.platform_data = &tegra_w1_pdata; - platform_device_register(&tegra_w1_device); -} - -/* powerup reason */ -#define ATAG_POWERUP_REASON 0xf1000401 -#define ATAG_POWERUP_REASON_SIZE 3 /* size + tag id + tag data */ - -static unsigned int powerup_reason = PU_REASON_PWR_KEY_PRESS; - -unsigned int stingray_powerup_reason (void) -{ - return powerup_reason; -} - -static int __init parse_tag_powerup_reason(const struct tag *tag) -{ - if (tag->hdr.size != ATAG_POWERUP_REASON_SIZE) - return -EINVAL; - memcpy(&powerup_reason, &tag->u, sizeof(powerup_reason)); - printk(KERN_INFO "powerup reason=0x%08x\n", powerup_reason); - return 0; -} -__tagtable(ATAG_POWERUP_REASON, parse_tag_powerup_reason); - -#define BOOT_MODE_MAX_LEN 30 -static char boot_mode[BOOT_MODE_MAX_LEN + 1]; -int __init board_boot_mode_init(char *s) -{ - strncpy(boot_mode, s, BOOT_MODE_MAX_LEN); - boot_mode[BOOT_MODE_MAX_LEN] = '\0'; - printk(KERN_INFO "boot_mode=%s\n", boot_mode); - return 1; -} -__setup("androidboot.mode=", board_boot_mode_init); - -#define SERIAL_NUMBER_LENGTH 16 -static char usb_serial_num[SERIAL_NUMBER_LENGTH + 1]; -static int __init mot_usb_serial_num_setup(char *options) -{ - strncpy(usb_serial_num, options, SERIAL_NUMBER_LENGTH); - usb_serial_num[SERIAL_NUMBER_LENGTH] = '\0'; - printk(KERN_INFO "usb_serial_num=%s\n", usb_serial_num); - return 1; -} -__setup("androidboot.serialno=", mot_usb_serial_num_setup); - -static int mot_boot_recovery = 0; -static int __init mot_bm_recovery_setup(char *options) -{ - mot_boot_recovery = 1; - return 1; -} -__setup("rec", mot_bm_recovery_setup); - -#define PRODUCT_TYPE_MAX_LEN 4 -static char product_type[PRODUCT_TYPE_MAX_LEN + 1] = "cw"; -static int __init stingray_product_type_parse(char *s) -{ - strncpy(product_type, s, PRODUCT_TYPE_MAX_LEN); - product_type[PRODUCT_TYPE_MAX_LEN] = '\0'; - printk(KERN_INFO "product_type=%s\n", product_type); - - return 1; -} -__setup("product_type=", stingray_product_type_parse); - -bool stingray_hw_has_cdma(void) -{ - return strstr(product_type, "c") != NULL; -} - -bool stingray_hw_has_lte(void) -{ - return strstr(product_type, "l") != NULL; -} - -bool stingray_hw_has_wifi(void) -{ - return strstr(product_type, "w") != NULL; -} - -bool stingray_hw_has_umts(void) -{ - return strstr(product_type, "u") != NULL; -} - -static void stingray_usb_init(void) -{ - char *src; - int i; - - struct android_usb_platform_data *platform_data; - - int factorycable = !strncmp(boot_mode, "factorycable", - BOOT_MODE_MAX_LEN); - - tegra_udc_device.dev.platform_data = &tegra_udc_pdata; - tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; - tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; - - if (!(factorycable && mot_boot_recovery)) - platform_device_register(&tegra_udc_device); - - if (stingray_hw_has_cdma()) - platform_device_register(&tegra_ehci2_device); - - platform_device_register(&tegra_ehci3_device); - -#ifdef CONFIG_USB_ANDROID_RNDIS - src = usb_serial_num; - - /* create a fake MAC address from our serial number. - * first byte is 0x02 to signify locally administered. - */ - rndis_pdata.ethaddr[0] = 0x02; - for (i = 0; *src; i++) { - /* XOR the USB serial across the remaining bytes */ - rndis_pdata.ethaddr[i % (ETH_ALEN - 1) + 1] ^= *src++; - } - platform_device_register(&rndis_device); -#endif - - if (!(factorycable && mot_boot_recovery)) { - if (factorycable) { - platform_data = &andusb_plat_factory; - platform_device_register(&usbnet_device); - } else if (!strncmp(boot_mode, "bp-tools", - BOOT_MODE_MAX_LEN)) { - platform_data = &andusb_plat_bp; - platform_device_register(&usbnet_device); - /* acm: LTE Modem + QC Modem + QC Diag */ - acm_pdata.num_inst = 3; - platform_device_register(&acm_device); - } else { - platform_data = &andusb_plat; - } - - if (stingray_hw_has_lte()) - platform_data->product_name = USB_PRODUCT_NAME_LTE; - else if (stingray_hw_has_cdma()) - platform_data->product_name = USB_PRODUCT_NAME; - else - platform_data->product_name = USB_PRODUCT_NAME_WIFI_ONLY; - - platform_data->serial_number = usb_serial_num; - androidusb_device.dev.platform_data = platform_data; - platform_device_register(&androidusb_device); - } -} - -static void stingray_reset(char mode, const char *cmd) -{ - /* Signal to CPCAP to stop the uC. */ - gpio_set_value(TEGRA_GPIO_PG3, 0); - mdelay(100); - gpio_set_value(TEGRA_GPIO_PG3, 1); - mdelay(100); - - tegra_assert_system_reset(); -} - -static void stingray_power_off(void) -{ - printk(KERN_INFO "stingray_pm_power_off...\n"); - - local_irq_disable(); - - /* signal WDI gpio to shutdown CPCAP, which will - cascade to all of the regulators. */ - gpio_direction_output(TEGRA_GPIO_PV7, 0); - - do {} while (1); - - local_irq_enable(); -} - -static void __init stingray_power_off_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PG3); - gpio_request(TEGRA_GPIO_PG3, "sys_restart_b"); - gpio_direction_output(TEGRA_GPIO_PG3, 1); - tegra_reset = stingray_reset; - - tegra_gpio_enable(TEGRA_GPIO_PV7); - if (!gpio_request(TEGRA_GPIO_PV7, "wdi")) - pm_power_off = stingray_power_off; -} - -static unsigned int stingray_board_revision = STINGRAY_REVISION_UNKNOWN; - -unsigned int stingray_revision(void) -{ - return stingray_board_revision; -} - -static int __init stingray_revision_parse(char *options) -{ - if (!strcmp(options, "m1")) - stingray_board_revision = STINGRAY_REVISION_M1; - else if (!strcmp(options, "p0")) - stingray_board_revision = STINGRAY_REVISION_P0; - else if (!strcmp(options, "p1")) - stingray_board_revision = STINGRAY_REVISION_P1; - else if (!strcmp(options, "p2")) - stingray_board_revision = STINGRAY_REVISION_P2; - else if (!strcmp(options, "p3")) - stingray_board_revision = STINGRAY_REVISION_P3; - else - stingray_board_revision = system_rev; - - printk(KERN_INFO "hw_rev=0x%x\n", stingray_board_revision); - - return 1; -} -__setup("hw_rev=", stingray_revision_parse); - -int stingray_qbp_usb_hw_bypass_enabled(void) -{ - /* We could use the boot_mode string instead of probing the HW, but - * that would not work if we enable run-time switching to this mode - * in the future. - */ - if (gpio_get_value(TEGRA_GPIO_PT3) && !gpio_get_value(TEGRA_GPIO_PV4)) { - pr_info("stingray_qbp_usb_hw_bypass enabled\n"); - return 1; - } - return 0; -} - -static struct tegra_suspend_platform_data stingray_suspend = { - .cpu_timer = 1500, - .cpu_off_timer = 1, - .core_timer = 0x7e7e, - .core_off_timer = 0xf, - .separate_req = true, - .corereq_high = true, - .sysclkreq_high = true, - .suspend_mode = TEGRA_SUSPEND_LP0, -}; - -static void *das_base = IO_ADDRESS(TEGRA_APB_MISC_BASE); - -static inline void das_writel(unsigned long value, unsigned long offset) -{ - writel(value, das_base + offset); -} - -#define APB_MISC_DAS_DAP_CTRL_SEL_0 0xc00 -#define APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0 0xc40 - -static void init_dac1(void) -{ - bool master = tegra_audio_pdata.i2s_master; - /* DAC1 -> DAP1 */ - das_writel((!master)<<31, APB_MISC_DAS_DAP_CTRL_SEL_0); - das_writel(0, APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0); -} - -static void init_dac2(bool bluetooth) -{ - if (!bluetooth) { - /* DAC2 -> DAP2 for CPCAP CODEC */ - bool master = tegra_audio2_pdata.i2s_master; - das_writel((!master)<<31 | 1, APB_MISC_DAS_DAP_CTRL_SEL_0 + 4); - das_writel(1<<28 | 1<<24 | 1, - APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0 + 4); - } else { - /* DAC2 -> DAP4 for Bluetooth Voice */ - bool master = tegra_audio2_pdata.dsp_master; - das_writel((!master)<<31 | 1, APB_MISC_DAS_DAP_CTRL_SEL_0 + 12); - das_writel(3<<28 | 3<<24 | 3, - APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0 + 4); - } -} - -void change_power_brcm_4329(bool enable) { - unsigned long flags; - - spin_lock_irqsave(&brcm_4329_enable_lock, flags); - if (enable) { - gpio_set_value(TEGRA_GPIO_PU4, enable); - brcm_4329_enable_count++; - // The following shouldn't happen but protect - // if the user doesn't cleanup. - if (brcm_4329_enable_count > 2) - brcm_4329_enable_count = 2; - } else { - if (brcm_4329_enable_count > 0) - brcm_4329_enable_count--; - if (!brcm_4329_enable_count) - gpio_set_value(TEGRA_GPIO_PU4, enable); - } - spin_unlock_irqrestore(&brcm_4329_enable_lock, flags); -} - -static void __init tegra_stingray_init(void) -{ - struct clk *clk; - struct resource *res; - - /* force consoles to stay enabled across suspend/resume */ - console_suspend_enabled = 0; - - tegra_common_init(); - tegra_init_suspend(&stingray_suspend); - stingray_init_emc(); - - /* Set the SDMMC2 (wifi) tap delay to 6. This value is determined - * based on propagation delay on the PCB traces. */ - clk = clk_get_sys("sdhci-tegra.1", NULL); - if (!IS_ERR(clk)) { - tegra_sdmmc_tap_delay(clk, 6); - clk_put(clk); - } else { - pr_err("Failed to set wifi sdmmc tap delay\n"); - } - - /* Stingray has a USB switch that disconnects the usb port from the T20 - unless a factory cable is used, the factory jumper is set, or the - usb_data_en gpio is set. - */ - if (!stingray_qbp_usb_hw_bypass_enabled()) { - tegra_gpio_enable(TEGRA_GPIO_PV4); - gpio_request(TEGRA_GPIO_PV4, "usb_data_en"); - gpio_direction_output(TEGRA_GPIO_PV4, 1); - } - - /* USB_FORCEON_N (TEGRA_GPIO_PC5) should be forced high at boot - and will be pulled low by the hardware on attach */ - tegra_gpio_enable(TEGRA_GPIO_PC5); - gpio_request(TEGRA_GPIO_PC5, "usb_forceon_n"); - gpio_direction_output(TEGRA_GPIO_PC5, 1); - gpio_export(TEGRA_GPIO_PC5, false); - - tegra_gpio_enable(TEGRA_GPIO_PQ6); - gpio_request(TEGRA_GPIO_PQ6, "usb_bp_rem_wake"); - gpio_direction_input(TEGRA_GPIO_PQ6); - gpio_export(TEGRA_GPIO_PQ6, false); - - /* Enable charging */ - tegra_gpio_enable(TEGRA_GPIO_PV5); - gpio_request(TEGRA_GPIO_PV5, "chg_stat1"); - gpio_direction_input(TEGRA_GPIO_PV5); - gpio_export(TEGRA_GPIO_PV5, false); - if (stingray_revision() <= STINGRAY_REVISION_P0) { - bq24617_device.resource = bq24617_resources_m1_p0; - bq24617_device.num_resources = ARRAY_SIZE(bq24617_resources_m1_p0); - - tegra_gpio_enable(TEGRA_GPIO_PV6); - gpio_request(TEGRA_GPIO_PV6, "chg_stat2"); - gpio_direction_input(TEGRA_GPIO_PV6); - gpio_export(TEGRA_GPIO_PV6, false); - - tegra_gpio_enable(TEGRA_GPIO_PJ0); - gpio_request(TEGRA_GPIO_PJ0, "chg_disable"); - gpio_direction_output(TEGRA_GPIO_PJ0, 0); - gpio_export(TEGRA_GPIO_PJ0, false); - } else { - tegra_gpio_enable(TEGRA_GPIO_PV6); - gpio_request(TEGRA_GPIO_PV6, "chg_detect"); - gpio_direction_input(TEGRA_GPIO_PV6); - gpio_export(TEGRA_GPIO_PV6, false); - - tegra_gpio_enable(TEGRA_GPIO_PD1); - gpio_request(TEGRA_GPIO_PD1, "chg_stat2"); - gpio_direction_input(TEGRA_GPIO_PD1); - gpio_export(TEGRA_GPIO_PD1, false); - - if (stingray_revision() >= STINGRAY_REVISION_P2) { - tegra_gpio_enable(TEGRA_GPIO_PS7); - gpio_request(TEGRA_GPIO_PS7, "chg_disable"); - gpio_direction_output(TEGRA_GPIO_PS7, 0); - gpio_export(TEGRA_GPIO_PS7, false); - } else { - tegra_gpio_enable(TEGRA_GPIO_PI4); - gpio_request(TEGRA_GPIO_PI4, "chg_disable"); - gpio_direction_output(TEGRA_GPIO_PI4, 0); - gpio_export(TEGRA_GPIO_PI4, false); - } - } - - /* Enable charge LEDs */ - if (stingray_revision() >= STINGRAY_REVISION_P2) { - tegra_gpio_enable(TEGRA_GPIO_PV0); - gpio_request(TEGRA_GPIO_PV0, "chg_led_disable"); - gpio_direction_output(TEGRA_GPIO_PV0, 0); - gpio_export(TEGRA_GPIO_PV0, false); - } else if (stingray_revision() >= STINGRAY_REVISION_P0) { - /* Set the SYS_CLK_REQ override bit to allow PZ5 to be used - as a GPIO. */ - writel(0, IO_TO_VIRT(TEGRA_PMC_BASE + 0x01C)); - tegra_gpio_enable(TEGRA_GPIO_PZ5); - gpio_request(TEGRA_GPIO_PZ5, "chg_led_disable"); - gpio_direction_output(TEGRA_GPIO_PZ5, 0); - gpio_export(TEGRA_GPIO_PZ5, false); - } - - if (stingray_revision() <= STINGRAY_REVISION_P1) { - pr_info("Disabling core dvfs on P1 hardware\n"); - tegra_dvfs_rail_disable_by_name("vdd_core"); - } - - /* disable spdif GPIO for now */ - /* spdif line is turned on but never used, this causes pops - on a speaker dock connected to HDMI monitor, later version - h/w with spdif audio out will need this pin */ - tegra_gpio_enable(TEGRA_GPIO_PD4); - gpio_request(TEGRA_GPIO_PD4, "spdif_enable"); - gpio_direction_output(TEGRA_GPIO_PD4, 0); - gpio_export(TEGRA_GPIO_PD4, false); - - /* Enable 4329 Power GPIO */ - tegra_gpio_enable(TEGRA_GPIO_PU4); - gpio_request(TEGRA_GPIO_PU4, "4329_pwr"); - gpio_direction_output(TEGRA_GPIO_PU4, 0); - - /* Enable GPIO for SD card detect */ - tegra_gpio_enable(TEGRA_GPIO_PI5); - gpio_request(TEGRA_GPIO_PI5, "sdcard_detect"); - gpio_direction_input(TEGRA_GPIO_PI5); - - stingray_pinmux_init(); - - tegra_clk_init_from_table(stingray_clk_init_table); - - clk = tegra_get_clock_by_name("uartb"); - tegra_serial_debug_init(TEGRA_UARTB_BASE, INT_UARTB, - clk, INT_QUAD_RES_31, -1); - - init_dac1(); - init_dac2(false); - tegra_i2s_device1.dev.platform_data = &tegra_audio_pdata; - tegra_i2s_device2.dev.platform_data = &tegra_audio2_pdata; - cpcap_device_register(&cpcap_audio_device); - tegra_spdif_device.dev.platform_data = &tegra_spdif_pdata; - - tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0]; - tegra_uartc_device.dev.platform_data = &tegra_uartc_pdata; - - res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0); - res->start = ramconsole_start; - res->end = ramconsole_start + ramconsole_size - 1; - - stingray_carveouts[1].base = tegra_carveout_start; - stingray_carveouts[1].size = tegra_carveout_size; - - platform_add_devices(stingray_devices, ARRAY_SIZE(stingray_devices)); - - stingray_i2c_init(); - stingray_power_off_init(); - stingray_keypad_init(); - stingray_touch_init(); - stingray_power_init(); - stingray_panel_init(); - stingray_sdhci_init(); - stingray_w1_init(); - stingray_sensors_init(); - stingray_wlan_init(); - stingray_gps_init(); - stingray_usb_init(); -} - -int __init stingray_protected_aperture_init(void) -{ - tegra_protected_aperture_init(tegra_grhost_aperture); - memblock_free(tegra_bootloader_fb_start, tegra_bootloader_fb_size); - return 0; -} -late_initcall(stingray_protected_aperture_init); - -void __init stingray_map_io(void) -{ - tegra_map_common_io(); -} - -static int __init stingray_ramconsole_arg(char *options) -{ - char *p = options; - - ramconsole_size = memparse(p, &p); - if (*p == '@') - ramconsole_start = memparse(p+1, &p); - - return 0; -} -early_param("ramconsole", stingray_ramconsole_arg); - -void __init stingray_reserve(void) -{ - long ret; - if (memblock_reserve(0x0, 4096) < 0) - pr_warn("Cannot reserve first 4K of memory for safety\n"); - - ret = memblock_remove(SZ_512M - SZ_2M, SZ_2M); - if (ret) - pr_info("Failed to remove ram console\n"); - else - pr_info("Reserved %08lx@%08lx for ram console\n", - ramconsole_start, ramconsole_size); - - tegra_reserve(SZ_256M, SZ_8M, SZ_16M); - - if (memblock_reserve(tegra_bootloader_fb_start, tegra_bootloader_fb_size)) - pr_info("Failed to reserve old framebuffer location\n"); - else - pr_info("HACK: Old framebuffer: %08lx - %08lx\n", - tegra_bootloader_fb_start, - tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1); -} - -MACHINE_START(STINGRAY, "stingray") - .boot_params = 0x00000100, - .phys_io = IO_APB_PHYS, - .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc, - .init_irq = tegra_init_irq, - .init_machine = tegra_stingray_init, - .map_io = stingray_map_io, - .reserve = stingray_reserve, - .timer = &tegra_timer, -MACHINE_END diff --git a/arch/arm/mach-tegra/board-stingray.h b/arch/arm/mach-tegra/board-stingray.h deleted file mode 100644 index 74c4641d3294..000000000000 --- a/arch/arm/mach-tegra/board-stingray.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * arch/arm/mach-tegra/board-stingray.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_TEGRA_BOARD_STINGRAY_H -#define _MACH_TEGRA_BOARD_STINGRAY_H - -void stingray_fb_alloc(void); - -void stingray_pinmux_init(void); -int stingray_panel_init(void); -int stingray_keypad_init(void); -int stingray_wlan_init(void); -int stingray_sensors_init(void); -int stingray_touch_init(void); -int stingray_power_init(void); -unsigned int stingray_revision(void); -unsigned int stingray_powerup_reason (void); -void stingray_gps_init(void); -int stingray_qbp_usb_hw_bypass_enabled(void); -void stingray_init_emc(void); -void change_power_brcm_4329(bool); - -bool stingray_hw_has_cdma(void); -bool stingray_hw_has_lte(void); -bool stingray_hw_has_wifi(void); -bool stingray_hw_has_umts(void); - -/* as defined in the bootloader*/ -#define HWREV(x) (((x)>>16) & 0xFFFF) -#define INSTANCE(x) ((x) & 0xFFFF) -#define _HWREV(x) ((x)<<16) -#define STINGRAY_REVISION_UNKNOWN _HWREV(0x0000) -#define SSTINGRAY_REVISION_DEF _HWREV(0xFF00) -#define STINGRAY_REVISION_S1 _HWREV(0x1100) -#define STINGRAY_REVISION_S2 _HWREV(0x1200) -#define STINGRAY_REVISION_S3 _HWREV(0x1300) -#define STINGRAY_REVISION_M1 _HWREV(0x2100) -#define STINGRAY_REVISION_M2 _HWREV(0x2200) -#define STINGRAY_REVISION_M3 _HWREV(0x2300) -#define STINGRAY_REVISION_P0 _HWREV(0x8000) -#define STINGRAY_REVISION_P1 _HWREV(0x8100) -#define STINGRAY_REVISION_P2 _HWREV(0x8200) -#define STINGRAY_REVISION_P3 _HWREV(0x8300) -#define STINGRAY_REVISION_P4 _HWREV(0x8400) -#define STINGRAY_REVISION_P5 _HWREV(0x8500) -#define STINGRAY_REVISION_P6 _HWREV(0x8600) - -/* - * These #defines are used for the bits in powerup_reason. - */ -#define PU_REASON_USB_CABLE 0x00000010 /* Bit 4 */ -#define PU_REASON_FACTORY_CABLE 0x00000020 /* Bit 5 */ -#define PU_REASON_PWR_KEY_PRESS 0x00000080 /* Bit 7 */ -#define PU_REASON_CHARGER 0x00000100 /* Bit 8 */ -#define PU_REASON_POWER_CUT 0x00000200 /* bit 9 */ -#define PU_REASON_SW_AP_RESET 0x00004000 /* Bit 14 */ -#define PU_REASON_WDOG_AP_RESET 0x00008000 /* Bit 15 */ -#define PU_REASON_AP_KERNEL_PANIC 0x00020000 /* Bit 17 */ - - -#endif diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c deleted file mode 100644 index f3e75e25bf6b..000000000000 --- a/arch/arm/mach-tegra/board-ventana-panel.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * arch/arm/mach-tegra/board-ventana-panel.c - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "devices.h" -#include "gpio-names.h" - -#define ventana_bl_enb TEGRA_GPIO_PD4 -#define ventana_lvds_shutdown TEGRA_GPIO_PB2 -#define ventana_hdmi_hpd TEGRA_GPIO_PN7 -#define ventana_hdmi_enb TEGRA_GPIO_PV5 - -static int ventana_backlight_init(struct device *dev) { - int ret; - - ret = gpio_request(ventana_bl_enb, "backlight_enb"); - if (ret < 0) - return ret; - - ret = gpio_direction_output(ventana_bl_enb, 1); - if (ret < 0) - gpio_free(ventana_bl_enb); - else - tegra_gpio_enable(ventana_bl_enb); - - return ret; -}; - -static void ventana_backlight_exit(struct device *dev) { - gpio_set_value(ventana_bl_enb, 0); - gpio_free(ventana_bl_enb); - tegra_gpio_disable(ventana_bl_enb); -} - -static int ventana_backlight_notify(struct device *unused, int brightness) -{ - gpio_set_value(ventana_bl_enb, !!brightness); - return brightness; -} - -static struct platform_pwm_backlight_data ventana_backlight_data = { - .pwm_id = 2, - .max_brightness = 255, - .dft_brightness = 224, - .pwm_period_ns = 5000000, - .init = ventana_backlight_init, - .exit = ventana_backlight_exit, - .notify = ventana_backlight_notify, -}; - -static struct platform_device ventana_backlight_device = { - .name = "pwm-backlight", - .id = -1, - .dev = { - .platform_data = &ventana_backlight_data, - }, -}; - -static int ventana_panel_enable(void) -{ - static struct regulator *reg = NULL; - - if (reg == NULL) { - reg = regulator_get(NULL, "avdd_lvds"); - if (WARN_ON(IS_ERR(reg))) - pr_err("%s: couldn't get regulator avdd_lvds: %ld\n", - __func__, PTR_ERR(reg)); - else - regulator_enable(reg); - } - - gpio_set_value(ventana_lvds_shutdown, 1); - return 0; -} - -static int ventana_panel_disable(void) -{ - gpio_set_value(ventana_lvds_shutdown, 0); - return 0; -} - -static int ventana_hdmi_enable(void) -{ - gpio_set_value(ventana_hdmi_enb, 1); - return 0; -} - -static int ventana_hdmi_disable(void) -{ - gpio_set_value(ventana_hdmi_enb, 0); - return 0; -} - -static struct resource ventana_disp1_resources[] = { - { - .name = "irq", - .start = INT_DISPLAY_GENERAL, - .end = INT_DISPLAY_GENERAL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "regs", - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, - .flags = IORESOURCE_MEM, - }, - { - .name = "fbmem", - .start = 0x18012000, - .end = 0x18414000 - 1, /* enough for 1080P 16bpp */ - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource ventana_disp2_resources[] = { - { - .name = "irq", - .start = INT_DISPLAY_B_GENERAL, - .end = INT_DISPLAY_B_GENERAL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "regs", - .start = TEGRA_DISPLAY2_BASE, - .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "fbmem", - .flags = IORESOURCE_MEM, - .start = 0x18414000, - .end = 0x18BFD000 - 1, - }, - { - .name = "hdmi_regs", - .start = TEGRA_HDMI_BASE, - .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_dc_mode ventana_panel_modes[] = { - { - .pclk = 62200000, - .h_ref_to_sync = 11, - .v_ref_to_sync = 1, - .h_sync_width = 58, - .v_sync_width = 4, - .h_back_porch = 58, - .v_back_porch = 4, - .h_active = 1366, - .v_active = 768, - .h_front_porch = 58, - .v_front_porch = 4, - }, -}; - -static struct tegra_fb_data ventana_fb_data = { - .win = 0, - .xres = 1366, - .yres = 768, - .bits_per_pixel = 16, -}; - -static struct tegra_fb_data ventana_hdmi_fb_data = { - .win = 0, - .xres = 1280, - .yres = 720, - .bits_per_pixel = 16, -}; - -static struct tegra_dc_out ventana_disp1_out = { - .type = TEGRA_DC_OUT_RGB, - - .align = TEGRA_DC_ALIGN_MSB, - .order = TEGRA_DC_ORDER_RED_BLUE, - - .modes = ventana_panel_modes, - .n_modes = ARRAY_SIZE(ventana_panel_modes), - - .enable = ventana_panel_enable, - .disable = ventana_panel_disable, -}; - -static struct tegra_dc_out ventana_disp2_out = { - .type = TEGRA_DC_OUT_HDMI, - .flags = TEGRA_DC_OUT_HOTPLUG_HIGH, - - .dcc_bus = 1, - .hotplug_gpio = ventana_hdmi_hpd, - - .align = TEGRA_DC_ALIGN_MSB, - .order = TEGRA_DC_ORDER_RED_BLUE, - - .enable = ventana_hdmi_enable, - .disable = ventana_hdmi_disable, -}; - -static struct tegra_dc_platform_data ventana_disp1_pdata = { - .flags = TEGRA_DC_FLAG_ENABLED, - .default_out = &ventana_disp1_out, - .fb = &ventana_fb_data, -}; - -static struct tegra_dc_platform_data ventana_disp2_pdata = { - .flags = TEGRA_DC_FLAG_ENABLED, - .default_out = &ventana_disp2_out, - .fb = &ventana_hdmi_fb_data, -}; - -static struct nvhost_device ventana_disp1_device = { - .name = "tegradc", - .id = 0, - .resource = ventana_disp1_resources, - .num_resources = ARRAY_SIZE(ventana_disp1_resources), - .dev = { - .platform_data = &ventana_disp1_pdata, - }, -}; - -static struct nvhost_device ventana_disp2_device = { - .name = "tegradc", - .id = 1, - .resource = ventana_disp2_resources, - .num_resources = ARRAY_SIZE(ventana_disp2_resources), - .dev = { - .platform_data = &ventana_disp2_pdata, - }, -}; - -static struct nvmap_platform_carveout ventana_carveouts[] = { - [0] = { - .name = "iram", - .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM, - .base = TEGRA_IRAM_BASE, - .size = TEGRA_IRAM_SIZE, - .buddy_size = 0, /* no buddy allocation for IRAM */ - }, - [1] = { - .name = "generic-0", - .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC, - .base = 0x18C00000, - .size = SZ_128M - 0xC00000, - .buddy_size = SZ_32K, - }, -}; - -static struct nvmap_platform_data ventana_nvmap_data = { - .carveouts = ventana_carveouts, - .nr_carveouts = ARRAY_SIZE(ventana_carveouts), -}; - -static struct platform_device ventana_nvmap_device = { - .name = "tegra-nvmap", - .id = -1, - .dev = { - .platform_data = &ventana_nvmap_data, - }, -}; - -static struct platform_device *ventana_gfx_devices[] __initdata = { - &ventana_nvmap_device, - &tegra_grhost_device, - &tegra_pwfm2_device, - &ventana_backlight_device, -}; - -int __init ventana_panel_init(void) -{ - int err; - - gpio_request(ventana_lvds_shutdown, "lvds_shdn"); - gpio_direction_output(ventana_lvds_shutdown, 1); - tegra_gpio_enable(ventana_lvds_shutdown); - - gpio_request(ventana_hdmi_enb, "hdmi_5v_en"); - gpio_direction_output(ventana_hdmi_enb, 0); - tegra_gpio_enable(ventana_hdmi_enb); - - gpio_request(ventana_hdmi_hpd, "hdmi_hpd"); - gpio_direction_input(ventana_hdmi_hpd); - tegra_gpio_enable(ventana_hdmi_hpd); - - err = platform_add_devices(ventana_gfx_devices, - ARRAY_SIZE(ventana_gfx_devices)); - - if (!err) - err = nvhost_device_register(&ventana_disp1_device); - - if (!err) - err = nvhost_device_register(&ventana_disp2_device); - - return err; -} - diff --git a/arch/arm/mach-tegra/board-ventana-pinmux.c b/arch/arm/mach-tegra/board-ventana-pinmux.c deleted file mode 100644 index e85034ccda50..000000000000 --- a/arch/arm/mach-tegra/board-ventana-pinmux.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * arch/arm/mach-tegra/board-ventana-pinmux.c - * - * Copyright (C) 2010 NVIDIA Corporation - * - * 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 -#include -#include - -#define DEFAULT_DRIVE(_name) \ - { \ - .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \ - .hsm = TEGRA_HSM_DISABLE, \ - .schmitt = TEGRA_SCHMITT_ENABLE, \ - .drive = TEGRA_DRIVE_DIV_1, \ - .pull_down = TEGRA_PULL_31, \ - .pull_up = TEGRA_PULL_31, \ - .slew_rising = TEGRA_SLEW_SLOWEST, \ - .slew_falling = TEGRA_SLEW_SLOWEST, \ - } - - -static __initdata struct tegra_drive_pingroup_config ventana_drive_pinmux[] = { - DEFAULT_DRIVE(DBG), - DEFAULT_DRIVE(DDC), - DEFAULT_DRIVE(VI1), - DEFAULT_DRIVE(VI2), - DEFAULT_DRIVE(SDIO1), -}; - -static __initdata struct tegra_pingroup_config ventana_pinmux[] = { - {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LCSN, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LDC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LM1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LSC1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSCK, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSDA, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, -}; - -void __init ventana_pinmux_init(void) -{ - tegra_pinmux_config_table(ventana_pinmux, ARRAY_SIZE(ventana_pinmux)); - tegra_drive_pinmux_config_table(ventana_drive_pinmux, - ARRAY_SIZE(ventana_drive_pinmux)); -} diff --git a/arch/arm/mach-tegra/board-ventana-power.c b/arch/arm/mach-tegra/board-ventana-power.c deleted file mode 100644 index fe1af074ab9e..000000000000 --- a/arch/arm/mach-tegra/board-ventana-power.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2010 NVIDIA, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpio-names.h" -#include "power.h" -#include "wakeups-t2.h" -#include "board.h" - -#define PMC_CTRL 0x0 -#define PMC_CTRL_INTR_LOW (1 << 17) - -static struct regulator_consumer_supply tps658621_sm0_supply[] = { - REGULATOR_SUPPLY("vdd_core", NULL), -}; -static struct regulator_consumer_supply tps658621_sm1_supply[] = { - REGULATOR_SUPPLY("vdd_cpu", NULL), -}; -static struct regulator_consumer_supply tps658621_sm2_supply[] = { - REGULATOR_SUPPLY("vdd_sm2", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo0_supply[] = { - REGULATOR_SUPPLY("p_cam_avdd", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo1_supply[] = { - REGULATOR_SUPPLY("avdd_pll", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo2_supply[] = { - REGULATOR_SUPPLY("vdd_rtc", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo3_supply[] = { - REGULATOR_SUPPLY("avdd_usb", NULL), - REGULATOR_SUPPLY("avdd_usb_pll", NULL), - REGULATOR_SUPPLY("avdd_lvds", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo4_supply[] = { - REGULATOR_SUPPLY("avdd_osc", NULL), - REGULATOR_SUPPLY("vddio_sys", "panjit_touch"), -}; -static struct regulator_consumer_supply tps658621_ldo5_supply[] = { - REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.1"), - REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.3"), -}; -static struct regulator_consumer_supply tps658621_ldo6_supply[] = { - REGULATOR_SUPPLY("vddio_vi", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo7_supply[] = { - REGULATOR_SUPPLY("avdd_hdmi", NULL), - REGULATOR_SUPPLY("vdd_fuse", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo8_supply[] = { - REGULATOR_SUPPLY("avdd_hdmi_pll", NULL), -}; -static struct regulator_consumer_supply tps658621_ldo9_supply[] = { - REGULATOR_SUPPLY("avdd_2v85", NULL), - REGULATOR_SUPPLY("vdd_ddr_rx", NULL), - REGULATOR_SUPPLY("avdd_amp", NULL), -}; - -#define REGULATOR_INIT(_id, _minmv, _maxmv) \ - { \ - .constraints = { \ - .min_uV = (_minmv)*1000, \ - .max_uV = (_maxmv)*1000, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL | \ - REGULATOR_MODE_STANDBY), \ - .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ - REGULATOR_CHANGE_STATUS | \ - REGULATOR_CHANGE_VOLTAGE), \ - }, \ - .num_consumer_supplies = ARRAY_SIZE(tps658621_##_id##_supply),\ - .consumer_supplies = tps658621_##_id##_supply, \ - } - -static struct regulator_init_data sm0_data = REGULATOR_INIT(sm0, 725, 1500); -static struct regulator_init_data sm1_data = REGULATOR_INIT(sm1, 725, 1500); -static struct regulator_init_data sm2_data = REGULATOR_INIT(sm2, 3000, 4550); -static struct regulator_init_data ldo0_data = REGULATOR_INIT(ldo0, 1250, 3300); -static struct regulator_init_data ldo1_data = REGULATOR_INIT(ldo1, 725, 1500); -static struct regulator_init_data ldo2_data = REGULATOR_INIT(ldo2, 725, 1500); -static struct regulator_init_data ldo3_data = REGULATOR_INIT(ldo3, 1250, 3300); -static struct regulator_init_data ldo4_data = REGULATOR_INIT(ldo4, 1700, 2475); -static struct regulator_init_data ldo5_data = REGULATOR_INIT(ldo5, 1250, 3300); -static struct regulator_init_data ldo6_data = REGULATOR_INIT(ldo6, 1250, 3300); -static struct regulator_init_data ldo7_data = REGULATOR_INIT(ldo7, 1250, 3300); -static struct regulator_init_data ldo8_data = REGULATOR_INIT(ldo8, 1250, 3300); -static struct regulator_init_data ldo9_data = REGULATOR_INIT(ldo9, 1250, 3300); - -static struct tps6586x_rtc_platform_data rtc_data = { - .irq = TEGRA_NR_IRQS + TPS6586X_INT_RTC_ALM1, -}; - -#define TPS_REG(_id, _data) \ - { \ - .id = TPS6586X_ID_##_id, \ - .name = "tps6586x-regulator", \ - .platform_data = _data, \ - } - -static struct tps6586x_subdev_info tps_devs[] = { - TPS_REG(SM_0, &sm0_data), - TPS_REG(SM_1, &sm1_data), - TPS_REG(SM_2, &sm2_data), - TPS_REG(LDO_0, &ldo0_data), - TPS_REG(LDO_1, &ldo1_data), - TPS_REG(LDO_2, &ldo2_data), - TPS_REG(LDO_3, &ldo3_data), - TPS_REG(LDO_4, &ldo4_data), - TPS_REG(LDO_5, &ldo5_data), - TPS_REG(LDO_6, &ldo6_data), - TPS_REG(LDO_7, &ldo7_data), - TPS_REG(LDO_8, &ldo8_data), - TPS_REG(LDO_9, &ldo9_data), - { - .id = 0, - .name = "tps6586x-rtc", - .platform_data = &rtc_data, - }, -}; - -static struct tps6586x_platform_data tps_platform = { - .irq_base = TEGRA_NR_IRQS, - .num_subdevs = ARRAY_SIZE(tps_devs), - .subdevs = tps_devs, - .gpio_base = TEGRA_NR_GPIOS, -}; - -static struct i2c_board_info __initdata ventana_regulators[] = { - { - I2C_BOARD_INFO("tps6586x", 0x34), - .irq = INT_EXTERNAL_PMU, - .platform_data = &tps_platform, - }, -}; - -static struct tegra_suspend_platform_data ventana_suspend_data = { - .cpu_timer = 2000, - .cpu_off_timer = 0, - .suspend_mode = TEGRA_SUSPEND_LP1, - .core_timer = 0x7e7e, - .core_off_timer = 0, - .separate_req = true, - .corereq_high = false, - .sysclkreq_high = true, - .wake_enb = TEGRA_WAKE_GPIO_PV2, - .wake_high = 0, - .wake_low = TEGRA_WAKE_GPIO_PV2, - .wake_any = 0, -}; - -int __init ventana_regulator_init(void) -{ - void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); - u32 pmc_ctrl; - - /* configure the power management controller to trigger PMU - * interrupts when low */ - pmc_ctrl = readl(pmc + PMC_CTRL); - writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL); - i2c_register_board_info(4, ventana_regulators, 1); - tegra_init_suspend(&ventana_suspend_data); - return 0; -} diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c deleted file mode 100644 index 13ab48b1c7a1..000000000000 --- a/arch/arm/mach-tegra/board-ventana-sdhci.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * arch/arm/mach-tegra/board-harmony-sdhci.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gpio-names.h" -#include "board.h" - -static struct resource sdhci_resource0[] = { - [0] = { - .start = INT_SDMMC1, - .end = INT_SDMMC1, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC1_BASE, - .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource2[] = { - [0] = { - .start = INT_SDMMC3, - .end = INT_SDMMC3, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC3_BASE, - .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource3[] = { - [0] = { - .start = INT_SDMMC4, - .end = INT_SDMMC4, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC4_BASE, - .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = { - .clk_id = NULL, - .force_hs = 1, - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = { - .clk_id = NULL, - .force_hs = 1, - .cd_gpio = TEGRA_GPIO_PI5, - .wp_gpio = TEGRA_GPIO_PH1, - .power_gpio = TEGRA_GPIO_PT3, -}; - -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = { - .clk_id = NULL, - .force_hs = 0, - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = TEGRA_GPIO_PI6, -}; - -static struct platform_device tegra_sdhci_device0 = { - .name = "sdhci-tegra", - .id = 0, - .resource = sdhci_resource0, - .num_resources = ARRAY_SIZE(sdhci_resource0), - .dev = { - .platform_data = &tegra_sdhci_platform_data0, - }, -}; - -static struct platform_device tegra_sdhci_device2 = { - .name = "sdhci-tegra", - .id = 2, - .resource = sdhci_resource2, - .num_resources = ARRAY_SIZE(sdhci_resource2), - .dev = { - .platform_data = &tegra_sdhci_platform_data2, - }, -}; - -static struct platform_device tegra_sdhci_device3 = { - .name = "sdhci-tegra", - .id = 3, - .resource = sdhci_resource3, - .num_resources = ARRAY_SIZE(sdhci_resource3), - .dev = { - .platform_data = &tegra_sdhci_platform_data3, - }, -}; - -int __init ventana_sdhci_init(void) -{ - gpio_request(tegra_sdhci_platform_data2.power_gpio, "sdhci2_power"); - gpio_request(tegra_sdhci_platform_data2.cd_gpio, "sdhci2_cd"); - gpio_request(tegra_sdhci_platform_data2.wp_gpio, "sdhci2_wp"); - gpio_request(tegra_sdhci_platform_data3.power_gpio, "sdhci3_power"); - - tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data2.cd_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data2.wp_gpio); - tegra_gpio_enable(tegra_sdhci_platform_data3.power_gpio); - - gpio_direction_output(tegra_sdhci_platform_data2.power_gpio, 1); - gpio_direction_output(tegra_sdhci_platform_data3.power_gpio, 1); - gpio_set_value(tegra_sdhci_platform_data3.power_gpio, 1); - - platform_device_register(&tegra_sdhci_device3); - platform_device_register(&tegra_sdhci_device2); - platform_device_register(&tegra_sdhci_device0); - - return 0; -} diff --git a/arch/arm/mach-tegra/board-ventana.c b/arch/arm/mach-tegra/board-ventana.c deleted file mode 100644 index 6302118a335b..000000000000 --- a/arch/arm/mach-tegra/board-ventana.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * arch/arm/mach-tegra/board-ventana.c - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "board.h" -#include "clock.h" -#include "board-ventana.h" -#include "devices.h" -#include "gpio-names.h" -#include "fuse.h" - -static struct plat_serial8250_port debug_uart_platform_data[] = { - { - .membase = IO_ADDRESS(TEGRA_UARTD_BASE), - .mapbase = TEGRA_UARTD_BASE, - .irq = INT_UARTD, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 216000000, - }, { - .flags = 0, - } -}; - -static struct platform_device debug_uart = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = debug_uart_platform_data, - }, -}; - -static __initdata struct tegra_clk_init_table ventana_clk_init_table[] = { - /* name parent rate enabled */ - { "uartd", "pll_p", 216000000, true}, - { "pll_m", "clk_m", 600000000, true}, - { "pwm", "clk_32k", 32768, false}, - { NULL, NULL, 0, 0}, -}; - -static char *usb_functions[] = { "mtp" }; -static char *usb_functions_adb[] = { "mtp", "adb" }; - -static struct android_usb_product usb_products[] = { - { - .product_id = 0x7102, - .num_functions = ARRAY_SIZE(usb_functions), - .functions = usb_functions, - }, - { - .product_id = 0x7100, - .num_functions = ARRAY_SIZE(usb_functions_adb), - .functions = usb_functions_adb, - }, -}; - -/* standard android USB platform data */ -static struct android_usb_platform_data andusb_plat = { - .vendor_id = 0x0955, - .product_id = 0x7100, - .manufacturer_name = "NVIDIA", - .product_name = "Ventana", - .serial_number = NULL, - .num_products = ARRAY_SIZE(usb_products), - .products = usb_products, - .num_functions = ARRAY_SIZE(usb_functions_adb), - .functions = usb_functions_adb, -}; - -static struct platform_device androidusb_device = { - .name = "android_usb", - .id = -1, - .dev = { - .platform_data = &andusb_plat, - }, -}; - -static struct tegra_i2c_platform_data ventana_i2c1_platform_data = { - .adapter_nr = 0, - .bus_count = 1, - .bus_clk_rate = { 400000, 0 }, -}; - -static const struct tegra_pingroup_config i2c2_ddc = { - .pingroup = TEGRA_PINGROUP_DDC, - .func = TEGRA_MUX_I2C2, -}; - -static const struct tegra_pingroup_config i2c2_gen2 = { - .pingroup = TEGRA_PINGROUP_PTA, - .func = TEGRA_MUX_I2C2, -}; - -static struct tegra_i2c_platform_data ventana_i2c2_platform_data = { - .adapter_nr = 1, - .bus_count = 2, - .bus_clk_rate = { 400000, 100000 }, - .bus_mux = { &i2c2_ddc, &i2c2_gen2 }, - .bus_mux_len = { 1, 1 }, -}; - -static struct tegra_i2c_platform_data ventana_i2c3_platform_data = { - .adapter_nr = 3, - .bus_count = 1, - .bus_clk_rate = { 400000, 0 }, -}; - -static struct tegra_i2c_platform_data ventana_dvc_platform_data = { - .adapter_nr = 4, - .bus_count = 1, - .bus_clk_rate = { 400000, 0 }, - .is_dvc = true, -}; - -static void ventana_i2c_init(void) -{ - tegra_i2c_device1.dev.platform_data = &ventana_i2c1_platform_data; - tegra_i2c_device2.dev.platform_data = &ventana_i2c2_platform_data; - tegra_i2c_device3.dev.platform_data = &ventana_i2c3_platform_data; - tegra_i2c_device4.dev.platform_data = &ventana_dvc_platform_data; - - platform_device_register(&tegra_i2c_device4); - platform_device_register(&tegra_i2c_device3); - platform_device_register(&tegra_i2c_device2); - platform_device_register(&tegra_i2c_device1); -} - -#define GPIO_KEY(_id, _gpio, _iswake) \ - { \ - .code = _id, \ - .gpio = TEGRA_GPIO_##_gpio, \ - .active_low = 1, \ - .desc = #_id, \ - .type = EV_KEY, \ - .wakeup = _iswake, \ - .debounce_interval = 10, \ - } - -static struct gpio_keys_button ventana_keys[] = { - [0] = GPIO_KEY(KEY_MENU, PQ3, 0), - [1] = GPIO_KEY(KEY_HOME, PQ1, 0), - [2] = GPIO_KEY(KEY_BACK, PQ2, 0), - [3] = GPIO_KEY(KEY_VOLUMEUP, PQ5, 0), - [4] = GPIO_KEY(KEY_VOLUMEDOWN, PQ4, 0), - [5] = GPIO_KEY(KEY_POWER, PV2, 1), -}; - -static struct gpio_keys_platform_data ventana_keys_platform_data = { - .buttons = ventana_keys, - .nbuttons = ARRAY_SIZE(ventana_keys), -}; - -static struct platform_device ventana_keys_device = { - .name = "gpio-keys", - .id = 0, - .dev = { - .platform_data = &ventana_keys_platform_data, - }, -}; - -static struct platform_device *ventana_devices[] __initdata = { - &tegra_otg_device, - &androidusb_device, - &debug_uart, - &pmu_device, - &tegra_udc_device, - &tegra_gart_device, - &tegra_aes_device, - &ventana_keys_device, -}; - -static void ventana_keys_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ventana_keys); i++) - tegra_gpio_enable(ventana_keys[i].gpio); -} - -static struct panjit_i2c_ts_platform_data panjit_data = { - .gpio_reset = TEGRA_GPIO_PQ7, -}; - -static const struct i2c_board_info ventana_i2c_bus1_touch_info[] = { - { - I2C_BOARD_INFO("panjit_touch", 0x3), - .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - .platform_data = &panjit_data, - }, -}; - -static int __init ventana_touch_init(void) -{ - tegra_gpio_enable(TEGRA_GPIO_PV6); - - tegra_gpio_enable(TEGRA_GPIO_PQ7); - i2c_register_board_info(0, ventana_i2c_bus1_touch_info, 1); - - return 0; -} - -static void __init tegra_ventana_init(void) -{ - char serial[20]; - - tegra_common_init(); - tegra_clk_init_from_table(ventana_clk_init_table); - ventana_pinmux_init(); - - snprintf(serial, sizeof(serial), "%llx", tegra_chip_uid()); - andusb_plat.serial_number = kstrdup(serial, GFP_KERNEL); - platform_add_devices(ventana_devices, ARRAY_SIZE(ventana_devices)); - - ventana_sdhci_init(); - ventana_i2c_init(); - ventana_regulator_init(); - ventana_touch_init(); - ventana_keys_init(); - ventana_panel_init(); -} - -MACHINE_START(VENTANA, "ventana") - .boot_params = 0x00000100, - .phys_io = IO_APB_PHYS, - .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc, - .init_irq = tegra_init_irq, - .init_machine = tegra_ventana_init, - .map_io = tegra_map_common_io, - .timer = &tegra_timer, -MACHINE_END diff --git a/arch/arm/mach-tegra/board-ventana.h b/arch/arm/mach-tegra/board-ventana.h deleted file mode 100644 index 39703583249d..000000000000 --- a/arch/arm/mach-tegra/board-ventana.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mach-tegra/board-ventana.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_TEGRA_BOARD_VENTANA_H -#define _MACH_TEGRA_BOARD_VENTANA_H - -int ventana_regulator_init(void); -int ventana_sdhci_init(void); -int ventana_pinmux_init(void); -int ventana_panel_init(void); - -#endif diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 04f1538b1a37..3d06354136f2 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h @@ -27,24 +27,6 @@ void __init tegra_common_init(void); void __init tegra_map_common_io(void); void __init tegra_init_irq(void); void __init tegra_init_clock(void); -void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size, - unsigned long fb2_size); -void __init tegra_protected_aperture_init(unsigned long aperture); -void tegra_move_framebuffer(unsigned long to, unsigned long from, - unsigned long size); -int tegra_dvfs_rail_disable_by_name(const char *reg_id); - -extern unsigned long tegra_bootloader_fb_start; -extern unsigned long tegra_bootloader_fb_size; -extern unsigned long tegra_fb_start; -extern unsigned long tegra_fb_size; -extern unsigned long tegra_fb2_start; -extern unsigned long tegra_fb2_size; -extern unsigned long tegra_carveout_start; -extern unsigned long tegra_carveout_size; -extern unsigned long tegra_lp0_vec_start; -extern unsigned long tegra_lp0_vec_size; -extern unsigned long tegra_grhost_aperture; extern struct sys_timer tegra_timer; #endif diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 964c4c39ddd0..03ad578349b9 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -18,270 +18,126 @@ #include #include -#include -#include -#include #include +#include #include -#include +#include #include - +#include #include -#include - -#include "board.h" #include "clock.h" -#include "dvfs.h" -/* - * Locking: - * - * Each struct clk has a lock. Depending on the cansleep flag, that lock - * may be a spinlock or a mutex. For most clocks, the spinlock is sufficient, - * and using the spinlock allows the clock to be manipulated from an interrupt - * or while holding a spinlock. Some clocks may need to adjust a regulator - * in order to maintain the required voltage for a new frequency. Those - * clocks set the cansleep flag, and take a mutex so that the regulator api - * can be used while holding the lock. - * - * To avoid AB-BA locking problems, locks must always be traversed from child - * clock to parent clock. For example, when enabling a clock, the clock's lock - * is taken, and then clk_enable is called on the parent, which take's the - * parent clock's lock. There are two exceptions to this ordering: - * 1. When setting a clock as cansleep, in which case the entire list of clocks - * is traversed to set the children as cansleep as well. This must occur - * during init, before any calls to clk_get, so no other clock locks can - * get taken. - * 2. When dumping the clock tree through debugfs. In this case, clk_lock_all - * is called, which attemps to iterate through the entire list of clocks - * and take every clock lock. If any call to clk_trylock fails, a locked - * clocks are unlocked, and the process is retried. When all the locks - * are held, the only clock operation that can be called is - * clk_get_rate_all_locked. - * - * Within a single clock, no clock operation can call another clock operation - * on itself, except for clk_get_rate_locked. Any clock operation can call - * any other clock operation on any of it's possible parents. - * - * clk_set_cansleep is used to mark a clock as sleeping. It is called during - * dvfs (Dynamic Voltage and Frequency Scaling) init on any clock that has a - * dvfs requirement. It can only be called on clocks that are the sole parent - * of all of their child clocks, meaning the child clock can not be reparented - * onto a different, possibly non-sleeping, clock. This is inherently true - * of all leaf clocks in the clock tree - * - * An additional lock, clock_list_lock, is used to protect the list of all - * clocks. - * - * The clock operations must lock internally to protect against - * read-modify-write on registers that are shared by multiple clocks - */ -static DEFINE_MUTEX(clock_list_lock); static LIST_HEAD(clocks); -static inline bool clk_is_auto_dvfs(struct clk *c) -{ - return c->auto_dvfs; -} - -static inline bool clk_is_dvfs(struct clk *c) -{ - return (c->dvfs != NULL); -} - -static inline bool clk_cansleep(struct clk *c) -{ - return c->cansleep; -} - -#define clk_lock_save(c, flags) \ - do { \ - if (clk_cansleep(c)) { \ - flags = 0; \ - mutex_lock(&c->mutex); \ - } else { \ - spin_lock_irqsave(&c->spinlock, flags); \ - } \ - } while (0) - -#define clk_unlock_restore(c, flags) \ - do { \ - if (clk_cansleep(c)) \ - mutex_unlock(&c->mutex); \ - else \ - spin_unlock_irqrestore(&c->spinlock, flags); \ - } while (0) - -static inline void clk_lock_init(struct clk *c) -{ - mutex_init(&c->mutex); - spin_lock_init(&c->spinlock); -} +static DEFINE_SPINLOCK(clock_lock); struct clk *tegra_get_clock_by_name(const char *name) { struct clk *c; struct clk *ret = NULL; - mutex_lock(&clock_list_lock); + unsigned long flags; + spin_lock_irqsave(&clock_lock, flags); list_for_each_entry(c, &clocks, node) { if (strcmp(c->name, name) == 0) { ret = c; break; } } - mutex_unlock(&clock_list_lock); + spin_unlock_irqrestore(&clock_lock, flags); return ret; } -/* Must be called with clk_lock(c) held */ -static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p) +int clk_reparent(struct clk *c, struct clk *parent) { - u64 rate; - - rate = clk_get_rate(p); - - if (c->mul != 0 && c->div != 0) { - rate *= c->mul; - rate += c->div / 2; /* round up */ - do_div(rate, c->div); - } - - return rate; + pr_debug("%s: %s\n", __func__, c->name); + if (c->refcnt && c->parent) + clk_disable_locked(c->parent); + c->parent = parent; + if (c->refcnt && c->parent) + clk_enable_locked(c->parent); + list_del(&c->sibling); + list_add_tail(&c->sibling, &parent->children); + return 0; } -/* Must be called with clk_lock(c) held */ -unsigned long clk_get_rate_locked(struct clk *c) +static void propagate_rate(struct clk *c) { - unsigned long rate; - - if (c->parent) - rate = clk_predict_rate_from_parent(c, c->parent); - else - rate = c->rate; - - return rate; + struct clk *clkp; + pr_debug("%s: %s\n", __func__, c->name); + list_for_each_entry(clkp, &c->children, sibling) { + pr_debug(" %s\n", clkp->name); + if (clkp->ops->recalculate_rate) + clkp->ops->recalculate_rate(clkp); + propagate_rate(clkp); + } } -unsigned long clk_get_rate(struct clk *c) +void clk_init(struct clk *c) { unsigned long flags; - unsigned long rate; - - clk_lock_save(c, flags); - rate = clk_get_rate_locked(c); + spin_lock_irqsave(&clock_lock, flags); - clk_unlock_restore(c, flags); - - return rate; -} -EXPORT_SYMBOL(clk_get_rate); - -static void __clk_set_cansleep(struct clk *c) -{ - struct clk *child; - BUG_ON(mutex_is_locked(&c->mutex)); - BUG_ON(spin_is_locked(&c->spinlock)); - - list_for_each_entry(child, &clocks, node) { - if (child->parent != c) - continue; - - WARN(child->ops && child->ops->set_parent, - "can't make child clock %s of %s " - "sleepable if it's parent could change", - child->name, c->name); - - __clk_set_cansleep(child); - } - - c->cansleep = true; -} - -/* Must be called before any clk_get calls */ -void clk_set_cansleep(struct clk *c) -{ - - mutex_lock(&clock_list_lock); - __clk_set_cansleep(c); - mutex_unlock(&clock_list_lock); -} - -int clk_reparent(struct clk *c, struct clk *parent) -{ - c->parent = parent; - return 0; -} - -void clk_init(struct clk *c) -{ - clk_lock_init(c); + INIT_LIST_HEAD(&c->children); + INIT_LIST_HEAD(&c->sibling); if (c->ops && c->ops->init) c->ops->init(c); - if (!c->ops || !c->ops->enable) { - c->refcnt++; - c->set = true; - if (c->parent) - c->state = c->parent->state; - else - c->state = ON; - } - - mutex_lock(&clock_list_lock); list_add(&c->node, &clocks); - mutex_unlock(&clock_list_lock); -} -int clk_enable(struct clk *c) -{ - int ret = 0; - unsigned long flags; - - clk_lock_save(c, flags); + if (c->parent) + list_add_tail(&c->sibling, &c->parent->children); - if (clk_is_auto_dvfs(c)) { - ret = tegra_dvfs_set_rate(c, clk_get_rate_locked(c)); - if (ret) - goto out; - } + spin_unlock_irqrestore(&clock_lock, flags); +} +int clk_enable_locked(struct clk *c) +{ + int ret; + pr_debug("%s: %s\n", __func__, c->name); if (c->refcnt == 0) { if (c->parent) { - ret = clk_enable(c->parent); + ret = clk_enable_locked(c->parent); if (ret) - goto out; + return ret; } if (c->ops && c->ops->enable) { ret = c->ops->enable(c); if (ret) { if (c->parent) - clk_disable(c->parent); - goto out; + clk_disable_locked(c->parent); + return ret; } c->state = ON; - c->set = true; +#ifdef CONFIG_DEBUG_FS + c->set = 1; +#endif } } c->refcnt++; -out: - clk_unlock_restore(c, flags); - return ret; + + return 0; } -EXPORT_SYMBOL(clk_enable); -void clk_disable(struct clk *c) +int clk_enable(struct clk *c) { + int ret; unsigned long flags; + spin_lock_irqsave(&clock_lock, flags); + ret = clk_enable_locked(c); + spin_unlock_irqrestore(&clock_lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_enable); - clk_lock_save(c, flags); - +void clk_disable_locked(struct clk *c) +{ + pr_debug("%s: %s\n", __func__, c->name); if (c->refcnt == 0) { WARN(1, "Attempting to disable clock %s with refcnt 0", c->name); - clk_unlock_restore(c, flags); return; } if (c->refcnt == 1) { @@ -289,53 +145,48 @@ void clk_disable(struct clk *c) c->ops->disable(c); if (c->parent) - clk_disable(c->parent); + clk_disable_locked(c->parent); c->state = OFF; } c->refcnt--; - - if (clk_is_auto_dvfs(c) && c->refcnt == 0) - tegra_dvfs_set_rate(c, 0); - - clk_unlock_restore(c, flags); } -EXPORT_SYMBOL(clk_disable); -int clk_set_parent(struct clk *c, struct clk *parent) +void clk_disable(struct clk *c) { - int ret = 0; unsigned long flags; - unsigned long new_rate; - unsigned long old_rate; - - clk_lock_save(c, flags); + spin_lock_irqsave(&clock_lock, flags); + clk_disable_locked(c); + spin_unlock_irqrestore(&clock_lock, flags); +} +EXPORT_SYMBOL(clk_disable); - if (!c->ops || !c->ops->set_parent) { - ret = -ENOSYS; - goto out; - } +int clk_set_parent_locked(struct clk *c, struct clk *parent) +{ + int ret; - new_rate = clk_predict_rate_from_parent(c, parent); - old_rate = clk_get_rate_locked(c); + pr_debug("%s: %s\n", __func__, c->name); - if (clk_is_auto_dvfs(c) && c->refcnt > 0 && - (!c->parent || new_rate > old_rate)) { - ret = tegra_dvfs_set_rate(c, new_rate); - if (ret) - goto out; - } + if (!c->ops || !c->ops->set_parent) + return -ENOSYS; ret = c->ops->set_parent(c, parent); + if (ret) - goto out; + return ret; - if (clk_is_auto_dvfs(c) && c->refcnt > 0 && - new_rate < old_rate) - ret = tegra_dvfs_set_rate(c, new_rate); + propagate_rate(c); -out: - clk_unlock_restore(c, flags); + return 0; +} + +int clk_set_parent(struct clk *c, struct clk *parent) +{ + int ret; + unsigned long flags; + spin_lock_irqsave(&clock_lock, flags); + ret = clk_set_parent_locked(c, parent); + spin_unlock_irqrestore(&clock_lock, flags); return ret; } EXPORT_SYMBOL(clk_set_parent); @@ -350,97 +201,39 @@ int clk_set_rate(struct clk *c, unsigned long rate) { int ret = 0; unsigned long flags; - unsigned long old_rate; - long new_rate; - - clk_lock_save(c, flags); - - if (!c->ops || !c->ops->set_rate) { - ret = -ENOSYS; - goto out; - } - old_rate = clk_get_rate_locked(c); + spin_lock_irqsave(&clock_lock, flags); - if (rate > c->max_rate) - rate = c->max_rate; + pr_debug("%s: %s\n", __func__, c->name); - if (c->ops && c->ops->round_rate) { - new_rate = c->ops->round_rate(c, rate); - - if (new_rate < 0) { - ret = new_rate; - goto out; - } - - rate = new_rate; - } - - if (clk_is_auto_dvfs(c) && rate > old_rate && c->refcnt > 0) { - ret = tegra_dvfs_set_rate(c, rate); - if (ret) - goto out; - } + if (c->ops && c->ops->set_rate) + ret = c->ops->set_rate(c, rate); + else + ret = -ENOSYS; - ret = c->ops->set_rate(c, rate); - if (ret) - goto out; + propagate_rate(c); - if (clk_is_auto_dvfs(c) && rate < old_rate && c->refcnt > 0) - ret = tegra_dvfs_set_rate(c, rate); + spin_unlock_irqrestore(&clock_lock, flags); -out: - clk_unlock_restore(c, flags); return ret; } EXPORT_SYMBOL(clk_set_rate); -/* Must be called with clocks lock and all indvidual clock locks held */ -unsigned long clk_get_rate_all_locked(struct clk *c) -{ - u64 rate; - int mul = 1; - int div = 1; - struct clk *p = c; - - while (p) { - c = p; - if (c->mul != 0 && c->div != 0) { - mul *= c->mul; - div *= c->div; - } - p = c->parent; - } - - rate = c->rate; - rate *= mul; - do_div(rate, div); - - return rate; -} - -long clk_round_rate(struct clk *c, unsigned long rate) +unsigned long clk_get_rate(struct clk *c) { unsigned long flags; - long ret; - - clk_lock_save(c, flags); + unsigned long ret; - if (!c->ops || !c->ops->round_rate) { - ret = -ENOSYS; - goto out; - } + spin_lock_irqsave(&clock_lock, flags); - if (rate > c->max_rate) - rate = c->max_rate; + pr_debug("%s: %s\n", __func__, c->name); - ret = c->ops->round_rate(c, rate); + ret = c->rate; -out: - clk_unlock_restore(c, flags); + spin_unlock_irqrestore(&clock_lock, flags); return ret; } -EXPORT_SYMBOL(clk_round_rate); +EXPORT_SYMBOL(clk_get_rate); static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table) { @@ -515,187 +308,23 @@ void tegra_periph_reset_assert(struct clk *c) } EXPORT_SYMBOL(tegra_periph_reset_assert); -void __init tegra_init_clock(void) +int __init tegra_init_clock(void) { tegra2_init_clocks(); - tegra2_init_dvfs(); -} - -/* - * Iterate through all clocks, disabling any for which the refcount is 0 - * but the clock init detected the bootloader left the clock on. - */ -int __init tegra_disable_boot_clocks(void) -{ - unsigned long flags; - struct clk *c; - - mutex_lock(&clock_list_lock); - - list_for_each_entry(c, &clocks, node) { - clk_lock_save(c, flags); - if (c->refcnt == 0 && c->state == ON && - c->ops && c->ops->disable) { - pr_warning("Disabling clock %s left on by bootloader\n", - c->name); - c->ops->disable(c); - c->state = OFF; - } - clk_unlock_restore(c, flags); - } - - mutex_unlock(&clock_list_lock); - return 0; -} -int __init tegra_late_init_clock(void) -{ - tegra_dvfs_late_init(); - tegra_disable_boot_clocks(); return 0; } -late_initcall(tegra_late_init_clock); - -/* The SDMMC controllers have extra bits in the clock source register that - * adjust the delay between the clock and data to compenstate for delays - * on the PCB. */ -void tegra_sdmmc_tap_delay(struct clk *c, int delay) { - unsigned long flags; - - clk_lock_save(c, flags); - tegra2_sdmmc_tap_delay(c, delay); - clk_unlock_restore(c, flags); -} #ifdef CONFIG_DEBUG_FS - -/* - * Attempt to lock all the clocks that are marked cansleep - * Must be called with irqs enabled - */ -static int __clk_lock_all_mutexes(void) -{ - struct clk *c; - - might_sleep(); - - list_for_each_entry(c, &clocks, node) - if (clk_cansleep(c)) - if (!mutex_trylock(&c->mutex)) - goto unlock_mutexes; - - return 0; - -unlock_mutexes: - list_for_each_entry_continue_reverse(c, &clocks, node) - if (clk_cansleep(c)) - mutex_unlock(&c->mutex); - - return -EAGAIN; -} - -/* - * Attempt to lock all the clocks that are not marked cansleep - * Must be called with irqs disabled - */ -static int __clk_lock_all_spinlocks(void) -{ - struct clk *c; - - list_for_each_entry(c, &clocks, node) - if (!clk_cansleep(c)) - if (!spin_trylock(&c->spinlock)) - goto unlock_spinlocks; - - return 0; - -unlock_spinlocks: - list_for_each_entry_continue_reverse(c, &clocks, node) - if (!clk_cansleep(c)) - spin_unlock(&c->spinlock); - - return -EAGAIN; -} - -static void __clk_unlock_all_mutexes(void) -{ - struct clk *c; - - list_for_each_entry_reverse(c, &clocks, node) - if (clk_cansleep(c)) - mutex_unlock(&c->mutex); -} - -static void __clk_unlock_all_spinlocks(void) -{ - struct clk *c; - - list_for_each_entry_reverse(c, &clocks, node) - if (!clk_cansleep(c)) - spin_unlock(&c->spinlock); -} - -/* - * This function retries until it can take all locks, and may take - * an arbitrarily long time to complete. - * Must be called with irqs enabled, returns with irqs disabled - * Must be called with clock_list_lock held - */ -static void clk_lock_all(void) -{ - int ret; -retry: - ret = __clk_lock_all_mutexes(); - if (ret) - goto failed_mutexes; - - local_irq_disable(); - - ret = __clk_lock_all_spinlocks(); - if (ret) - goto failed_spinlocks; - - /* All locks taken successfully, return */ - return; - -failed_spinlocks: - local_irq_enable(); - __clk_unlock_all_mutexes(); -failed_mutexes: - msleep(1); - goto retry; -} - -/* - * Unlocks all clocks after a clk_lock_all - * Must be called with irqs disabled, returns with irqs enabled - * Must be called with clock_list_lock held - */ -static void clk_unlock_all(void) -{ - __clk_unlock_all_spinlocks(); - - local_irq_enable(); - - __clk_unlock_all_mutexes(); -} - static struct dentry *clk_debugfs_root; -static void dvfs_show_one(struct seq_file *s, struct dvfs *d, int level) -{ - seq_printf(s, "%*s %-*s%21s%d mV\n", - level * 3 + 1, "", - 30 - level * 3, d->dvfs_rail->reg_id, - "", - d->cur_millivolts); -} static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) { struct clk *child; + struct clk *safe; const char *state = "uninit"; - char div[8] = {0}; + char div[5] = {0}; if (c->state == ON) state = "on"; @@ -703,36 +332,19 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) state = "off"; if (c->mul != 0 && c->div != 0) { - if (c->mul > c->div) { - int mul = c->mul / c->div; - int mul2 = (c->mul * 10 / c->div) % 10; - int mul3 = (c->mul * 10) % c->div; - if (mul2 == 0 && mul3 == 0) - snprintf(div, sizeof(div), "x%d", mul); - else if (mul3 == 0) - snprintf(div, sizeof(div), "x%d.%d", mul, mul2); - else - snprintf(div, sizeof(div), "x%d.%d..", mul, mul2); - } else { + BUG_ON(c->mul > 2); + if (c->mul > c->div) + snprintf(div, sizeof(div), "x%d", c->mul / c->div); + else snprintf(div, sizeof(div), "%d%s", c->div / c->mul, (c->div % c->mul) ? ".5" : ""); - } } - seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n", - level * 3 + 1, "", - c->rate > c->max_rate ? '!' : ' ', - !c->set ? '*' : ' ', + seq_printf(s, "%*s%-*s %-6s %-3d %-5s %-10lu\n", + level * 3 + 1, c->set ? "" : "*", 30 - level * 3, c->name, - state, c->refcnt, div, clk_get_rate_all_locked(c)); - - if (c->dvfs) - dvfs_show_one(s, c->dvfs, level + 1); - - list_for_each_entry(child, &clocks, node) { - if (child->parent != c) - continue; - + state, c->refcnt, div, c->rate); + list_for_each_entry_safe(child, safe, &c->children, sibling) { clock_tree_show_one(s, child, level + 1); } } @@ -740,20 +352,14 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) static int clock_tree_show(struct seq_file *s, void *data) { struct clk *c; - seq_printf(s, " clock state ref div rate\n"); - seq_printf(s, "--------------------------------------------------------------\n"); - - mutex_lock(&clock_list_lock); - - clk_lock_all(); - + unsigned long flags; + seq_printf(s, " clock state ref div rate \n"); + seq_printf(s, "-----------------------------------------------------------\n"); + spin_lock_irqsave(&clock_lock, flags); list_for_each_entry(c, &clocks, node) if (c->parent == NULL) clock_tree_show_one(s, c, 0); - - clk_unlock_all(); - - mutex_unlock(&clock_list_lock); + spin_unlock_irqrestore(&clock_lock, flags); return 0; } @@ -832,36 +438,6 @@ err_out: return -ENOMEM; } -static char tegra_clk_dump_buff[16 * 1024]; - -void tegra_clk_dump(void) -{ - struct seq_file s; - int i; - char c; - - memset(&s, 0x0, sizeof(s)); - - s.buf = tegra_clk_dump_buff; - s.size = sizeof(tegra_clk_dump_buff); - - clock_tree_show(&s, NULL); - - i = 0; - while (i < s.count ) { - if ((s.count - i) > 256) { - c = s.buf[i + 256]; - s.buf[i + 256] = 0; - printk("%s", s.buf + i); - s.buf[i + 256] = c; - } else { - printk("%s", s.buf + i); - } - i += 256; - } -} - - static int clk_debugfs_register(struct clk *c) { int err; @@ -897,9 +473,6 @@ static int __init clk_debugfs_init(void) if (!d) goto err_out; - if (dvfs_debugfs_init(clk_debugfs_root)) - goto err_out; - list_for_each_entry(c, &clocks, node) { err = clk_debugfs_register(c); if (err) diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index f3319d30e29c..af7c70e2a3ba 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h @@ -21,25 +21,21 @@ #define __MACH_TEGRA_CLOCK_H #include -#include -#include #include #define DIV_BUS (1 << 0) #define DIV_U71 (1 << 1) #define DIV_U71_FIXED (1 << 2) #define DIV_2 (1 << 3) -#define DIV_U16 (1 << 4) -#define PLL_FIXED (1 << 5) -#define PLL_HAS_CPCON (1 << 6) -#define MUX (1 << 7) -#define PLLD (1 << 8) -#define PERIPH_NO_RESET (1 << 9) -#define PERIPH_NO_ENB (1 << 10) -#define PERIPH_EMC_ENB (1 << 11) -#define PERIPH_MANUAL_RESET (1 << 12) -#define PLL_ALT_MISC_REG (1 << 13) -#define PLLU (1 << 14) +#define PLL_FIXED (1 << 4) +#define PLL_HAS_CPCON (1 << 5) +#define MUX (1 << 6) +#define PLLD (1 << 7) +#define PERIPH_NO_RESET (1 << 8) +#define PERIPH_NO_ENB (1 << 9) +#define PERIPH_EMC_ENB (1 << 10) +#define PERIPH_MANUAL_RESET (1 << 11) +#define PLL_ALT_MISC_REG (1 << 12) #define ENABLE_ON_INIT (1 << 28) struct clk; @@ -49,7 +45,7 @@ struct clk_mux_sel { u32 value; }; -struct clk_pll_freq_table { +struct clk_pll_table { unsigned long input_rate; unsigned long output_rate; u16 n; @@ -62,10 +58,12 @@ struct clk_ops { void (*init)(struct clk *); int (*enable)(struct clk *); void (*disable)(struct clk *); + void (*recalc)(struct clk *); int (*set_parent)(struct clk *, struct clk *); int (*set_rate)(struct clk *, unsigned long); + unsigned long (*get_rate)(struct clk *); long (*round_rate)(struct clk *, unsigned long); - void (*reset)(struct clk *, bool); + unsigned long (*recalculate_rate)(struct clk *); }; enum clk_state { @@ -76,70 +74,52 @@ enum clk_state { struct clk { /* node for master clocks list */ - struct list_head node; /* node for list of all clocks */ - struct dvfs *dvfs; - struct clk_lookup lookup; - + struct list_head node; + struct list_head children; /* list of children */ + struct list_head sibling; /* node for children */ #ifdef CONFIG_DEBUG_FS - struct dentry *dent; - struct dentry *parent_dent; + struct dentry *dent; + struct dentry *parent_dent; #endif - bool set; - struct clk_ops *ops; - unsigned long dvfs_rate; - unsigned long rate; - unsigned long max_rate; - unsigned long min_rate; - bool auto_dvfs; - bool cansleep; - u32 flags; - const char *name; - - u32 refcnt; - enum clk_state state; - struct clk *parent; - u32 div; - u32 mul; - - const struct clk_mux_sel *inputs; + struct clk_ops *ops; + struct clk *parent; + struct clk_lookup lookup; + unsigned long rate; + u32 flags; + u32 refcnt; + const char *name; u32 reg; u32 reg_shift; + unsigned int clk_num; + enum clk_state state; +#ifdef CONFIG_DEBUG_FS + bool set; +#endif - struct list_head shared_bus_list; - - union { - struct { - unsigned int clk_num; - } periph; - struct { - unsigned long input_min; - unsigned long input_max; - unsigned long cf_min; - unsigned long cf_max; - unsigned long vco_min; - unsigned long vco_max; - const struct clk_pll_freq_table *freq_table; - int lock_delay; - } pll; - struct { - u32 sel; - u32 reg_mask; - } mux; - struct { - struct clk *main; - struct clk *backup; - } cpu; - struct { - struct list_head node; - bool enabled; - unsigned long rate; - } shared_bus_user; - } u; - - struct mutex mutex; - spinlock_t spinlock; + /* PLL */ + unsigned long input_min; + unsigned long input_max; + unsigned long cf_min; + unsigned long cf_max; + unsigned long vco_min; + unsigned long vco_max; + u32 m; + u32 n; + u32 p; + u32 cpcon; + const struct clk_pll_table *pll_table; + + /* DIV */ + u32 div; + u32 mul; + + /* MUX */ + const struct clk_mux_sel *inputs; + u32 sel; + u32 reg_mask; }; + struct clk_duplicate { const char *name; struct clk_lookup lookup; @@ -158,10 +138,10 @@ void tegra2_periph_reset_assert(struct clk *c); void clk_init(struct clk *clk); struct clk *tegra_get_clock_by_name(const char *name); unsigned long clk_measure_input_freq(void); +void clk_disable_locked(struct clk *c); +int clk_enable_locked(struct clk *c); +int clk_set_parent_locked(struct clk *c, struct clk *parent); int clk_reparent(struct clk *c, struct clk *parent); void tegra_clk_init_from_table(struct tegra_clk_init_table *table); -void clk_set_cansleep(struct clk *c); -unsigned long clk_get_rate_locked(struct clk *c); -void tegra2_sdmmc_tap_delay(struct clk *c, int delay); #endif diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 4672c774bd9c..039a514b61ef 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -1,5 +1,5 @@ /* - * arch/arm/mach-tegra/common.c + * arch/arm/mach-tegra/board-harmony.c * * Copyright (C) 2010 Google, Inc. * @@ -17,69 +17,27 @@ * */ -#include #include #include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include "apbio.h" #include "board.h" #include "clock.h" -#include "fuse.h" - -#define MC_SECURITY_CFG2 0x7c - -unsigned long tegra_bootloader_fb_start; -unsigned long tegra_bootloader_fb_size; -unsigned long tegra_fb_start; -unsigned long tegra_fb_size; -unsigned long tegra_fb2_start; -unsigned long tegra_fb2_size; -unsigned long tegra_carveout_start; -unsigned long tegra_carveout_size; -unsigned long tegra_lp0_vec_start; -unsigned long tegra_lp0_vec_size; -unsigned long tegra_grhost_aperture; - -void (*tegra_reset)(char mode, const char *cmd); static __initdata struct tegra_clk_init_table common_clk_init_table[] = { - /* set up clocks that should always be on */ /* name parent rate enabled */ { "clk_m", NULL, 0, true }, { "pll_p", "clk_m", 216000000, true }, { "pll_p_out1", "pll_p", 28800000, true }, { "pll_p_out2", "pll_p", 48000000, true }, { "pll_p_out3", "pll_p", 72000000, true }, - { "pll_m_out1", "pll_m", 120000000, true }, - { "sclk", "pll_m_out1", 120000000, true }, - { "hclk", "sclk", 120000000, true }, - { "pclk", "hclk", 60000000, true }, - { "pll_x", NULL, 0, true }, - { "cpu", NULL, 0, true }, - { "emc", NULL, 0, true }, - { "csite", NULL, 0, true }, - { "timer", NULL, 0, true }, - { "kfuse", NULL, 0, true }, - { "rtc", NULL, 0, true }, - - /* set frequencies of some device clocks */ - { "pll_u", "clk_m", 480000000, false }, - { "sdmmc1", "pll_p", 48000000, false}, - { "sdmmc2", "pll_p", 48000000, false}, - { "sdmmc3", "pll_p", 48000000, false}, - { "sdmmc4", "pll_p", 48000000, false}, + { "pll_p_out4", "pll_p", 108000000, true }, + { "sys", "pll_p_out4", 108000000, true }, + { "hclk", "sys", 108000000, true }, + { "pclk", "hclk", 54000000, true }, { NULL, NULL, 0, 0}, }; @@ -90,222 +48,14 @@ void __init tegra_init_cache(void) writel(0x331, p + L2X0_TAG_LATENCY_CTRL); writel(0x441, p + L2X0_DATA_LATENCY_CTRL); - writel(2, p + L2X0_PWR_CTRL); - l2x0_init(p, 0x6C480001, 0x8200c3fe); + l2x0_init(p, 0x6C080001, 0x8200c3fe); #endif - -} - -static void __init tegra_init_power(void) -{ - tegra_powergate_power_off(TEGRA_POWERGATE_MPE); - tegra_powergate_power_off(TEGRA_POWERGATE_3D); -} - -static bool console_flushed; - -static void tegra_pm_flush_console(void) -{ - if (console_flushed) - return; - console_flushed = true; - - printk("\n"); - pr_emerg("Restarting %s\n", linux_banner); - if (!try_acquire_console_sem()) { - release_console_sem(); - return; - } - - mdelay(50); - - local_irq_disable(); - if (try_acquire_console_sem()) - pr_emerg("tegra_restart: Console was locked! Busting\n"); - else - pr_emerg("tegra_restart: Console was locked!\n"); - release_console_sem(); -} - -static void tegra_pm_restart(char mode, const char *cmd) -{ - tegra_pm_flush_console(); - arm_machine_restart(mode, cmd); } void __init tegra_common_init(void) { - arm_pm_restart = tegra_pm_restart; - tegra_init_fuse(); tegra_init_clock(); tegra_clk_init_from_table(common_clk_init_table); - tegra_init_power(); tegra_init_cache(); - tegra_dma_init(); - tegra_init_apb_dma(); -} - -static int __init tegra_bootloader_fb_arg(char *options) -{ - char *p = options; - - tegra_bootloader_fb_size = memparse(p, &p); - if (*p == '@') - tegra_bootloader_fb_start = memparse(p+1, &p); - - pr_info("Found tegra_fbmem: %08lx@%08lx\n", - tegra_bootloader_fb_size, tegra_bootloader_fb_start); - - return 0; -} -early_param("tegra_fbmem", tegra_bootloader_fb_arg); - -static int __init tegra_lp0_vec_arg(char *options) -{ - char *p = options; - - tegra_lp0_vec_size = memparse(p, &p); - if (*p == '@') - tegra_lp0_vec_start = memparse(p+1, &p); - - return 0; -} -early_param("lp0_vec", tegra_lp0_vec_arg); - -/* - * Tegra has a protected aperture that prevents access by most non-CPU - * memory masters to addresses above the aperture value. Enabling it - * secures the CPU's memory from the GPU, except through the GART. - */ -void __init tegra_protected_aperture_init(unsigned long aperture) -{ -#ifndef CONFIG_NVMAP_ALLOW_SYSMEM - void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE); - pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture); - writel(aperture, mc_base + MC_SECURITY_CFG2); -#else - pr_err("Tegra protected aperture disabled because nvmap is using " - "system memory\n"); -#endif -} - -/* - * Due to conflicting restrictions on the placement of the framebuffer, - * the bootloader is likely to leave the framebuffer pointed at a location - * in memory that is outside the grhost aperture. This function will move - * the framebuffer contents from a physical address that is anywher (lowmem, - * highmem, or outside the memory map) to a physical address that is outside - * the memory map. - */ -void tegra_move_framebuffer(unsigned long to, unsigned long from, - unsigned long size) -{ - struct page *page; - void __iomem *to_io; - void *from_virt; - unsigned long i; - - BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to); - BUG_ON(PAGE_ALIGN(from) != from); - BUG_ON(PAGE_ALIGN(size) != size); - - to_io = ioremap(to, size); - if (!to_io) { - pr_err("%s: Failed to map target framebuffer\n", __func__); - return; - } - - if (pfn_valid(page_to_pfn(phys_to_page(from)))) { - for (i = 0 ; i < size; i += PAGE_SIZE) { - page = phys_to_page(from + i); - from_virt = kmap(page); - memcpy_toio(to_io + i, from_virt, PAGE_SIZE); - kunmap(page); - } - } else { - void __iomem *from_io = ioremap(from, size); - if (!from_io) { - pr_err("%s: Failed to map source framebuffer\n", - __func__); - goto out; - } - - for (i = 0; i < size; i+= 4) - writel(readl(from_io + i), to_io + i); - - iounmap(from_io); - } -out: - iounmap(to_io); -} - -void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size, - unsigned long fb2_size) -{ - if (tegra_lp0_vec_size) - if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) - pr_err("Failed to reserve lp0_vec %08lx@%08lx\n", - tegra_lp0_vec_size, tegra_lp0_vec_start); - - - tegra_carveout_start = memblock_end_of_DRAM() - carveout_size; - if (memblock_remove(tegra_carveout_start, carveout_size)) - pr_err("Failed to remove carveout %08lx@%08lx from memory " - "map\n", - tegra_carveout_start, carveout_size); - else - tegra_carveout_size = carveout_size; - - tegra_fb2_start = memblock_end_of_DRAM() - fb2_size; - if (memblock_remove(tegra_fb2_start, fb2_size)) - pr_err("Failed to remove second framebuffer %08lx@%08lx from " - "memory map\n", - tegra_fb2_start, fb2_size); - else - tegra_fb2_size = fb2_size; - - tegra_fb_start = memblock_end_of_DRAM() - fb_size; - if (memblock_remove(tegra_fb_start, fb_size)) - pr_err("Failed to remove framebuffer %08lx@%08lx from memory " - "map\n", - tegra_fb_start, fb_size); - else - tegra_fb_size = fb_size; - - if (tegra_fb_size) - tegra_grhost_aperture = tegra_fb_start; - - if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture) - tegra_grhost_aperture = tegra_fb2_start; - - if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture) - tegra_grhost_aperture = tegra_carveout_start; - - /* - * TODO: We should copy the bootloader's framebuffer to the framebuffer - * allocated above, and then free this one. - */ - if (tegra_bootloader_fb_size) - if (memblock_reserve(tegra_bootloader_fb_start, - tegra_bootloader_fb_size)) - pr_err("Failed to reserve lp0_vec %08lx@%08lx\n", - tegra_lp0_vec_size, tegra_lp0_vec_start); - - pr_info("Tegra reserved memory:\n" - "LP0: %08lx - %08lx\n" - "Bootloader framebuffer: %08lx - %08lx\n" - "Framebuffer: %08lx - %08lx\n" - "2nd Framebuffer: %08lx - %08lx\n" - "Carveout: %08lx - %08lx\n", - tegra_lp0_vec_start, - tegra_lp0_vec_start + tegra_lp0_vec_size - 1, - tegra_bootloader_fb_start, - tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1, - tegra_fb_start, - tegra_fb_start + tegra_fb_size - 1, - tegra_fb2_start, - tegra_fb2_start + tegra_fb2_size - 1, - tegra_carveout_start, - tegra_carveout_start + tegra_carveout_size - 1); } diff --git a/arch/arm/mach-tegra/cortex-a9.S b/arch/arm/mach-tegra/cortex-a9.S deleted file mode 100644 index 1ca815d0fab8..000000000000 --- a/arch/arm/mach-tegra/cortex-a9.S +++ /dev/null @@ -1,716 +0,0 @@ -/* - * arch/arm/mach-tegra/cortex-a9.S - * - * CPU state save & restore routines for CPU hotplug - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* .section ".cpuinit.text", "ax"*/ - -#define TTB_FLAGS 0x6A @ IRGN_WBWA, OC_RGN_WBWA, S, NOS - -/* - * spooled CPU context is 1KB / CPU - */ -#define CTX_SP 0 -#define CTX_CPSR 4 -#define CTX_SPSR 8 -#define CTX_CPACR 12 -#define CTX_CSSELR 16 -#define CTX_SCTLR 20 -#define CTX_ACTLR 24 -#define CTX_PCTLR 28 - -#define CTX_FPEXC 32 -#define CTX_FPSCR 36 -#define CTX_DIAGNOSTIC 40 - -#define CTX_TTBR0 48 -#define CTX_TTBR1 52 -#define CTX_TTBCR 56 -#define CTX_DACR 60 -#define CTX_PAR 64 -#define CTX_PRRR 68 -#define CTX_NMRR 72 -#define CTX_VBAR 76 -#define CTX_CONTEXTIDR 80 -#define CTX_TPIDRURW 84 -#define CTX_TPIDRURO 88 -#define CTX_TPIDRPRW 92 - -#define CTX_SVC_SP 0 -#define CTX_SVC_LR -1 @ stored on stack -#define CTX_SVC_SPSR 8 - -#define CTX_SYS_SP 96 -#define CTX_SYS_LR 100 - -#define CTX_ABT_SPSR 112 -#define CTX_ABT_SP 116 -#define CTX_ABT_LR 120 - -#define CTX_UND_SPSR 128 -#define CTX_UND_SP 132 -#define CTX_UND_LR 136 - -#define CTX_IRQ_SPSR 144 -#define CTX_IRQ_SP 148 -#define CTX_IRQ_LR 152 - -#define CTX_FIQ_SPSR 160 -#define CTX_FIQ_R8 164 -#define CTX_FIQ_R9 168 -#define CTX_FIQ_R10 172 -#define CTX_FIQ_R11 178 -#define CTX_FIQ_R12 180 -#define CTX_FIQ_SP 184 -#define CTX_FIQ_LR 188 - -/* context only relevant for master cpu */ -#ifdef CONFIG_CACHE_L2X0 -#define CTX_L2_CTRL 224 -#define CTX_L2_AUX 228 -#define CTX_L2_TAG_CTRL 232 -#define CTX_L2_DAT_CTRL 236 -#define CTX_L2_PREFETCH 240 -#endif - -#define CTX_VFP_REGS 256 -#define CTX_VFP_SIZE (32 * 8) - -#define CTX_CP14_REGS 512 -#define CTS_CP14_DSCR 512 -#define CTX_CP14_WFAR 516 -#define CTX_CP14_VCR 520 -#define CTX_CP14_CLAIM 524 - -/* Each of the folowing is 2 32-bit registers */ -#define CTS_CP14_BKPT_0 528 -#define CTS_CP14_BKPT_1 536 -#define CTS_CP14_BKPT_2 544 -#define CTS_CP14_BKPT_3 552 -#define CTS_CP14_BKPT_4 560 -#define CTS_CP14_BKPT_5 568 - -/* Each of the folowing is 2 32-bit registers */ -#define CTS_CP14_WPT_0 576 -#define CTS_CP14_WPT_1 584 -#define CTS_CP14_WPT_2 592 -#define CTS_CP14_WPT_3 600 - -#include "power.h" -#include "power-macros.S" - -.macro ctx_ptr, rd, tmp - cpu_id \tmp - mov32 \rd, tegra_context_area - ldr \rd, [\rd] - add \rd, \rd, \tmp, lsl #(CONTEXT_SIZE_BYTES_SHIFT) -.endm - -.macro translate, pa, va, tmp - mov \tmp, #0x1000 - sub \tmp, \tmp, #1 - bic \pa, \va, \tmp - mcr p15, 0, \pa, c7, c8, 1 - mrc p15, 0, \pa, c7, c4, 0 - bic \pa, \pa, \tmp - and \tmp, \va, \tmp - orr \pa, \pa, \tmp -.endm - -/* - * __cortex_a9_save(unsigned int mode) - * - * spools out the volatile processor state to memory, so that - * the CPU may be safely powered down. does not preserve: - * - CP15 c0 registers (except cache size select 2,c0/c0,0) - * - CP15 c1 secure registers (c1/c1, 0-3) - * - CP15 c5 fault status registers (c5/c0 0&1, c5/c1 0&1) - * - CP15 c6 fault address registers (c6/c0 0&2) - * - CP15 c9 performance monitor registers (c9/c12 0-5, - * c9/c13 0-2, c9/c14 0-2) - * - CP15 c10 TLB lockdown register (c10/c0, 0) - * - CP15 c12 MVBAR (c12/c0, 1) - * - CP15 c15 TLB lockdown registers - */ - .align L1_CACHE_SHIFT -ENTRY(__cortex_a9_save) - mrs r3, cpsr - cps 0x13 @ save off svc registers - mov r1, sp - stmfd sp!, {r3-r12, lr} - - bic r2, sp, #(L1_CACHE_BYTES-1) - -1: mcr p15, 0, r2, c7, c14, 1 @ clean out dirty stack cachelines - add r2, r2, #L1_CACHE_BYTES - cmp r2, r1 - ble 1b - dsb - - ctx_ptr r8, r9 - mov r12, r0 - - /* zero-out context area */ - mov r9, r8 - add r10, r8, #(CONTEXT_SIZE_BYTES) - mov r0, #0 - mov r1, #0 - mov r2, #0 - mov r3, #0 - mov r4, #0 - mov r5, #0 - mov r6, #0 - mov r7, #0 -2: stmia r9!, {r0-r7} - cmp r9, r10 - blo 2b - - mov r0, sp - mov sp, r12 @ sp holds the power mode - mrs r1, cpsr - mrs r2, spsr - - mrc p15, 0, r3, c1, c0, 2 @ cpacr - stmia r8, {r0-r3} - mrc p15, 2, r0, c0, c0, 0 @ csselr - mrc p15, 0, r1, c1, c0, 0 @ sctlr - mrc p15, 0, r2, c1, c0, 1 @ actlr - mrc p15, 0, r4, c15, c0, 0 @ pctlr - add r9, r8, #CTX_CSSELR - stmia r9, {r0-r2, r4} - -#ifdef CONFIG_VFPv3 - orr r2, r3, #0xF00000 - mcr p15, 0, r2, c1, c0, 2 @ enable access to FPU - VFPFMRX r2, FPEXC - str r2, [r8, #CTX_FPEXC] - mov r1, #0x40000000 @ enable access to FPU - VFPFMXR FPEXC, r1 - VFPFMRX r1, FPSCR - str r1, [r8, #CTX_FPSCR] - isb - add r9, r8, #CTX_VFP_REGS - - VFPFSTMIA r9, r12 @ save out (16 or 32)*8B of FPU registers - VFPFMXR FPEXC, r2 - mrc p15, 0, r3, c1, c0, 2 @ restore original FPEXC/CPACR -#endif - mrc p15, 0, r0, c15, c0, 1 @ diag - str r0, [r8, #CTX_DIAGNOSTIC] - - add r9, r8, #CTX_TTBR0 - mrc p15, 0, r0, c2, c0, 0 @ TTBR0 - mrc p15, 0, r1, c2, c0, 1 @ TTBR1 - mrc p15, 0, r2, c2, c0, 2 @ TTBCR - mrc p15, 0, r3, c3, c0, 0 @ domain access control reg - mrc p15, 0, r4, c7, c4, 0 @ PAR - mrc p15, 0, r5, c10, c2, 0 @ PRRR - mrc p15, 0, r6, c10, c2, 1 @ NMRR - mrc p15, 0, r7, c12, c0, 0 @ VBAR - stmia r9!, {r0-r7} - mrc p15, 0, r0, c13, c0, 1 @ CONTEXTIDR - mrc p15, 0, r1, c13, c0, 2 @ TPIDRURW - mrc p15, 0, r2, c13, c0, 3 @ TPIDRURO - mrc p15, 0, r3, c13, c0, 4 @ TPIDRPRW - stmia r9, {r0-r3} - - cps 0x1f @ SYS mode - add r9, r8, #CTX_SYS_SP - stmia r9, {sp,lr} - - cps 0x17 @ Abort mode - mrs r12, spsr - add r9, r8, #CTX_ABT_SPSR - stmia r9, {r12,sp,lr} - - cps 0x12 @ IRQ mode - mrs r12, spsr - add r9, r8, #CTX_IRQ_SPSR - stmia r9, {r12,sp,lr} - - cps 0x1b @ Undefined mode - mrs r12, spsr - add r9, r8, #CTX_UND_SPSR - stmia r9, {r12,sp,lr} - - mov r0, r8 - add r1, r8, #CTX_FIQ_SPSR - cps 0x11 @ FIQ mode - mrs r7, spsr - stmia r1, {r7-r12,sp,lr} - - cps 0x13 @ back to SVC - mov r8, r0 - - /* Save CP14 debug controller context */ - add r9, r8, #CTX_CP14_REGS - mrc p14, 0, r0, c0, c1, 0 @ DSCR - mrc p14, 0, r1, c0, c6, 0 @ WFAR - mrc p14, 0, r2, c0, c7, 0 @ VCR - mrc p14, 0, r3, c7, c9, 6 @ CLAIM - stmia r9, {r0-r3} - - add r9, r8, #CTS_CP14_BKPT_0 - mrc p14, 0, r2, c0, c0, 4 - mrc p14, 0, r3, c0, c0, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - mrc p14, 0, r2, c0, c1, 4 - mrc p14, 0, r3, c0, c1, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - mrc p14, 0, r2, c0, c2, 4 - mrc p14, 0, r3, c0, c2, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - mrc p14, 0, r2, c0, c3, 4 - mrc p14, 0, r3, c0, c3, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - mrc p14, 0, r2, c0, c4, 4 - mrc p14, 0, r3, c0, c4, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - mrc p14, 0, r2, c0, c5, 4 - mrc p14, 0, r3, c0, c5, 5 - stmia r9!, {r2-r3} @ BRKPT_0 - - add r9, r8, #CTS_CP14_WPT_0 - mrc p14, 0, r2, c0, c0, 6 - mrc p14, 0, r3, c0, c0, 7 - stmia r9!, {r2-r3} @ WPT_0 - mrc p14, 0, r2, c0, c1, 6 - mrc p14, 0, r3, c0, c1, 7 - stmia r9!, {r2-r3} @ WPT_0 - mrc p14, 0, r2, c0, c2, 6 - mrc p14, 0, r3, c0, c2, 7 - stmia r9!, {r2-r3} @ WPT_0 - mrc p14, 0, r2, c0, c3, 6 - mrc p14, 0, r3, c0, c3, 7 - stmia r9!, {r2-r3} @ WPT_0 - -#ifdef CONFIG_CACHE_L2X0 - cpu_id r4 - cmp r4, #0 - bne __cortex_a9_save_clean_cache - mov32 r4, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT) - add r9, r8, #CTX_L2_CTRL - ldr r0, [r4, #L2X0_CTRL] - ldr r1, [r4, #L2X0_AUX_CTRL] - ldr r2, [r4, #L2X0_TAG_LATENCY_CTRL] - ldr r3, [r4, #L2X0_DATA_LATENCY_CTRL] - ldr r4, [r4, #L2X0_PREFETCH_OFFSET] - stmia r9, {r0-r4} -#endif - - -__cortex_a9_save_clean_cache: - mov r10, r8 - add r9, r10, #(CONTEXT_SIZE_BYTES) - add r9, r9, #(L1_CACHE_BYTES-1) - bic r10, r10, #(L1_CACHE_BYTES-1) - bic r9, r9, #(L1_CACHE_BYTES-1) - -3: mcr p15, 0, r10, c7, c10, 1 - add r10, r10, #L1_CACHE_BYTES - cmp r10, r9 - blo 3b - dsb - - translate r10, r8, r1 - - mov r0, #0 - mcr p15, 0, r0, c1, c0, 1 @ exit coherency - isb - cpu_id r0 - mov32 r1, (TEGRA_ARM_PERIF_BASE-IO_CPU_PHYS+IO_CPU_VIRT+0xC) - mov r3, r0, lsl #2 - mov r2, #0xf - mov r2, r2, lsl r3 - str r2, [r1] @ invalidate SCU tags for CPU - - cmp r0, #0 - bne __put_cpu_in_reset - mov r8, r10 - b __tear_down_master -ENDPROC(__cortex_a9_save) - -/* - * __cortex_a9_restore - * - * reloads the volatile CPU state from the context area - * the MMU should already be enabled using the secondary_data - * page tables for cpu_up before this function is called, and the - * CPU should be coherent with the SMP complex - */ - .align L1_CACHE_SHIFT -ENTRY(__cortex_a9_restore) - cps 0x13 - ctx_ptr r0, r9 - - cps 0x11 @ FIQ mode - add r1, r0, #CTX_FIQ_SPSR - ldmia r1, {r7-r12,sp,lr} - msr spsr_fsxc, r7 - - cps 0x12 @ IRQ mode - add r1, r0, #CTX_IRQ_SPSR - ldmia r1, {r12, sp, lr} - msr spsr_fsxc, r12 - - cps 0x17 @ abort mode - add r1, r0, #CTX_ABT_SPSR - ldmia r1, {r12, sp, lr} - msr spsr_fsxc, r12 - - cps 0x1f @ SYS mode - add r1, r0, #CTX_SYS_SP - ldmia r1, {sp, lr} - - cps 0x1b @ Undefined mode - add r1, r0, #CTX_UND_SPSR - ldmia r1, {r12, sp, lr} - msr spsr_fsxc, r12 - - cps 0x13 @ back to SVC - mov r8, r0 - - add r9, r8, #CTX_CSSELR - ldmia r9, {r0-r3} - - mcr p15, 2, r0, c0, c0, 0 @ csselr - mcr p15, 0, r1, c1, c0, 0 @ sctlr - mcr p15, 0, r2, c1, c0, 1 @ actlr - mcr p15, 0, r3, c15, c0, 0 @ pctlr - - add r9, r8, #CTX_TTBR0 - ldmia r9!, {r0-r7} - - mcr p15, 0, r4, c7, c4, 0 @ PAR - mcr p15, 0, r7, c12, c0, 0 @ VBAR - mcr p15, 0, r3, c3, c0, 0 @ domain access control reg - isb - mcr p15, 0, r2, c2, c0, 2 @ TTBCR - isb - mcr p15, 0, r5, c10, c2, 0 @ PRRR - isb - mcr p15, 0, r6, c10, c2, 1 @ NMRR - isb - - ldmia r9, {r4-r7} - - mcr p15, 0, r5, c13, c0, 2 @ TPIDRURW - mcr p15, 0, r6, c13, c0, 3 @ TPIDRURO - mcr p15, 0, r7, c13, c0, 4 @ TPIDRPRW - - ldmia r8, {r5-r7, lr} - - /* perform context switch to previous context */ - mov r9, #0 - mcr p15, 0, r9, c13, c0, 1 @ set reserved context - isb - mcr p15, 0, r0, c2, c0, 0 @ TTBR0 - isb - mcr p15, 0, r4, c13, c0, 1 @ CONTEXTIDR - isb - mcr p15, 0, r1, c2, c0, 1 @ TTBR1 - isb - - mov r4, #0 - mcr p15, 0, r4, c8, c3, 0 @ invalidate TLB - mcr p15, 0, r4, c7, c5, 6 @ flush BTAC - mcr p15, 0, r4, c7, c5, 0 @ flush instruction cache - dsb - isb - - mov sp, r5 - msr cpsr_cxsf, r6 - msr spsr_cxsf, r7 - - /* Restore CP14 debug controller context */ - add r9, r8, #CTX_CP14_REGS - ldmia r9, {r0-r3} - mcr p14, 0, r1, c0, c6, 0 @ WFAR - mcr p14, 0, r2, c0, c7, 0 @ VCR - mcr p14, 0, r3, c7, c8, 6 @ CLAIM - - add r9, r8, #CTS_CP14_BKPT_0 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c0, 4 - mcr p14, 0, r3, c0, c0, 5 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c1, 4 - mcr p14, 0, r3, c0, c1, 5 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c2, 4 - mcr p14, 0, r3, c0, c2, 5 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c3, 4 - mcr p14, 0, r3, c0, c3, 5 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c4, 4 - mcr p14, 0, r3, c0, c4, 5 - ldmia r9!, {r2-r3} @ BRKPT_0 - mcr p14, 0, r2, c0, c5, 4 - mcr p14, 0, r3, c0, c5, 5 - - add r9, r8, #CTS_CP14_WPT_0 - ldmia r9!, {r2-r3} @ WPT_0 - mcr p14, 0, r2, c0, c0, 6 - mcr p14, 0, r3, c0, c0, 7 - ldmia r9!, {r2-r3} @ WPT_0 - mcr p14, 0, r2, c0, c1, 6 - mcr p14, 0, r3, c0, c1, 7 - ldmia r9!, {r2-r3} @ WPT_0 - mcr p14, 0, r2, c0, c2, 6 - mcr p14, 0, r3, c0, c2, 7 - ldmia r9!, {r2-r3} @ WPT_0 - mcr p14, 0, r2, c0, c3, 6 - mcr p14, 0, r3, c0, c3, 7 - isb - mcr p14, 0, r0, c0, c2, 2 @ DSCR - isb - -#ifdef CONFIG_VFPv3 - orr r4, lr, #0xF00000 - mcr p15, 0, r4, c1, c0, 2 @ enable coproc access - mov r5, #0x40000000 - VFPFMXR FPEXC, r5 @ enable FPU access - add r9, r8, #CTX_VFP_REGS - add r7, r8, #CTX_FPEXC - VFPFLDMIA r9, r10 - ldmia r7, {r0, r4} - VFPFMXR FPSCR, r4 - VFPFMXR FPEXC, r0 -#endif - mcr p15, 0, lr, c1, c0, 2 @ cpacr (loaded before VFP) - - ldr r9, [r8, #CTX_DIAGNOSTIC] - mcr p15, 0, r9, c15, c0, 1 @ diag - - /* finally, restore the stack and return */ - ldmfd sp!, {r3-r12, lr} - msr cpsr_fsxc, r3 @ restore original processor mode - isb - mov pc, lr -ENDPROC(__cortex_a9_restore) - -/* - * __cortex_a9_l2x0_restart(bool invalidate) - * - * Reconfigures the L2 cache following a power event. - */ - .align L1_CACHE_SHIFT -ENTRY(__cortex_a9_l2x0_restart) -#ifdef CONFIG_CACHE_L2X0 - ctx_ptr r8, r9 - mov32 r9, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT) - add r10, r8, #CTX_L2_CTRL - ldmia r10, {r3-r7} - str r5, [r9, #L2X0_TAG_LATENCY_CTRL] - str r6, [r9, #L2X0_DATA_LATENCY_CTRL] - str r7, [r9, #L2X0_PREFETCH_OFFSET] - str r4, [r9, #L2X0_AUX_CTRL] - mov r4, #0x2 @ L2X0_DYNAMIC_CLK_GATING_EN - str r4, [r9, #L2X0_PWR_CTRL] - cmp r0, #0 - - beq __reenable_l2x0 - - mov r0, #0xff - str r0, [r9, #L2X0_INV_WAY] -1: ldr r1, [r9, #L2X0_INV_WAY] - tst r1, r0 - bne 1b - mov r0, #0 - str r0, [r9, #L2X0_CACHE_SYNC] -__reenable_l2x0: - mov r5, #0 - mcr p15, 0, r5, c8, c3, 0 @ invalidate TLB - mcr p15, 0, r5, c7, c5, 6 @ flush BTAC - mcr p15, 0, r5, c7, c5, 0 @ flush instruction cache - dsb - isb - str r3, [r9, #L2X0_CTRL] -#endif - b __cortex_a9_restore - - - .align L1_CACHE_SHIFT -ENTRY(__shut_off_mmu) - mrc p15, 0, r3, c1, c0, 0 - movw r2, #(1<<12) | (1<<11) | (1<<2) | (1<<0) - bic r3, r3, r2 - dsb - mcr p15, 0, r3, c1, c0, 0 - isb - bx r9 -ENDPROC(__shut_off_mmu) - -/* - * __invalidate_l1 - * - * Invalidates the L1 data cache (no clean) during initial boot of - * a secondary processor - * - * Corrupted registers: r0-r6 - */ -__invalidate_l1: - mov r0, #0 - mcr p15, 2, r0, c0, c0, 0 - mrc p15, 1, r0, c0, c0, 0 - - movw r1, #0x7fff - and r2, r1, r0, lsr #13 - - movw r1, #0x3ff - - and r3, r1, r0, lsr #3 @ NumWays - 1 - add r2, r2, #1 @ NumSets - - and r0, r0, #0x7 - add r0, r0, #4 @ SetShift - - clz r1, r3 @ WayShift - add r4, r3, #1 @ NumWays -1: sub r2, r2, #1 @ NumSets-- - mov r3, r4 @ Temp = NumWays -2: subs r3, r3, #1 @ Temp-- - mov r5, r3, lsl r1 - mov r6, r2, lsl r0 - orr r5, r5, r6 @ Reg = (Temp< - * Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -/* - * Frequency table index must be sequential starting at 0 and frequencies - * must be ascending. - */ -static struct cpufreq_frequency_table freq_table[] = { - { 0, 216000 }, - { 1, 312000 }, - { 2, 456000 }, - { 3, 608000 }, - { 4, 760000 }, - { 5, 816000 }, - { 6, 912000 }, - { 7, 1000000 }, - { 8, CPUFREQ_TABLE_END }, -}; - -#define NUM_CPUS 2 - -static struct clk *cpu_clk; -static struct clk *emc_clk; - -static unsigned long target_cpu_speed[NUM_CPUS]; -static DEFINE_MUTEX(tegra_cpu_lock); -static bool is_suspended; - -unsigned int tegra_getspeed(unsigned int cpu); -static int tegra_update_cpu_speed(unsigned long rate); -static unsigned long tegra_cpu_highest_speed(void); - -#ifdef CONFIG_TEGRA_THERMAL_THROTTLE -/* CPU frequency is gradually lowered when throttling is enabled */ -#define THROTTLE_LOWEST_INDEX 2 /* 456000 */ -#define THROTTLE_HIGHEST_INDEX 6 /* 912000 */ -#define THROTTLE_DELAY msecs_to_jiffies(2000) - -static bool is_throttling; -static int throttle_index; -static int throttle_next_index; -static struct delayed_work throttle_work; -static struct workqueue_struct *workqueue; - -#define tegra_cpu_is_throttling() (is_throttling) - -static void tegra_throttle_work_func(struct work_struct *work) -{ - unsigned int current_freq; - - mutex_lock(&tegra_cpu_lock); - current_freq = tegra_getspeed(0); - throttle_index = throttle_next_index; - - if (freq_table[throttle_index].frequency < current_freq) - tegra_update_cpu_speed(freq_table[throttle_index].frequency); - - if (throttle_index > THROTTLE_LOWEST_INDEX) { - throttle_next_index = throttle_index - 1; - queue_delayed_work(workqueue, &throttle_work, THROTTLE_DELAY); - } - - mutex_unlock(&tegra_cpu_lock); -} - -/* - * tegra_throttling_enable - * This function may sleep - */ -void tegra_throttling_enable(bool enable) -{ - mutex_lock(&tegra_cpu_lock); - - if (enable && !is_throttling) { - unsigned int current_freq = tegra_getspeed(0); - - is_throttling = true; - - for (throttle_index = THROTTLE_HIGHEST_INDEX; - throttle_index >= THROTTLE_LOWEST_INDEX; - throttle_index--) - if (freq_table[throttle_index].frequency - < current_freq) - break; - - throttle_index = max(throttle_index, THROTTLE_LOWEST_INDEX); - throttle_next_index = throttle_index; - queue_delayed_work(workqueue, &throttle_work, 0); - } else if (!enable && is_throttling) { - cancel_delayed_work_sync(&throttle_work); - is_throttling = false; - /* restore speed requested by governor */ - tegra_update_cpu_speed(tegra_cpu_highest_speed()); - } - - mutex_unlock(&tegra_cpu_lock); -} -EXPORT_SYMBOL_GPL(tegra_throttling_enable); - -static unsigned int throttle_governor_speed(unsigned int requested_speed) -{ - return tegra_cpu_is_throttling() ? - min(requested_speed, freq_table[throttle_index].frequency) : - requested_speed; -} - -static ssize_t show_throttle(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%u\n", is_throttling); -} - -cpufreq_freq_attr_ro(throttle); - -#ifdef CONFIG_DEBUG_FS -static int throttle_debug_set(void *data, u64 val) -{ - tegra_throttling_enable(val); - return 0; -} -static int throttle_debug_get(void *data, u64 *val) -{ - *val = (u64) is_throttling; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(throttle_fops, throttle_debug_get, throttle_debug_set, "%llu\n"); - -static struct dentry *cpu_tegra_debugfs_root; - -static int __init tegra_cpu_debug_init(void) -{ - cpu_tegra_debugfs_root = debugfs_create_dir("cpu-tegra", 0); - - if (!cpu_tegra_debugfs_root) - return -ENOMEM; - - if (!debugfs_create_file("throttle", 0644, cpu_tegra_debugfs_root, NULL, &throttle_fops)) - goto err_out; - - return 0; - -err_out: - debugfs_remove_recursive(cpu_tegra_debugfs_root); - return -ENOMEM; - -} - -static void __exit tegra_cpu_debug_exit(void) -{ - debugfs_remove_recursive(cpu_tegra_debugfs_root); -} - -late_initcall(tegra_cpu_debug_init); -module_exit(tegra_cpu_debug_exit); -#endif /* CONFIG_DEBUG_FS */ - -#else /* CONFIG_TEGRA_THERMAL_THROTTLE */ -#define tegra_cpu_is_throttling() (0) -#define throttle_governor_speed(requested_speed) (requested_speed) - -void tegra_throttling_enable(bool enable) -{ -} -#endif /* CONFIG_TEGRA_THERMAL_THROTTLE */ - -int tegra_verify_speed(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, freq_table); -} - -unsigned int tegra_getspeed(unsigned int cpu) -{ - unsigned long rate; - - if (cpu >= NUM_CPUS) - return 0; - - rate = clk_get_rate(cpu_clk) / 1000; - return rate; -} - -static int tegra_update_cpu_speed(unsigned long rate) -{ - int ret = 0; - struct cpufreq_freqs freqs; - - freqs.old = tegra_getspeed(0); - freqs.new = rate; - - if (freqs.old == freqs.new) - return ret; - - /* - * Vote on memory bus frequency based on cpu frequency - * This sets the minimum frequency, display or avp may request higher - */ - if (rate >= 816000) - clk_set_rate(emc_clk, 600000000); /* cpu 816 MHz, emc max */ - else if (rate >= 456000) - clk_set_rate(emc_clk, 300000000); /* cpu 456 MHz, emc 150Mhz */ - else - clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */ - - for_each_online_cpu(freqs.cpu) - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - -#ifdef CONFIG_CPU_FREQ_DEBUG - printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n", - freqs.old, freqs.new); -#endif - - ret = clk_set_rate(cpu_clk, freqs.new * 1000); - if (ret) { - pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n", - freqs.new); - return ret; - } - - for_each_online_cpu(freqs.cpu) - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return 0; -} - -static unsigned long tegra_cpu_highest_speed(void) { - unsigned long rate = 0; - int i; - - for_each_online_cpu(i) - rate = max(rate, target_cpu_speed[i]); - return rate; -} - -static int tegra_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int idx; - unsigned int freq; - unsigned int new_speed; - int ret = 0; - - mutex_lock(&tegra_cpu_lock); - - if (is_suspended) { - ret = -EBUSY; - goto out; - } - - cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &idx); - - freq = freq_table[idx].frequency; - - target_cpu_speed[policy->cpu] = freq; - new_speed = throttle_governor_speed(tegra_cpu_highest_speed()); - ret = tegra_update_cpu_speed(new_speed); -out: - mutex_unlock(&tegra_cpu_lock); - return ret; -} - - -static int tegra_pm_notify(struct notifier_block *nb, unsigned long event, - void *dummy) -{ - mutex_lock(&tegra_cpu_lock); - if (event == PM_SUSPEND_PREPARE) { - is_suspended = true; - pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", - freq_table[0].frequency); - tegra_update_cpu_speed(freq_table[0].frequency); - } else if (event == PM_POST_SUSPEND) { - is_suspended = false; - } - mutex_unlock(&tegra_cpu_lock); - - return NOTIFY_OK; -} - -static struct notifier_block tegra_cpu_pm_notifier = { - .notifier_call = tegra_pm_notify, -}; - -static int tegra_cpu_init(struct cpufreq_policy *policy) -{ - if (policy->cpu >= NUM_CPUS) - return -EINVAL; - - cpu_clk = clk_get_sys(NULL, "cpu"); - if (IS_ERR(cpu_clk)) - return PTR_ERR(cpu_clk); - - emc_clk = clk_get_sys("cpu", "emc"); - if (IS_ERR(emc_clk)) { - clk_put(cpu_clk); - return PTR_ERR(emc_clk); - } - clk_enable(emc_clk); - - cpufreq_frequency_table_cpuinfo(policy, freq_table); - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); - policy->cur = tegra_getspeed(policy->cpu); - target_cpu_speed[policy->cpu] = policy->cur; - - /* FIXME: what's the actual transition time? */ - policy->cpuinfo.transition_latency = 300 * 1000; - - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - cpumask_copy(policy->related_cpus, cpu_possible_mask); - - if (policy->cpu == 0) { - register_pm_notifier(&tegra_cpu_pm_notifier); - } - - return 0; -} - -static int tegra_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_cpuinfo(policy, freq_table); - clk_disable(emc_clk); - clk_put(emc_clk); - clk_put(cpu_clk); - return 0; -} - -static struct freq_attr *tegra_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, -#ifdef CONFIG_TEGRA_THERMAL_THROTTLE - &throttle, -#endif - NULL, -}; - -static struct cpufreq_driver tegra_cpufreq_driver = { - .verify = tegra_verify_speed, - .target = tegra_target, - .get = tegra_getspeed, - .init = tegra_cpu_init, - .exit = tegra_cpu_exit, - .name = "tegra", - .attr = tegra_cpufreq_attr, -}; - -static int __init tegra_cpufreq_init(void) -{ -#ifdef CONFIG_TEGRA_THERMAL_THROTTLE - /* - * High-priority, others flags default: not bound to a specific - * CPU, has rescue worker task (in case of allocation deadlock, - * etc.). Single-threaded. - */ - workqueue = alloc_workqueue("cpu-tegra", - WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1); - if (!workqueue) - return -ENOMEM; - INIT_DELAYED_WORK(&throttle_work, tegra_throttle_work_func); -#endif - return cpufreq_register_driver(&tegra_cpufreq_driver); -} - -static void __exit tegra_cpufreq_exit(void) -{ -#ifdef CONFIG_TEGRA_THERMAL_THROTTLE - destroy_workqueue(workqueue); -#endif - cpufreq_unregister_driver(&tegra_cpufreq_driver); -} - - -MODULE_AUTHOR("Colin Cross "); -MODULE_DESCRIPTION("cpufreq driver for Nvidia Tegra2"); -MODULE_LICENSE("GPL"); -module_init(tegra_cpufreq_init); -module_exit(tegra_cpufreq_exit); diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c deleted file mode 100644 index 23cb9acc588c..000000000000 --- a/arch/arm/mach-tegra/cpuidle.c +++ /dev/null @@ -1,714 +0,0 @@ -/* - * arch/arm/mach-tegra/cpuidle.c - * - * CPU idle driver for Tegra CPUs - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "power.h" - -#define TEGRA_CPUIDLE_BOTH_IDLE INT_QUAD_RES_24 -#define TEGRA_CPUIDLE_TEAR_DOWN INT_QUAD_RES_25 - -#define EVP_CPU_RESET_VECTOR \ - (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) -#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340) -#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) -#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) - -static bool lp2_in_idle __read_mostly = true; -static bool lp2_disabled_by_suspend; -module_param(lp2_in_idle, bool, 0644); - -static s64 tegra_cpu1_idle_time = LLONG_MAX;; -static int tegra_lp2_exit_latency; -static int tegra_lp2_power_off_time; - -static struct { - unsigned int cpu_ready_count[2]; - unsigned long long cpu_wants_lp2_time[2]; - unsigned long long in_lp2_time; - unsigned int both_idle_count; - unsigned int tear_down_count; - unsigned int lp2_count; - unsigned int lp2_completed_count; - unsigned int lp2_count_bin[32]; - unsigned int lp2_completed_count_bin[32]; - unsigned int lp2_int_count[NR_IRQS]; - unsigned int last_lp2_int_count[NR_IRQS]; -} idle_stats; - -struct cpuidle_driver tegra_idle = { - .name = "tegra_idle", - .owner = THIS_MODULE, -}; - -static DEFINE_PER_CPU(struct cpuidle_device *, idle_devices); - -#define FLOW_CTRL_WAITEVENT (2<<29) -#define FLOW_CTRL_JTAG_RESUME (1<<28) -#define FLOW_CTRL_HALT_CPUx_EVENTS(cpu) ((cpu)?((cpu-1)*0x8 + 0x14) : 0x0) - -#define PMC_SCRATCH_38 0x134 -#define PMC_SCRATCH_39 0x138 - -#define CLK_RESET_CLK_MASK_ARM 0x44 - -static inline unsigned int time_to_bin(unsigned int time) -{ - return fls(time); -} - -static inline void tegra_unmask_irq(int irq) -{ - struct irq_chip *chip = get_irq_chip(irq); - chip->unmask(irq); -} - -static inline void tegra_mask_irq(int irq) -{ - struct irq_chip *chip = get_irq_chip(irq); - chip->mask(irq); -} - -static inline int tegra_pending_interrupt(void) -{ - void __iomem *gic_cpu = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100); - u32 reg = readl(gic_cpu + 0x18); - reg &= 0x3FF; - - return reg; -} - -static inline void tegra_flow_wfi(struct cpuidle_device *dev) -{ - void __iomem *flow_ctrl = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE); - u32 reg = FLOW_CTRL_WAITEVENT | FLOW_CTRL_JTAG_RESUME; - - flow_ctrl = flow_ctrl + FLOW_CTRL_HALT_CPUx_EVENTS(dev->cpu); - - stop_critical_timings(); - dsb(); - __raw_writel(reg, flow_ctrl); - reg = __raw_readl(flow_ctrl); - __asm__ volatile ("wfi"); - __raw_writel(0, flow_ctrl); - reg = __raw_readl(flow_ctrl); - start_critical_timings(); -} - -#ifdef CONFIG_SMP -static inline bool tegra_wait_for_both_idle(struct cpuidle_device *dev) -{ - int wake_int; - - tegra_unmask_irq(TEGRA_CPUIDLE_BOTH_IDLE); - - tegra_flow_wfi(dev); - - wake_int = tegra_pending_interrupt(); - - tegra_mask_irq(TEGRA_CPUIDLE_BOTH_IDLE); - - return wake_int == TEGRA_CPUIDLE_BOTH_IDLE && - tegra_pending_interrupt() == 1023; -} - -static inline bool tegra_wait_for_tear_down(struct cpuidle_device *dev) -{ - int wake_int; - irq_set_affinity(TEGRA_CPUIDLE_TEAR_DOWN, cpumask_of(1)); - tegra_unmask_irq(TEGRA_CPUIDLE_TEAR_DOWN); - - tegra_flow_wfi(dev); - - wake_int = tegra_pending_interrupt(); - - tegra_mask_irq(TEGRA_CPUIDLE_TEAR_DOWN); - - return wake_int == TEGRA_CPUIDLE_TEAR_DOWN && - tegra_pending_interrupt() == 1023; -} - -static inline bool tegra_cpu_in_reset(int cpu) -{ - return !!(readl(CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET) & (1 << cpu)); -} - -static int tegra_tear_down_cpu1(void) -{ - u32 reg; - - /* Signal to CPU1 to tear down */ - tegra_legacy_force_irq_set(TEGRA_CPUIDLE_TEAR_DOWN); - - /* At this point, CPU0 can no longer abort LP2, but CP1 can */ - /* TODO: any way not to poll here? Use the LP2 timer to wfi? */ - /* takes ~80 us */ - while (!tegra_cpu_in_reset(1) && - tegra_legacy_force_irq_status(TEGRA_CPUIDLE_BOTH_IDLE)) - cpu_relax(); - - tegra_legacy_force_irq_clr(TEGRA_CPUIDLE_TEAR_DOWN); - - /* If CPU1 aborted LP2, restart the process */ - if (!tegra_legacy_force_irq_status(TEGRA_CPUIDLE_BOTH_IDLE)) - return -EAGAIN; - - /* CPU1 is ready for LP2, clock gate it */ - reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - writel(reg | (1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - - return 0; -} - -static void tegra_wake_cpu1(void) -{ - unsigned long boot_vector; - unsigned long old_boot_vector; - unsigned long timeout; - u32 reg; - - boot_vector = virt_to_phys(tegra_hotplug_startup); - old_boot_vector = readl(EVP_CPU_RESET_VECTOR); - writel(boot_vector, EVP_CPU_RESET_VECTOR); - - /* enable cpu clock on cpu */ - reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - writel(reg & ~(1 << (8 + 1)), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - - reg = 0x1111 << 1; - writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); - - /* unhalt the cpu */ - writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14); - - timeout = jiffies + msecs_to_jiffies(1000); - while (time_before(jiffies, timeout)) { - if (readl(EVP_CPU_RESET_VECTOR) != boot_vector) - break; - udelay(10); - } - - /* put the old boot vector back */ - writel(old_boot_vector, EVP_CPU_RESET_VECTOR); - - /* CPU1 is now started */ -} -#else -static inline bool tegra_wait_for_both_idle(struct cpuidle_device *dev) -{ - return true; -} - -static inline int tegra_tear_down_cpu1(void) -{ - return 0; -} - -static inline void tegra_wake_cpu1(void) -{ -} -#endif - -static void tegra_idle_enter_lp2_cpu0(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - s64 request; - ktime_t enter; - ktime_t exit; - bool sleep_completed = false; - int bin; - -restart: - if (!tegra_wait_for_both_idle(dev)) - return; - - idle_stats.both_idle_count++; - - if (need_resched()) - return; - - /* CPU1 woke CPU0 because both are idle */ - - request = ktime_to_us(tick_nohz_get_sleep_length()); - if (request < state->target_residency) { - /* Not enough time left to enter LP2 */ - tegra_flow_wfi(dev); - return; - } - - idle_stats.tear_down_count++; - - if (tegra_tear_down_cpu1()) - goto restart; - - /* Enter LP2 */ - request = ktime_to_us(tick_nohz_get_sleep_length()); - smp_rmb(); - request = min_t(s64, request, tegra_cpu1_idle_time); - - enter = ktime_get(); - if (request > state->target_residency) { - s64 sleep_time = request - tegra_lp2_exit_latency; - - bin = time_to_bin((u32)request / 1000); - idle_stats.lp2_count++; - idle_stats.lp2_count_bin[bin]++; - - if (tegra_suspend_lp2(sleep_time) == 0) - sleep_completed = true; - else - idle_stats.lp2_int_count[tegra_pending_interrupt()]++; - } - - /* Bring CPU1 out of LP2 */ - /* TODO: polls for CPU1 to boot, wfi would be better */ - /* takes ~80 us */ - - /* set the reset vector to point to the secondary_startup routine */ - smp_wmb(); - - tegra_wake_cpu1(); - - /* - * TODO: is it worth going back to wfi if no interrupt is pending - * and the requested sleep time has not passed? - */ - - exit = ktime_get(); - if (sleep_completed) { - /* - * Stayed in LP2 for the full time until the next tick, - * adjust the exit latency based on measurement - */ - int offset = ktime_to_us(ktime_sub(exit, enter)) - request; - int latency = tegra_lp2_exit_latency + offset / 16; - latency = clamp(latency, 0, 10000); - tegra_lp2_exit_latency = latency; - smp_wmb(); - - idle_stats.lp2_completed_count++; - idle_stats.lp2_completed_count_bin[bin]++; - idle_stats.in_lp2_time += ktime_to_us(ktime_sub(exit, enter)); - - pr_debug("%lld %lld %d %d\n", request, - ktime_to_us(ktime_sub(exit, enter)), - offset, bin); - } -} - -#ifdef CONFIG_SMP -static void tegra_idle_enter_lp2_cpu1(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - u32 twd_ctrl; - u32 twd_load; - s64 request; - - tegra_legacy_force_irq_set(TEGRA_CPUIDLE_BOTH_IDLE); - - if (!tegra_wait_for_tear_down(dev)) - goto out; - - if (need_resched()) - goto out; - - /* - * CPU1 woke CPU0 because both were idle - * CPU0 responded by waking CPU1 to tell it to disable itself - */ - - request = ktime_to_us(tick_nohz_get_sleep_length()); - if (request < tegra_lp2_exit_latency) { - /* - * Not enough time left to enter LP2 - * Signal to CPU0 that CPU1 rejects LP2, and stay in - */ - tegra_legacy_force_irq_clr(TEGRA_CPUIDLE_BOTH_IDLE); - tegra_flow_wfi(dev); - goto out; - } - - tegra_cpu1_idle_time = request; - smp_wmb(); - - /* Prepare CPU1 for LP2 by putting it in reset */ - - stop_critical_timings(); - gic_cpu_exit(0); - barrier(); - twd_ctrl = readl(twd_base + 0x8); - twd_load = readl(twd_base + 0); - - flush_cache_all(); - barrier(); - __cortex_a9_save(0); - /* CPU1 is in reset, waiting for CPU0 to boot it, possibly after LP2 */ - - - /* CPU0 booted CPU1 out of reset */ - barrier(); - writel(twd_ctrl, twd_base + 0x8); - writel(twd_load, twd_base + 0); - gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100); - tegra_unmask_irq(IRQ_LOCALTIMER); - - tegra_legacy_force_irq_clr(TEGRA_CPUIDLE_BOTH_IDLE); - - writel(smp_processor_id(), EVP_CPU_RESET_VECTOR); - start_critical_timings(); - - /* - * TODO: is it worth going back to wfi if no interrupt is pending - * and the requested sleep time has not passed? - */ - - return; - -out: - tegra_legacy_force_irq_clr(TEGRA_CPUIDLE_BOTH_IDLE); -} -#endif - -static int tegra_idle_enter_lp3(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - ktime_t enter, exit; - s64 us; - - local_irq_disable(); - local_fiq_disable(); - - enter = ktime_get(); - if (!need_resched()) - tegra_flow_wfi(dev); - exit = ktime_sub(ktime_get(), enter); - us = ktime_to_us(exit); - - local_fiq_enable(); - local_irq_enable(); - return (int)us; -} - -static int tegra_idle_enter_lp2(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - ktime_t enter, exit; - s64 us; - - if (!lp2_in_idle || lp2_disabled_by_suspend) - return tegra_idle_enter_lp3(dev, state); - - local_irq_disable(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); - local_fiq_disable(); - enter = ktime_get(); - - idle_stats.cpu_ready_count[dev->cpu]++; - -#ifdef CONFIG_SMP - if (dev->cpu == 0) - tegra_idle_enter_lp2_cpu0(dev, state); - else - tegra_idle_enter_lp2_cpu1(dev, state); -#else - tegra_idle_enter_lp2_cpu0(dev, state); -#endif - - exit = ktime_sub(ktime_get(), enter); - us = ktime_to_us(exit); - - local_fiq_enable(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); - local_irq_enable(); - - smp_rmb(); - state->exit_latency = tegra_lp2_exit_latency; - state->target_residency = tegra_lp2_exit_latency + - tegra_lp2_power_off_time; - - idle_stats.cpu_wants_lp2_time[dev->cpu] += us; - - return (int)us; -} - -static int tegra_cpuidle_register_device(unsigned int cpu) -{ - struct cpuidle_device *dev; - struct cpuidle_state *state; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->state_count = 0; - dev->cpu = cpu; - - tegra_lp2_power_off_time = tegra_cpu_power_off_time(); - - state = &dev->states[0]; - snprintf(state->name, CPUIDLE_NAME_LEN, "LP3"); - snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU flow-controlled"); - state->exit_latency = 10; - state->target_residency = 10; - state->power_usage = 600; - state->flags = CPUIDLE_FLAG_SHALLOW | CPUIDLE_FLAG_TIME_VALID; - state->enter = tegra_idle_enter_lp3; - dev->safe_state = state; - dev->state_count++; - - state = &dev->states[1]; - snprintf(state->name, CPUIDLE_NAME_LEN, "LP2"); - snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU power-gate"); - state->exit_latency = tegra_cpu_power_good_time(); - - state->target_residency = tegra_cpu_power_off_time() + - tegra_cpu_power_good_time(); - state->power_usage = 0; - state->flags = CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_TIME_VALID; - state->enter = tegra_idle_enter_lp2; - - dev->power_specified = 1; - dev->safe_state = state; - dev->state_count++; - - if (cpuidle_register_device(dev)) { - pr_err("CPU%u: failed to register idle device\n", cpu); - kfree(dev); - return -EIO; - } - per_cpu(idle_devices, cpu) = dev; - return 0; -} - -/* The IRQs that are used for communication between the cpus to agree on the - * cpuidle state should never get handled - */ -static irqreturn_t tegra_cpuidle_irq(int irq, void *dev) -{ - pr_err("%s: unexpected interrupt %d on cpu %d\n", __func__, irq, - smp_processor_id()); - BUG(); -} - -static int tegra_cpuidle_pm_notify(struct notifier_block *nb, - unsigned long event, void *dummy) -{ - if (event == PM_SUSPEND_PREPARE) - lp2_disabled_by_suspend = true; - else if (event == PM_POST_SUSPEND) - lp2_disabled_by_suspend = false; - - return NOTIFY_OK; -} - -static struct notifier_block tegra_cpuidle_pm_notifier = { - .notifier_call = tegra_cpuidle_pm_notify, -}; - -static int __init tegra_cpuidle_init(void) -{ - unsigned int cpu; - void __iomem *mask_arm; - unsigned int reg; - int ret; - - irq_set_affinity(TEGRA_CPUIDLE_BOTH_IDLE, cpumask_of(0)); - irq_set_affinity(TEGRA_CPUIDLE_TEAR_DOWN, cpumask_of(1)); - - ret = request_irq(TEGRA_CPUIDLE_BOTH_IDLE, tegra_cpuidle_irq, - IRQF_NOAUTOEN, "tegra_cpuidle_both_idle", NULL); - if (ret) { - pr_err("%s: Failed to request cpuidle irq\n", __func__); - return ret; - } - - ret = request_irq(TEGRA_CPUIDLE_TEAR_DOWN, tegra_cpuidle_irq, - IRQF_NOAUTOEN, "tegra_cpuidle_tear_down_cpu1", NULL); - if (ret) { - pr_err("%s: Failed to request cpuidle irq\n", __func__); - return ret; - } - - - disable_irq(TEGRA_CPUIDLE_BOTH_IDLE); - disable_irq(TEGRA_CPUIDLE_TEAR_DOWN); - tegra_mask_irq(TEGRA_CPUIDLE_BOTH_IDLE); - tegra_mask_irq(TEGRA_CPUIDLE_TEAR_DOWN); - - mask_arm = IO_ADDRESS(TEGRA_CLK_RESET_BASE) + CLK_RESET_CLK_MASK_ARM; - - reg = readl(mask_arm); - writel(reg | (1<<31), mask_arm); - - ret = cpuidle_register_driver(&tegra_idle); - - if (ret) - return ret; - - for_each_possible_cpu(cpu) { - if (tegra_cpuidle_register_device(cpu)) - pr_err("CPU%u: error initializing idle loop\n", cpu); - } - - tegra_lp2_exit_latency = tegra_cpu_power_good_time(); - - register_pm_notifier(&tegra_cpuidle_pm_notifier); - - return 0; -} - -static void __exit tegra_cpuidle_exit(void) -{ - cpuidle_unregister_driver(&tegra_idle); -} - -module_init(tegra_cpuidle_init); -module_exit(tegra_cpuidle_exit); - -#ifdef CONFIG_DEBUG_FS -static int tegra_lp2_debug_show(struct seq_file *s, void *data) -{ - int bin; - int i; - seq_printf(s, " cpu0 cpu1\n"); - seq_printf(s, "-------------------------------------------------\n"); - seq_printf(s, "cpu ready: %8u %8u\n", - idle_stats.cpu_ready_count[0], - idle_stats.cpu_ready_count[1]); - seq_printf(s, "both idle: %8u %7u%% %7u%%\n", - idle_stats.both_idle_count, - idle_stats.both_idle_count * 100 / - (idle_stats.cpu_ready_count[0] ?: 1), - idle_stats.both_idle_count * 100 / - (idle_stats.cpu_ready_count[1] ?: 1)); - seq_printf(s, "tear down: %8u %7u%%\n", idle_stats.tear_down_count, - idle_stats.tear_down_count * 100 / - (idle_stats.both_idle_count ?: 1)); - seq_printf(s, "lp2: %8u %7u%%\n", idle_stats.lp2_count, - idle_stats.lp2_count * 100 / - (idle_stats.both_idle_count ?: 1)); - seq_printf(s, "lp2 completed: %8u %7u%%\n", - idle_stats.lp2_completed_count, - idle_stats.lp2_completed_count * 100 / - (idle_stats.lp2_count ?: 1)); - - seq_printf(s, "\n"); - seq_printf(s, "cpu ready time: %8llu %8llu ms\n", - div64_u64(idle_stats.cpu_wants_lp2_time[0], 1000), - div64_u64(idle_stats.cpu_wants_lp2_time[1], 1000)); - seq_printf(s, "lp2 time: %8llu ms %7d%% %7d%%\n", - div64_u64(idle_stats.in_lp2_time, 1000), - (int)div64_u64(idle_stats.in_lp2_time * 100, - idle_stats.cpu_wants_lp2_time[0] ?: 1), - (int)div64_u64(idle_stats.in_lp2_time * 100, - idle_stats.cpu_wants_lp2_time[1] ?: 1)); - - seq_printf(s, "\n"); - seq_printf(s, "%19s %8s %8s %8s\n", "", "lp2", "comp", "%"); - seq_printf(s, "-------------------------------------------------\n"); - for (bin = 0; bin < 32; bin++) { - if (idle_stats.lp2_count_bin[bin] == 0) - continue; - seq_printf(s, "%6u - %6u ms: %8u %8u %7u%%\n", - 1 << (bin - 1), 1 << bin, - idle_stats.lp2_count_bin[bin], - idle_stats.lp2_completed_count_bin[bin], - idle_stats.lp2_completed_count_bin[bin] * 100 / - idle_stats.lp2_count_bin[bin]); - } - - seq_printf(s, "\n"); - seq_printf(s, "%3s %20s %6s %10s\n", - "int", "name", "count", "last count"); - seq_printf(s, "--------------------------------------------\n"); - for (i = 0; i < NR_IRQS; i++) { - if (idle_stats.lp2_int_count[i] == 0) - continue; - seq_printf(s, "%3d %20s %6d %10d\n", - i, irq_to_desc(i)->action ? - irq_to_desc(i)->action->name ?: "???" : "???", - idle_stats.lp2_int_count[i], - idle_stats.lp2_int_count[i] - - idle_stats.last_lp2_int_count[i]); - idle_stats.last_lp2_int_count[i] = idle_stats.lp2_int_count[i]; - }; - return 0; -} - -static int tegra_lp2_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_lp2_debug_show, inode->i_private); -} - -static const struct file_operations tegra_lp2_debug_ops = { - .open = tegra_lp2_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init tegra_cpuidle_debug_init(void) -{ - struct dentry *dir; - struct dentry *d; - - dir = debugfs_create_dir("cpuidle", NULL); - if (!dir) - return -ENOMEM; - - d = debugfs_create_file("lp2", S_IRUGO, dir, NULL, - &tegra_lp2_debug_ops); - if (!d) - return -ENOMEM; - - return 0; -} -#endif - -late_initcall(tegra_cpuidle_debug_init); diff --git a/arch/arm/mach-tegra/delay.S b/arch/arm/mach-tegra/delay.S deleted file mode 100644 index c345c056bb1d..000000000000 --- a/arch/arm/mach-tegra/delay.S +++ /dev/null @@ -1,51 +0,0 @@ -/* - * arch/arm/mach-tegra/delay.S - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include -#include -#include -#include "power-macros.S" - - .text - -ENTRY(__udelay) -ENTRY(__const_udelay) - mov32 r3, (IO_PPSB_VIRT + TEGRA_TMRUS_BASE - IO_PPSB_PHYS) - ldr r1, [r3] - -/* r0 - usecs to wait - * r1 - initial value of the counter - */ -loop: - ldr r2, [r3] - sub r2, r2, r1 - cmp r2, r0 - bls loop - mov pc, lr -ENDPROC(__const_udelay) -ENDPROC(__udelay) - - -@ Delay routine -ENTRY(__delay) - subs r0, r0, #1 - bhi __delay - mov pc, lr -ENDPROC(__delay) diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c deleted file mode 100644 index dac6bbbf0e2c..000000000000 --- a/arch/arm/mach-tegra/devices.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * arch/arm/mach-tegra/devices.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * Erik Gilling - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -static struct resource i2c_resource1[] = { - [0] = { - .start = INT_I2C, - .end = INT_I2C, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_I2C_BASE, - .end = TEGRA_I2C_BASE + TEGRA_I2C_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource i2c_resource2[] = { - [0] = { - .start = INT_I2C2, - .end = INT_I2C2, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_I2C2_BASE, - .end = TEGRA_I2C2_BASE + TEGRA_I2C2_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource i2c_resource3[] = { - [0] = { - .start = INT_I2C3, - .end = INT_I2C3, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_I2C3_BASE, - .end = TEGRA_I2C3_BASE + TEGRA_I2C3_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource i2c_resource4[] = { - [0] = { - .start = INT_DVC, - .end = INT_DVC, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_DVC_BASE, - .end = TEGRA_DVC_BASE + TEGRA_DVC_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device tegra_i2c_device1 = { - .name = "tegra-i2c", - .id = 0, - .resource = i2c_resource1, - .num_resources = ARRAY_SIZE(i2c_resource1), - .dev = { - .platform_data = 0, - }, -}; - -struct platform_device tegra_i2c_device2 = { - .name = "tegra-i2c", - .id = 1, - .resource = i2c_resource2, - .num_resources = ARRAY_SIZE(i2c_resource2), - .dev = { - .platform_data = 0, - }, -}; - -struct platform_device tegra_i2c_device3 = { - .name = "tegra-i2c", - .id = 2, - .resource = i2c_resource3, - .num_resources = ARRAY_SIZE(i2c_resource3), - .dev = { - .platform_data = 0, - }, -}; - -struct platform_device tegra_i2c_device4 = { - .name = "tegra-i2c", - .id = 3, - .resource = i2c_resource4, - .num_resources = ARRAY_SIZE(i2c_resource4), - .dev = { - .platform_data = 0, - }, -}; - -static struct resource spi_resource1[] = { - [0] = { - .start = INT_S_LINK1, - .end = INT_S_LINK1, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SPI1_BASE, - .end = TEGRA_SPI1_BASE + TEGRA_SPI1_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource spi_resource2[] = { - [0] = { - .start = INT_SPI_2, - .end = INT_SPI_2, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SPI2_BASE, - .end = TEGRA_SPI2_BASE + TEGRA_SPI2_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource spi_resource3[] = { - [0] = { - .start = INT_SPI_3, - .end = INT_SPI_3, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SPI3_BASE, - .end = TEGRA_SPI3_BASE + TEGRA_SPI3_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource spi_resource4[] = { - [0] = { - .start = INT_SPI_4, - .end = INT_SPI_4, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SPI4_BASE, - .end = TEGRA_SPI4_BASE + TEGRA_SPI4_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device tegra_spi_device1 = { - .name = "spi_tegra", - .id = 0, - .resource = spi_resource1, - .num_resources = ARRAY_SIZE(spi_resource1), - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device tegra_spi_device2 = { - .name = "spi_tegra", - .id = 1, - .resource = spi_resource2, - .num_resources = ARRAY_SIZE(spi_resource2), - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device tegra_spi_device3 = { - .name = "spi_tegra", - .id = 2, - .resource = spi_resource3, - .num_resources = ARRAY_SIZE(spi_resource3), - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device tegra_spi_device4 = { - .name = "spi_tegra", - .id = 3, - .resource = spi_resource4, - .num_resources = ARRAY_SIZE(spi_resource4), - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - - -static struct resource sdhci_resource1[] = { - [0] = { - .start = INT_SDMMC1, - .end = INT_SDMMC1, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC1_BASE, - .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource2[] = { - [0] = { - .start = INT_SDMMC2, - .end = INT_SDMMC2, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC2_BASE, - .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource3[] = { - [0] = { - .start = INT_SDMMC3, - .end = INT_SDMMC3, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC3_BASE, - .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource sdhci_resource4[] = { - [0] = { - .start = INT_SDMMC4, - .end = INT_SDMMC4, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = TEGRA_SDMMC4_BASE, - .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1, - .flags = IORESOURCE_MEM, - }, -}; - -/* board files should fill in platform_data register the devices themselvs. - * See board-harmony.c for an example - */ -struct platform_device tegra_sdhci_device1 = { - .name = "sdhci-tegra", - .id = 0, - .resource = sdhci_resource1, - .num_resources = ARRAY_SIZE(sdhci_resource1), -}; - -struct platform_device tegra_sdhci_device2 = { - .name = "sdhci-tegra", - .id = 1, - .resource = sdhci_resource2, - .num_resources = ARRAY_SIZE(sdhci_resource2), -}; - -struct platform_device tegra_sdhci_device3 = { - .name = "sdhci-tegra", - .id = 2, - .resource = sdhci_resource3, - .num_resources = ARRAY_SIZE(sdhci_resource3), -}; - -struct platform_device tegra_sdhci_device4 = { - .name = "sdhci-tegra", - .id = 3, - .resource = sdhci_resource4, - .num_resources = ARRAY_SIZE(sdhci_resource4), -}; - -static struct resource w1_resources[] = { - [0] = { - .start = INT_OWR, - .end = INT_OWR, - .flags = IORESOURCE_IRQ - }, - [1] = { - .start = TEGRA_OWR_BASE, - .end = TEGRA_OWR_BASE + TEGRA_OWR_SIZE - 1, - .flags = IORESOURCE_MEM - } -}; - -struct platform_device tegra_w1_device = { - .name = "tegra_w1", - .id = -1, - .resource = w1_resources, - .num_resources = ARRAY_SIZE(w1_resources), -}; - -static struct resource tegra_udc_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB, - .end = INT_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_usb1_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB, - .end = INT_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_usb2_resources[] = { - [0] = { - .start = TEGRA_USB2_BASE, - .end = TEGRA_USB2_BASE + TEGRA_USB2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB2, - .end = INT_USB2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_usb3_resources[] = { - [0] = { - .start = TEGRA_USB3_BASE, - .end = TEGRA_USB3_BASE + TEGRA_USB3_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB3, - .end = INT_USB3, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 tegra_udc_dmamask = DMA_BIT_MASK(32); - -static struct fsl_usb2_platform_data tegra_udc_pdata = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - -struct platform_device tegra_udc_device = { - .name = "fsl-tegra-udc", - .id = -1, - .dev = { - .dma_mask = &tegra_udc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &tegra_udc_pdata, - }, - .resource = tegra_udc_resources, - .num_resources = ARRAY_SIZE(tegra_udc_resources), -}; - -static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32); - -struct platform_device tegra_ehci1_device = { - .name = "tegra-ehci", - .id = 0, - .dev = { - .dma_mask = &tegra_ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = tegra_usb1_resources, - .num_resources = ARRAY_SIZE(tegra_usb1_resources), -}; - -struct platform_device tegra_ehci2_device = { - .name = "tegra-ehci", - .id = 1, - .dev = { - .dma_mask = &tegra_ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = tegra_usb2_resources, - .num_resources = ARRAY_SIZE(tegra_usb2_resources), -}; - -struct platform_device tegra_ehci3_device = { - .name = "tegra-ehci", - .id = 2, - .dev = { - .dma_mask = &tegra_ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = tegra_usb3_resources, - .num_resources = ARRAY_SIZE(tegra_usb3_resources), -}; - -static struct resource tegra_otg_resources[] = { - [0] = { - .start = TEGRA_USB_BASE, - .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_USB, - .end = INT_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device tegra_otg_device = { - .name = "tegra-otg", - .id = -1, - .resource = tegra_otg_resources, - .num_resources = ARRAY_SIZE(tegra_otg_resources), -}; - -static struct resource i2s_resource1[] = { - [0] = { - .start = INT_I2S1, - .end = INT_I2S1, - .flags = IORESOURCE_IRQ - }, - [1] = { - .start = TEGRA_DMA_REQ_SEL_I2S_1, - .end = TEGRA_DMA_REQ_SEL_I2S_1, - .flags = IORESOURCE_DMA - }, - [2] = { - .start = TEGRA_I2S1_BASE, - .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1, - .flags = IORESOURCE_MEM - } -}; - -static struct resource i2s_resource2[] = { - [0] = { - .start = INT_I2S2, - .end = INT_I2S2, - .flags = IORESOURCE_IRQ - }, - [1] = { - .start = TEGRA_DMA_REQ_SEL_I2S2_1, - .end = TEGRA_DMA_REQ_SEL_I2S2_1, - .flags = IORESOURCE_DMA - }, - [2] = { - .start = TEGRA_I2S2_BASE, - .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1, - .flags = IORESOURCE_MEM - } -}; - -static struct resource spdif_resource[] = { - [0] = { - .start = INT_SPDIF, - .end = INT_SPDIF, - .flags = IORESOURCE_IRQ - }, - [1] = { - .start = TEGRA_DMA_REQ_SEL_SPD_I, - .end = TEGRA_DMA_REQ_SEL_SPD_I, - .flags = IORESOURCE_DMA - }, - [2] = { - .start = TEGRA_SPDIF_BASE, - .end = TEGRA_SPDIF_BASE + TEGRA_SPDIF_SIZE - 1, - .flags = IORESOURCE_MEM - } -}; - -struct platform_device tegra_i2s_device1 = { - .name = "i2s", - .id = 0, - .resource = i2s_resource1, - .num_resources = ARRAY_SIZE(i2s_resource1), -}; - -struct platform_device tegra_i2s_device2 = { - .name = "i2s", - .id = 1, - .resource = i2s_resource2, - .num_resources = ARRAY_SIZE(i2s_resource2), -}; - -struct platform_device tegra_spdif_device = { - .name = "spdif_out", - .id = -1, - .resource = spdif_resource, - .num_resources = ARRAY_SIZE(spdif_resource), -}; - -static struct resource tegra_gart_resources[] = { - [0] = { - .name = "mc", - .flags = IORESOURCE_MEM, - .start = TEGRA_MC_BASE, - .end = TEGRA_MC_BASE + TEGRA_MC_SIZE - 1, - }, - [1] = { - .name = "gart", - .flags = IORESOURCE_MEM, - .start = TEGRA_GART_BASE, - .end = TEGRA_GART_BASE + TEGRA_GART_SIZE - 1, - } -}; - -struct platform_device tegra_gart_device = { - .name = "tegra_gart", - .id = -1, - .num_resources = ARRAY_SIZE(tegra_gart_resources), - .resource = tegra_gart_resources -}; - -static struct resource pmu_resources[] = { - [0] = { - .start = INT_CPU0_PMU_INTR, - .end = INT_CPU0_PMU_INTR, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = INT_CPU1_PMU_INTR, - .end = INT_CPU1_PMU_INTR, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device pmu_device = { - .name = "arm-pmu", - .id = ARM_PMU_DEVICE_CPU, - .num_resources = ARRAY_SIZE(pmu_resources), - .resource = pmu_resources, -}; - -#define CLK_RESET_RST_SOURCE 0x0 -static struct resource tegra_wdt_resources[] = { - [0] = { - .start = TEGRA_CLK_RESET_BASE + CLK_RESET_RST_SOURCE, - .end = TEGRA_CLK_RESET_BASE + CLK_RESET_RST_SOURCE + 4 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = TEGRA_TMR1_BASE, - .end = TEGRA_TMR1_BASE + TEGRA_TMR1_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = INT_TMR1, - .end = INT_TMR1, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device tegra_wdt_device = { - .name = "tegra_wdt", - .id = -1, - .num_resources = ARRAY_SIZE(tegra_wdt_resources), - .resource = tegra_wdt_resources, -}; - -static struct resource tegra_pwfm0_resource = { - .start = TEGRA_PWFM0_BASE, - .end = TEGRA_PWFM0_BASE + TEGRA_PWFM0_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct resource tegra_pwfm1_resource = { - .start = TEGRA_PWFM1_BASE, - .end = TEGRA_PWFM1_BASE + TEGRA_PWFM1_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct resource tegra_pwfm2_resource = { - .start = TEGRA_PWFM2_BASE, - .end = TEGRA_PWFM2_BASE + TEGRA_PWFM2_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct resource tegra_pwfm3_resource = { - .start = TEGRA_PWFM3_BASE, - .end = TEGRA_PWFM3_BASE + TEGRA_PWFM3_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -struct platform_device tegra_pwfm0_device = { - .name = "tegra_pwm", - .id = 0, - .num_resources = 1, - .resource = &tegra_pwfm0_resource, -}; - -struct platform_device tegra_pwfm1_device = { - .name = "tegra_pwm", - .id = 1, - .num_resources = 1, - .resource = &tegra_pwfm1_resource, -}; - -struct platform_device tegra_pwfm2_device = { - .name = "tegra_pwm", - .id = 2, - .num_resources = 1, - .resource = &tegra_pwfm2_resource, -}; - -struct platform_device tegra_pwfm3_device = { - .name = "tegra_pwm", - .id = 3, - .num_resources = 1, - .resource = &tegra_pwfm3_resource, -}; - -static struct resource tegra_uarta_resources[] = { - [0] = { - .start = TEGRA_UARTA_BASE, - .end = TEGRA_UARTA_BASE + TEGRA_UARTA_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_UARTA, - .end = INT_UARTA, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_uartb_resources[]= { - [0] = { - .start = TEGRA_UARTB_BASE, - .end = TEGRA_UARTB_BASE + TEGRA_UARTB_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_UARTB, - .end = INT_UARTB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_uartc_resources[] = { - [0] = { - .start = TEGRA_UARTC_BASE, - .end = TEGRA_UARTC_BASE + TEGRA_UARTC_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_UARTC, - .end = INT_UARTC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_uartd_resources[] = { - [0] = { - .start = TEGRA_UARTD_BASE, - .end = TEGRA_UARTD_BASE + TEGRA_UARTD_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_UARTD, - .end = INT_UARTD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource tegra_uarte_resources[] = { - [0] = { - .start = TEGRA_UARTE_BASE, - .end = TEGRA_UARTE_BASE + TEGRA_UARTE_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = INT_UARTE, - .end = INT_UARTE, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device tegra_uarta_device = { - .name = "tegra_uart", - .id = 0, - .num_resources = ARRAY_SIZE(tegra_uarta_resources), - .resource = tegra_uarta_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -struct platform_device tegra_uartb_device = { - .name = "tegra_uart", - .id = 1, - .num_resources = ARRAY_SIZE(tegra_uartb_resources), - .resource = tegra_uartb_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -struct platform_device tegra_uartc_device = { - .name = "tegra_uart", - .id = 2, - .num_resources = ARRAY_SIZE(tegra_uartc_resources), - .resource = tegra_uartc_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -struct platform_device tegra_uartd_device = { - .name = "tegra_uart", - .id = 3, - .num_resources = ARRAY_SIZE(tegra_uartd_resources), - .resource = tegra_uartd_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -struct platform_device tegra_uarte_device = { - .name = "tegra_uart", - .id = 4, - .num_resources = ARRAY_SIZE(tegra_uarte_resources), - .resource = tegra_uarte_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -static struct resource tegra_grhost_resources[] = { - { - .start = TEGRA_HOST1X_BASE, - .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_DISPLAY_BASE, - .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_DISPLAY2_BASE, - .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_VI_BASE, - .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_ISP_BASE, - .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = TEGRA_MPE_BASE, - .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SYNCPT_THRESH_BASE, - .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1, - .flags = IORESOURCE_IRQ, - }, - { - .start = INT_HOST1X_MPCORE_GENERAL, - .end = INT_HOST1X_MPCORE_GENERAL, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device tegra_grhost_device = { - .name = "tegra_grhost", - .id = -1, - .resource = tegra_grhost_resources, - .num_resources = ARRAY_SIZE(tegra_grhost_resources), -}; - -static struct resource tegra_avp_resources[] = { - [0] = { - .start = INT_SHR_SEM_INBOX_IBF, - .end = INT_SHR_SEM_INBOX_IBF, - .flags = IORESOURCE_IRQ, - .name = "mbox_from_avp_pending", - }, -}; - -struct platform_device tegra_avp_device = { - .name = "tegra-avp", - .id = -1, - .num_resources = ARRAY_SIZE(tegra_avp_resources), - .resource = tegra_avp_resources, - .dev = { - .coherent_dma_mask = 0xffffffffULL, - }, -}; - -static struct resource tegra_aes_resources[] = { - { - .start = TEGRA_VDE_BASE, - .end = TEGRA_VDE_BASE + TEGRA_VDE_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static u64 tegra_aes_dma_mask = DMA_BIT_MASK(32); - -struct platform_device tegra_aes_device = { - .name = "tegra-aes", - .id = -1, - .resource = tegra_aes_resources, - .num_resources = ARRAY_SIZE(tegra_aes_resources), - .dev = { - .dma_mask = &tegra_aes_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h deleted file mode 100644 index 1c547257a34f..000000000000 --- a/arch/arm/mach-tegra/devices.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/arm/mach-tegra/devices.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_DEVICES_H -#define __MACH_TEGRA_DEVICES_H - -#include - -extern struct platform_device tegra_sdhci_device1; -extern struct platform_device tegra_sdhci_device2; -extern struct platform_device tegra_sdhci_device3; -extern struct platform_device tegra_sdhci_device4; -extern struct platform_device tegra_i2c_device1; -extern struct platform_device tegra_i2c_device2; -extern struct platform_device tegra_i2c_device3; -extern struct platform_device tegra_i2c_device4; -extern struct platform_device tegra_spi_device1; -extern struct platform_device tegra_spi_device2; -extern struct platform_device tegra_spi_device3; -extern struct platform_device tegra_spi_device4; -extern struct platform_device tegra_w1_device; -extern struct platform_device tegra_udc_device; -extern struct platform_device tegra_ehci1_device; -extern struct platform_device tegra_ehci2_device; -extern struct platform_device tegra_ehci3_device; -extern struct platform_device tegra_i2s_device1; -extern struct platform_device tegra_i2s_device2; -extern struct platform_device tegra_gart_device; -extern struct platform_device pmu_device; -extern struct platform_device tegra_wdt_device; -extern struct platform_device tegra_pwfm0_device; -extern struct platform_device tegra_pwfm1_device; -extern struct platform_device tegra_pwfm2_device; -extern struct platform_device tegra_pwfm3_device; -extern struct platform_device tegra_otg_device; -extern struct platform_device tegra_uarta_device; -extern struct platform_device tegra_uartb_device; -extern struct platform_device tegra_uartc_device; -extern struct platform_device tegra_uartd_device; -extern struct platform_device tegra_uarte_device; -extern struct platform_device tegra_spdif_device; -extern struct platform_device tegra_grhost_device; -extern struct platform_device tegra_spdif_device; -extern struct platform_device tegra_avp_device; -extern struct platform_device tegra_aes_device; - -#endif diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c deleted file mode 100644 index 44f70a9cde7a..000000000000 --- a/arch/arm/mach-tegra/dma.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * arch/arm/mach-tegra/dma.c - * - * System DMA driver for NVIDIA Tegra SoCs - * - * Copyright (c) 2008-2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APB_DMA_GEN 0x000 -#define GEN_ENABLE (1<<31) - -#define APB_DMA_CNTRL 0x010 - -#define APB_DMA_IRQ_MASK 0x01c - -#define APB_DMA_IRQ_MASK_SET 0x020 - -#define APB_DMA_CHAN_CSR 0x000 -#define CSR_ENB (1<<31) -#define CSR_IE_EOC (1<<30) -#define CSR_HOLD (1<<29) -#define CSR_DIR (1<<28) -#define CSR_ONCE (1<<27) -#define CSR_FLOW (1<<21) -#define CSR_REQ_SEL_SHIFT 16 -#define CSR_REQ_SEL_MASK (0x1F<addr + APB_DMA_CHAN_CSR); - csr &= ~CSR_IE_EOC; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - - csr &= ~CSR_ENB; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - - status = readl(ch->addr + APB_DMA_CHAN_STA); - if (status & STA_ISE_EOC) - writel(status, ch->addr + APB_DMA_CHAN_STA); -} - -bool tegra_dma_is_stopped(struct tegra_dma_channel *ch) -{ - return !!(readl(ch->addr + APB_DMA_CHAN_STA) & CSR_ENB); -} - -int tegra_dma_cancel(struct tegra_dma_channel *ch) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&ch->lock, irq_flags); - while (!list_empty(&ch->list)) - list_del(ch->list.next); - - tegra_dma_stop(ch); - - spin_unlock_irqrestore(&ch->lock, irq_flags); - return 0; -} - -/* should be called with the channel lock held */ -static unsigned int dma_active_count(struct tegra_dma_channel *ch, - struct tegra_dma_req *req, unsigned int status) -{ - unsigned int to_transfer; - unsigned int req_transfer_count; - - unsigned int bytes_transferred; - - to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT; - req_transfer_count = ch->req_transfer_count; - req_transfer_count += 1; - to_transfer += 1; - - bytes_transferred = req_transfer_count; - - if (status & STA_BUSY) - bytes_transferred -= to_transfer; - - /* In continuous transfer mode, DMA only tracks the count of the - * half DMA buffer. So, if the DMA already finished half the DMA - * then add the half buffer to the completed count. - */ - if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) - if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) - bytes_transferred += req_transfer_count; - - if (status & STA_ISE_EOC) - bytes_transferred += req_transfer_count; - - bytes_transferred *= 4; - - return bytes_transferred; -} - -int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, - struct tegra_dma_req *_req) -{ - struct tegra_dma_req *req = NULL; - int found = 0; - unsigned int status; - unsigned long irq_flags; - int stop = 0; - void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); - - spin_lock_irqsave(&ch->lock, irq_flags); - - if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req) - stop = 1; - - list_for_each_entry(req, &ch->list, node) { - if (req == _req) { - list_del(&req->node); - found = 1; - break; - } - } - if (!found) { - spin_unlock_irqrestore(&ch->lock, irq_flags); - return -EINVAL; - } - - if (!stop) - goto skip_status; - - /* STOP the DMA and get the transfer count. - * Getting the transfer count is tricky. - * - Globally disable DMA on all channels - * - Read the channel's status register to know the number of pending - * bytes to be transfered. - * - Stop the dma channel - * - Globally re-enable DMA to resume other transfers - */ - spin_lock(&enable_lock); - writel(0, addr + APB_DMA_GEN); - udelay(20); - status = readl(ch->addr + APB_DMA_CHAN_STA); - tegra_dma_stop(ch); - writel(GEN_ENABLE, addr + APB_DMA_GEN); - spin_unlock(&enable_lock); - - req->bytes_transferred = dma_active_count(ch, req, status); - - if (!list_empty(&ch->list)) { - /* if the list is not empty, queue the next request */ - struct tegra_dma_req *next_req; - next_req = list_entry(ch->list.next, - typeof(*next_req), node); - tegra_dma_update_hw(ch, next_req); - } -skip_status: - req->status = -TEGRA_DMA_REQ_ERROR_ABORTED; - - spin_unlock_irqrestore(&ch->lock, irq_flags); - - return 0; -} -EXPORT_SYMBOL(tegra_dma_dequeue_req); - -bool tegra_dma_is_empty(struct tegra_dma_channel *ch) -{ - unsigned long irq_flags; - bool is_empty; - - spin_lock_irqsave(&ch->lock, irq_flags); - if (list_empty(&ch->list)) - is_empty = true; - else - is_empty = false; - spin_unlock_irqrestore(&ch->lock, irq_flags); - return is_empty; -} -EXPORT_SYMBOL(tegra_dma_is_empty); - -bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch, - struct tegra_dma_req *_req) -{ - unsigned long irq_flags; - struct tegra_dma_req *req; - - spin_lock_irqsave(&ch->lock, irq_flags); - list_for_each_entry(req, &ch->list, node) { - if (req == _req) { - spin_unlock_irqrestore(&ch->lock, irq_flags); - return true; - } - } - spin_unlock_irqrestore(&ch->lock, irq_flags); - return false; -} -EXPORT_SYMBOL(tegra_dma_is_req_inflight); - -int tegra_dma_enqueue_req(struct tegra_dma_channel *ch, - struct tegra_dma_req *req) -{ - unsigned long irq_flags; - struct tegra_dma_req *_req; - int start_dma = 0; - - if (req->size > TEGRA_DMA_MAX_TRANSFER_SIZE || - req->source_addr & 0x3 || req->dest_addr & 0x3) { - pr_err("Invalid DMA request for channel %d\n", ch->id); - return -EINVAL; - } - - spin_lock_irqsave(&ch->lock, irq_flags); - - list_for_each_entry(_req, &ch->list, node) { - if (req == _req) { - spin_unlock_irqrestore(&ch->lock, irq_flags); - return -EEXIST; - } - } - - req->bytes_transferred = 0; - req->status = 0; - /* STATUS_EMPTY just means the DMA hasn't processed the buf yet. */ - req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_EMPTY; - if (list_empty(&ch->list)) - start_dma = 1; - - list_add_tail(&req->node, &ch->list); - - if (start_dma) - tegra_dma_update_hw(ch, req); - /* Check to see if this request needs to be pushed immediately. - * For continuous single-buffer DMA: - * The first buffer is always in-flight. The 2nd buffer should - * also be in-flight. The 3rd buffer becomes in-flight when the - * first is completed in the interrupt. - */ - else if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_SINGLE) { - struct tegra_dma_req *first_req, *second_req; - first_req = list_entry(ch->list.next, - typeof(*first_req), node); - second_req = list_entry(first_req->node.next, - typeof(*second_req), node); - if (second_req == req) { - unsigned long status = - readl(ch->addr + APB_DMA_CHAN_STA); - if (!(status & STA_ISE_EOC)) - tegra_dma_update_hw_partial(ch, req); - /* Handle the case where the IRQ fired while we're - * writing the interrupts. - */ - if (status & STA_ISE_EOC) { - /* Interrupt fired, let the IRQ stop/restart - * the DMA with this buffer in a clean way. - */ - req->status = TEGRA_DMA_REQ_SUCCESS; - } - } - } - - spin_unlock_irqrestore(&ch->lock, irq_flags); - - return 0; -} -EXPORT_SYMBOL(tegra_dma_enqueue_req); - -struct tegra_dma_channel *tegra_dma_allocate_channel(int mode) -{ - int channel; - struct tegra_dma_channel *ch = NULL; - - mutex_lock(&tegra_dma_lock); - - /* first channel is the shared channel */ - if (mode & TEGRA_DMA_SHARED) { - channel = TEGRA_SYSTEM_DMA_CH_MIN; - } else { - channel = find_first_zero_bit(channel_usage, - ARRAY_SIZE(dma_channels)); - if (channel >= ARRAY_SIZE(dma_channels)) { - pr_err("%s: failed to allocate a DMA channel", - __func__); - goto out; - } - } - __set_bit(channel, channel_usage); - ch = &dma_channels[channel]; - ch->mode = mode; - -out: - mutex_unlock(&tegra_dma_lock); - return ch; -} -EXPORT_SYMBOL(tegra_dma_allocate_channel); - -void tegra_dma_free_channel(struct tegra_dma_channel *ch) -{ - if (ch->mode & TEGRA_DMA_SHARED) - return; - tegra_dma_cancel(ch); - mutex_lock(&tegra_dma_lock); - __clear_bit(ch->id, channel_usage); - mutex_unlock(&tegra_dma_lock); -} -EXPORT_SYMBOL(tegra_dma_free_channel); - -static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch, - struct tegra_dma_req *req) -{ - u32 apb_ptr; - u32 ahb_ptr; - u32 csr; - - if (req->to_memory) { - apb_ptr = req->source_addr; - ahb_ptr = req->dest_addr; - } else { - apb_ptr = req->dest_addr; - ahb_ptr = req->source_addr; - } - writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); - writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR); - - if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) - ch->req_transfer_count = (req->size >> 3) - 1; - else - ch->req_transfer_count = (req->size >> 2) - 1; - csr = readl(ch->addr + APB_DMA_CHAN_CSR); - csr &= ~CSR_WCOUNT_MASK; - csr |= ch->req_transfer_count << CSR_WCOUNT_SHIFT; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - - req->status = TEGRA_DMA_REQ_INFLIGHT; - return; -} - -static void tegra_dma_update_hw(struct tegra_dma_channel *ch, - struct tegra_dma_req *req) -{ - int ahb_addr_wrap; - int apb_addr_wrap; - int ahb_bus_width; - int apb_bus_width; - int index; - - u32 ahb_seq; - u32 apb_seq; - u32 ahb_ptr; - u32 apb_ptr; - u32 csr; - - csr = CSR_IE_EOC | CSR_FLOW; - ahb_seq = AHB_SEQ_INTR_ENB | AHB_SEQ_BURST_1; - apb_seq = 0; - - csr |= req->req_sel << CSR_REQ_SEL_SHIFT; - - ch->req_transfer_count = (req->size >> 2) - 1; - - /* One shot mode is always single buffered. Continuous mode could - * support either. - */ - if (ch->mode & TEGRA_DMA_MODE_ONESHOT) { - csr |= CSR_ONCE; - } else if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) { - ahb_seq |= AHB_SEQ_DBL_BUF; - /* We want an interrupt halfway through, then on the - * completion. The double buffer means 2 interrupts - * pass before the DMA HW latches a new AHB_PTR etc. - */ - ch->req_transfer_count = (req->size >> 3) - 1; - } - csr |= ch->req_transfer_count << CSR_WCOUNT_SHIFT; - - if (req->to_memory) { - apb_ptr = req->source_addr; - ahb_ptr = req->dest_addr; - - apb_addr_wrap = req->source_wrap; - ahb_addr_wrap = req->dest_wrap; - apb_bus_width = req->source_bus_width; - ahb_bus_width = req->dest_bus_width; - - } else { - csr |= CSR_DIR; - apb_ptr = req->dest_addr; - ahb_ptr = req->source_addr; - - apb_addr_wrap = req->dest_wrap; - ahb_addr_wrap = req->source_wrap; - apb_bus_width = req->dest_bus_width; - ahb_bus_width = req->source_bus_width; - } - - apb_addr_wrap >>= 2; - ahb_addr_wrap >>= 2; - - /* set address wrap for APB size */ - index = 0; - do { - if (apb_addr_wrap_table[index] == apb_addr_wrap) - break; - index++; - } while (index < ARRAY_SIZE(apb_addr_wrap_table)); - BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table)); - apb_seq |= index << APB_SEQ_WRAP_SHIFT; - - /* set address wrap for AHB size */ - index = 0; - do { - if (ahb_addr_wrap_table[index] == ahb_addr_wrap) - break; - index++; - } while (index < ARRAY_SIZE(ahb_addr_wrap_table)); - BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table)); - ahb_seq |= index << AHB_SEQ_WRAP_SHIFT; - - for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { - if (bus_width_table[index] == ahb_bus_width) - break; - } - BUG_ON(index == ARRAY_SIZE(bus_width_table)); - ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT; - - for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { - if (bus_width_table[index] == apb_bus_width) - break; - } - BUG_ON(index == ARRAY_SIZE(bus_width_table)); - apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT; - - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - writel(apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ); - writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); - writel(ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ); - writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR); - - csr |= CSR_ENB; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - - req->status = TEGRA_DMA_REQ_INFLIGHT; -} - -static void handle_oneshot_dma(struct tegra_dma_channel *ch) -{ - struct tegra_dma_req *req; - unsigned long irq_flags; - - spin_lock_irqsave(&ch->lock, irq_flags); - if (list_empty(&ch->list)) { - spin_unlock_irqrestore(&ch->lock, irq_flags); - return; - } - - req = list_entry(ch->list.next, typeof(*req), node); - if (req) { - list_del(&req->node); - req->bytes_transferred = req->size; - req->status = TEGRA_DMA_REQ_SUCCESS; - - spin_unlock_irqrestore(&ch->lock, irq_flags); - /* Callback should be called without any lock */ - pr_debug("%s: transferred %d bytes\n", __func__, - req->bytes_transferred); - req->complete(req); - spin_lock_irqsave(&ch->lock, irq_flags); - } - - if (!list_empty(&ch->list)) { - req = list_entry(ch->list.next, typeof(*req), node); - /* the complete function we just called may have enqueued - another req, in which case dma has already started */ - if (req->status != TEGRA_DMA_REQ_INFLIGHT) - tegra_dma_update_hw(ch, req); - } - spin_unlock_irqrestore(&ch->lock, irq_flags); -} - -static void handle_continuous_dbl_dma(struct tegra_dma_channel *ch) -{ - struct tegra_dma_req *req; - struct tegra_dma_req *next_req; - unsigned long irq_flags; - - spin_lock_irqsave(&ch->lock, irq_flags); - if (list_empty(&ch->list)) { - spin_unlock_irqrestore(&ch->lock, irq_flags); - return; - } - - req = list_entry(ch->list.next, typeof(*req), node); - if (req) { - if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) { - bool is_dma_ping_complete; - is_dma_ping_complete = - !!(readl(ch->addr + APB_DMA_CHAN_STA) & - STA_PING_PONG); - if (req->to_memory) - is_dma_ping_complete = !is_dma_ping_complete; - /* Out of sync - Release current buffer */ - if (!is_dma_ping_complete) { - req->buffer_status = - TEGRA_DMA_REQ_BUF_STATUS_FULL; - req->bytes_transferred = req->size; - req->status = TEGRA_DMA_REQ_SUCCESS; - tegra_dma_stop(ch); - - if (!list_is_last(&req->node, &ch->list)) { - next_req = list_entry(req->node.next, - typeof(*next_req), node); - tegra_dma_update_hw(ch, next_req); - } - - list_del(&req->node); - - /* DMA lock is NOT held when callbak is - * called. */ - spin_unlock_irqrestore(&ch->lock, irq_flags); - req->complete(req); - return; - } - /* Load the next request into the hardware, if - * available. */ - if (!list_is_last(&req->node, &ch->list)) { - next_req = list_entry(req->node.next, - typeof(*next_req), node); - tegra_dma_update_hw_partial(ch, next_req); - } - req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL; - req->status = TEGRA_DMA_REQ_SUCCESS; - /* DMA lock is NOT held when callback is called */ - spin_unlock_irqrestore(&ch->lock, irq_flags); - if (likely(req->threshold)) - req->threshold(req); - return; - - } else if (req->buffer_status == - TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) { - /* Callback when the buffer is completely full (i.e on - * the second interrupt */ - - req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL; - req->bytes_transferred = req->size; - req->status = TEGRA_DMA_REQ_SUCCESS; - if (list_is_last(&req->node, &ch->list)) - tegra_dma_stop(ch); - else { - /* It may be possible that req came after - * half dma complete so it need to start - * immediately */ - next_req = list_entry(req->node.next, - typeof(*next_req), node); - if (next_req->status != - TEGRA_DMA_REQ_INFLIGHT) { - tegra_dma_stop(ch); - tegra_dma_update_hw(ch, next_req); - } - } - - list_del(&req->node); - - /* DMA lock is NOT held when callbak is called */ - spin_unlock_irqrestore(&ch->lock, irq_flags); - req->complete(req); - return; - - } else { - tegra_dma_stop(ch); - /* Dma should be stop much earlier */ - BUG(); - } - } - spin_unlock_irqrestore(&ch->lock, irq_flags); -} - -static void handle_continuous_sngl_dma(struct tegra_dma_channel *ch) -{ - struct tegra_dma_req *req; - struct tegra_dma_req *next_req; - struct tegra_dma_req *next_next_req; - unsigned long irq_flags; - - spin_lock_irqsave(&ch->lock, irq_flags); - if (list_empty(&ch->list)) { - tegra_dma_stop(ch); - spin_unlock_irqrestore(&ch->lock, irq_flags); - pr_err("%s: No requests in the list.\n", __func__); - return; - } - req = list_entry(ch->list.next, typeof(*req), node); - if (!req || (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_FULL)) { - tegra_dma_stop(ch); - spin_unlock_irqrestore(&ch->lock, irq_flags); - pr_err("%s: DMA complete irq without corresponding req\n", - __func__); - return; - } - - /* Handle the case when buffer is completely full */ - req->bytes_transferred = req->size; - req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL; - req->status = TEGRA_DMA_REQ_SUCCESS; - if (list_is_last(&req->node, &ch->list)) { - pr_debug("%s: stop\n", __func__); - tegra_dma_stop(ch); - } else { - /* The next entry should have already been queued and is now - * in the middle of xfer. We can then write the next->next one - * if it exists. - */ - next_req = list_entry(req->node.next, typeof(*next_req), node); - if (next_req->status != TEGRA_DMA_REQ_INFLIGHT) { - pr_debug("%s: interrupt during enqueue\n", __func__); - tegra_dma_stop(ch); - tegra_dma_update_hw(ch, next_req); - } else if (!list_is_last(&next_req->node, &ch->list)) { - next_next_req = list_entry(next_req->node.next, - typeof(*next_next_req), node); - tegra_dma_update_hw_partial(ch, next_next_req); - } - } - list_del(&req->node); - spin_unlock_irqrestore(&ch->lock, irq_flags); - req->complete(req); -} - -static irqreturn_t dma_isr(int irq, void *data) -{ - struct tegra_dma_channel *ch = data; - unsigned long status; - - status = readl(ch->addr + APB_DMA_CHAN_STA); - if (status & STA_ISE_EOC) - writel(status, ch->addr + APB_DMA_CHAN_STA); - else { - pr_warning("Got a spurious ISR for DMA channel %d\n", ch->id); - return IRQ_HANDLED; - } - - if (ch->mode & TEGRA_DMA_MODE_ONESHOT) - handle_oneshot_dma(ch); - else if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_DOUBLE) - handle_continuous_dbl_dma(ch); - else if (ch->mode & TEGRA_DMA_MODE_CONTINUOUS_SINGLE) - handle_continuous_sngl_dma(ch); - else - pr_err("Bad channel mode for DMA ISR to handle\n"); - return IRQ_HANDLED; -} - -int __init tegra_dma_init(void) -{ - int ret = 0; - int i; - unsigned int irq; - void __iomem *addr; - - addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); - writel(GEN_ENABLE, addr + APB_DMA_GEN); - writel(0, addr + APB_DMA_CNTRL); - writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX), - addr + APB_DMA_IRQ_MASK_SET); - - memset(channel_usage, 0, sizeof(channel_usage)); - memset(dma_channels, 0, sizeof(dma_channels)); - - /* Reserve all the channels we are not supposed to touch */ - for (i = 0; i < TEGRA_SYSTEM_DMA_CH_MIN; i++) - __set_bit(i, channel_usage); - - for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { - struct tegra_dma_channel *ch = &dma_channels[i]; - - __clear_bit(i, channel_usage); - - ch->id = i; - snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i); - - ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + - TEGRA_APB_DMA_CH0_SIZE * i); - - spin_lock_init(&ch->lock); - INIT_LIST_HEAD(&ch->list); - - irq = INT_APB_DMA_CH0 + i; - ret = request_irq(irq, dma_isr, 0, dma_channels[i].name, ch); - if (ret) { - pr_err("Failed to register IRQ %d for DMA %d\n", - irq, i); - goto fail; - } - ch->irq = irq; - } - /* mark the shared channel allocated */ - __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage); - - for (i = TEGRA_SYSTEM_DMA_CH_MAX+1; i < NV_DMA_MAX_CHANNELS; i++) - __set_bit(i, channel_usage); - - return ret; -fail: - writel(0, addr + APB_DMA_GEN); - for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { - struct tegra_dma_channel *ch = &dma_channels[i]; - if (ch->irq) - free_irq(ch->irq, ch); - } - return ret; -} - -#ifdef CONFIG_PM -static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3]; - -void tegra_dma_suspend(void) -{ - void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); - u32 *ctx = apb_dma; - int i; - - *ctx++ = readl(addr + APB_DMA_GEN); - *ctx++ = readl(addr + APB_DMA_CNTRL); - *ctx++ = readl(addr + APB_DMA_IRQ_MASK); - - for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) { - addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + - TEGRA_APB_DMA_CH0_SIZE * i); - - *ctx++ = readl(addr + APB_DMA_CHAN_CSR); - *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR); - *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ); - *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR); - *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ); - } -} - -void tegra_dma_resume(void) -{ - void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); - u32 *ctx = apb_dma; - int i; - - writel(*ctx++, addr + APB_DMA_GEN); - writel(*ctx++, addr + APB_DMA_CNTRL); - writel(*ctx++, addr + APB_DMA_IRQ_MASK); - - for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) { - addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + - TEGRA_APB_DMA_CH0_SIZE * i); - - writel(*ctx++, addr + APB_DMA_CHAN_CSR); - writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR); - writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ); - writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR); - writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ); - } -} - -#endif diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c deleted file mode 100644 index bc1e1a391b5a..000000000000 --- a/arch/arm/mach-tegra/dvfs.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "board.h" -#include "clock.h" -#include "dvfs.h" - -static LIST_HEAD(dvfs_rail_list); -static DEFINE_MUTEX(dvfs_lock); - -static int dvfs_rail_update(struct dvfs_rail *rail); - -void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n) -{ - int i; - struct dvfs_relationship *rel; - - mutex_lock(&dvfs_lock); - - for (i = 0; i < n; i++) { - rel = &rels[i]; - list_add_tail(&rel->from_node, &rel->to->relationships_from); - list_add_tail(&rel->to_node, &rel->from->relationships_to); - } - - mutex_unlock(&dvfs_lock); -} - -int tegra_dvfs_init_rails(struct dvfs_rail *rails[], int n) -{ - int i; - - mutex_lock(&dvfs_lock); - - for (i = 0; i < n; i++) { - INIT_LIST_HEAD(&rails[i]->dvfs); - INIT_LIST_HEAD(&rails[i]->relationships_from); - INIT_LIST_HEAD(&rails[i]->relationships_to); - rails[i]->millivolts = rails[i]->nominal_millivolts; - rails[i]->new_millivolts = rails[i]->nominal_millivolts; - if (!rails[i]->step) - rails[i]->step = rails[i]->max_millivolts; - - list_add_tail(&rails[i]->node, &dvfs_rail_list); - } - - mutex_unlock(&dvfs_lock); - - return 0; -}; - -static int dvfs_solve_relationship(struct dvfs_relationship *rel) -{ - return rel->solve(rel->from, rel->to); -} - -/* Sets the voltage on a dvfs rail to a specific value, and updates any - * rails that depend on this rail. */ -static int dvfs_rail_set_voltage(struct dvfs_rail *rail, int millivolts) -{ - int ret = 0; - struct dvfs_relationship *rel; - int step = (millivolts > rail->millivolts) ? rail->step : -rail->step; - int i; - int steps; - - if (!rail->reg) { - if (millivolts == rail->millivolts) - return 0; - else - return -EINVAL; - } - - if (rail->disabled) - return 0; - - steps = DIV_ROUND_UP(abs(millivolts - rail->millivolts), rail->step); - - for (i = 0; i < steps; i++) { - if (abs(millivolts - rail->millivolts) > rail->step) - rail->new_millivolts = rail->millivolts + step; - else - rail->new_millivolts = millivolts; - - /* Before changing the voltage, tell each rail that depends - * on this rail that the voltage will change. - * This rail will be the "from" rail in the relationship, - * the rail that depends on this rail will be the "to" rail. - * from->millivolts will be the old voltage - * from->new_millivolts will be the new voltage */ - list_for_each_entry(rel, &rail->relationships_to, to_node) { - ret = dvfs_rail_update(rel->to); - if (ret) - return ret; - } - - if (!rail->disabled) { - ret = regulator_set_voltage(rail->reg, - rail->new_millivolts * 1000, - rail->max_millivolts * 1000); - } - if (ret) { - pr_err("Failed to set dvfs regulator %s\n", rail->reg_id); - return ret; - } - - rail->millivolts = rail->new_millivolts; - - /* After changing the voltage, tell each rail that depends - * on this rail that the voltage has changed. - * from->millivolts and from->new_millivolts will be the - * new voltage */ - list_for_each_entry(rel, &rail->relationships_to, to_node) { - ret = dvfs_rail_update(rel->to); - if (ret) - return ret; - } - } - - if (unlikely(rail->millivolts != millivolts)) { - pr_err("%s: rail didn't reach target %d in %d steps (%d)\n", - __func__, millivolts, steps, rail->millivolts); - return -EINVAL; - } - - return ret; -} - -/* Determine the minimum valid voltage for a rail, taking into account - * the dvfs clocks and any rails that this rail depends on. Calls - * dvfs_rail_set_voltage with the new voltage, which will call - * dvfs_rail_update on any rails that depend on this rail. */ -static int dvfs_rail_update(struct dvfs_rail *rail) -{ - int millivolts = 0; - struct dvfs *d; - struct dvfs_relationship *rel; - int ret = 0; - - /* if dvfs is suspended, return and handle it during resume */ - if (rail->suspended) - return 0; - - /* if regulators are not connected yet, return and handle it later */ - if (!rail->reg) - return 0; - - /* Find the maximum voltage requested by any clock */ - list_for_each_entry(d, &rail->dvfs, reg_node) - millivolts = max(d->cur_millivolts, millivolts); - - rail->new_millivolts = millivolts; - - /* Check any rails that this rail depends on */ - list_for_each_entry(rel, &rail->relationships_from, from_node) - rail->new_millivolts = dvfs_solve_relationship(rel); - - if (rail->new_millivolts != rail->millivolts) - ret = dvfs_rail_set_voltage(rail, rail->new_millivolts); - - return ret; -} - -static int dvfs_rail_connect_to_regulator(struct dvfs_rail *rail) -{ - struct regulator *reg; - - if (!rail->reg) { - reg = regulator_get(NULL, rail->reg_id); - if (IS_ERR(reg)) - return -EINVAL; - } - - rail->reg = reg; - - return 0; -} - -static int -__tegra_dvfs_set_rate(struct dvfs *d, unsigned long rate) -{ - int i = 0; - int ret; - - if (d->freqs == NULL || d->millivolts == NULL) - return -ENODEV; - - if (rate > d->freqs[d->num_freqs - 1]) { - pr_warn("tegra_dvfs: rate %lu too high for dvfs on %s\n", rate, - d->clk_name); - return -EINVAL; - } - - if (rate == 0) { - d->cur_millivolts = 0; - } else { - while (i < d->num_freqs && rate > d->freqs[i]) - i++; - - d->cur_millivolts = d->millivolts[i]; - } - - d->cur_rate = rate; - - ret = dvfs_rail_update(d->dvfs_rail); - if (ret) - pr_err("Failed to set regulator %s for clock %s to %d mV\n", - d->dvfs_rail->reg_id, d->clk_name, d->cur_millivolts); - - return ret; -} - -int tegra_dvfs_set_rate(struct clk *c, unsigned long rate) -{ - int ret; - - if (!c->dvfs) - return -EINVAL; - - mutex_lock(&dvfs_lock); - ret = __tegra_dvfs_set_rate(c->dvfs, rate); - mutex_unlock(&dvfs_lock); - - return ret; -} -EXPORT_SYMBOL(tegra_dvfs_set_rate); - -/* May only be called during clock init, does not take any locks on clock c. */ -int __init tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d) -{ - int i; - - if (c->dvfs) { - pr_err("Error when enabling dvfs on %s for clock %s:\n", - d->dvfs_rail->reg_id, c->name); - pr_err("DVFS already enabled for %s\n", - c->dvfs->dvfs_rail->reg_id); - return -EINVAL; - } - - for (i = 0; i < MAX_DVFS_FREQS; i++) { - if (d->millivolts[i] == 0) - break; - - d->freqs[i] *= d->freqs_mult; - - /* If final frequencies are 0, pad with previous frequency */ - if (d->freqs[i] == 0 && i > 1) - d->freqs[i] = d->freqs[i - 1]; - } - d->num_freqs = i; - - if (d->auto_dvfs) { - c->auto_dvfs = true; - clk_set_cansleep(c); - } - - c->dvfs = d; - - mutex_lock(&dvfs_lock); - list_add_tail(&d->reg_node, &d->dvfs_rail->dvfs); - mutex_unlock(&dvfs_lock); - - return 0; -} - -static bool tegra_dvfs_all_rails_suspended(void) -{ - struct dvfs_rail *rail; - bool all_suspended = true; - - list_for_each_entry(rail, &dvfs_rail_list, node) - if (!rail->suspended && !rail->disabled) - all_suspended = false; - - return all_suspended; -} - -static bool tegra_dvfs_from_rails_suspended(struct dvfs_rail *to) -{ - struct dvfs_relationship *rel; - bool all_suspended = true; - - list_for_each_entry(rel, &to->relationships_from, from_node) - if (!rel->from->suspended && !rel->from->disabled) - all_suspended = false; - - return all_suspended; -} - -static int tegra_dvfs_suspend_one(void) -{ - struct dvfs_rail *rail; - int ret; - - list_for_each_entry(rail, &dvfs_rail_list, node) { - if (!rail->suspended && !rail->disabled && - tegra_dvfs_from_rails_suspended(rail)) { - ret = dvfs_rail_set_voltage(rail, - rail->nominal_millivolts); - if (ret) - return ret; - rail->suspended = true; - return 0; - } - } - - return -EINVAL; -} - -static void tegra_dvfs_resume(void) -{ - struct dvfs_rail *rail; - - mutex_lock(&dvfs_lock); - - list_for_each_entry(rail, &dvfs_rail_list, node) - rail->suspended = false; - - list_for_each_entry(rail, &dvfs_rail_list, node) - dvfs_rail_update(rail); - - mutex_unlock(&dvfs_lock); -} - -static int tegra_dvfs_suspend(void) -{ - int ret = 0; - - mutex_lock(&dvfs_lock); - - while (!tegra_dvfs_all_rails_suspended()) { - ret = tegra_dvfs_suspend_one(); - if (ret) - break; - } - - mutex_unlock(&dvfs_lock); - - if (ret) - tegra_dvfs_resume(); - - return ret; -} - -static int tegra_dvfs_pm_notify(struct notifier_block *nb, - unsigned long event, void *data) -{ - switch (event) { - case PM_SUSPEND_PREPARE: - if (tegra_dvfs_suspend()) - return NOTIFY_STOP; - break; - case PM_POST_SUSPEND: - tegra_dvfs_resume(); - break; - } - - return NOTIFY_OK; -}; - -static struct notifier_block tegra_dvfs_nb = { - .notifier_call = tegra_dvfs_pm_notify, -}; - -/* must be called with dvfs lock held */ -static void __tegra_dvfs_rail_disable(struct dvfs_rail *rail) -{ - int ret; - - if (!rail->disabled) { - ret = dvfs_rail_set_voltage(rail, rail->nominal_millivolts); - if (ret) - pr_info("dvfs: failed to set regulator %s to disable " - "voltage %d\n", rail->reg_id, - rail->nominal_millivolts); - rail->disabled = true; - } -} - -/* must be called with dvfs lock held */ -static void __tegra_dvfs_rail_enable(struct dvfs_rail *rail) -{ - if (rail->disabled) { - rail->disabled = false; - dvfs_rail_update(rail); - } -} - -void tegra_dvfs_rail_enable(struct dvfs_rail *rail) -{ - mutex_lock(&dvfs_lock); - __tegra_dvfs_rail_enable(rail); - mutex_unlock(&dvfs_lock); -} - -void tegra_dvfs_rail_disable(struct dvfs_rail *rail) -{ - mutex_lock(&dvfs_lock); - __tegra_dvfs_rail_disable(rail); - mutex_unlock(&dvfs_lock); -} - -int tegra_dvfs_rail_disable_by_name(const char *reg_id) -{ - struct dvfs_rail *rail; - int ret = 0; - - mutex_lock(&dvfs_lock); - list_for_each_entry(rail, &dvfs_rail_list, node) { - if (!strcmp(reg_id, rail->reg_id)) { - __tegra_dvfs_rail_disable(rail); - goto out; - } - } - - ret = -EINVAL; - -out: - mutex_unlock(&dvfs_lock); - return ret; -} - -/* - * Iterate through all the dvfs regulators, finding the regulator exported - * by the regulator api for each one. Must be called in late init, after - * all the regulator api's regulators are initialized. - */ -int __init tegra_dvfs_late_init(void) -{ - struct dvfs_rail *rail; - - mutex_lock(&dvfs_lock); - - list_for_each_entry(rail, &dvfs_rail_list, node) - dvfs_rail_connect_to_regulator(rail); - - list_for_each_entry(rail, &dvfs_rail_list, node) - dvfs_rail_update(rail); - - mutex_unlock(&dvfs_lock); - - register_pm_notifier(&tegra_dvfs_nb); - - return 0; -} - -#ifdef CONFIG_DEBUG_FS -static int dvfs_tree_sort_cmp(void *p, struct list_head *a, struct list_head *b) -{ - struct dvfs *da = list_entry(a, struct dvfs, reg_node); - struct dvfs *db = list_entry(b, struct dvfs, reg_node); - int ret; - - ret = strcmp(da->dvfs_rail->reg_id, db->dvfs_rail->reg_id); - if (ret != 0) - return ret; - - if (da->cur_millivolts < db->cur_millivolts) - return 1; - if (da->cur_millivolts > db->cur_millivolts) - return -1; - - return strcmp(da->clk_name, db->clk_name); -} - -static int dvfs_tree_show(struct seq_file *s, void *data) -{ - struct dvfs *d; - struct dvfs_rail *rail; - struct dvfs_relationship *rel; - - seq_printf(s, " clock rate mV\n"); - seq_printf(s, "--------------------------------\n"); - - mutex_lock(&dvfs_lock); - - list_for_each_entry(rail, &dvfs_rail_list, node) { - seq_printf(s, "%s %d mV%s:\n", rail->reg_id, - rail->millivolts, rail->disabled ? " disabled" : ""); - list_for_each_entry(rel, &rail->relationships_from, from_node) { - seq_printf(s, " %-10s %-7d mV %-4d mV\n", - rel->from->reg_id, - rel->from->millivolts, - dvfs_solve_relationship(rel)); - } - - list_sort(NULL, &rail->dvfs, dvfs_tree_sort_cmp); - - list_for_each_entry(d, &rail->dvfs, reg_node) { - seq_printf(s, " %-10s %-10lu %-4d mV\n", d->clk_name, - d->cur_rate, d->cur_millivolts); - } - } - - mutex_unlock(&dvfs_lock); - - return 0; -} - -static int dvfs_tree_open(struct inode *inode, struct file *file) -{ - return single_open(file, dvfs_tree_show, inode->i_private); -} - -static const struct file_operations dvfs_tree_fops = { - .open = dvfs_tree_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -int __init dvfs_debugfs_init(struct dentry *clk_debugfs_root) -{ - struct dentry *d; - - d = debugfs_create_file("dvfs", S_IRUGO, clk_debugfs_root, NULL, - &dvfs_tree_fops); - if (!d) - return -ENOMEM; - - return 0; -} - -#endif diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h deleted file mode 100644 index 68622b899c59..000000000000 --- a/arch/arm/mach-tegra/dvfs.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _TEGRA_DVFS_H_ -#define _TEGRA_DVFS_H_ - -#define MAX_DVFS_FREQS 16 - -struct clk; -struct dvfs_rail; - -/* - * dvfs_relationship between to rails, "from" and "to" - * when the rail changes, it will call dvfs_rail_update on the rails - * in the relationship_to list. - * when determining the voltage to set a rail to, it will consider each - * rail in the relationship_from list. - */ -struct dvfs_relationship { - struct dvfs_rail *to; - struct dvfs_rail *from; - int (*solve)(struct dvfs_rail *, struct dvfs_rail *); - - struct list_head to_node; /* node in relationship_to list */ - struct list_head from_node; /* node in relationship_from list */ -}; - -struct dvfs_rail { - const char *reg_id; - int min_millivolts; - int max_millivolts; - int nominal_millivolts; - int step; - bool disabled; - - struct list_head node; /* node in dvfs_rail_list */ - struct list_head dvfs; /* list head of attached dvfs clocks */ - struct list_head relationships_to; - struct list_head relationships_from; - struct regulator *reg; - int millivolts; - int new_millivolts; - bool suspended; -}; - -struct dvfs { - /* Used only by tegra2_clock.c */ - const char *clk_name; - int cpu_process_id; - - /* Must be initialized before tegra_dvfs_init */ - int freqs_mult; - unsigned long freqs[MAX_DVFS_FREQS]; - const int *millivolts; - struct dvfs_rail *dvfs_rail; - bool auto_dvfs; - - /* Filled in by tegra_dvfs_init */ - int max_millivolts; - int num_freqs; - - int cur_millivolts; - unsigned long cur_rate; - struct list_head node; - struct list_head debug_node; - struct list_head reg_node; -}; - -void tegra2_init_dvfs(void); -int tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d); -int dvfs_debugfs_init(struct dentry *clk_debugfs_root); -int tegra_dvfs_late_init(void); -int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n); -void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n); -void tegra_dvfs_rail_enable(struct dvfs_rail *rail); -void tegra_dvfs_rail_disable(struct dvfs_rail *rail); - -#endif diff --git a/arch/arm/mach-tegra/fiq.c b/arch/arm/mach-tegra/fiq.c deleted file mode 100644 index d5470169b553..000000000000 --- a/arch/arm/mach-tegra/fiq.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Brian Swetland - * Iliyan Malchev - * - * 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 -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "board.h" - -void tegra_fiq_enable(int irq) -{ - void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100); - /* enable FIQ */ - u32 val = readl(base + GIC_CPU_CTRL); - val &= ~8; /* pass FIQs through */ - val |= 2; /* enableNS */ - writel(val, base + GIC_CPU_CTRL); - tegra_legacy_select_fiq(irq, true); - tegra_legacy_unmask_irq(irq); -} - -void tegra_fiq_disable(int irq) -{ - tegra_legacy_mask_irq(irq); - tegra_legacy_select_fiq(irq, false); -} diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c deleted file mode 100644 index 101af0a2de15..000000000000 --- a/arch/arm/mach-tegra/fuse.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * arch/arm/mach-tegra/fuse.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include - -#include - -#include "fuse.h" -#include "apbio.h" - -#define FUSE_UID_LOW 0x108 -#define FUSE_UID_HIGH 0x10c -#define FUSE_SKU_INFO 0x110 -#define FUSE_SPARE_BIT 0x200 - -static const char *tegra_revision_name[TEGRA_REVISION_MAX] = { - [TEGRA_REVISION_UNKNOWN] = "unknown", - [TEGRA_REVISION_A02] = "A02", - [TEGRA_REVISION_A03] = "A03", - [TEGRA_REVISION_A03p] = "A03 prime", -}; - -u32 tegra_fuse_readl(unsigned long offset) -{ - return tegra_apb_readl(TEGRA_FUSE_BASE + offset); -} - -void tegra_fuse_writel(u32 value, unsigned long offset) -{ - tegra_apb_writel(value, TEGRA_FUSE_BASE + offset); -} - -static inline bool get_spare_fuse(int bit) -{ - return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); -} - -void tegra_init_fuse(void) -{ - u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); - reg |= 1 << 28; - writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); - - pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n", - tegra_revision_name[tegra_get_revision()], - tegra_sku_id(), tegra_cpu_process_id(), - tegra_core_process_id()); -} - -unsigned long long tegra_chip_uid(void) -{ - unsigned long long lo, hi; - - lo = tegra_fuse_readl(FUSE_UID_LOW); - hi = tegra_fuse_readl(FUSE_UID_HIGH); - return (hi << 32ull) | lo; -} - -int tegra_sku_id(void) -{ - int sku_id; - u32 reg = tegra_fuse_readl(FUSE_SKU_INFO); - sku_id = reg & 0xFF; - return sku_id; -} - -int tegra_cpu_process_id(void) -{ - int cpu_process_id; - u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT); - cpu_process_id = (reg >> 6) & 3; - return cpu_process_id; -} - -int tegra_core_process_id(void) -{ - int core_process_id; - u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT); - core_process_id = (reg >> 12) & 3; - return core_process_id; -} - -enum tegra_revision tegra_get_revision(void) -{ - void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804; - u32 id = readl(chip_id); - - switch ((id >> 16) & 0xf) { - case 2: - return TEGRA_REVISION_A02; - case 3: - if (get_spare_fuse(18) || get_spare_fuse(19)) - return TEGRA_REVISION_A03p; - else - return TEGRA_REVISION_A03; - default: - return TEGRA_REVISION_UNKNOWN; - } -} diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h deleted file mode 100644 index e48838e69e95..000000000000 --- a/arch/arm/mach-tegra/fuse.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/arm/mach-tegra/fuse.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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. - * - */ - -enum tegra_revision { - TEGRA_REVISION_UNKNOWN = 0, - TEGRA_REVISION_A02, - TEGRA_REVISION_A03, - TEGRA_REVISION_A03p, - TEGRA_REVISION_MAX, -}; - -unsigned long long tegra_chip_uid(void); -int tegra_sku_id(void); -int tegra_cpu_process_id(void); -int tegra_core_process_id(void); -void tegra_init_fuse(void); -u32 tegra_fuse_readl(unsigned long offset); -void tegra_fuse_writel(u32 value, unsigned long offset); -enum tegra_revision tegra_get_revision(void); diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c index 0187aaa61cd9..fe78fba25f3c 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/arch/arm/mach-tegra/gpio.c @@ -19,13 +19,11 @@ #include #include -#include #include #include #include -#include #define GPIO_BANK(x) ((x) >> 5) #define GPIO_PORT(x) (((x) >> 3) & 0x3) @@ -62,13 +60,6 @@ struct tegra_gpio_bank { int bank; int irq; spinlock_t lvl_lock[4]; -#ifdef CONFIG_PM - u32 cnf[4]; - u32 out[4]; - u32 oe[4]; - u32 int_enb[4]; - u32 int_lvl[4]; -#endif }; @@ -140,7 +131,7 @@ static struct gpio_chip tegra_gpio_chip = { .direction_output = tegra_gpio_direction_output, .set = tegra_gpio_set, .base = 0, - .ngpio = TEGRA_NR_GPIOS, + .ngpio = ARCH_NR_GPIOS, }; static void tegra_gpio_irq_ack(unsigned int irq) @@ -212,9 +203,6 @@ static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) __set_irq_handler_unlocked(irq, handle_edge_irq); - if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0) - tegra_set_lp0_wake_type(irq, type); - return 0; } @@ -256,85 +244,6 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) } -#ifdef CONFIG_PM -void tegra_gpio_resume(void) -{ - unsigned long flags; - int b, p, i; - - local_irq_save(flags); - - for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { - struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; - - for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { - unsigned int gpio = (b<<5) | (p<<3); - __raw_writel(bank->cnf[p], GPIO_CNF(gpio)); - __raw_writel(bank->out[p], GPIO_OUT(gpio)); - __raw_writel(bank->oe[p], GPIO_OE(gpio)); - __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); - __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); - } - } - - local_irq_restore(flags); - - for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { - struct irq_desc *desc = irq_to_desc(i); - if (!desc || (desc->status & IRQ_WAKEUP)) - continue; - enable_irq(i); - } -} - -void tegra_gpio_suspend(void) -{ - unsigned long flags; - int b, p, i; - - for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { - struct irq_desc *desc = irq_to_desc(i); - if (!desc) - continue; - if (desc->status & IRQ_WAKEUP) { - int gpio = i - INT_GPIO_BASE; - pr_debug("gpio %d.%d is wakeup\n", gpio/8, gpio&7); - continue; - } - disable_irq(i); - } - - local_irq_save(flags); - for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { - struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; - - for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { - unsigned int gpio = (b<<5) | (p<<3); - bank->cnf[p] = __raw_readl(GPIO_CNF(gpio)); - bank->out[p] = __raw_readl(GPIO_OUT(gpio)); - bank->oe[p] = __raw_readl(GPIO_OE(gpio)); - bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio)); - bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio)); - } - } - local_irq_restore(flags); -} - -static int tegra_gpio_wake_enable(unsigned int irq, unsigned int enable) -{ - int ret; - struct tegra_gpio_bank *bank = get_irq_chip_data(irq); - - ret = tegra_set_lp1_wake(bank->irq, enable); - if (ret) - return ret; - - if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0) - return tegra_set_lp0_wake(irq, enable); - - return 0; -} -#endif static struct irq_chip tegra_gpio_irq_chip = { .name = "GPIO", @@ -342,9 +251,6 @@ static struct irq_chip tegra_gpio_irq_chip = { .mask = tegra_gpio_irq_mask, .unmask = tegra_gpio_irq_unmask, .set_type = tegra_gpio_irq_set_type, -#ifdef CONFIG_PM - .set_wake = tegra_gpio_wake_enable, -#endif }; @@ -368,7 +274,7 @@ static int __init tegra_gpio_init(void) gpiochip_add(&tegra_gpio_chip); - for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) { bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class); @@ -406,16 +312,15 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) for (i = 0; i < 7; i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); - seq_printf(s, - "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", - i, j, - __raw_readl(GPIO_CNF(gpio)), - __raw_readl(GPIO_OE(gpio)), - __raw_readl(GPIO_OUT(gpio)), - __raw_readl(GPIO_IN(gpio)), - __raw_readl(GPIO_INT_STA(gpio)), - __raw_readl(GPIO_INT_ENB(gpio)), - __raw_readl(GPIO_INT_LVL(gpio))); + seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", + i, j, + __raw_readl(GPIO_CNF(gpio)), + __raw_readl(GPIO_OE(gpio)), + __raw_readl(GPIO_OUT(gpio)), + __raw_readl(GPIO_IN(gpio)), + __raw_readl(GPIO_INT_STA(gpio)), + __raw_readl(GPIO_INT_ENB(gpio)), + __raw_readl(GPIO_INT_LVL(gpio))); } } return 0; diff --git a/arch/arm/mach-tegra/headsmp-t2.S b/arch/arm/mach-tegra/headsmp-t2.S deleted file mode 100644 index 9da0ed68e63d..000000000000 --- a/arch/arm/mach-tegra/headsmp-t2.S +++ /dev/null @@ -1,218 +0,0 @@ -/* - * arch/arm/mach-tegra/headsmp.S - * - * SMP initialization routines for Tegra SoCs - * - * Copyright (c) 2009-2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "power-macros.S" - -#define TTB_FLAGS 0x6A @ IRGN_WBWA, OC_RGN_WBWA, S, NOS - -#define PMC_DPD_SAMPLE 0x20 -#define PMC_DPD_ENABLE 0x24 -#define PMC_SCRATCH1 0x54 -#define PMC_SCRATCH39 0x138 -#define RST_DEVICES_U 0xc - -#define CLK_RESET_PLLX_BASE 0xe0 -#define CLK_RESET_PLLX_MISC 0xe4 -#define CLK_RESET_PLLP_BASE 0xa0 -#define CLK_RESET_PLLP_OUTA 0xa4 -#define CLK_RESET_PLLP_OUTB 0xa8 -#define CLK_RESET_PLLP_MISC 0xac - -/* .section ".cpuinit.text", "ax"*/ - -.macro poke_ev, val, tmp - mov32 \tmp, (TEGRA_EXCEPTION_VECTORS_BASE + 0x100) - str \val, [\tmp] -.endm - -#ifdef CONFIG_SMP -/* - * tegra_secondary_startup - * - * Initial secondary processor boot vector; jumps to kernel's - * secondary_startup routine - */ -ENTRY(tegra_secondary_startup) - msr cpsr_fsxc, #0xd3 - bl __invalidate_cpu_state - cpu_id r0 - enable_coresite r1 - poke_ev r0, r1 - b secondary_startup -ENDPROC(tegra_secondary_startup) -#endif - -/* - * __restart_plls - * - * Loads the saved PLLX and PLLP parameters into the PLLs, to - * allow them to stabilize while the rest of the CPU state is restored. - * Should be called after the MMU is enabled. Jumps directly - * to __cortex_a9_restore - */ - .align L1_CACHE_SHIFT -__restart_plls: - mov32 r0, tegra_sctx - mov32 r3, (TEGRA_CLK_RESET_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT) - mov32 r4, (TEGRA_TMRUS_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT) - - ldr r1, [r0, #0x0] @ pllx_misc - ldr r2, [r0, #0x4] @ pllx_base - str r1, [r3, #CLK_RESET_PLLX_MISC] - str r2, [r3, #CLK_RESET_PLLX_BASE] - - ldr r1, [r0, #0x8] @ pllp_misc - ldr r2, [r0, #0xc] @ pllp_base - str r1, [r3, #CLK_RESET_PLLP_MISC] - str r2, [r3, #CLK_RESET_PLLP_BASE] - - ldr r1, [r0, #0x10] @ pllp_outa - ldr r2, [r0, #0x14] @ pllp_outb - str r1, [r3, #CLK_RESET_PLLP_OUTA] - str r2, [r3, #CLK_RESET_PLLP_OUTB] - - /* record the time that PLLX and PLLP will be stable */ - ldr r1, [r4] - add r1, r1, #300 - str r1, [r0, #0x18] @ pll_timeout - /* FIXME: need to record actual power transition here */ - mov r0, #0 - b __cortex_a9_l2x0_restart -ENDPROC(__restart_pllx) -/* - * __enable_coresite_access - * - * Takes the coresite debug interface out of reset, enables - * access to all CPUs. Called with MMU disabled. - */ - .align L1_CACHE_SHIFT -__enable_coresite_access: - mov32 r0, (TEGRA_CLK_RESET_BASE + RST_DEVICES_U) - mov32 r2, (TEGRA_TMRUS_BASE) - - /* assert reset for 2usec */ - ldr r1, [r0] - orr r1, #(1<<9) - str r1, [r0] - wait_for_us r3, r2, r4 - add r3, r3, #2 - bic r1, r1, #(1<<9) - wait_until r3, r2, r4 - str r1, [r0] - enable_coresite r3 - bx lr -ENDPROC(__enable_coresite_access) -/* - * tegra_lp2_startup - * - * Secondary CPU boot vector when restarting the master CPU following - * an LP2 idle transition. Re-enable coresight access, re-enable - * MMU, re-start PLLX, restore processor context. - */ - .align L1_CACHE_SHIFT -ENTRY(tegra_lp2_startup) - setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 - - mov32 r0, TEGRA_TMRUS_BASE - ldr r1, [r0] - mov32 r0, TEGRA_PMC_BASE - str r1, [r0, #PMC_SCRATCH39] @ save off exact lp2 exit time - mov r1, #0 - str r1, [r0, #PMC_DPD_SAMPLE] - str r1, [r0, #PMC_DPD_ENABLE] - - bl __invalidate_cpu_state - bl __enable_coresite_access - - mrc p15, 0, r0, c1, c0, 1 - orr r0, r0, #(1 << 6) | (1 << 0) @ re-enable coherency - mcr p15, 0, r0, c1, c0, 1 - - /* enable SCU */ - mov32 r0, TEGRA_ARM_PERIF_BASE - ldr r1, [r0] - orr r1, r1, #1 - str r1, [r0] - - adr r4, __tegra_lp2_data - ldmia r4, {r5, r7, r12} - mov r1, r12 @ ctx_restore = __cortex_a9_restore - sub r4, r4, r5 - ldr r0, [r7, r4] @ pgdir = tegra_pgd_phys - b __return_to_virtual -ENDPROC(tegra_lp2_startup) - .type __tegra_lp2_data, %object -__tegra_lp2_data: - .long . - .long tegra_pgd_phys - .long __restart_plls - .size __tegra_lp2_data, . - __tegra_lp2_data - -#ifdef CONFIG_HOTPLUG_CPU -/* - * tegra_hotplug_startup - * - * Secondary CPU boot vector when restarting a CPU following a - * hot-unplug. Uses the page table created by smp_prepare_cpus and - * stored in tegra_pgd_phys as the safe page table for - * __return_to_virtual, and jumps directly to __cortex_a9_restore. - */ - .align L1_CACHE_SHIFT -ENTRY(tegra_hotplug_startup) - setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 - bl __invalidate_cpu_state - enable_coresite r1 - - /* most of the below is a retread of what happens in __v7_setup and - * secondary_startup, to get the MMU re-enabled and to branch - * to secondary_kernel_startup */ - mrc p15, 0, r0, c1, c0, 1 - orr r0, r0, #(1 << 6) | (1 << 0) @ re-enable coherency - mcr p15, 0, r0, c1, c0, 1 - - adr r4, __tegra_hotplug_data - ldmia r4, {r5, r7, r12} - mov r1, r12 @ ctx_restore = __cortex_a9_restore - sub r4, r4, r5 - ldr r0, [r7, r4] @ pgdir = secondary_data.pgdir - b __return_to_virtual -ENDPROC(tegra_hotplug_startup) - - - .type __tegra_hotplug_data, %object -__tegra_hotplug_data: - .long . - .long tegra_pgd_phys - .long __cortex_a9_restore - .size __tegra_hotplug_data, . - __tegra_hotplug_data -#endif diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S new file mode 100644 index 000000000000..b5349b2f13d2 --- /dev/null +++ b/arch/arm/mach-tegra/headsmp.S @@ -0,0 +1,61 @@ +#include +#include + + .section ".text.head", "ax" + __CPUINIT + +/* + * Tegra specific entry point for secondary CPUs. + * The secondary kernel init calls v7_flush_dcache_all before it enables + * the L1; however, the L1 comes out of reset in an undefined state, so + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch + * of cache lines with uninitialized data and uninitialized tags to get + * written out to memory, which does really unpleasant things to the main + * processor. We fix this by performing an invalidate, rather than a + * clean + invalidate, before jumping into the kernel. + */ +ENTRY(v7_invalidate_l1) + mov r0, #0 + mcr p15, 2, r0, c0, c0, 0 + mrc p15, 1, r0, c0, c0, 0 + + ldr r1, =0x7fff + and r2, r1, r0, lsr #13 + + ldr r1, =0x3ff + + and r3, r1, r0, lsr #3 @ NumWays - 1 + add r2, r2, #1 @ NumSets + + and r0, r0, #0x7 + add r0, r0, #4 @ SetShift + + clz r1, r3 @ WayShift + add r4, r3, #1 @ NumWays +1: sub r2, r2, #1 @ NumSets-- + mov r3, r4 @ Temp = NumWays +2: subs r3, r3, #1 @ Temp-- + mov r5, r3, lsl r1 + mov r6, r2, lsl r0 + orr r5, r5, r6 @ Reg = (Temp< +#include +#include +#include + +#include + +static DECLARE_COMPLETION(cpu_killed); + +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + asm volatile( + " mcr p15, 0, %1, c7, c5, 0\n" + " mcr p15, 0, %1, c7, c10, 4\n" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, #0x20\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0) + : "cc"); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, #0x20\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : + : "cc"); +} + +static inline void platform_do_lowpower(unsigned int cpu) +{ + /* + * there is no power-control hardware on this platform, so all + * we can do is put the core into WFI; this is safe as the calling + * code will have already disabled interrupts + */ + for (;;) { + /* + * here's the WFI + */ + asm(".word 0xe320f003\n" + : + : + : "memory", "cc"); + + /*if (pen_release == cpu) {*/ + /* + * OK, proper wakeup, we're done + */ + break; + /*}*/ + + /* + * getting here, means that we have come out of WFI without + * having been woken up - this shouldn't happen + * + * The trouble is, letting people know about this is not really + * possible, since we are currently running incoherently, and + * therefore cannot safely call printk() or anything else + */ +#ifdef DEBUG + printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu); +#endif + } +} + +int platform_cpu_kill(unsigned int cpu) +{ + return wait_for_completion_timeout(&cpu_killed, 5000); +} + +/* + * platform-specific code to shutdown a CPU + * + * Called with IRQs disabled + */ +void platform_cpu_die(unsigned int cpu) +{ +#ifdef DEBUG + unsigned int this_cpu = hard_smp_processor_id(); + + if (cpu != this_cpu) { + printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", + this_cpu, cpu); + BUG(); + } +#endif + + printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); + complete(&cpu_killed); + + /* + * we're ready for shutdown now, so do it + */ + cpu_enter_lowpower(); + platform_do_lowpower(cpu); + + /* + * bring this CPU back into the world of cache + * coherency, and then restore interrupts + */ + cpu_leave_lowpower(); +} + +int platform_cpu_disable(unsigned int cpu) +{ + /* + * we don't allow CPU 0 to be shutdown (it is still too special + * e.g. clock tick interrupts) + */ + return cpu == 0 ? -EPERM : 0; +} diff --git a/arch/arm/mach-tegra/include/mach/arb_sema.h b/arch/arm/mach-tegra/include/mach/arb_sema.h deleted file mode 100644 index 374c5a913700..000000000000 --- a/arch/arm/mach-tegra/include/mach/arb_sema.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/arb_sema.h - * - * Hardware arbitration semaphore interface - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MACH_TEGRA_ARB_SEMA_H -#define __MACH_TEGRA_ARB_SEMA_H - -enum tegra_arb_module { - TEGRA_ARB_AES = 0, -}; - -int tegra_arb_mutex_lock_timeout(enum tegra_arb_module lock, int msecs); - -int tegra_arb_mutex_unlock(enum tegra_arb_module lock); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/audio.h b/arch/arm/mach-tegra/include/mach/audio.h deleted file mode 100644 index 5950ececae00..000000000000 --- a/arch/arm/mach-tegra/include/mach/audio.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/audio.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARCH_ARM_MACH_TEGRA_AUDIO_H -#define __ARCH_ARM_MACH_TEGRA_AUDIO_H - -#include -#include -#include - -#define FIFO1 0 -#define FIFO2 1 - -/* FIXME: this is not enforced by the hardware. */ -#define I2S_FIFO_TX FIFO1 -#define I2S_FIFO_RX FIFO2 - -#define TEGRA_AUDIO_ENABLE_TX 1 -#define TEGRA_AUDIO_ENABLE_RX 2 - -struct tegra_audio_platform_data { - bool i2s_master; - bool dsp_master; - int i2s_master_clk; /* When I2S mode and master, the framesync rate. */ - int dsp_master_clk; /* When DSP mode and master, the framesync rate. */ - bool dma_on; - unsigned long i2s_clk_rate; - const char *dap_clk; - const char *audio_sync_clk; - - int mode; /* I2S, LJM, RJM, etc. */ - int fifo_fmt; - int bit_size; - int i2s_bus_width; /* 32-bit for 16-bit packed I2S */ - int dsp_bus_width; /* 16-bit for DSP data format */ - int mask; /* enable tx and rx? */ - bool stereo_capture; /* True if hardware supports stereo */ - void *driver_data; -}; - -#endif /* __ARCH_ARM_MACH_TEGRA_AUDIO_H */ diff --git a/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h b/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h deleted file mode 100644 index d49a17510158..000000000000 --- a/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_BCM_BT_LPM_H -#define __ASM_ARCH_BCM_BT_LPM_H - -#include - -/* Uart driver must call this every time it beings TX, to ensure - * this driver keeps WAKE asserted during TX. Called with uart - * spinlock held. */ -extern void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport); - -/* Uart driver must call this when the rx is done.*/ -extern void bcm_bt_rx_done_locked(struct uart_port *uport); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h index d89463dcdf89..2896f25ebfb5 100644 --- a/arch/arm/mach-tegra/include/mach/clk.h +++ b/arch/arm/mach-tegra/include/mach/clk.h @@ -20,13 +20,7 @@ #ifndef __MACH_CLK_H #define __MACH_CLK_H -struct dvfs; - void tegra_periph_reset_deassert(struct clk *c); void tegra_periph_reset_assert(struct clk *c); -int tegra_dvfs_set_rate(struct clk *c, unsigned long rate); -unsigned long clk_get_rate_all_locked(struct clk *c); -void tegra_sdmmc_tap_delay(struct clk *c, int delay); - #endif diff --git a/arch/arm/mach-tegra/include/mach/cpcap_audio.h b/arch/arm/mach-tegra/include/mach/cpcap_audio.h deleted file mode 100644 index 33c71c05fce7..000000000000 --- a/arch/arm/mach-tegra/include/mach/cpcap_audio.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/cpcap_audio.h - * - * Copyright (C) 2010 Google, Inc. - * Copyright (C) 2007 - 2010 Motorola, Inc. - * - * Author: - * Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARCH_ARM_MACH_TEGRA_CPCAP_AUDIO_H_ -#define __ARCH_ARM_MACH_TEGRA_CPCAP_AUDIO_H_ - -#include -#include -#include -#include -#include - -enum { - CPCAP_AUDIO_MODE_NORMAL, /* mode of normal audio operation */ - CPCAP_AUDIO_MODE_DAI, /* CPCAP_AUDIO is configured for DAI testing */ - CPCAP_AUDIO_MODE_DAI_DOWNLINK = CPCAP_AUDIO_MODE_DAI, - CPCAP_AUDIO_MODE_DAI_UPLINK, - CPCAP_AUDIO_MODE_TTY /* CPCAP_AUDIO is configured for TTY */ -}; - -enum { - CPCAP_AUDIO_CODEC_OFF, /* codec is powered down */ - CPCAP_AUDIO_CODEC_CLOCK_ONLY, /* codec powered down, clocks running */ - CPCAP_AUDIO_CODEC_ON, /* codec is completely operational */ - CPCAP_AUDIO_CODEC_LOOPBACK /* xcap in (analog->digital->analog) mode */ -}; - -enum { - CPCAP_AUDIO_CODEC_RATE_8000_HZ, - /* codec is running at 8Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_11025_HZ, - /* codec is running at 11.025Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_12000_HZ, - /* codec is running at 12Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_16000_HZ, - /* codec is running at 16Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_22050_HZ, - /* codec is running at 22.05Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_24000_HZ, - /* codec is running at 24Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_32000_HZ, - /* codec is running at 32Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_44100_HZ, - /* codec is running at 44.1Khz sample rate */ - CPCAP_AUDIO_CODEC_RATE_48000_HZ, - /* codec is running at 48Khz sample rate */ -}; - -enum { - CPCAP_AUDIO_CODEC_UNMUTE, /* codec is unmuted */ - CPCAP_AUDIO_CODEC_MUTE, /* codec is muted */ - CPCAP_AUDIO_CODEC_BYPASS_LOOP - /* codec is bypassed - * (analog-only loopback mode) */ -}; - -enum { - CPCAP_AUDIO_STDAC_OFF, - /* stereo dac is powered down */ - CPCAP_AUDIO_STDAC_CLOCK_ONLY, - /* stereo dac is powered down, but clocks are activated */ - CPCAP_AUDIO_STDAC_ON - /* stereo dac is completely operational */ -}; - -enum { - /* THESE MUST CORRESPOND TO XCPCAP_AUDIO SETTINGS */ - CPCAP_AUDIO_STDAC_RATE_8000_HZ, - /* stereo dac set for 8Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_11025_HZ, - /* stereo dac set for 11.025Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_12000_HZ, - /* stereo dac set for 12Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_16000_HZ, - /* stereo dac set for 16Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_22050_HZ, - /* stereo dac set for 22.05Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_24000_HZ, - /* stereo dac set for 24Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_32000_HZ, - /* stereo dac set for 32Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_44100_HZ, - /* stereo dac set for 44.1Khz sample rate */ - CPCAP_AUDIO_STDAC_RATE_48000_HZ - /* stereo dac set for 48Khz sample rate */ -}; - -enum { - CPCAP_AUDIO_STDAC_UNMUTE, /* stereo dac is unmuted */ - CPCAP_AUDIO_STDAC_MUTE /* stereo dac is muted */ -}; - -enum { - CPCAP_AUDIO_ANALOG_SOURCE_OFF, - /* Analog PGA input is disabled */ - CPCAP_AUDIO_ANALOG_SOURCE_R, - /* Right analog PGA input is enabled */ - CPCAP_AUDIO_ANALOG_SOURCE_L, - /* Left analog PGA input is enabled */ - CPCAP_AUDIO_ANALOG_SOURCE_STEREO - /* Both analog PGA inputs are enabled */ -}; - -enum { - CPCAP_AUDIO_OUT_NONE, - /* No audio output selected */ - CPCAP_AUDIO_OUT_HANDSET, - /* handset (earpiece) speaker */ - CPCAP_AUDIO_OUT_LOUDSPEAKER, - /* loudspeaker (speakerphone) */ - CPCAP_AUDIO_OUT_LINEAR_VIBRATOR, - /* linear vibrator, if equipped */ - CPCAP_AUDIO_OUT_MONO_HEADSET, - /* mono (R channel) x.5mm headset */ - CPCAP_AUDIO_OUT_STEREO_HEADSET, - /* stereo x.5mm headset */ - CPCAP_AUDIO_OUT_EXT_BUS_MONO, - /* accessory bus mono output(EMU) */ - CPCAP_AUDIO_OUT_EMU_MONO, - CPCAP_AUDIO_OUT_EXT_BUS_STEREO, - /* accessory bus stereo output (EMU only) */ - CPCAP_AUDIO_OUT_EMU_STEREO, - CPCAP_AUDIO_OUT_LINEOUT, - CPCAP_AUDIO_OUT_BT_MONO, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - /* Max number of audio output paths */ -}; - -enum { - CPCAP_AUDIO_IN_NONE, - /* No audio input selected */ - CPCAP_AUDIO_IN_HANDSET, - /* handset (internal) microphone */ - CPCAP_AUDIO_IN_AUX_INTERNAL, - /* Auxiliary (second) internal mic */ - CPCAP_AUDIO_IN_DUAL_INTERNAL, - /* both internal microphones are connected */ - CPCAP_AUDIO_IN_HEADSET, - /* Audio <- x.5mm headset microphone */ - CPCAP_AUDIO_IN_EXT_BUS, - /* Audio <- accessory bus analog input (EMU) */ - CPCAP_AUDIO_IN_EMU = CPCAP_AUDIO_IN_EXT_BUS, - CPCAP_AUDIO_IN_HEADSET_BIAS_ONLY, - /* 3.5mm headset control when no mic is selected */ - CPCAP_AUDIO_IN_DUAL_EXTERNAL, - /* Recording from external source */ - CPCAP_AUDIO_IN_BT_MONO, - CPCAP_AUDIO_IN_NUM_OF_PATHS - /* Max number of audio input paths */ -}; - -enum { - /* Defines the audio path type */ - CPCAP_AUDIO_AUDIO_IN_PATH, - /* Audio input path refers to CPCAP_AUDIO_MIC_TYPE */ - CPCAP_AUDIO_AUDIO_OUT_PATH - /* Audio output path refers to CPCAP_AUDIO_SPEAKER_TYPE */ -}; - -enum { - CPCAP_AUDIO_BALANCE_NEUTRAL,/* audio routed normally */ - CPCAP_AUDIO_BALANCE_R_ONLY, /* audio routed to left channel only */ - CPCAP_AUDIO_BALANCE_L_ONLY /* audio routed to right channel only */ -}; - -enum { - CPCAP_AUDIO_RAT_NONE, /* Not in a call mode */ - CPCAP_AUDIO_RAT_2G, /* In 2G call mode */ - CPCAP_AUDIO_RAT_3G, /* In 3G call mode */ - CPCAP_AUDIO_RAT_CDMA /* In CDMA call mode */ -}; - -/* Clock multipliers for A2LA register */ -enum { - CPCAP_AUDIO_A2_CLOCK_MASK = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK1 | - CPCAP_BIT_A2_CLK0, - CPCAP_AUDIO_A2_CLOCK_15_36 = CPCAP_BIT_A2_CLK0, - CPCAP_AUDIO_A2_CLOCK_16_80 = CPCAP_BIT_A2_CLK1, - CPCAP_AUDIO_A2_CLOCK_19_20 = CPCAP_BIT_A2_CLK1 | CPCAP_BIT_A2_CLK0, - CPCAP_AUDIO_A2_CLOCK_26_00 = CPCAP_BIT_A2_CLK2, - CPCAP_AUDIO_A2_CLOCK_33_60 = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK0, - CPCAP_AUDIO_A2_CLOCK_38_40 = CPCAP_BIT_A2_CLK2 | CPCAP_BIT_A2_CLK1 -}; - -struct cpcap_audio_state { - struct cpcap_device *cpcap; - int mode; - int codec_mode; - int codec_rate; - int codec_mute; - int stdac_mode; - int stdac_rate; - int stdac_mute; - int analog_source; - int codec_primary_speaker; - int codec_secondary_speaker; - int stdac_primary_speaker; - int stdac_secondary_speaker; - int ext_primary_speaker; - int ext_secondary_speaker; - int codec_primary_balance; - int stdac_primary_balance; - int ext_primary_balance; - unsigned int output_gain; - int microphone; - unsigned int input_gain; - int rat_type; -}; - -struct cpcap_audio_platform_data { - bool master; - const char *regulator; - struct cpcap_audio_state *state; - int speaker_gpio; - int headset_gpio; - int spdif_gpio; - void (*bluetooth_bypass)(bool); -}; - -int cpcap_audio_init(struct cpcap_audio_state *state, const char *regulator); -void cpcap_audio_register_dump(struct cpcap_audio_state *state); -void cpcap_audio_state_dump(struct cpcap_audio_state *state); -void cpcap_audio_set_audio_state(struct cpcap_audio_state *state); - -#endif/*__ARCH_ARM_MACH_TEGRA_CPCAP_AUDIO_H_*/ diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h deleted file mode 100644 index daaeb3b8a72e..000000000000 --- a/arch/arm/mach-tegra/include/mach/dc.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/dc.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_DC_H -#define __MACH_TEGRA_DC_H - -#include - -#define TEGRA_MAX_DC 2 -#define DC_N_WINDOWS 3 - -struct tegra_dc_mode { - int pclk; - int h_ref_to_sync; - int v_ref_to_sync; - int h_sync_width; - int v_sync_width; - int h_back_porch; - int v_back_porch; - int h_active; - int v_active; - int h_front_porch; - int v_front_porch; - u32 flags; -}; - -#define TEGRA_DC_MODE_FLAG_NEG_V_SYNC (1 << 0) -#define TEGRA_DC_MODE_FLAG_NEG_H_SYNC (1 << 1) - -enum { - TEGRA_DC_OUT_RGB, - TEGRA_DC_OUT_HDMI, -}; - -struct tegra_dc_out { - int type; - unsigned flags; - - /* size in mm */ - unsigned h_size; - unsigned v_size; - - int dcc_bus; - int hotplug_gpio; - - unsigned order; - unsigned align; - unsigned depth; - - unsigned height; /* mm */ - unsigned width; /* mm */ - - struct tegra_dc_mode *modes; - int n_modes; - - int (*enable)(void); - int (*disable)(void); -}; - -/* bits for tegra_dc_out.flags */ -#define TEGRA_DC_OUT_HOTPLUG_HIGH (0 << 1) -#define TEGRA_DC_OUT_HOTPLUG_LOW (1 << 1) -#define TEGRA_DC_OUT_HOTPLUG_MASK (1 << 1) -#define TEGRA_DC_OUT_NVHDCP_POLICY_ALWAYS_ON (0 << 2) -#define TEGRA_DC_OUT_NVHDCP_POLICY_ON_DEMAND (1 << 2) -#define TEGRA_DC_OUT_NVHDCP_POLICY_MASK (1 << 2) - -#define TEGRA_DC_ALIGN_MSB 0 -#define TEGRA_DC_ALIGN_LSB 1 - -#define TEGRA_DC_ORDER_RED_BLUE 0 -#define TEGRA_DC_ORDER_BLUE_RED 1 - -struct tegra_dc; -struct nvmap_handle_ref; - -struct tegra_dc_win { - u8 idx; - u8 fmt; - u32 flags; - - void *virt_addr; - dma_addr_t phys_addr; - unsigned offset_u; - unsigned offset_v; - unsigned stride; - unsigned stride_uv; - unsigned x; - unsigned y; - unsigned w; - unsigned h; - unsigned out_x; - unsigned out_y; - unsigned out_w; - unsigned out_h; - unsigned z; - - int dirty; - int underflows; - struct tegra_dc *dc; - - struct nvmap_handle_ref *cur_handle; -}; - - -#define TEGRA_WIN_FLAG_ENABLED (1 << 0) -#define TEGRA_WIN_FLAG_BLEND_PREMULT (1 << 1) -#define TEGRA_WIN_FLAG_BLEND_COVERAGE (1 << 2) -#define TEGRA_WIN_FLAG_INVERT_H (1 << 3) -#define TEGRA_WIN_FLAG_INVERT_V (1 << 4) -#define TEGRA_WIN_FLAG_TILED (1 << 5) - -#define TEGRA_WIN_BLEND_FLAGS_MASK \ - (TEGRA_WIN_FLAG_BLEND_PREMULT | TEGRA_WIN_FLAG_BLEND_COVERAGE) - -/* Note: These are the actual values written to the DC_WIN_COLOR_DEPTH register - * and may change in new tegra architectures. - */ -#define TEGRA_WIN_FMT_P1 0 -#define TEGRA_WIN_FMT_P2 1 -#define TEGRA_WIN_FMT_P4 2 -#define TEGRA_WIN_FMT_P8 3 -#define TEGRA_WIN_FMT_B4G4R4A4 4 -#define TEGRA_WIN_FMT_B5G5R5A 5 -#define TEGRA_WIN_FMT_B5G6R5 6 -#define TEGRA_WIN_FMT_AB5G5R5 7 -#define TEGRA_WIN_FMT_B8G8R8A8 12 -#define TEGRA_WIN_FMT_R8G8B8A8 13 -#define TEGRA_WIN_FMT_B6x2G6x2R6x2A8 14 -#define TEGRA_WIN_FMT_R6x2G6x2B6x2A8 15 -#define TEGRA_WIN_FMT_YCbCr422 16 -#define TEGRA_WIN_FMT_YUV422 17 -#define TEGRA_WIN_FMT_YCbCr420P 18 -#define TEGRA_WIN_FMT_YUV420P 19 -#define TEGRA_WIN_FMT_YCbCr422P 20 -#define TEGRA_WIN_FMT_YUV422P 21 -#define TEGRA_WIN_FMT_YCbCr422R 22 -#define TEGRA_WIN_FMT_YUV422R 23 -#define TEGRA_WIN_FMT_YCbCr422RA 24 -#define TEGRA_WIN_FMT_YUV422RA 25 - -struct tegra_fb_data { - int win; - - int xres; - int yres; - int bits_per_pixel; /* -1 means autodetect */ - - unsigned long flags; -}; - -#define TEGRA_FB_FLIP_ON_PROBE (1 << 0) - -struct tegra_dc_platform_data { - unsigned long flags; - unsigned long emc_clk_rate; - struct tegra_dc_out *default_out; - struct tegra_fb_data *fb; -}; - -#define TEGRA_DC_FLAG_ENABLED (1 << 0) - -struct tegra_dc *tegra_dc_get_dc(unsigned idx); -struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win); - -void tegra_dc_enable(struct tegra_dc *dc); -void tegra_dc_disable(struct tegra_dc *dc); - -u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc); -u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc); -void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, u32 val); - -/* tegra_dc_update_windows and tegra_dc_sync_windows do not support windows - * with differenct dcs in one call - */ -int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n); -int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n); - -int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode); - -unsigned tegra_dc_get_out_height(struct tegra_dc *dc); -unsigned tegra_dc_get_out_width(struct tegra_dc *dc); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S index 34b1804a2743..55a39564b43c 100644 --- a/arch/arm/mach-tegra/include/mach/debug-macro.S +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S @@ -19,15 +19,26 @@ */ #include -#include .macro addruart,rx, tmp mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? ldreq \rx, =IO_APB_PHYS @ physical ldrne \rx, =IO_APB_VIRT @ virtual - ldr \tmp, =(TEGRA_DEBUG_UART_BASE & 0xFFFF) +#if defined(CONFIG_TEGRA_DEBUG_UART_NONE) +#error "A debug UART must be selected in the kernel config to use DEBUG_LL" +#elif defined(CONFIG_TEGRA_DEBUG_UARTA) + orr \rx, \rx, #0x6000 +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) + ldr \tmp, =0x6040 orr \rx, \rx, \tmp +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) + orr \rx, \rx, #0x6200 +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) + orr \rx, \rx, #0x6300 +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) + orr \rx, \rx, #0x6400 +#endif .endm #define UART_SHIFT 2 diff --git a/arch/arm/mach-tegra/include/mach/delay.h b/arch/arm/mach-tegra/include/mach/delay.h deleted file mode 100644 index 2defb7b9b658..000000000000 --- a/arch/arm/mach-tegra/include/mach/delay.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/delay.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_TEGRA_DELAY_H -#define __MACH_TEGRA_DELAY_H - -/* needed by loops_per_jiffy calculations */ -extern void __delay(int loops); - -extern void __udelay(unsigned long usecs); -extern void __const_udelay(unsigned long usecs); - -/* we don't have any restrictions on maximum udelay length, but we'll enforce - * the same restriction as the ARM default so we don't introduce any - * incompatibilties in drivers. - */ -extern void __bad_udelay(void); - -#define MAX_UDELAY_MS 2 - -#define udelay(n) \ - ((__builtin_constant_p(n) && (n) > (MAX_UDELAY_MS * 1000)) ? \ - __bad_udelay() : \ - __udelay(n)) - -#endif /* defined(__MACH_TEGRA_DELAY_H) */ diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h deleted file mode 100644 index 60b669ae3948..000000000000 --- a/arch/arm/mach-tegra/include/mach/dma.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/dma.h - * - * Copyright (c) 2008-2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MACH_TEGRA_DMA_H -#define __MACH_TEGRA_DMA_H - -#include - -#if defined(CONFIG_TEGRA_SYSTEM_DMA) - -struct tegra_dma_req; -struct tegra_dma_channel; - -#define TEGRA_DMA_REQ_SEL_CNTR 0 -#define TEGRA_DMA_REQ_SEL_I2S_2 1 -#define TEGRA_DMA_REQ_SEL_I2S_1 2 -#define TEGRA_DMA_REQ_SEL_SPD_I 3 -#define TEGRA_DMA_REQ_SEL_UI_I 4 -#define TEGRA_DMA_REQ_SEL_MIPI 5 -#define TEGRA_DMA_REQ_SEL_I2S2_2 6 -#define TEGRA_DMA_REQ_SEL_I2S2_1 7 -#define TEGRA_DMA_REQ_SEL_UARTA 8 -#define TEGRA_DMA_REQ_SEL_UARTB 9 -#define TEGRA_DMA_REQ_SEL_UARTC 10 -#define TEGRA_DMA_REQ_SEL_SPI 11 -#define TEGRA_DMA_REQ_SEL_AC97 12 -#define TEGRA_DMA_REQ_SEL_ACMODEM 13 -#define TEGRA_DMA_REQ_SEL_SL4B 14 -#define TEGRA_DMA_REQ_SEL_SL2B1 15 -#define TEGRA_DMA_REQ_SEL_SL2B2 16 -#define TEGRA_DMA_REQ_SEL_SL2B3 17 -#define TEGRA_DMA_REQ_SEL_SL2B4 18 -#define TEGRA_DMA_REQ_SEL_UARTD 19 -#define TEGRA_DMA_REQ_SEL_UARTE 20 -#define TEGRA_DMA_REQ_SEL_I2C 21 -#define TEGRA_DMA_REQ_SEL_I2C2 22 -#define TEGRA_DMA_REQ_SEL_I2C3 23 -#define TEGRA_DMA_REQ_SEL_DVC_I2C 24 -#define TEGRA_DMA_REQ_SEL_OWR 25 -#define TEGRA_DMA_REQ_SEL_INVALID 31 - -#define TEGRA_DMA_MAX_TRANSFER_SIZE 0x10000 - -enum tegra_dma_mode { - TEGRA_DMA_SHARED = 1, - TEGRA_DMA_MODE_CONTINUOUS = 2, - TEGRA_DMA_MODE_CONTINUOUS_DOUBLE = TEGRA_DMA_MODE_CONTINUOUS, - TEGRA_DMA_MODE_CONTINUOUS_SINGLE = 4, - TEGRA_DMA_MODE_ONESHOT = 8, -}; - -enum tegra_dma_req_error { - TEGRA_DMA_REQ_SUCCESS = 0, - TEGRA_DMA_REQ_ERROR_ABORTED, - TEGRA_DMA_REQ_INFLIGHT, -}; - -enum tegra_dma_req_buff_status { - TEGRA_DMA_REQ_BUF_STATUS_EMPTY = 0, - TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL, - TEGRA_DMA_REQ_BUF_STATUS_FULL, -}; - -struct tegra_dma_req { - struct list_head node; - unsigned int modid; - int instance; - - /* Called when the req is complete and from the DMA ISR context. - * When this is called the req structure is no longer queued by - * the DMA channel. - * - * State of the DMA depends on the number of req it has. If there are - * no DMA requests queued up, then it will STOP the DMA. It there are - * more requests in the DMA, then it will queue the next request. - */ - void (*complete)(struct tegra_dma_req *req); - - /* This is a called from the DMA ISR context when the DMA is still in - * progress and is actively filling same buffer. - * - * In case of continuous mode receive, this threshold is 1/2 the buffer - * size. In other cases, this will not even be called as there is no - * hardware support for it. - * - * In the case of continuous mode receive, if there is next req already - * queued, DMA programs the HW to use that req when this req is - * completed. If there is no "next req" queued, then DMA ISR doesn't do - * anything before calling this callback. - * - * This is mainly used by the cases, where the clients has queued - * only one req and want to get some sort of DMA threshold - * callback to program the next buffer. - * - */ - void (*threshold)(struct tegra_dma_req *req); - - /* 1 to copy to memory. - * 0 to copy from the memory to device FIFO */ - int to_memory; - - void *virt_addr; - - unsigned long source_addr; - unsigned long dest_addr; - unsigned long dest_wrap; - unsigned long source_wrap; - unsigned long source_bus_width; - unsigned long dest_bus_width; - unsigned long req_sel; - unsigned int size; - - /* Updated by the DMA driver on the conpletion of the request. */ - int bytes_transferred; - int status; - - /* DMA completion tracking information */ - int buffer_status; - - /* Client specific data */ - void *dev; -}; - -int tegra_dma_enqueue_req(struct tegra_dma_channel *ch, - struct tegra_dma_req *req); -int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, - struct tegra_dma_req *req); -void tegra_dma_flush(struct tegra_dma_channel *ch); - -bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch, - struct tegra_dma_req *req); -bool tegra_dma_is_empty(struct tegra_dma_channel *ch); -bool tegra_dma_is_stopped(struct tegra_dma_channel *ch); - -struct tegra_dma_channel *tegra_dma_allocate_channel(int mode); -void tegra_dma_free_channel(struct tegra_dma_channel *ch); -int tegra_dma_cancel(struct tegra_dma_channel *ch); - -int __init tegra_dma_init(void); - -#else /* !defined(CONFIG_TEGRA_SYSTEM_DMA) */ -static inline int tegra_dma_init(void) -{ - return 0; -} - -#endif - -#endif diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S index 17a42dac3b01..2ba9e5c9d2f6 100644 --- a/arch/arm/mach-tegra/include/mach/entry-macro.S +++ b/arch/arm/mach-tegra/include/mach/entry-macro.S @@ -20,7 +20,7 @@ #include /* Uses the GIC interrupt controller built into the cpu */ -#define ICTRL_BASE (IO_CPU_VIRT + 0x40100) +#define ICTRL_BASE (IO_CPU_VIRT + 0x100) .macro disable_fiq .endm diff --git a/arch/arm/mach-tegra/include/mach/fb.h b/arch/arm/mach-tegra/include/mach/fb.h deleted file mode 100644 index 8130da0ed8e7..000000000000 --- a/arch/arm/mach-tegra/include/mach/fb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/fb.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_FB_H -#define __MACH_TEGRA_FB_H - -#include - -struct nvhost_device; -struct tegra_dc; -struct tegra_fb_data; -struct tegra_fb_info; -struct resource; - -#ifdef CONFIG_FB_TEGRA -struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev, - struct tegra_dc *dc, - struct tegra_fb_data *fb_data, - struct resource *fb_mem); -void tegra_fb_unregister(struct tegra_fb_info *fb_info); -void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info, - struct fb_monspecs *specs, - bool (*mode_filter)(struct fb_videomode *mode)); -/* called by display controller on suspend */ -void tegra_fb_suspend(struct tegra_fb_info *tegra_fb); -#else -static inline struct tegra_fb_info *tegra_fb_register(struct nvhost_device *ndev, - struct tegra_dc *dc, - struct tegra_fb_data *fb_data, - struct resource *fb_mem) -{ - return NULL; -} - -static inline void tegra_fb_unregister(struct tegra_fb_info *fb_info) -{ -} - -static inline void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info, - struct fb_monspecs *specs, - bool (*mode_filter)(struct fb_videomode *mode)) -{ -} -static inline void tegra_fb_suspend(struct tegra_fb_info *tegra_fb) -{ -} -#endif - -#endif diff --git a/arch/arm/mach-tegra/include/mach/fiq.h b/arch/arm/mach-tegra/include/mach/fiq.h deleted file mode 100644 index 17625facf627..000000000000 --- a/arch/arm/mach-tegra/include/mach/fiq.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ASM_ARCH_TEGRA_FIQ_H -#define __ASM_ARCH_TEGRA_FIQ_H - -/* enable/disable an interrupt that is an FIQ (safe from FIQ context?) */ -void tegra_fiq_enable(int n); -void tegra_fiq_disable(int n); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h index e31f486d69a2..540e822e50f7 100644 --- a/arch/arm/mach-tegra/include/mach/gpio.h +++ b/arch/arm/mach-tegra/include/mach/gpio.h @@ -22,7 +22,7 @@ #include -#define TEGRA_NR_GPIOS INT_GPIO_NR +#define ARCH_NR_GPIOS INT_GPIO_NR #include @@ -35,7 +35,7 @@ static inline int gpio_to_irq(unsigned int gpio) { - if (gpio < TEGRA_NR_GPIOS) + if (gpio < ARCH_NR_GPIOS) return INT_GPIO_BASE + gpio; return -EINVAL; } diff --git a/arch/arm/mach-tegra/include/mach/i2s.h b/arch/arm/mach-tegra/include/mach/i2s.h deleted file mode 100644 index 42cce885cdac..000000000000 --- a/arch/arm/mach-tegra/include/mach/i2s.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/i2s.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARCH_ARM_MACH_TEGRA_I2S_H -#define __ARCH_ARM_MACH_TEGRA_I2S_H - -#include -#include -#include - -/* Offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */ - -#define I2S_I2S_CTRL_0 0 -#define I2S_I2S_STATUS_0 4 -#define I2S_I2S_TIMING_0 8 -#define I2S_I2S_FIFO_SCR_0 0x0c -#define I2S_I2S_PCM_CTRL_0 0x10 -#define I2S_I2S_NW_CTRL_0 0x14 -#define I2S_I2S_TDM_CTRL_0 0x20 -#define I2S_I2S_TDM_TX_RX_CTRL_0 0x24 -#define I2S_I2S_FIFO1_0 0x40 -#define I2S_I2S_FIFO2_0 0x80 - -/* - * I2S_I2S_CTRL_0 - */ - -#define I2S_I2S_CTRL_FIFO2_TX_ENABLE (1<<30) -#define I2S_I2S_CTRL_FIFO1_ENABLE (1<<29) -#define I2S_I2S_CTRL_FIFO2_ENABLE (1<<28) -#define I2S_I2S_CTRL_FIFO1_RX_ENABLE (1<<27) -#define I2S_I2S_CTRL_FIFO_LPBK_ENABLE (1<<26) -#define I2S_I2S_CTRL_MASTER_ENABLE (1<<25) -#define I2S_I2S_CTRL_L_R_CTRL (1<<24) /* 0 = L/R: low/high */ - -#define I2S_BIT_FORMAT_I2S 0 -#define I2S_BIT_FORMAT_RJM 1 -#define I2S_BIT_FORMAT_LJM 2 -#define I2S_BIT_FORMAT_DSP 3 -#define I2S_BIT_FORMAT_SHIFT 10 - -#define I2S_I2S_CTRL_BIT_FORMAT_MASK (3<<10) -#define I2S_I2S_CTRL_BIT_FORMAT_I2S (I2S_BIT_FORMAT_I2S<<10) -#define I2S_I2S_CTRL_BIT_FORMAT_RJM (I2S_BIT_FORMAT_RJM<<10) -#define I2S_I2S_CTRL_BIT_FORMAT_LJM (I2S_BIT_FORMAT_LJM<<10) -#define I2S_I2S_CTRL_BIT_FORMAT_DSP (I2S_BIT_FORMAT_DSP<<10) - -#define I2S_BIT_SIZE_16 0 -#define I2S_BIT_SIZE_20 1 -#define I2S_BIT_SIZE_24 2 -#define I2S_BIT_SIZE_32 3 -#define I2S_BIT_SIZE_SHIFT 8 - -#define I2S_I2S_CTRL_BIT_SIZE_MASK (3 << I2S_BIT_SIZE_SHIFT) -#define I2S_I2S_CTRL_BIT_SIZE_16 (I2S_BIT_SIZE_16 << I2S_BIT_SIZE_SHIFT) -#define I2S_I2S_CTRL_BIT_SIZE_20 (I2S_BIT_SIZE_20 << I2S_BIT_SIZE_SHIFT) -#define I2S_I2S_CTRL_BIT_SIZE_24 (I2S_BIT_SIZE_24 << I2S_BIT_SIZE_SHIFT) -#define I2S_I2S_CTRL_BIT_SIZE_32 (I2S_BIT_SIZE_32 << I2S_BIT_SIZE_SHIFT) - -#define I2S_FIFO_16_LSB 0 -#define I2S_FIFO_20_LSB 1 -#define I2S_FIFO_24_LSB 2 -#define I2S_FIFO_32 3 -#define I2S_FIFO_PACKED 7 -#define I2S_FIFO_SHIFT 4 - -#define I2S_I2S_CTRL_FIFO_FORMAT_MASK (7<<4) -#define I2S_I2S_CTRL_FIFO_FORMAT_16_LSB \ - (I2S_FIFO_16_LSB << I2S_FIFO_SHIFT) -#define I2S_I2S_CTRL_FIFO_FORMAT_20_LSB \ - (I2S_FIFO_20_LSB << I2S_FIFO_SHIFT) -#define I2S_I2S_CTRL_FIFO_FORMAT_24_LSB \ - (I2S_FIFO_24_LSB << I2S_FIFO_SHIFT) -#define I2S_I2S_CTRL_FIFO_FORMAT_32 \ - (I2S_FIFO_32 << I2S_FIFO_SHIFT) -#define I2S_I2S_CTRL_FIFO_FORMAT_PACKED \ - (I2S_FIFO_PACKED << I2S_FIFO_SHIFT) - -#define I2S_I2S_IE_FIFO1_ERR (1<<3) -#define I2S_I2S_IE_FIFO2_ERR (1<<2) -#define I2S_I2S_QE_FIFO1 (1<<1) -#define I2S_I2S_QE_FIFO2 (1<<0) - -/* - * I2S_I2S_STATUS_0 - */ - -#define I2S_I2S_STATUS_FIFO1_RDY (1<<31) -#define I2S_I2S_STATUS_FIFO2_RDY (1<<30) -#define I2S_I2S_STATUS_FIFO1_BSY (1<<29) -#define I2S_I2S_STATUS_FIFO2_BSY (1<<28) -#define I2S_I2S_STATUS_FIFO1_ERR (1<<3) -#define I2S_I2S_STATUS_FIFO2_ERR (1<<2) -#define I2S_I2S_STATUS_QS_FIFO1 (1<<1) -#define I2S_I2S_STATUS_QS_FIFO2 (1<<0) - -/* - * I2S_I2S_TIMING_0 - */ - -#define I2S_I2S_TIMING_NON_SYM_ENABLE (1<<12) -#define I2S_I2S_TIMING_CHANNEL_BIT_COUNT_MASK 0x7ff -#define I2S_I2S_TIMING_CHANNEL_BIT_COUNT (1<<0) - -/* - * I2S_I2S_FIFO_SCR_0 - */ - -#define I2S_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f -#define I2S_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24 -#define I2S_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16 - -#define I2S_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_MASK (0x3f<<24) -#define I2S_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_MASK (0x3f<<16) - -#define I2S_I2S_FIFO_SCR_FIFO2_CLR (1<<12) -#define I2S_I2S_FIFO_SCR_FIFO1_CLR (1<<8) - -#define I2S_FIFO_ATN_LVL_ONE_SLOT 0 -#define I2S_FIFO_ATN_LVL_FOUR_SLOTS 1 -#define I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2 -#define I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3 -#define I2S_FIFO2_ATN_LVL_SHIFT 4 -#define I2S_FIFO1_ATN_LVL_SHIFT 0 - -#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK \ - (3 << I2S_FIFO2_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT \ - (I2S_FIFO_ATN_LVL_ONE_SLOT << I2S_FIFO2_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS \ - (I2S_FIFO_ATN_LVL_FOUR_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS \ - (I2S_FIFO_ATN_LVL_EIGHT_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS \ - (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO2_ATN_LVL_SHIFT) - -#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK \ - (3 << I2S_FIFO1_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT \ - (I2S_FIFO_ATN_LVL_ONE_SLOT << I2S_FIFO1_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS \ - (I2S_FIFO_ATN_LVL_FOUR_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS \ - (I2S_FIFO_ATN_LVL_EIGHT_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT) -#define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS \ - (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT) -/* - * I2S_I2S_PCM_CTRL_0 - */ -#define I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ 0 -#define I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ 1 -#define I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ 2 -#define I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ 3 -#define I2S_PCM_TRM_EDGE_CTRL_SHIFT 9 - -#define I2S_I2S_PCM_TRM_EDGE_CTRL_MASK \ - (3 << I2S_I2S_PCM_TRM_EDGE_CTRL_SHIFT) -#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \ - (I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \ - << I2S_PCM_TRM_EDGE_CTRL_SHIFT) -#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ \ - (I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ \ - << I2S_PCM_TRM_EDGE_CTRL_SHIFT) -#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \ - (I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ \ - << I2S_PCM_TRM_EDGE_CTRL_SHIFT) -#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \ - (I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ \ - << I2S_PCM_TRM_EDGE_CTRL_SHIFT) - -#define I2S_PCM_TRM_MASK_BITS_ZERO 0 -#define I2S_PCM_TRM_MASK_BITS_ONE 1 -#define I2S_PCM_TRM_MASK_BITS_TWO 2 -#define I2S_PCM_TRM_MASK_BITS_THREE 3 -#define I2S_PCM_TRM_MASK_BITS_FOUR 4 -#define I2S_PCM_TRM_MASK_BITS_FIVE 5 -#define I2S_PCM_TRM_MASK_BITS_SIX 6 -#define I2S_PCM_TRM_MASK_BITS_SEVEN 7 -#define I2S_PCM_TRM_MASK_BITS_SHIFT 6 - -#define I2S_I2S_PCM_TRM_MASK_BITS_MASK \ - (7 << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_ZERO \ - (I2S_PCM_TRM_MASK_BITS_ZERO \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_ONE \ - (I2S_PCM_TRM_MASK_BITS_ONE \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_TWO \ - (I2S_PCM_TRM_MASK_BITS_TWO \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_THREE \ - (I2S_PCM_TRM_MASK_BITS_THREE \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_FOUR \ - (I2S_PCM_TRM_MASK_BITS_FOUR \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_FIVE \ - (I2S_PCM_TRM_MASK_BITS_FIVE \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_SIX \ - (I2S_PCM_TRM_MASK_BITS_SIX \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_TRM_MASK_BITS_SEVEN \ - (I2S_PCM_TRM_MASK_BITS_SEVEN \ - << I2S_PCM_TRM_MASK_BITS_SHIFT) - -#define I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL (1<<5) -#define I2S_I2S_PCM_CTRL_TRM_MODE (1<<4) - -#define I2S_PCM_RCV_MASK_BITS_ZERO 0 -#define I2S_PCM_RCV_MASK_BITS_ONE 1 -#define I2S_PCM_RCV_MASK_BITS_TWO 2 -#define I2S_PCM_RCV_MASK_BITS_THREE 3 -#define I2S_PCM_RCV_MASK_BITS_FOUR 4 -#define I2S_PCM_RCV_MASK_BITS_FIVE 5 -#define I2S_PCM_RCV_MASK_BITS_SIX 6 -#define I2S_PCM_RCV_MASK_BITS_SEVEN 7 -#define I2S_PCM_RCV_MASK_BITS_SHIFT 1 - -#define I2S_I2S_PCM_RCV_MASK_BITS_MASK \ - (7 << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_ZERO \ - (I2S_PCM_RCV_MASK_BITS_ZERO \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_ONE \ - (I2S_PCM_RCV_MASK_BITS_ONE \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_TWO \ - (I2S_PCM_RCV_MASK_BITS_TWO \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_THREE \ - (I2S_PCM_RCV_MASK_BITS_THREE \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_FOUR \ - (I2S_PCM_RCV_MASK_BITS_FOUR \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_FIVE \ - (I2S_PCM_RCV_MASK_BITS_FIVE \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_SIX \ - (I2S_PCM_RCV_MASK_BITS_SIX \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) -#define I2S_I2S_PCM_RCV_MASK_BITS_SEVEN \ - (I2S_PCM_RCV_MASK_BITS_SEVEN \ - << I2S_PCM_RCV_MASK_BITS_SHIFT) - -#define I2S_I2S_PCM_CTRL_RCV_MODE (1<<0) - -/* - * I2S_I2S_NW_CTRL_0 - */ - -#define I2S_TRM_TLPHY_SLOT_SEL_SLOT1 0 -#define I2S_TRM_TLPHY_SLOT_SEL_SLOT2 1 -#define I2S_TRM_TLPHY_SLOT_SEL_SLOT3 2 -#define I2S_TRM_TLPHY_SLOT_SEL_SLOT4 3 -#define I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT 4 - -#define I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_MASK \ - (3 << I2S_TRM_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT1 \ - (I2S_TRM_TLPHY_SLOT_SEL_SLOT1 \ - << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT2 \ - (I2S_TRM_TLPHY_SLOT_SEL_SLOT2 \ - << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT3 \ - (I2S_TRM_TLPHY_SLOT_SEL_SLOT3 \ - << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_TRM_TLPHY_SLOT_SEL_SLOT4 \ - (I2S_TRM_TLPHY_SLOT_SEL_SLOT4 \ - << I2S_I2S_NW_TRM_TLPHY_SLOT_SEL_SHIFT) - -#define I2S_I2S_NW_CTRL_TRM_TLPHY_MODE (1<<3) - -#define I2S_RCV_TLPHY_SLOT_SEL_SLOT1 0 -#define I2S_RCV_TLPHY_SLOT_SEL_SLOT2 1 -#define I2S_RCV_TLPHY_SLOT_SEL_SLOT3 2 -#define I2S_RCV_TLPHY_SLOT_SEL_SLOT4 3 -#define I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT 1 - -#define I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_MASK \ - (3 << I2S_RCV_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT1 \ - (I2S_RCV_TLPHY_SLOT_SEL_SLOT1 \ - << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT2 \ - (I2S_RCV_TLPHY_SLOT_SEL_SLOT2 \ - << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT3 \ - (I2S_RCV_TLPHY_SLOT_SEL_SLOT3 \ - << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT) -#define I2S_I2S_RCV_TLPHY_SLOT_SEL_SLOT4 \ - (I2S_RCV_TLPHY_SLOT_SEL_SLOT4 \ - << I2S_I2S_NW_RCV_TLPHY_SLOT_SEL_SHIFT) - -#define I2S_I2S_NW_CTRL_RCV_TLPHY_MODE (1<<0) - -#endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */ diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h index 9a7f8b93ea10..35edfc32ffc9 100644 --- a/arch/arm/mach-tegra/include/mach/io.h +++ b/arch/arm/mach-tegra/include/mach/io.h @@ -33,13 +33,9 @@ * */ -#define IO_IRAM_PHYS 0x40000000 -#define IO_IRAM_VIRT 0xFE400000 -#define IO_IRAM_SIZE SZ_256K - -#define IO_CPU_PHYS 0x50000000 +#define IO_CPU_PHYS 0x50040000 #define IO_CPU_VIRT 0xFE000000 -#define IO_CPU_SIZE SZ_1M +#define IO_CPU_SIZE SZ_16K #define IO_PPSB_PHYS 0x60000000 #define IO_PPSB_VIRT 0xFE200000 @@ -49,18 +45,6 @@ #define IO_APB_VIRT 0xFE300000 #define IO_APB_SIZE SZ_1M -#define IO_USB_PHYS 0xC5000000 -#define IO_USB_VIRT 0xFE500000 -#define IO_USB_SIZE SZ_1M - -#define IO_SDMMC_PHYS 0xC8000000 -#define IO_SDMMC_VIRT 0xFE600000 -#define IO_SDMMC_SIZE SZ_1M - -#define IO_HOST1X_PHYS 0x54000000 -#define IO_HOST1X_VIRT 0xFE700000 -#define IO_HOST1X_SIZE SZ_4M - #define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) #define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) @@ -71,14 +55,6 @@ IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \ IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \ IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_HOST1X_PHYS, IO_HOST1X_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_HOST1X_PHYS, IO_HOST1X_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_USB_PHYS, IO_USB_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_USB_PHYS, IO_USB_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_SDMMC_PHYS, IO_SDMMC_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_SDMMC_PHYS, IO_SDMMC_VIRT) : \ 0) #ifndef __ASSEMBLER__ diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h index e77176e7c87e..1741f7dd7a9b 100644 --- a/arch/arm/mach-tegra/include/mach/iomap.h +++ b/arch/arm/mach-tegra/include/mach/iomap.h @@ -23,77 +23,44 @@ #include -#define TEGRA_IRAM_BASE 0x40000000 -#define TEGRA_IRAM_SIZE SZ_256K - -#define TEGRA_HOST1X_BASE 0x50000000 -#define TEGRA_HOST1X_SIZE 0x24000 - #define TEGRA_ARM_PERIF_BASE 0x50040000 #define TEGRA_ARM_PERIF_SIZE SZ_8K -#define TEGRA_ARM_PL310_BASE 0x50043000 -#define TEGRA_ARM_PL310_SIZE SZ_4K - #define TEGRA_ARM_INT_DIST_BASE 0x50041000 #define TEGRA_ARM_INT_DIST_SIZE SZ_4K -#define TEGRA_MPE_BASE 0x54040000 -#define TEGRA_MPE_SIZE SZ_256K - -#define TEGRA_VI_BASE 0x54080000 -#define TEGRA_VI_SIZE SZ_256K - -#define TEGRA_ISP_BASE 0x54100000 -#define TEGRA_ISP_SIZE SZ_256K - #define TEGRA_DISPLAY_BASE 0x54200000 #define TEGRA_DISPLAY_SIZE SZ_256K #define TEGRA_DISPLAY2_BASE 0x54240000 #define TEGRA_DISPLAY2_SIZE SZ_256K -#define TEGRA_HDMI_BASE 0x54280000 -#define TEGRA_HDMI_SIZE SZ_256K - -#define TEGRA_GART_BASE 0x58000000 -#define TEGRA_GART_SIZE SZ_32M - -#define TEGRA_RES_SEMA_BASE 0x60001000 -#define TEGRA_RES_SEMA_SIZE SZ_4K - -#define TEGRA_ARB_SEMA_BASE 0x60002000 -#define TEGRA_ARB_SEMA_SIZE SZ_4K - #define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE 64 - -#define TEGRA_ARBGNT_ICTLR_BASE 0x60004040 -#define TEGRA_ARBGNT_ICTLR_SIZE 192 +#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 #define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE 64 +#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 #define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE 64 +#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 #define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZE 64 +#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 #define TEGRA_TMR1_BASE 0x60005000 -#define TEGRA_TMR1_SIZE 8 +#define TEGRA_TMR1_SIZE SZ_8 #define TEGRA_TMR2_BASE 0x60005008 -#define TEGRA_TMR2_SIZE 8 +#define TEGRA_TMR2_SIZE SZ_8 #define TEGRA_TMRUS_BASE 0x60005010 -#define TEGRA_TMRUS_SIZE 64 +#define TEGRA_TMRUS_SIZE SZ_64 #define TEGRA_TMR3_BASE 0x60005050 -#define TEGRA_TMR3_SIZE 8 +#define TEGRA_TMR3_SIZE SZ_8 #define TEGRA_TMR4_BASE 0x60005058 -#define TEGRA_TMR4_SIZE 8 +#define TEGRA_TMR4_SIZE SZ_8 #define TEGRA_CLK_RESET_BASE 0x60006000 #define TEGRA_CLK_RESET_SIZE SZ_4K @@ -101,25 +68,7 @@ #define TEGRA_FLOW_CTRL_BASE 0x60007000 #define TEGRA_FLOW_CTRL_SIZE 20 -#define TEGRA_AHB_DMA_BASE 0x60008000 -#define TEGRA_AHB_DMA_SIZE SZ_4K - -#define TEGRA_AHB_DMA_CH0_BASE 0x60009000 -#define TEGRA_AHB_DMA_CH0_SIZE 32 - -#define TEGRA_APB_DMA_BASE 0x6000A000 -#define TEGRA_APB_DMA_SIZE SZ_4K - -#define TEGRA_APB_DMA_CH0_BASE 0x6000B000 -#define TEGRA_APB_DMA_CH0_SIZE 32 - -#define TEGRA_AVP_CACHE_BASE 0x6000C000 -#define TEGRA_AVP_CACHE_SIZE 4 - -#define TEGRA_AHB_GIZMO_BASE 0x6000C004 -#define TEGRA_AHB_GIZMO_SIZE 0x10C - -#define TEGRA_STATMON_BASE 0x6000C400 +#define TEGRA_STATMON_BASE 0x6000C4000 #define TEGRA_STATMON_SIZE SZ_1K #define TEGRA_GPIO_BASE 0x6000D000 @@ -128,9 +77,6 @@ #define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000 #define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K -#define TEGRA_VDE_BASE 0x6001A000 -#define TEGRA_VDE_SIZE (SZ_8K + SZ_4K - SZ_256) - #define TEGRA_APB_MISC_BASE 0x70000000 #define TEGRA_APB_MISC_SIZE SZ_4K @@ -147,10 +93,10 @@ #define TEGRA_I2S2_SIZE SZ_256 #define TEGRA_UARTA_BASE 0x70006000 -#define TEGRA_UARTA_SIZE 64 +#define TEGRA_UARTA_SIZE SZ_64 #define TEGRA_UARTB_BASE 0x70006040 -#define TEGRA_UARTB_SIZE 64 +#define TEGRA_UARTB_SIZE SZ_64 #define TEGRA_UARTC_BASE 0x70006200 #define TEGRA_UARTC_SIZE SZ_256 @@ -173,18 +119,6 @@ #define TEGRA_PWFM_BASE 0x7000A000 #define TEGRA_PWFM_SIZE SZ_256 -#define TEGRA_PWFM0_BASE 0x7000A000 -#define TEGRA_PWFM0_SIZE 4 - -#define TEGRA_PWFM1_BASE 0x7000A010 -#define TEGRA_PWFM1_SIZE 4 - -#define TEGRA_PWFM2_BASE 0x7000A020 -#define TEGRA_PWFM2_SIZE 4 - -#define TEGRA_PWFM3_BASE 0x7000A030 -#define TEGRA_PWFM3_SIZE 4 - #define TEGRA_MIPI_BASE 0x7000B000 #define TEGRA_MIPI_SIZE SZ_256 @@ -203,7 +137,7 @@ #define TEGRA_I2C3_BASE 0x7000C500 #define TEGRA_I2C3_SIZE SZ_256 -#define TEGRA_OWR_BASE 0x7000C600 +#define TEGRA_OWR_BASE 0x7000D000 #define TEGRA_OWR_SIZE 80 #define TEGRA_DVC_BASE 0x7000D000 @@ -248,11 +182,11 @@ #define TEGRA_USB_BASE 0xC5000000 #define TEGRA_USB_SIZE SZ_16K -#define TEGRA_USB2_BASE 0xC5004000 -#define TEGRA_USB2_SIZE SZ_16K +#define TEGRA_USB1_BASE 0xC5004000 +#define TEGRA_USB1_SIZE SZ_16K -#define TEGRA_USB3_BASE 0xC5008000 -#define TEGRA_USB3_SIZE SZ_16K +#define TEGRA_USB2_BASE 0xC5008000 +#define TEGRA_USB2_SIZE SZ_16K #define TEGRA_SDMMC1_BASE 0xC8000000 #define TEGRA_SDMMC1_SIZE SZ_512 @@ -266,18 +200,4 @@ #define TEGRA_SDMMC4_BASE 0xC8000600 #define TEGRA_SDMMC4_SIZE SZ_512 -#if defined(CONFIG_TEGRA_DEBUG_UART_NONE) -# define TEGRA_DEBUG_UART_BASE 0 -#elif defined(CONFIG_TEGRA_DEBUG_UARTA) -# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE -#elif defined(CONFIG_TEGRA_DEBUG_UARTB) -# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE -#elif defined(CONFIG_TEGRA_DEBUG_UARTC) -# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE -#elif defined(CONFIG_TEGRA_DEBUG_UARTD) -# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE -#elif defined(CONFIG_TEGRA_DEBUG_UARTE) -# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE -#endif - #endif diff --git a/arch/arm/mach-tegra/include/mach/iovmm.h b/arch/arm/mach-tegra/include/mach/iovmm.h deleted file mode 100644 index 8f111605e065..000000000000 --- a/arch/arm/mach-tegra/include/mach/iovmm.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/iovmm.h - * - * Copyright (c) 2010, NVIDIA 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 i the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You 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 -#include -#include -#include -#include -#include - -#ifndef _MACH_TEGRA_IOVMM_H_ -#define _MACH_TEGRA_IOVMM_H_ - -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) -typedef u32 tegra_iovmm_addr_t; -#else -#error "Unsupported tegra architecture family" -#endif - -struct tegra_iovmm_device_ops; - -/* each I/O virtual memory manager unit should register a device with - * the iovmm system - */ -struct tegra_iovmm_device { - struct tegra_iovmm_device_ops *ops; - const char *name; - struct list_head list; - int pgsize_bits; -}; - -/* tegra_iovmm_domain serves a purpose analagous to mm_struct as defined in - * - it defines a virtual address space within which - * tegra_iovmm_areas can be created. - */ -struct tegra_iovmm_domain { - atomic_t clients; - atomic_t locks; - spinlock_t block_lock; - unsigned long flags; - wait_queue_head_t delay_lock; /* when lock_client fails */ - struct rw_semaphore map_lock; - struct rb_root all_blocks; /* ordered by address */ - struct rb_root free_blocks; /* ordered by size */ - struct tegra_iovmm_device *dev; -}; - -/* tegra_iovmm_client is analagous to an individual task in the task group - * which owns an mm_struct. - */ - -struct iovmm_share_group; - -struct tegra_iovmm_client { - const char *name; - unsigned long flags; - struct iovmm_share_group *group; - struct tegra_iovmm_domain *domain; - struct list_head list; -}; - -/* tegra_iovmm_area serves a purpose analagous to vm_area_struct as defined - * in - it defines a virtual memory area which can be - * mapped to physical memory by a client-provided mapping function. */ - -struct tegra_iovmm_area { - struct tegra_iovmm_domain *domain; - tegra_iovmm_addr_t iovm_start; - tegra_iovmm_addr_t iovm_length; - pgprot_t pgprot; - struct tegra_iovmm_area_ops *ops; -}; - -struct tegra_iovmm_device_ops { - /* maps a VMA using the page residency functions provided by the VMA */ - int (*map)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_area *io_vma); - /* marks all PTEs in a VMA as invalid; decommits the virtual addres - * space (potentially freeing PDEs when decommit is true.) */ - void (*unmap)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_area *io_vma, bool decommit); - void (*map_pfn)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_area *io_vma, - tegra_iovmm_addr_t offs, unsigned long pfn); - /* ensures that a domain is resident in the hardware's mapping region - * so that it may be used by a client */ - int (*lock_domain)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_domain *domain); - void (*unlock_domain)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_domain *domain); - /* allocates a vmm_domain for the specified client; may return the same - * domain for multiple clients */ - struct tegra_iovmm_domain* (*alloc_domain)( - struct tegra_iovmm_device *dev, - struct tegra_iovmm_client *client); - void (*free_domain)(struct tegra_iovmm_device *dev, - struct tegra_iovmm_domain *domain); - int (*suspend)(struct tegra_iovmm_device *dev); - void (*resume)(struct tegra_iovmm_device *dev); -}; - -struct tegra_iovmm_area_ops { - /* ensures that the page of data starting at the specified offset - * from the start of the iovma is resident and pinned for use by - * DMA, returns the system pfn, or an invalid pfn if the - * operation fails. */ - unsigned long (*lock_makeresident)(struct tegra_iovmm_area *area, - tegra_iovmm_addr_t offs); - /* called when the page is unmapped from the I/O VMA */ - void (*release)(struct tegra_iovmm_area *area, tegra_iovmm_addr_t offs); -}; - -#ifdef CONFIG_TEGRA_IOVMM -/* called by clients to allocate an I/O VMM client mapping context which - * will be shared by all clients in the same share_group */ -struct tegra_iovmm_client *tegra_iovmm_alloc_client(const char *name, - const char *share_group); - -size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client); - -void tegra_iovmm_free_client(struct tegra_iovmm_client *client); - -/* called by clients to ensure that their mapping context is resident - * before performing any DMA operations addressing I/O VMM regions. - * client_lock may return -EINTR. */ -int tegra_iovmm_client_lock(struct tegra_iovmm_client *client); -int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client); - -/* called by clients after DMA operations are complete */ -void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client); - -/* called by clients to allocate a new iovmm_area and reserve I/O virtual - * address space for it. if ops is NULL, clients should subsequently call - * tegra_iovmm_vm_map_pages and/or tegra_iovmm_vm_insert_pfn to explicitly - * map the I/O virtual address to an OS-allocated page or physical address, - * respectively. VM operations may be called before this call returns */ -struct tegra_iovmm_area *tegra_iovmm_create_vm( - struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops, - unsigned long size, pgprot_t pgprot); - -/* called by clients to "zap" an iovmm_area, and replace all mappings - * in it with invalid ones, without freeing the virtual address range */ -void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm); - -/* after zapping a demand-loaded iovmm_area, the client should unzap it - * to allow the VMM device to remap the page range. */ -void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm); - -/* called by clients to return an iovmm_area to the free pool for the domain */ -void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm); - -/* called by client software to map the page-aligned I/O address vaddr to - * a specific physical address pfn. I/O VMA should have been created with - * a NULL tegra_iovmm_area_ops structure. */ -void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area, - tegra_iovmm_addr_t vaddr, unsigned long pfn); - -/* called by clients to return the iovmm_area containing addr, or NULL if - * addr has not been allocated. caller should call tegra_iovmm_put_area when - * finished using the returned pointer */ -struct tegra_iovmm_area *tegra_iovmm_find_area_get( - struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr); - -struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm); -void tegra_iovmm_area_put(struct tegra_iovmm_area *vm); - -/* called by drivers to initialize a tegra_iovmm_domain structure */ -int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start, - tegra_iovmm_addr_t end); - -/* called by drivers to register an I/O VMM device with the system */ -int tegra_iovmm_register(struct tegra_iovmm_device *dev); - -/* called by drivers to remove an I/O VMM device from the system */ -int tegra_iovmm_unregister(struct tegra_iovmm_device *dev); - -/* called by platform suspend code to save IOVMM context */ -int tegra_iovmm_suspend(void); - -/* restores IOVMM context */ -void tegra_iovmm_resume(void); - -#else /* CONFIG_TEGRA_IOVMM */ - -static inline struct tegra_iovmm_client *tegra_iovmm_alloc_client( - const char *name, const char *share_group) -{ - return NULL; -} - -static inline size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client) -{ - return 0; -} - -static inline void tegra_iovmm_free_client(struct tegra_iovmm_client *client) -{} - -static inline int tegra_iovmm_client_lock(struct tegra_iovmm_client *client) -{ - return 0; -} - -static inline int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client) -{ - return 0; -} - -static inline void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client) -{} - -static inline struct tegra_iovmm_area *tegra_iovmm_create_vm( - struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops, - unsigned long size, pgprot_t pgprot) -{ - return NULL; -} - -static inline void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm) { } - -static inline void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm) { } - -static inline void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm) { } - -static inline void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area, - tegra_iovmm_addr_t vaddr, unsigned long pfn) { } - -static inline struct tegra_iovmm_area *tegra_iovmm_find_area_get( - struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr) -{ - return NULL; -} - -static inline struct tegra_iovmm_area *tegra_iovmm_area_get( - struct tegra_iovmm_area *vm) -{ - return NULL; -} - -static inline void tegra_iovmm_area_put(struct tegra_iovmm_area *vm) { } - -static inline int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start, - tegra_iovmm_addr_t end) -{ - return 0; -} - -static inline int tegra_iovmm_register(struct tegra_iovmm_device *dev) -{ - return 0; -} - -static inline int tegra_iovmm_unregister(struct tegra_iovmm_device *dev) -{ - return 0; -} - -static inline int tegra_iovmm_suspend(void) -{ - return 0; -} - -static inline void tegra_iovmm_resume(void) { } -#endif /* CONFIG_TEGRA_IOVMM */ - - -#endif diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h index 2352c2c77b61..20f640edaa0d 100644 --- a/arch/arm/mach-tegra/include/mach/irqs.h +++ b/arch/arm/mach-tegra/include/mach/irqs.h @@ -25,7 +25,6 @@ #define IRQ_LOCALTIMER 29 -#ifdef CONFIG_ARCH_TEGRA_2x_SOC /* Primary Interrupt Controller */ #define INT_PRI_BASE (INT_GIC_BASE + 32) #define INT_TMR1 (INT_PRI_BASE + 0) @@ -88,7 +87,7 @@ #define INT_SYS_STATS_MON (INT_SEC_BASE + 22) #define INT_GPIO5 (INT_SEC_BASE + 23) #define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24) -#define INT_CPU1_PMU_INTR (INT_SEC_BASE + 25) +#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25) #define INT_SEC_RES_26 (INT_SEC_BASE + 26) #define INT_S_LINK1 (INT_SEC_BASE + 27) #define INT_APB_DMA_COP (INT_SEC_BASE + 28) @@ -166,23 +165,9 @@ #define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) #define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) -#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE) - -#define INT_SYNCPT_THRESH_BASE (INT_QUAD_BASE + 32) -#define INT_SYNCPT_THRESH_NR 32 - -#define INT_GPIO_BASE (INT_SYNCPT_THRESH_BASE + \ - INT_SYNCPT_THRESH_NR) +#define INT_GPIO_BASE (INT_QUAD_BASE + 32) #define INT_GPIO_NR (28 * 8) -#define FIQ_START INT_GIC_BASE - -#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) - -#define INT_BOARD_BASE TEGRA_NR_IRQS -#define NR_BOARD_IRQS 32 - -#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS) -#endif +#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) #endif diff --git a/arch/arm/mach-tegra/include/mach/kfuse.h b/arch/arm/mach-tegra/include/mach/kfuse.h deleted file mode 100644 index cfe85cc86ff2..000000000000 --- a/arch/arm/mach-tegra/include/mach/kfuse.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-tegra/kfuse.h - * - * Copyright (C) 2010-2011 NVIDIA Corporation. - * - * 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. - * - */ - -/* there are 144 32-bit values in total */ -#define KFUSE_DATA_SZ (144 * 4) - -int tegra_kfuse_read(void *dest, size_t len); diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h deleted file mode 100644 index 3a2bfab9e54f..000000000000 --- a/arch/arm/mach-tegra/include/mach/legacy_irq.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/legacy_irq.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H -#define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H - -void tegra_legacy_mask_irq(unsigned int irq); -void tegra_legacy_unmask_irq(unsigned int irq); -void tegra_legacy_select_fiq(unsigned int irq, bool fiq); -void tegra_legacy_force_irq_set(unsigned int irq); -void tegra_legacy_force_irq_clr(unsigned int irq); -int tegra_legacy_force_irq_status(unsigned int irq); -void tegra_legacy_select_fiq(unsigned int irq, bool fiq); -unsigned long tegra_legacy_vfiq(int nr); -unsigned long tegra_legacy_class(int nr); -int tegra_legacy_irq_set_wake(int irq, int enable); -void tegra_legacy_irq_set_lp1_wake_mask(void); -void tegra_legacy_irq_restore_mask(void); -void tegra_init_legacy_irq(void); -void tegra_legacy_irq_suspend(void); -void tegra_legacy_irq_resume(void); -#endif diff --git a/arch/arm/mach-tegra/include/mach/mc.h b/arch/arm/mach-tegra/include/mach/mc.h deleted file mode 100644 index 167081067f9e..000000000000 --- a/arch/arm/mach-tegra/include/mach/mc.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/mc.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_MC_H -#define __MACH_TEGRA_MC_H - -#define TEGRA_MC_FPRI_CTRL_AVPC 0x17c -#define TEGRA_MC_FPRI_CTRL_DC 0x180 -#define TEGRA_MC_FPRI_CTRL_DCB 0x184 -#define TEGRA_MC_FPRI_CTRL_EPP 0x188 -#define TEGRA_MC_FPRI_CTRL_G2 0x18c -#define TEGRA_MC_FPRI_CTRL_HC 0x190 -#define TEGRA_MC_FPRI_CTRL_ISP 0x194 -#define TEGRA_MC_FPRI_CTRL_MPCORE 0x198 -#define TEGRA_MC_FPRI_CTRL_MPEA 0x19c -#define TEGRA_MC_FPRI_CTRL_MPEB 0x1a0 -#define TEGRA_MC_FPRI_CTRL_MPEC 0x1a4 -#define TEGRA_MC_FPRI_CTRL_NV 0x1a8 -#define TEGRA_MC_FPRI_CTRL_PPCS 0x1ac -#define TEGRA_MC_FPRI_CTRL_VDE 0x1b0 -#define TEGRA_MC_FPRI_CTRL_VI 0x1b4 - -#define TEGRA_MC_CLIENT_AVPCARM7R ((TEGRA_MC_FPRI_CTRL_AVPC << 8) | 0) -#define TEGRA_MC_CLIENT_AVPCARM7W ((TEGRA_MC_FPRI_CTRL_AVPC << 8) | 2) -#define TEGRA_MC_CLIENT_DISPLAY0A ((TEGRA_MC_FPRI_CTRL_DC << 8) | 0) -#define TEGRA_MC_CLIENT_DISPLAY0B ((TEGRA_MC_FPRI_CTRL_DC << 8) | 2) -#define TEGRA_MC_CLIENT_DISPLAY0C ((TEGRA_MC_FPRI_CTRL_DC << 8) | 4) -#define TEGRA_MC_CLIENT_DISPLAY1B ((TEGRA_MC_FPRI_CTRL_DC << 8) | 6) -#define TEGRA_MC_CLIENT_DISPLAYHC ((TEGRA_MC_FPRI_CTRL_DC << 8) | 8) -#define TEGRA_MC_CLIENT_DISPLAY0AB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 0) -#define TEGRA_MC_CLIENT_DISPLAY0BB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 2) -#define TEGRA_MC_CLIENT_DISPLAY0CB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 4) -#define TEGRA_MC_CLIENT_DISPLAY1BB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 6) -#define TEGRA_MC_CLIENT_DISPLAYHCB ((TEGRA_MC_FPRI_CTRL_DCB << 8) | 8) -#define TEGRA_MC_CLIENT_EPPUP ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 0) -#define TEGRA_MC_CLIENT_EPPU ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 2) -#define TEGRA_MC_CLIENT_EPPV ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 4) -#define TEGRA_MC_CLIENT_EPPY ((TEGRA_MC_FPRI_CTRL_EPP << 8) | 6) -#define TEGRA_MC_CLIENT_G2PR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 0) -#define TEGRA_MC_CLIENT_G2SR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 2) -#define TEGRA_MC_CLIENT_G2DR ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 4) -#define TEGRA_MC_CLIENT_G2DW ((TEGRA_MC_FPRI_CTRL_G2 << 8) | 6) -#define TEGRA_MC_CLIENT_HOST1XDMAR ((TEGRA_MC_FPRI_CTRL_HC << 8) | 0) -#define TEGRA_MC_CLIENT_HOST1XR ((TEGRA_MC_FPRI_CTRL_HC << 8) | 2) -#define TEGRA_MC_CLIENT_HOST1XW ((TEGRA_MC_FPRI_CTRL_HC << 8) | 4) -#define TEGRA_MC_CLIENT_ISPW ((TEGRA_MC_FPRI_CTRL_ISP << 8) | 0) -#define TEGRA_MC_CLIENT_MPCORER ((TEGRA_MC_FPRI_CTRL_MPCORE << 8) | 0) -#define TEGRA_MC_CLIENT_MPCOREW ((TEGRA_MC_FPRI_CTRL_MPCORE << 8) | 2) -#define TEGRA_MC_CLIENT_MPEAMEMRD ((TEGRA_MC_FPRI_CTRL_MPEA << 8) | 0) -#define TEGRA_MC_CLIENT_MPEUNIFBR ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 0) -#define TEGRA_MC_CLIENT_MPE_IPRED ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 2) -#define TEGRA_MC_CLIENT_MPEUNIFBW ((TEGRA_MC_FPRI_CTRL_MPEB << 8) | 4) -#define TEGRA_MC_CLIENT_MPECSRD ((TEGRA_MC_FPRI_CTRL_MPEC << 8) | 0) -#define TEGRA_MC_CLIENT_MPECSWR ((TEGRA_MC_FPRI_CTRL_MPEC << 8) | 2) -#define TEGRA_MC_CLIENT_FDCDRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 0) -#define TEGRA_MC_CLIENT_IDXSRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 2) -#define TEGRA_MC_CLIENT_TEXSRD ((TEGRA_MC_FPRI_CTRL_NV << 8) | 4) -#define TEGRA_MC_CLIENT_FDCDWR ((TEGRA_MC_FPRI_CTRL_NV << 8) | 6) -#define TEGRA_MC_CLIENT_PPCSAHBDMAR ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 0) -#define TEGRA_MC_CLIENT_PPCSAHBSLVR ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 2) -#define TEGRA_MC_CLIENT_PPCSAHBDMAW ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 4) -#define TEGRA_MC_CLIENT_PPCSAHBSLVW ((TEGRA_MC_FPRI_CTRL_PPCS << 8) | 6) -#define TEGRA_MC_CLIENT_VDEBSEVR ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 0) -#define TEGRA_MC_CLIENT_VDEMBER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 2) -#define TEGRA_MC_CLIENT_VDEMCER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 4) -#define TEGRA_MC_CLIENT_VDETPER ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 6) -#define TEGRA_MC_CLIENT_VDEBSEVW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 8) -#define TEGRA_MC_CLIENT_VDEMBEW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 10) -#define TEGRA_MC_CLIENT_VDETPMW ((TEGRA_MC_FPRI_CTRL_VDE << 8) | 12) -#define TEGRA_MC_CLIENT_VIRUV ((TEGRA_MC_FPRI_CTRL_VI << 8) | 0) -#define TEGRA_MC_CLIENT_VIWSB ((TEGRA_MC_FPRI_CTRL_VI << 8) | 2) -#define TEGRA_MC_CLIENT_VIWU ((TEGRA_MC_FPRI_CTRL_VI << 8) | 4) -#define TEGRA_MC_CLIENT_VIWV ((TEGRA_MC_FPRI_CTRL_VI << 8) | 6) -#define TEGRA_MC_CLIENT_VIWY ((TEGRA_MC_FPRI_CTRL_VI << 8) | 8) - -#define TEGRA_MC_PRIO_LOWEST 0 -#define TEGRA_MC_PRIO_LOW 1 -#define TEGRA_MC_PRIO_MED 2 -#define TEGRA_MC_PRIO_HIGH 3 -#define TEGRA_MC_PRIO_MASK 3 - -void tegra_mc_set_priority(unsigned long client, unsigned long prio); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h index 7c225b1d4d63..6151bab62af2 100644 --- a/arch/arm/mach-tegra/include/mach/memory.h +++ b/arch/arm/mach-tegra/include/mach/memory.h @@ -24,10 +24,5 @@ /* physical offset of RAM */ #define PHYS_OFFSET UL(0) -#define NET_IP_ALIGN 0 -#define NET_SKB_PAD L1_CACHE_BYTES - -#define CONSISTENT_DMA_SIZE (14 * SZ_1M) - #endif diff --git a/arch/arm/mach-tegra/include/mach/nand.h b/arch/arm/mach-tegra/include/mach/nand.h deleted file mode 100644 index 2d26fec30f4b..000000000000 --- a/arch/arm/mach-tegra/include/mach/nand.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/nand.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * Dima Zavin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_NAND_H -#define __MACH_TEGRA_NAND_H - -struct tegra_nand_chip_parms { - uint8_t vendor_id; - uint8_t device_id; - uint32_t flags; - - uint32_t capacity; - - /* all timing info is in nanoseconds */ - struct { - uint32_t trp; - uint32_t trh; - uint32_t twp; - uint32_t twh; - uint32_t tcs; - uint32_t twhr; - uint32_t tcr_tar_trr; - uint32_t twb; - uint32_t trp_resp; - uint32_t tadl; - } timing; -}; - -struct tegra_nand_platform { - uint8_t max_chips; - struct tegra_nand_chip_parms *chip_parms; - unsigned int nr_chip_parms; - struct mtd_partition *parts; - unsigned int nr_parts; -}; - -#endif diff --git a/arch/arm/mach-tegra/include/mach/nvhost.h b/arch/arm/mach-tegra/include/mach/nvhost.h deleted file mode 100644 index 4bec3127a545..000000000000 --- a/arch/arm/mach-tegra/include/mach/nvhost.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * include/linux/nvhost.h - * - * Tegra graphics host driver - * - * Copyright (c) 2009-2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __LINUX_NVHOST_H -#define __LINUX_NVHOST_H - -#include -#include -#include - -struct nvhost_master; - -struct nvhost_device { - const char *name; - struct device dev; - int id; - u32 num_resources; - struct resource *resource; - - struct nvhost_master *host; -}; - -extern int nvhost_device_register(struct nvhost_device *); -extern void nvhost_device_unregister(struct nvhost_device *); - -extern struct bus_type nvhost_bus_type; - -struct nvhost_driver { - int (*probe)(struct nvhost_device *); - int (*remove)(struct nvhost_device *); - void (*shutdown)(struct nvhost_device *); - int (*suspend)(struct nvhost_device *, pm_message_t state); - int (*resume)(struct nvhost_device *); - struct device_driver driver; -}; - -extern int nvhost_driver_register(struct nvhost_driver *); -extern void nvhost_driver_unregister(struct nvhost_driver *); -extern struct resource *nvhost_get_resource(struct nvhost_device *, unsigned int, unsigned int); -extern int nvhost_get_irq(struct nvhost_device *, unsigned int); -extern struct resource *nvhost_get_resource_byname(struct nvhost_device *, unsigned int, const char *); -extern int nvhost_get_irq_byname(struct nvhost_device *, const char *); - -#define to_nvhost_device(x) container_of((x), struct nvhost_device, dev) -#define to_nvhost_driver(drv) (container_of((drv), struct nvhost_driver, \ - driver)) - -#define nvhost_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) -#define nvhost_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) - -int nvhost_bus_register(struct nvhost_master *host); - -#if !defined(__KERNEL__) -#define __user -#endif - -#define NVHOST_NO_TIMEOUT (-1) -#define NVHOST_IOCTL_MAGIC 'H' - -struct nvhost_submit_hdr { - __u32 syncpt_id; - __u32 syncpt_incrs; - __u32 num_cmdbufs; - __u32 num_relocs; - __u32 num_waitchks; - __u32 waitchk_mask; -}; - -struct nvhost_cmdbuf { - __u32 mem; - __u32 offset; - __u32 words; -}; - -struct nvhost_reloc { - __u32 cmdbuf_mem; - __u32 cmdbuf_offset; - __u32 target; - __u32 target_offset; -}; - -struct nvhost_waitchk { - __u32 mem; - __u32 offset; - __u32 syncpt_id; - __u32 thresh; -}; - -struct nvhost_get_param_args { - __u32 value; -}; - -struct nvhost_set_nvmap_fd_args { - __u32 fd; -}; - -#define NVHOST_IOCTL_CHANNEL_FLUSH \ - _IOR(NVHOST_IOCTL_MAGIC, 1, struct nvhost_get_param_args) -#define NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS \ - _IOR(NVHOST_IOCTL_MAGIC, 2, struct nvhost_get_param_args) -#define NVHOST_IOCTL_CHANNEL_GET_WAITBASES \ - _IOR(NVHOST_IOCTL_MAGIC, 3, struct nvhost_get_param_args) -#define NVHOST_IOCTL_CHANNEL_GET_MODMUTEXES \ - _IOR(NVHOST_IOCTL_MAGIC, 4, struct nvhost_get_param_args) -#define NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD \ - _IOW(NVHOST_IOCTL_MAGIC, 5, struct nvhost_set_nvmap_fd_args) -#define NVHOST_IOCTL_CHANNEL_LAST \ - _IOC_NR(NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD) -#define NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvhost_get_param_args) - -struct nvhost_ctrl_syncpt_read_args { - __u32 id; - __u32 value; -}; - -struct nvhost_ctrl_syncpt_incr_args { - __u32 id; -}; - -struct nvhost_ctrl_syncpt_wait_args { - __u32 id; - __u32 thresh; - __s32 timeout; -}; - -struct nvhost_ctrl_module_mutex_args { - __u32 id; - __u32 lock; -}; - -struct nvhost_ctrl_module_regrdwr_args { - __u32 id; - __u32 num_offsets; - __u32 block_size; - __u32 *offsets; - __u32 *values; - __u32 write; -}; - -#define NVHOST_IOCTL_CTRL_SYNCPT_READ \ - _IOWR(NVHOST_IOCTL_MAGIC, 1, struct nvhost_ctrl_syncpt_read_args) -#define NVHOST_IOCTL_CTRL_SYNCPT_INCR \ - _IOW(NVHOST_IOCTL_MAGIC, 2, struct nvhost_ctrl_syncpt_incr_args) -#define NVHOST_IOCTL_CTRL_SYNCPT_WAIT \ - _IOW(NVHOST_IOCTL_MAGIC, 3, struct nvhost_ctrl_syncpt_wait_args) - -#define NVHOST_IOCTL_CTRL_MODULE_MUTEX \ - _IOWR(NVHOST_IOCTL_MAGIC, 4, struct nvhost_ctrl_module_mutex_args) -#define NVHOST_IOCTL_CTRL_MODULE_REGRDWR \ - _IOWR(NVHOST_IOCTL_MAGIC, 5, struct nvhost_ctrl_module_regrdwr_args) - -#define NVHOST_IOCTL_CTRL_LAST \ - _IOC_NR(NVHOST_IOCTL_CTRL_MODULE_REGRDWR) -#define NVHOST_IOCTL_CTRL_MAX_ARG_SIZE sizeof(struct nvhost_ctrl_module_regrdwr_args) - -#endif diff --git a/arch/arm/mach-tegra/include/mach/nvmap.h b/arch/arm/mach-tegra/include/mach/nvmap.h deleted file mode 100644 index 7a79748e5433..000000000000 --- a/arch/arm/mach-tegra/include/mach/nvmap.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * include/linux/nvmap.h - * - * structure declarations for nvmem and nvmap user-space ioctls - * - * Copyright (c) 2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#if !defined(__KERNEL__) -#define __user -#endif - -#ifndef __NVMAP_H -#define __NVMAP_H - -#define NVMAP_HEAP_SYSMEM (1ul<<31) -#define NVMAP_HEAP_IOVMM (1ul<<30) - -/* common carveout heaps */ -#define NVMAP_HEAP_CARVEOUT_IRAM (1ul<<29) -#define NVMAP_HEAP_CARVEOUT_GENERIC (1ul<<0) - -#define NVMAP_HEAP_CARVEOUT_MASK (NVMAP_HEAP_IOVMM - 1) - -/* allocation flags */ -#define NVMAP_HANDLE_UNCACHEABLE (0x0ul << 0) -#define NVMAP_HANDLE_WRITE_COMBINE (0x1ul << 0) -#define NVMAP_HANDLE_INNER_CACHEABLE (0x2ul << 0) -#define NVMAP_HANDLE_CACHEABLE (0x3ul << 0) -#define NVMAP_HANDLE_CACHE_FLAG (0x3ul << 0) - -#define NVMAP_HANDLE_SECURE (0x1ul << 2) - - -#if defined(__KERNEL__) - -struct nvmap_handle_ref; -struct nvmap_handle; -struct nvmap_client; -struct nvmap_device; - -#define nvmap_ref_to_handle(_ref) (*(struct nvmap_handle **)(_ref)) -#define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) - -struct nvmap_pinarray_elem { - __u32 patch_mem; - __u32 patch_offset; - __u32 pin_mem; - __u32 pin_offset; -}; - -struct nvmap_client *nvmap_create_client(struct nvmap_device *dev, - const char *name); - -struct nvmap_handle_ref *nvmap_alloc(struct nvmap_client *client, size_t size, - size_t align, unsigned int flags); - -void nvmap_free(struct nvmap_client *client, struct nvmap_handle_ref *r); - -void *nvmap_mmap(struct nvmap_handle_ref *r); - -void nvmap_munmap(struct nvmap_handle_ref *r, void *addr); - -struct nvmap_client *nvmap_client_get_file(int fd); - -struct nvmap_client *nvmap_client_get(struct nvmap_client *client); - -void nvmap_client_put(struct nvmap_client *c); - -unsigned long nvmap_pin(struct nvmap_client *c, struct nvmap_handle_ref *r); - -unsigned long nvmap_handle_address(struct nvmap_client *c, unsigned long id); - -void nvmap_unpin(struct nvmap_client *client, struct nvmap_handle_ref *r); - -int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather, - const struct nvmap_pinarray_elem *arr, int nr, - struct nvmap_handle **unique); - -void nvmap_unpin_handles(struct nvmap_client *client, - struct nvmap_handle **h, int nr); - -int nvmap_patch_wait(struct nvmap_client *client, - struct nvmap_handle *patch, - u32 patch_offset, u32 patch_value); - -struct nvmap_platform_carveout { - const char *name; - unsigned int usage_mask; - unsigned long base; - size_t size; - size_t buddy_size; -}; - -struct nvmap_platform_data { - const struct nvmap_platform_carveout *carveouts; - unsigned int nr_carveouts; -}; - -extern struct nvmap_device *nvmap_dev; - -#endif - -#endif diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-t2.h deleted file mode 100644 index 4c2626347263..000000000000 --- a/arch/arm/mach-tegra/include/mach/pinmux-t2.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * linux/arch/arm/mach-tegra/include/mach/pinmux-t2.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_PINMUX_T2_H -#define __MACH_TEGRA_PINMUX_T2_H - -enum tegra_pingroup { - TEGRA_PINGROUP_ATA = 0, - TEGRA_PINGROUP_ATB, - TEGRA_PINGROUP_ATC, - TEGRA_PINGROUP_ATD, - TEGRA_PINGROUP_ATE, - TEGRA_PINGROUP_CDEV1, - TEGRA_PINGROUP_CDEV2, - TEGRA_PINGROUP_CRTP, - TEGRA_PINGROUP_CSUS, - TEGRA_PINGROUP_DAP1, - TEGRA_PINGROUP_DAP2, - TEGRA_PINGROUP_DAP3, - TEGRA_PINGROUP_DAP4, - TEGRA_PINGROUP_DDC, - TEGRA_PINGROUP_DTA, - TEGRA_PINGROUP_DTB, - TEGRA_PINGROUP_DTC, - TEGRA_PINGROUP_DTD, - TEGRA_PINGROUP_DTE, - TEGRA_PINGROUP_DTF, - TEGRA_PINGROUP_GMA, - TEGRA_PINGROUP_GMB, - TEGRA_PINGROUP_GMC, - TEGRA_PINGROUP_GMD, - TEGRA_PINGROUP_GME, - TEGRA_PINGROUP_GPU, - TEGRA_PINGROUP_GPU7, - TEGRA_PINGROUP_GPV, - TEGRA_PINGROUP_HDINT, - TEGRA_PINGROUP_I2CP, - TEGRA_PINGROUP_IRRX, - TEGRA_PINGROUP_IRTX, - TEGRA_PINGROUP_KBCA, - TEGRA_PINGROUP_KBCB, - TEGRA_PINGROUP_KBCC, - TEGRA_PINGROUP_KBCD, - TEGRA_PINGROUP_KBCE, - TEGRA_PINGROUP_KBCF, - TEGRA_PINGROUP_LCSN, - TEGRA_PINGROUP_LD0, - TEGRA_PINGROUP_LD1, - TEGRA_PINGROUP_LD10, - TEGRA_PINGROUP_LD11, - TEGRA_PINGROUP_LD12, - TEGRA_PINGROUP_LD13, - TEGRA_PINGROUP_LD14, - TEGRA_PINGROUP_LD15, - TEGRA_PINGROUP_LD16, - TEGRA_PINGROUP_LD17, - TEGRA_PINGROUP_LD2, - TEGRA_PINGROUP_LD3, - TEGRA_PINGROUP_LD4, - TEGRA_PINGROUP_LD5, - TEGRA_PINGROUP_LD6, - TEGRA_PINGROUP_LD7, - TEGRA_PINGROUP_LD8, - TEGRA_PINGROUP_LD9, - TEGRA_PINGROUP_LDC, - TEGRA_PINGROUP_LDI, - TEGRA_PINGROUP_LHP0, - TEGRA_PINGROUP_LHP1, - TEGRA_PINGROUP_LHP2, - TEGRA_PINGROUP_LHS, - TEGRA_PINGROUP_LM0, - TEGRA_PINGROUP_LM1, - TEGRA_PINGROUP_LPP, - TEGRA_PINGROUP_LPW0, - TEGRA_PINGROUP_LPW1, - TEGRA_PINGROUP_LPW2, - TEGRA_PINGROUP_LSC0, - TEGRA_PINGROUP_LSC1, - TEGRA_PINGROUP_LSCK, - TEGRA_PINGROUP_LSDA, - TEGRA_PINGROUP_LSDI, - TEGRA_PINGROUP_LSPI, - TEGRA_PINGROUP_LVP0, - TEGRA_PINGROUP_LVP1, - TEGRA_PINGROUP_LVS, - TEGRA_PINGROUP_OWC, - TEGRA_PINGROUP_PMC, - TEGRA_PINGROUP_PTA, - TEGRA_PINGROUP_RM, - TEGRA_PINGROUP_SDB, - TEGRA_PINGROUP_SDC, - TEGRA_PINGROUP_SDD, - TEGRA_PINGROUP_SDIO1, - TEGRA_PINGROUP_SLXA, - TEGRA_PINGROUP_SLXC, - TEGRA_PINGROUP_SLXD, - TEGRA_PINGROUP_SLXK, - TEGRA_PINGROUP_SPDI, - TEGRA_PINGROUP_SPDO, - TEGRA_PINGROUP_SPIA, - TEGRA_PINGROUP_SPIB, - TEGRA_PINGROUP_SPIC, - TEGRA_PINGROUP_SPID, - TEGRA_PINGROUP_SPIE, - TEGRA_PINGROUP_SPIF, - TEGRA_PINGROUP_SPIG, - TEGRA_PINGROUP_SPIH, - TEGRA_PINGROUP_UAA, - TEGRA_PINGROUP_UAB, - TEGRA_PINGROUP_UAC, - TEGRA_PINGROUP_UAD, - TEGRA_PINGROUP_UCA, - TEGRA_PINGROUP_UCB, - TEGRA_PINGROUP_UDA, - /* these pin groups only have pullup and pull down control */ - TEGRA_PINGROUP_CK32, - TEGRA_PINGROUP_DDRC, - TEGRA_PINGROUP_PMCA, - TEGRA_PINGROUP_PMCB, - TEGRA_PINGROUP_PMCC, - TEGRA_PINGROUP_PMCD, - TEGRA_PINGROUP_PMCE, - TEGRA_PINGROUP_XM2C, - TEGRA_PINGROUP_XM2D, - TEGRA_MAX_PINGROUP, -}; - -enum tegra_drive_pingroup { - TEGRA_DRIVE_PINGROUP_AO1 = 0, - TEGRA_DRIVE_PINGROUP_AO2, - TEGRA_DRIVE_PINGROUP_AT1, - TEGRA_DRIVE_PINGROUP_AT2, - TEGRA_DRIVE_PINGROUP_CDEV1, - TEGRA_DRIVE_PINGROUP_CDEV2, - TEGRA_DRIVE_PINGROUP_CSUS, - TEGRA_DRIVE_PINGROUP_DAP1, - TEGRA_DRIVE_PINGROUP_DAP2, - TEGRA_DRIVE_PINGROUP_DAP3, - TEGRA_DRIVE_PINGROUP_DAP4, - TEGRA_DRIVE_PINGROUP_DBG, - TEGRA_DRIVE_PINGROUP_LCD1, - TEGRA_DRIVE_PINGROUP_LCD2, - TEGRA_DRIVE_PINGROUP_SDMMC2, - TEGRA_DRIVE_PINGROUP_SDMMC3, - TEGRA_DRIVE_PINGROUP_SPI, - TEGRA_DRIVE_PINGROUP_UAA, - TEGRA_DRIVE_PINGROUP_UAB, - TEGRA_DRIVE_PINGROUP_UART2, - TEGRA_DRIVE_PINGROUP_UART3, - TEGRA_DRIVE_PINGROUP_VI1, - TEGRA_DRIVE_PINGROUP_VI2, - TEGRA_DRIVE_PINGROUP_XM2A, - TEGRA_DRIVE_PINGROUP_XM2C, - TEGRA_DRIVE_PINGROUP_XM2D, - TEGRA_DRIVE_PINGROUP_XM2CLK, - TEGRA_DRIVE_PINGROUP_MEMCOMP, - TEGRA_DRIVE_PINGROUP_SDIO1, - TEGRA_DRIVE_PINGROUP_CRT, - TEGRA_DRIVE_PINGROUP_DDC, - TEGRA_DRIVE_PINGROUP_GMA, - TEGRA_DRIVE_PINGROUP_GMB, - TEGRA_DRIVE_PINGROUP_GMC, - TEGRA_DRIVE_PINGROUP_GMD, - TEGRA_DRIVE_PINGROUP_GME, - TEGRA_DRIVE_PINGROUP_OWR, - TEGRA_DRIVE_PINGROUP_UAD, - TEGRA_MAX_DRIVE_PINGROUP, -}; - -#endif - diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h index defd8775defa..41c8ce5b7c27 100644 --- a/arch/arm/mach-tegra/include/mach/pinmux.h +++ b/arch/arm/mach-tegra/include/mach/pinmux.h @@ -17,11 +17,126 @@ #ifndef __MACH_TEGRA_PINMUX_H #define __MACH_TEGRA_PINMUX_H -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) -#include "pinmux-t2.h" -#else -#error "Undefined Tegra architecture" -#endif +enum tegra_pingroup { + TEGRA_PINGROUP_ATA = 0, + TEGRA_PINGROUP_ATB, + TEGRA_PINGROUP_ATC, + TEGRA_PINGROUP_ATD, + TEGRA_PINGROUP_ATE, + TEGRA_PINGROUP_CDEV1, + TEGRA_PINGROUP_CDEV2, + TEGRA_PINGROUP_CRTP, + TEGRA_PINGROUP_CSUS, + TEGRA_PINGROUP_DAP1, + TEGRA_PINGROUP_DAP2, + TEGRA_PINGROUP_DAP3, + TEGRA_PINGROUP_DAP4, + TEGRA_PINGROUP_DDC, + TEGRA_PINGROUP_DTA, + TEGRA_PINGROUP_DTB, + TEGRA_PINGROUP_DTC, + TEGRA_PINGROUP_DTD, + TEGRA_PINGROUP_DTE, + TEGRA_PINGROUP_DTF, + TEGRA_PINGROUP_GMA, + TEGRA_PINGROUP_GMB, + TEGRA_PINGROUP_GMC, + TEGRA_PINGROUP_GMD, + TEGRA_PINGROUP_GME, + TEGRA_PINGROUP_GPU, + TEGRA_PINGROUP_GPU7, + TEGRA_PINGROUP_GPV, + TEGRA_PINGROUP_HDINT, + TEGRA_PINGROUP_I2CP, + TEGRA_PINGROUP_IRRX, + TEGRA_PINGROUP_IRTX, + TEGRA_PINGROUP_KBCA, + TEGRA_PINGROUP_KBCB, + TEGRA_PINGROUP_KBCC, + TEGRA_PINGROUP_KBCD, + TEGRA_PINGROUP_KBCE, + TEGRA_PINGROUP_KBCF, + TEGRA_PINGROUP_LCSN, + TEGRA_PINGROUP_LD0, + TEGRA_PINGROUP_LD1, + TEGRA_PINGROUP_LD10, + TEGRA_PINGROUP_LD11, + TEGRA_PINGROUP_LD12, + TEGRA_PINGROUP_LD13, + TEGRA_PINGROUP_LD14, + TEGRA_PINGROUP_LD15, + TEGRA_PINGROUP_LD16, + TEGRA_PINGROUP_LD17, + TEGRA_PINGROUP_LD2, + TEGRA_PINGROUP_LD3, + TEGRA_PINGROUP_LD4, + TEGRA_PINGROUP_LD5, + TEGRA_PINGROUP_LD6, + TEGRA_PINGROUP_LD7, + TEGRA_PINGROUP_LD8, + TEGRA_PINGROUP_LD9, + TEGRA_PINGROUP_LDC, + TEGRA_PINGROUP_LDI, + TEGRA_PINGROUP_LHP0, + TEGRA_PINGROUP_LHP1, + TEGRA_PINGROUP_LHP2, + TEGRA_PINGROUP_LHS, + TEGRA_PINGROUP_LM0, + TEGRA_PINGROUP_LM1, + TEGRA_PINGROUP_LPP, + TEGRA_PINGROUP_LPW0, + TEGRA_PINGROUP_LPW1, + TEGRA_PINGROUP_LPW2, + TEGRA_PINGROUP_LSC0, + TEGRA_PINGROUP_LSC1, + TEGRA_PINGROUP_LSCK, + TEGRA_PINGROUP_LSDA, + TEGRA_PINGROUP_LSDI, + TEGRA_PINGROUP_LSPI, + TEGRA_PINGROUP_LVP0, + TEGRA_PINGROUP_LVP1, + TEGRA_PINGROUP_LVS, + TEGRA_PINGROUP_OWC, + TEGRA_PINGROUP_PMC, + TEGRA_PINGROUP_PTA, + TEGRA_PINGROUP_RM, + TEGRA_PINGROUP_SDB, + TEGRA_PINGROUP_SDC, + TEGRA_PINGROUP_SDD, + TEGRA_PINGROUP_SDIO1, + TEGRA_PINGROUP_SLXA, + TEGRA_PINGROUP_SLXC, + TEGRA_PINGROUP_SLXD, + TEGRA_PINGROUP_SLXK, + TEGRA_PINGROUP_SPDI, + TEGRA_PINGROUP_SPDO, + TEGRA_PINGROUP_SPIA, + TEGRA_PINGROUP_SPIB, + TEGRA_PINGROUP_SPIC, + TEGRA_PINGROUP_SPID, + TEGRA_PINGROUP_SPIE, + TEGRA_PINGROUP_SPIF, + TEGRA_PINGROUP_SPIG, + TEGRA_PINGROUP_SPIH, + TEGRA_PINGROUP_UAA, + TEGRA_PINGROUP_UAB, + TEGRA_PINGROUP_UAC, + TEGRA_PINGROUP_UAD, + TEGRA_PINGROUP_UCA, + TEGRA_PINGROUP_UCB, + TEGRA_PINGROUP_UDA, + /* these pin groups only have pullup and pull down control */ + TEGRA_PINGROUP_CK32, + TEGRA_PINGROUP_DDRC, + TEGRA_PINGROUP_PMCA, + TEGRA_PINGROUP_PMCB, + TEGRA_PINGROUP_PMCC, + TEGRA_PINGROUP_PMCD, + TEGRA_PINGROUP_PMCE, + TEGRA_PINGROUP_XM2C, + TEGRA_PINGROUP_XM2D, + TEGRA_MAX_PINGROUP, +}; enum tegra_mux_func { TEGRA_MUX_RSVD = 0x8000, @@ -90,7 +205,6 @@ enum tegra_mux_func { TEGRA_MUX_VI, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_MUX_XIO, - TEGRA_MUX_SAFE, TEGRA_MAX_MUX, }; @@ -105,18 +219,6 @@ enum tegra_tristate { TEGRA_TRI_TRISTATE = 1, }; -enum tegra_vddio { - TEGRA_VDDIO_BB = 0, - TEGRA_VDDIO_LCD, - TEGRA_VDDIO_VI, - TEGRA_VDDIO_UART, - TEGRA_VDDIO_DDR, - TEGRA_VDDIO_NAND, - TEGRA_VDDIO_SYS, - TEGRA_VDDIO_AUDIO, - TEGRA_VDDIO_SD, -}; - struct tegra_pingroup_config { enum tegra_pingroup pingroup; enum tegra_mux_func func; @@ -168,6 +270,38 @@ enum tegra_pull_strength { TEGRA_MAX_PULL, }; +enum tegra_drive_pingroup { + TEGRA_DRIVE_PINGROUP_AO1 = 0, + TEGRA_DRIVE_PINGROUP_AO2, + TEGRA_DRIVE_PINGROUP_AT1, + TEGRA_DRIVE_PINGROUP_AT2, + TEGRA_DRIVE_PINGROUP_CDEV1, + TEGRA_DRIVE_PINGROUP_CDEV2, + TEGRA_DRIVE_PINGROUP_CSUS, + TEGRA_DRIVE_PINGROUP_DAP1, + TEGRA_DRIVE_PINGROUP_DAP2, + TEGRA_DRIVE_PINGROUP_DAP3, + TEGRA_DRIVE_PINGROUP_DAP4, + TEGRA_DRIVE_PINGROUP_DBG, + TEGRA_DRIVE_PINGROUP_LCD1, + TEGRA_DRIVE_PINGROUP_LCD2, + TEGRA_DRIVE_PINGROUP_SDMMC2, + TEGRA_DRIVE_PINGROUP_SDMMC3, + TEGRA_DRIVE_PINGROUP_SPI, + TEGRA_DRIVE_PINGROUP_UAA, + TEGRA_DRIVE_PINGROUP_UAB, + TEGRA_DRIVE_PINGROUP_UART2, + TEGRA_DRIVE_PINGROUP_UART3, + TEGRA_DRIVE_PINGROUP_VI1, + TEGRA_DRIVE_PINGROUP_VI2, + TEGRA_DRIVE_PINGROUP_XM2A, + TEGRA_DRIVE_PINGROUP_XM2C, + TEGRA_DRIVE_PINGROUP_XM2D, + TEGRA_DRIVE_PINGROUP_XM2CLK, + TEGRA_DRIVE_PINGROUP_MEMCOMP, + TEGRA_MAX_DRIVE_PINGROUP, +}; + enum tegra_drive { TEGRA_DRIVE_DIV_8 = 0, TEGRA_DRIVE_DIV_4, @@ -197,44 +331,18 @@ struct tegra_drive_pingroup_config { enum tegra_slew slew_falling; }; -struct tegra_drive_pingroup_desc { - const char *name; - s16 reg; -}; - -struct tegra_pingroup_desc { - const char *name; - int funcs[4]; - int func_safe; - int vddio; - s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */ - s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */ - s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */ - s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */ - s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */ - s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */ -}; - -extern const struct tegra_pingroup_desc tegra_soc_pingroups[]; -extern const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[]; +int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func); +int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate); +int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd); -int tegra_pinmux_set_tristate(enum tegra_pingroup pg, +void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup, + enum tegra_mux_func func, enum tegra_pullupdown pupd, enum tegra_tristate tristate); -int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, - enum tegra_pullupdown pupd); -void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, - int len); +void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len); void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config, int len); -void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config, - int len); -void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config, - int len); -void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config, - int len, enum tegra_tristate tristate); -void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config, - int len, enum tegra_pullupdown pupd); + #endif diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h deleted file mode 100644 index 401d1b725291..000000000000 --- a/arch/arm/mach-tegra/include/mach/powergate.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * drivers/regulator/tegra-regulator.c - * - * Copyright (c) 2010 Google, Inc - * - * Author: - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_TEGRA_POWERGATE_H_ -#define _MACH_TEGRA_POWERGATE_H_ - -#define TEGRA_POWERGATE_CPU 0 -#define TEGRA_POWERGATE_3D 1 -#define TEGRA_POWERGATE_VENC 2 -#define TEGRA_POWERGATE_PCIE 3 -#define TEGRA_POWERGATE_VDEC 4 -#define TEGRA_POWERGATE_L2 5 -#define TEGRA_POWERGATE_MPE 6 -#define TEGRA_NUM_POWERGATE 7 - -int tegra_powergate_power_on(int id); -int tegra_powergate_power_off(int id); -bool tegra_powergate_is_powered(int id); -int tegra_powergate_remove_clamping(int id); - -/* Must be called with clk disabled, and returns with clk enabled */ -int tegra_powergate_sequence_power_up(int id, struct clk *clk); - -#endif /* _MACH_TEGRA_POWERGATE_H_ */ diff --git a/arch/arm/mach-tegra/include/mach/sdhci.h b/arch/arm/mach-tegra/include/mach/sdhci.h deleted file mode 100644 index a6e7fc5fc984..000000000000 --- a/arch/arm/mach-tegra/include/mach/sdhci.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * include/asm-arm/arch-tegra/sdhci.h - * - * Copyright (C) 2009 Palm, Inc. - * Author: Yvonne Yip - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __ASM_ARM_ARCH_TEGRA_SDHCI_H -#define __ASM_ARM_ARCH_TEGRA_SDHCI_H - -#include -#include - -struct tegra_sdhci_platform_data { - const char *clk_id; - int force_hs; - int rt_disable; - int cd_gpio; - int wp_gpio; - int power_gpio; - struct mmc_platform_data mmc_data; - - void (*board_probe)(int id, struct mmc_host *); - void (*board_remove)(int id, struct mmc_host *); -}; - -#endif diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h index cd6a3fc567f1..8b42dab79a70 100644 --- a/arch/arm/mach-tegra/include/mach/smp.h +++ b/arch/arm/mach-tegra/include/mach/smp.h @@ -17,7 +17,6 @@ */ static inline void smp_cross_call(const struct cpumask *mask) { - dsb(); gic_raise_softirq(mask, 1); } diff --git a/arch/arm/mach-tegra/include/mach/spdif.h b/arch/arm/mach-tegra/include/mach/spdif.h deleted file mode 100644 index 96103fae91b1..000000000000 --- a/arch/arm/mach-tegra/include/mach/spdif.h +++ /dev/null @@ -1,392 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/spdif.h - * - * - * Copyright (c) 2008-2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - - -#ifndef __ARCH_ARM_MACH_TEGRA_SPDIF_H -#define __ARCH_ARM_MACH_TEGRA_SPDIF_H - -#include -#include -#include - -/* Offsets from TEGRA_SPDIF_BASE */ - -#define SPDIF_CTRL_0 0x0 -#define SPDIF_STATUS_0 0x4 -#define SPDIF_STROBE_CTRL_0 0x8 -#define SPDIF_DATA_FIFO_CSR_0 0x0C -#define SPDIF_DATA_OUT_0 0x40 -#define SPDIF_DATA_IN_0 0x80 -#define SPDIF_CH_STA_RX_A_0 0x100 -#define SPDIF_CH_STA_RX_B_0 0x104 -#define SPDIF_CH_STA_RX_C_0 0x108 -#define SPDIF_CH_STA_RX_D_0 0x10C -#define SPDIF_CH_STA_RX_E_0 0x110 -#define SPDIF_CH_STA_RX_F_0 0x114 -#define SPDIF_CH_STA_TX_A_0 0x140 -#define SPDIF_CH_STA_TX_B_0 0x144 -#define SPDIF_CH_STA_TX_C_0 0x148 -#define SPDIF_CH_STA_TX_D_0 0x14C -#define SPDIF_CH_STA_TX_E_0 0x150 -#define SPDIF_CH_STA_TX_F_0 0x154 -#define SPDIF_USR_STA_RX_A_0 0x180 -#define SPDIF_USR_DAT_TX_A_0 0x1C0 - -/* - * Register SPDIF_CTRL_0 - */ - -/* - * 1=start capturing from left channel,0=start - * capturing from right channel. - */ -#define SPDIF_CTRL_0_CAP_LC (1<<30) - -/* SPDIF receiver(RX): 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_RX_EN (1<<29) - -/* SPDIF Transmitter(TX): 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_TX_EN (1<<28) - -/* Transmit Channel status: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_TC_EN (1<<27) - -/* Transmit user Data: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_TU_EN (1<<26) - -/* Interrupt on transmit error: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_IE_TXE (1<<25) - -/* Interrupt on receive error: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_IE_RXE (1<<24) - -/* Interrupt on invalid preamble: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_IE_P (1<<23) - -/* Interrupt on "B" preamble: 1=enable, 0=disable. */ -#define SPDIF_CTRL_0_IE_B (1<<22) - -/* - * Interrupt when block of channel status received: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_IE_C (1<<21) - -/* - * Interrupt when a valid information unit (IU) recieve: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_IE_U (1<<20) - -/* - * Interrupt when RX user FIFO attn. level is reached: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_QE_RU (1<<19) - -/* - * Interrupt when TX user FIFO attn. level is reached: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_QE_TU (1<<18) - -/* - * Interrupt when RX data FIFO attn. level is reached: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_QE_RX (1<<17) - -/* - * Interrupt when TX data FIFO attn. level is reached: - * 1=enable, 0=disable. - */ -#define SPDIF_CTRL_0_QE_TX (1<<16) - -/* Loopback test mode: 1=enable internal loopback, 0=Normal mode. */ -#define SPDIF_CTRL_0_LBK_EN (1<<15) - -/* - * Pack data mode: - * 1=Packeted left/right channel data into a single word, - * 0=Single data (16 bit needs to be padded to match the - * interface data bit size) - */ -#define SPDIF_CTRL_0_PACK (1<<14) - -/* - * 00=16bit data - * 01=20bit data - * 10=24bit data - * 11=raw data - */ -#define SPDIF_BIT_MODE_MODE16BIT (0) -#define SPDIF_BIT_MODE_MODE20BIT (1) -#define SPDIF_BIT_MODE_MODE24BIT (2) -#define SPDIF_BIT_MODE_MODERAW (3) -#define SPDIF_CTRL_0_BIT_MODE_SHIFT (12) - -#define SPDIF_CTRL_0_BIT_MODE_MASK \ - ((0x3) << SPDIF_CTRL_0_BIT_MODE_SHIFT) -#define SPDIF_CTRL_0_BIT_MODE_MODE16BIT \ - (SPDIF_BIT_MODE_MODE16BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT) -#define SPDIF_CTRL_0_BIT_MODE_MODE20BIT \ - (SPDIF_BIT_MODE_MODE20BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT) -#define SPDIF_CTRL_0_BIT_MODE_MODE24BIT \ - (SPDIF_BIT_MODE_MODE24BIT << SPDIF_CTRL_0_BIT_MODE_SHIFT) -#define SPDIF_CTRL_0_BIT_MODE_MODERAW \ - (SPDIF_BIT_MODE_MODERAW << SPDIF_CTRL_0_BIT_MODE_SHIFT) - - -/* - * SPDIF Status Register - * ------------------------- - * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. - * Software must write a 1 to the corresponding bit location - * to clear the status. - */ - -/* Register SPDIF_STATUS_0 */ - -/* - * Receiver(RX) shifter is busy receiving data. 1=busy, 0=not busy. - * This bit is asserted when the receiver first locked onto the - * preamble of the data stream after RX_EN is asserted. This bit is - * deasserted when either, - * (a) the end of a frame is reached after RX_EN is deeasserted, or - * (b) the SPDIF data stream becomes inactive. - */ -#define SPDIF_STATUS_0_RX_BSY (1<<29) - - -/* - * Transmitter(TX) shifter is busy transmitting data. - * 1=busy, 0=not busy. - * This bit is asserted when TX_EN is asserted. - * This bit is deasserted when the end of a frame is reached after - * TX_EN is deasserted. - */ -#define SPDIF_STATUS_0_TX_BSY (1<<28) - -/* - * TX is busy shifting out channel status. 1=busy, 0=not busy. - * This bit is asserted when both TX_EN and TC_EN are asserted and - * data from CH_STA_TX_A register is loaded into the internal shifter. - * This bit is deasserted when either, - * (a) the end of a frame is reached after TX_EN is deasserted, or - * (b) CH_STA_TX_F register is loaded into the internal shifter. - */ -#define SPDIF_STATUS_0_TC_BSY (1<<27) - -/* - * TX User data FIFO busy. 1=busy, 0=not busy. - * This bit is asserted when TX_EN and TXU_EN are asserted and - * there's data in the TX user FIFO. This bit is deassert when either, - * (a) the end of a frame is reached after TX_EN is deasserted, or - * (b) there's no data left in the TX user FIFO. - */ -#define SPDIF_STATUS_0_TU_BSY (1<<26) - -/* Tx FIFO Underrun error status: 1=error, 0=no error */ -#define SPDIF_STATUS_0_TX_ERR (1<<25) - -/* Rx FIFO Overrun error status: 1=error, 0=no error */ -#define SPDIF_STATUS_0_RX_ERR (1<<24) - -/* Preamble status: 1=bad/missing preamble, 0=Preamble ok */ -#define SPDIF_STATUS_0_IS_P (1<<23) - -/* B-preamble detection status: 0=not detected, 1=B-preamble detected */ -#define SPDIF_STATUS_0_IS_B (1<<22) - -/* - * RX channel block data receive status: - * 1=received entire block of channel status, - * 0=entire block not recieved yet. - */ -#define SPDIF_STATUS_0_IS_C (1<<21) - -/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */ -#define SPDIF_STATUS_0_IS_U (1<<20) - -/* - * RX User FIFO Status: - * 1=attention level reached, 0=attention level not reached. - */ -#define SPDIF_STATUS_0_QS_RU (1<<19) - -/* - * TX User FIFO Status: - * 1=attention level reached, 0=attention level not reached. - */ -#define SPDIF_STATUS_0_QS_TU (1<<18) - -/* - * RX Data FIFO Status: - * 1=attention level reached, 0=attention level not reached. - */ -#define SPDIF_STATUS_0_QS_RX (1<<17) - -/* - * TX Data FIFO Status: - * 1=attention level reached, 0=attention level not reached. - */ -#define SPDIF_STATUS_0_QS_TX (1<<16) - - -/* SPDIF FIFO Configuration and Status Register */ - -/* Register SPDIF_DATA_FIFO_CSR_0 */ - -#define SPDIF_FIFO_ATN_LVL_ONE_SLOT 0 -#define SPDIF_FIFO_ATN_LVL_FOUR_SLOTS 1 -#define SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS 2 -#define SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS 3 - - -/* Clear Receiver User FIFO (RX USR.FIFO) */ -#define SPDIF_DATA_FIFO_CSR_0_RU_CLR (1<<31) - -/* - * RX USR.FIFO Attention Level: - * 00=1-slot-full, 01=2-slots-full, 10=3-slots-full, 11=4-slots-full. - */ - -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1 (0) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2 (1) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3 (2) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4 (3) - -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIFT (29) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_MASK \ - (0x3 << SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1_WORD_FULL \ - (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU1 << \ - SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2_WORD_FULL \ - (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU2 << \ - SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3_WORD_FULL \ - (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU3 << \ - SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF) -#define SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4_WORD_FULL \ - (SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_RU4 << \ - SPDIF_DATA_FIFO_CSR_0_RU_ATN_LVL_SHIF) - -/* Number of RX USR.FIFO levels with valid data. */ -#define SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_SHIFT (24) -#define SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_MASK \ - (0x1f << SPDIF_DATA_FIFO_CSR_0_FULL_COUNT_SHIFT) - -/* Clear Transmitter User FIFO (TX USR.FIFO) */ -#define SPDIF_DATA_FIFO_CSR_0_TU_CLR (1<<23) - -/* - * TxUSR.FIFO Attention Level: - * 11=4-slots-empty, 10=3-slots-empty, 01=2-slots-empty, 00=1-slot-empty. - */ - -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1 (0) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2 (1) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3 (2) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4 (3) - -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT (21) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_MASK \ - (0x3 << SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1_WORD_EMPTY \ - (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU1 << \ - SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2_WORD_EMPTY \ - (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU2 << \ - SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3_WORD_EMPTY \ - (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU3 << \ - SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4_WORD_EMPTY \ - (SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_TU4 << \ - SPDIF_DATA_FIFO_CSR_0_TU_ATN_LVL_SHIFT) - -/* Number of Tx USR.FIFO levels that could be filled. */ -#define SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_SHIFT (16) -#define SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_FIELD \ - ((0x1f) << SPDIF_DATA_FIFO_CSR_0_TU_EMPTY_COUNT_SHIFT) - -/* Clear Receiver Data FIFO (RX DATA.FIFO). */ -#define SPDIF_DATA_FIFO_CSR_0_RX_CLR (1<<15) - -/* - * Rx FIFO Attention Level: - * 11=12-slots-full, 10=8-slots-full, 01=4-slots-full, 00=1-slot-full. - */ -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT (13) -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_MASK \ - (0x3 << SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX1_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_ONE_SLOT << \ - SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX4_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_FOUR_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX8_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_RX12_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_RX_ATN_LVL_SHIFT) - - -/* Number of RX DATA.FIFO levels with valid data */ -#define SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_SHIFT (8) -#define SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_FIELD \ - ((0x1f) << SPDIF_DATA_FIFO_CSR_0_RX_DATA_FIFO_FULL_COUNT_SHIFT) - -/* Clear Transmitter Data FIFO (TX DATA.FIFO) */ -#define SPDIF_DATA_FIFO_CSR_0_TX_CLR (1<<7) - -/* - * Tx FIFO Attention Level: - * 11=12-slots-empty, 10=8-slots-empty, 01=4-slots-empty, 00=1-slot-empty - */ -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT (5) -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_MASK \ - (0x3 << SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX1_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_ONE_SLOT << \ - SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX4_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_FOUR_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX8_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT) -#define SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_TX12_WORD_FULL \ - (SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS << \ - SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT) - - -/* Number of Tx DATA.FIFO levels that could be filled. */ -#define SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_SHIFT (0) -#define SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_MASK \ - ((0x1f) << SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_SHIFT) - - -#endif /* __ARCH_ARM_MACH_TEGRA_SPDIF_H */ diff --git a/arch/arm/mach-tegra/include/mach/suspend.h b/arch/arm/mach-tegra/include/mach/suspend.h deleted file mode 100644 index e6043ae614cc..000000000000 --- a/arch/arm/mach-tegra/include/mach/suspend.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/suspend.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - - -#ifndef _MACH_TEGRA_SUSPEND_H_ -#define _MACH_TEGRA_SUSPEND_H_ - -enum tegra_suspend_mode { - TEGRA_SUSPEND_NONE = 0, - TEGRA_SUSPEND_LP2, /* CPU voltage off */ - TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ - TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ - TEGRA_MAX_SUSPEND_MODE, -}; - -struct tegra_suspend_platform_data { - unsigned long cpu_timer; /* CPU power good time in us, LP2/LP1 */ - unsigned long cpu_off_timer; /* CPU power off time us, LP2/LP1 */ - unsigned long core_timer; /* core power good time in ticks, LP0 */ - unsigned long core_off_timer; /* core power off time ticks, LP0 */ - unsigned long wake_enb; /* mask of enabled wake pads */ - unsigned long wake_high; /* high-level-triggered wake pads */ - unsigned long wake_low; /* low-level-triggered wake pads */ - unsigned long wake_any; /* any-edge-triggered wake pads */ - bool corereq_high; /* Core power request active-high */ - bool sysclkreq_high; /* System clock request is active-high */ - bool separate_req; /* Core & CPU power request are separate */ - enum tegra_suspend_mode suspend_mode; -}; - -unsigned long tegra_cpu_power_good_time(void); -unsigned long tegra_cpu_power_off_time(void); -enum tegra_suspend_mode tegra_get_suspend_mode(void); - -void __tegra_lp1_reset(void); -void __tegra_iram_end(void); - -void lp0_suspend_init(void); - -void tegra_pinmux_suspend(void); -void tegra_irq_suspend(void); -void tegra_gpio_suspend(void); -void tegra_clk_suspend(void); -void tegra_dma_suspend(void); -void tegra_timer_suspend(void); - -void tegra_pinmux_resume(void); -void tegra_irq_resume(void); -void tegra_gpio_resume(void); -void tegra_clk_resume(void); -void tegra_dma_resume(void); -void tegra_timer_resume(void); - -int tegra_irq_to_wake(int irq); -int tegra_wake_to_irq(int wake); - -int tegra_set_lp0_wake(int irq, int enable); -int tegra_set_lp0_wake_type(int irq, int flow_type); -int tegra_set_lp1_wake(int irq, int enable); -void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any); - -void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat); - -#endif /* _MACH_TEGRA_SUSPEND_H_ */ diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h index ccf371aefc9c..84d5d46113f7 100644 --- a/arch/arm/mach-tegra/include/mach/system.h +++ b/arch/arm/mach-tegra/include/mach/system.h @@ -24,30 +24,16 @@ #include #include -extern void (*tegra_reset)(char mode, const char *cmd); - static inline void arch_idle(void) { } -static inline void tegra_assert_system_reset(void) +static inline void arch_reset(char mode, const char *cmd) { void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04); - u32 reg; - - reg = readl_relaxed(reset); + u32 reg = readl(reset); reg |= 0x04; - writel_relaxed(reg, reset); -} - -static inline void arch_reset(char mode, const char *cmd) -{ - if (tegra_reset) - tegra_reset(mode, cmd); - else - tegra_assert_system_reset(); - - do { } while (1); + writel(reg, reset); } #endif diff --git a/arch/arm/mach-tegra/include/mach/tegra2_fuse.h b/arch/arm/mach-tegra/include/mach/tegra2_fuse.h deleted file mode 100644 index 3935ec75cbbe..000000000000 --- a/arch/arm/mach-tegra/include/mach/tegra2_fuse.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/tegra2_fuse.h - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MACH_TEGRA2_FUSE_H -#define __MACH_TEGRA2_FUSE_H - -#include - -#define SBK_DEVKEY_STATUS_SZ sizeof(u32) - -#define TEGRA_FUSE_IOCTL_PROGRAM_SBK _IOWR(0x99, 100, int*) -#define TEGRA_FUSE_IOCTL_GET_UID _IOWR(0x99, 101, int*) -#define TEGRA_FUSE_IOCTL_PROGRAM_SDMMC _IOWR(0x99, 102, int) -#define TEGRA_FUSE_IOCTL_VERIFY_SBK _IOWR(0x99, 103, int) -#define TEGRA_FUSE_IOCTL_VERIFY_PROD_ODM _IOWR(0x99, 104, int) - -#define SIZE_OF_UID 16 -#define SIZE_OF_SBK 16 - -/* fuse io parameters */ -enum fuse_io_param { - DEVKEY, - JTAG_DIS, - /* - * Programming the odm production fuse at the same - * time as the sbk or dev_key is not allowed as it is not possible to - * verify that the sbk or dev_key were programmed correctly. - */ - ODM_PROD_MODE, - SEC_BOOT_DEV_CFG, - SEC_BOOT_DEV_SEL, - SBK, - SW_RSVD, - IGNORE_DEV_SEL_STRAPS, - ODM_RSVD, - SBK_DEVKEY_STATUS, - MASTER_ENB, - _PARAMS_U32 = 0x7FFFFFFF -}; - -#define MAX_PARAMS ODM_RSVD - -/* the order of the members is pre-decided. please do not change */ -struct fuse_data { - u32 devkey; - u32 jtag_dis; - u32 odm_prod_mode; - u32 bootdev_cfg; - u32 bootdev_sel; - u32 sbk[4]; - u32 sw_rsvd; - u32 ignore_devsel_straps; - u32 odm_rsvd[8]; -}; - -/* secondary boot device options */ -enum { - SECBOOTDEV_SDMMC, - SECBOOTDEV_NOR, - SECBOOTDEV_SPI, - SECBOOTDEV_NAND, - SECBOOTDEV_LBANAND, - SECBOOTDEV_MUXONENAND, - _SECBOOTDEV_MAX, - _SECBOOTDEV_U32 = 0x7FFFFFFF -}; - -/* - * read the fuse settings - * @param: io_param_type - param type enum - * @param: size - read size in bytes - */ -int tegra_fuse_read(u32 io_param_type, u32 *data, int size); - -#define FLAGS_DEVKEY BIT(DEVKEY) -#define FLAGS_JTAG_DIS BIT(JTAG_DIS) -#define FLAGS_SBK_DEVKEY_STATUS BIT(SBK_DEVKEY_STATUS) -#define FLAGS_ODM_PROD_MODE BIT(ODM_PROD_MODE) -#define FLAGS_SEC_BOOT_DEV_CFG BIT(SEC_BOOT_DEV_CFG) -#define FLAGS_SEC_BOOT_DEV_SEL BIT(SEC_BOOT_DEV_SEL) -#define FLAGS_SBK BIT(SBK) -#define FLAGS_SW_RSVD BIT(SW_RSVD) -#define FLAGS_IGNORE_DEV_SEL_STRAPS BIT(IGNORE_DEV_SEL_STRAPS) -#define FLAGS_ODMRSVD BIT(ODM_RSVD) - -/* - * Prior to invoking this routine, the caller is responsible for supplying - * valid fuse programming voltage. - * - * @param: pgm_data - entire data to be programmed - * @flags: program flags (e.g. FLAGS_DEVKEY) - */ -int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags); - -/* Disables the fuse programming until the next system reset */ -void tegra_fuse_program_disable(void); - -#endif diff --git a/arch/arm/mach-tegra/include/mach/tegra_fb.h b/arch/arm/mach-tegra/include/mach/tegra_fb.h deleted file mode 100644 index 84ae8869b247..000000000000 --- a/arch/arm/mach-tegra/include/mach/tegra_fb.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/tegra_fb.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * 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. - * - */ - -/* Platform data structure to be passed to the driver */ -struct tegra_fb_lcd_data { - int fb_xres; - int fb_yres; - /* Resolution of the output to the LCD. If different from the - framebuffer resolution, the Tegra display block will scale it */ - int lcd_xres; - int lcd_yres; - int bits_per_pixel; -}; diff --git a/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h b/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h deleted file mode 100644 index 4d1a0b54f2ae..000000000000 --- a/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * linux/arch/arm/mach-tegra/include/mach/tegra_fiq_debugger.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_FIQ_DEBUGGER_H -#define __MACH_TEGRA_FIQ_DEBUGGER_H - -#ifdef CONFIG_TEGRA_FIQ_DEBUGGER -void tegra_serial_debug_init(unsigned int base, int irq, - struct clk *clk, int signal_irq, int wakeup_irq); -#else -static inline void tegra_serial_debug_init(unsigned int base, int irq, - struct clk *clk, int signal_irq, int wakeup_irq) -{ -} -#endif - -#endif diff --git a/arch/arm/mach-tegra/include/mach/tegra_hsuart.h b/arch/arm/mach-tegra/include/mach/tegra_hsuart.h deleted file mode 100644 index 4e07d50d103f..000000000000 --- a/arch/arm/mach-tegra/include/mach/tegra_hsuart.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * Author: Jaikumar Ganesh - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_TEGRA_HSUART_H -#define __ASM_ARCH_TEGRA_HSUART_H - -/* Optional platform device data for tegra_hsuart driver. */ -struct tegra_hsuart_platform_data { - void (*exit_lpm_cb)(struct uart_port *); - void (*rx_done_cb)(struct uart_port *); -}; - -#endif diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h index 64dd4995467b..6c4dd815abd7 100644 --- a/arch/arm/mach-tegra/include/mach/uncompress.h +++ b/arch/arm/mach-tegra/include/mach/uncompress.h @@ -26,9 +26,23 @@ #include +#if defined(CONFIG_TEGRA_DEBUG_UARTA) +#define DEBUG_UART_BASE TEGRA_UARTA_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) +#define DEBUG_UART_BASE TEGRA_UARTB_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) +#define DEBUG_UART_BASE TEGRA_UARTC_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) +#define DEBUG_UART_BASE TEGRA_UARTD_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) +#define DEBUG_UART_BASE TEGRA_UARTE_BASE +#else +#define DEBUG_UART_BASE NULL +#endif + static void putc(int c) { - volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; int shift = 2; if (uart == NULL) @@ -45,14 +59,14 @@ static inline void flush(void) static inline void arch_decomp_setup(void) { - volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; int shift = 2; if (uart == NULL) return; uart[UART_LCR << shift] |= UART_LCR_DLAB; - uart[UART_DLL << shift] = 0xe; + uart[UART_DLL << shift] = 0x75; uart[UART_DLM << shift] = 0x0; uart[UART_LCR << shift] = 3; } diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h deleted file mode 100644 index bca649d80e38..000000000000 --- a/arch/arm/mach-tegra/include/mach/usb_phy.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/usb_phy.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_USB_PHY_H -#define __MACH_USB_PHY_H - -#include -#include - -struct tegra_utmip_config { - u8 hssync_start_delay; - u8 elastic_limit; - u8 idle_wait_delay; - u8 term_range_adj; - u8 xcvr_setup; - u8 xcvr_lsfslew; - u8 xcvr_lsrslew; -}; - -struct tegra_ulpi_config { - int reset_gpio; - const char *clk; -}; - -enum tegra_usb_phy_port_speed { - TEGRA_USB_PHY_PORT_SPEED_FULL = 0, - TEGRA_USB_PHY_PORT_SPEED_LOW, - TEGRA_USB_PHY_PORT_SPEED_HIGH, -}; - -enum tegra_usb_phy_mode { - TEGRA_USB_PHY_MODE_DEVICE, - TEGRA_USB_PHY_MODE_HOST, -}; - -struct tegra_xtal_freq; - -struct tegra_usb_phy { - int instance; - const struct tegra_xtal_freq *freq; - void __iomem *regs; - void __iomem *pad_regs; - struct clk *clk; - struct clk *pll_u; - struct clk *pad_clk; - enum tegra_usb_phy_mode mode; - void *config; - struct otg_transceiver *ulpi; - int initialized; -}; - -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode); - -int tegra_usb_phy_power_on(struct tegra_usb_phy *phy); - -void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); - -void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); - -void tegra_usb_phy_power_off(struct tegra_usb_phy *phy); - -void tegra_usb_phy_preresume(struct tegra_usb_phy *phy); - -void tegra_usb_phy_postresume(struct tegra_usb_phy *phy); - -void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed); - -void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); - -void tegra_usb_phy_close(struct tegra_usb_phy *phy); - -#endif /* __MACH_USB_PHY_H */ diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h index af56a1cf3fac..fd6aa65b2dc6 100644 --- a/arch/arm/mach-tegra/include/mach/vmalloc.h +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h @@ -1,4 +1,3 @@ - /* * arch/arm/mach-tegra/include/mach/vmalloc.h * @@ -24,6 +23,6 @@ #include -#define VMALLOC_END 0xF8000000UL +#define VMALLOC_END 0xFE000000UL #endif diff --git a/arch/arm/mach-tegra/include/mach/w1.h b/arch/arm/mach-tegra/include/mach/w1.h deleted file mode 100644 index c96df7abdf96..000000000000 --- a/arch/arm/mach-tegra/include/mach/w1.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * include/mach/w1.h - * - * Copyright (C) 2010 Motorola, Inc - * Author: Andrei Warkentin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __ASM_ARM_ARCH_TEGRA_W1_H -#define __ASM_ARM_ARCH_TEGRA_W1_H - -struct tegra_w1_timings { - - /* tsu, trelease, trdv, tlow0, tlow1 and tslot are formed - into the value written into OWR_RST_PRESENCE_TCTL_0 register. */ - - /* Read data setup, Tsu = N owr clks, Range = tsu < 1, - Typical value = 0x1 */ - uint32_t tsu; - - /* Release 1-wire time, Trelease = N owr clks, - Range = 0 <= trelease < 45, Typical value = 0xf */ - uint32_t trelease; - - /* Read data valid time, Trdv = N+1 owr clks, Range = Exactly 15 */ - uint32_t trdv; - - /* Write zero time low, Tlow0 = N+1 owr clks, - Range = 60 <= tlow0 < tslot < 120, typical value = 0x3c. */ - uint32_t tlow0; - - /* Write one time low, or TLOWR both are same Tlow1 = N+1 owr clks, - Range = 1 <= tlow1 < 15 TlowR = N+1 owr clks, - Range = 1 <= tlowR < 15, Typical value = 0x1. */ - uint32_t tlow1; - - /* Active time slot for write or read data, Tslot = N+1 owr clks, - Range = 60 <= tslot < 120, Typical value = 0x77. */ - uint32_t tslot; - - /* tpdl, tpdh, trstl, trsth are formed in the the value written - into the OWR_RST_PRESENCE_TCTL_0 register. */ - - /* Tpdl = N owr clks, Range = 60 <= tpdl < 240, - Typical value = 0x78. */ - uint32_t tpdl; - - /* Tpdh = N+1 owr clks, Range = 15 <= tpdh < 60. - Typical value = 0x1e. */ - uint32_t tpdh; - - /* Trstl = N+1 owr clks, Range = 480 <= trstl < infinity, - Typical value = 0x1df. */ - uint32_t trstl; - - /* Trsth = N+1 owr clks, Range = 480 <= trsth < infinity, - Typical value = 0x1df. */ - uint32_t trsth; - - /* Read data sample clock. Should be <= to (tlow1 - 6) clks, - 6 clks are used for deglitch. If deglitch bypassed it - is 3 clks, Typical value = 0x7. */ - uint32_t rdsclk; - - /* Presence sample clock. Should be <= to (tpdl - 6) clks, - 6 clks are used for deglitch. If deglitch bypassed it is 3 clks, - Typical value = 0x50. */ - uint32_t psclk; -}; - -struct tegra_w1_platform_data { - const char *clk_id; - struct tegra_w1_timings *timings; -}; - -#endif diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c index a1674da7dd81..9fe2c5c683d4 100644 --- a/arch/arm/mach-tegra/io.c +++ b/arch/arm/mach-tegra/io.c @@ -49,30 +49,6 @@ static struct map_desc tegra_io_desc[] __initdata = { .length = IO_CPU_SIZE, .type = MT_DEVICE, }, - { - .virtual = IO_IRAM_VIRT, - .pfn = __phys_to_pfn(IO_IRAM_PHYS), - .length = IO_IRAM_SIZE, - .type = MT_DEVICE, - }, - { - .virtual = IO_HOST1X_VIRT, - .pfn = __phys_to_pfn(IO_HOST1X_PHYS), - .length = IO_HOST1X_SIZE, - .type = MT_DEVICE, - }, - { - .virtual = IO_USB_VIRT, - .pfn = __phys_to_pfn(IO_USB_PHYS), - .length = IO_USB_SIZE, - .type = MT_DEVICE, - }, - { - .virtual = IO_SDMMC_VIRT, - .pfn = __phys_to_pfn(IO_SDMMC_PHYS), - .length = IO_SDMMC_SIZE, - .type = MT_DEVICE, - }, }; void __init tegra_map_common_io(void) @@ -86,20 +62,8 @@ void __init tegra_map_common_io(void) void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type) { void __iomem *v = IO_ADDRESS(p); - - /* - * __arm_ioremap fails to set the domain of ioremapped memory - * correctly, only use it on physical memory. - */ - if (v == NULL && p < SZ_1G) + if (v == NULL) v = __arm_ioremap(p, size, type); - - /* - * If the physical address was not physical memory or statically - * mapped, there's nothing we can do to map it safely. - */ - BUG_ON(v == NULL); - return v; } EXPORT_SYMBOL(tegra_ioremap); diff --git a/arch/arm/mach-tegra/iovmm-gart.c b/arch/arm/mach-tegra/iovmm-gart.c deleted file mode 100644 index fbab0362c081..000000000000 --- a/arch/arm/mach-tegra/iovmm-gart.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * arch/arm/mach-tegra/iovmm-gart.c - * - * Tegra I/O VMM implementation for GART devices in Tegra and Tegra 2 series - * systems-on-a-chip. - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) -#define GART_CONFIG 0x24 -#define GART_ENTRY_ADDR 0x28 -#define GART_ENTRY_DATA 0x2c -#endif - -#define VMM_NAME "iovmm-gart" -#define DRIVER_NAME "tegra_gart" - -#define GART_PAGE_SHIFT (12) -#define GART_PAGE_MASK (~((1<enable) - return 0; - - spin_lock(&gart->pte_lock); - reg = gart->iovmm_base; - for (i=0; ipage_count; i++) { - writel(reg, gart->regs + GART_ENTRY_ADDR); - gart->savedata[i] = readl(gart->regs + GART_ENTRY_DATA); - dmb(); - reg += 1 << GART_PAGE_SHIFT; - } - spin_unlock(&gart->pte_lock); - return 0; -} - -static void do_gart_setup(struct gart_device *gart, const u32 *data) -{ - unsigned long reg; - unsigned int i; - - writel(1, gart->regs + GART_CONFIG); - - reg = gart->iovmm_base; - for (i=0; ipage_count; i++) { - writel(reg, gart->regs + GART_ENTRY_ADDR); - writel((data) ? data[i] : 0, gart->regs + GART_ENTRY_DATA); - wmb(); - reg += 1 << GART_PAGE_SHIFT; - } - wmb(); -} - -static void gart_resume(struct tegra_iovmm_device *dev) -{ - struct gart_device *gart = container_of(dev, struct gart_device, iovmm); - - if (!gart || !gart->enable || (gart->enable && !gart->savedata)) - return; - - spin_lock(&gart->pte_lock); - do_gart_setup(gart, gart->savedata); - spin_unlock(&gart->pte_lock); -} - -static int gart_remove(struct platform_device *pdev) -{ - struct gart_device *gart = platform_get_drvdata(pdev); - - if (!gart) - return 0; - - if (gart->enable) - writel(0, gart->regs + GART_CONFIG); - - gart->enable = 0; - platform_set_drvdata(pdev, NULL); - tegra_iovmm_unregister(&gart->iovmm); - if (gart->savedata) - vfree(gart->savedata); - if (gart->regs) - iounmap(gart->regs); - kfree(gart); - return 0; -} - -static int gart_probe(struct platform_device *pdev) -{ - struct gart_device *gart = NULL; - struct resource *res, *res_remap; - void __iomem *gart_regs = NULL; - int e; - - if (!pdev) { - pr_err(DRIVER_NAME ": platform_device required\n"); - return -ENODEV; - } - - if (PAGE_SHIFT != GART_PAGE_SHIFT) { - pr_err(DRIVER_NAME ": GART and CPU page size must match\n"); - return -ENXIO; - } - - /* the GART memory aperture is required */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1); - - if (!res || !res_remap) { - pr_err(DRIVER_NAME ": GART memory aperture expected\n"); - return -ENXIO; - } - gart = kzalloc(sizeof(*gart), GFP_KERNEL); - if (!gart) { - pr_err(DRIVER_NAME ": failed to allocate tegra_iovmm_device\n"); - e = -ENOMEM; - goto fail; - } - - gart_regs = ioremap_wc(res->start, res->end - res->start + 1); - if (!gart_regs) { - pr_err(DRIVER_NAME ": failed to remap GART registers\n"); - e = -ENXIO; - goto fail; - } - - gart->iovmm.name = VMM_NAME; - gart->iovmm.ops = &tegra_iovmm_gart_ops; - gart->iovmm.pgsize_bits = GART_PAGE_SHIFT; - spin_lock_init(&gart->pte_lock); - - platform_set_drvdata(pdev, gart); - - e = tegra_iovmm_register(&gart->iovmm); - if (e) goto fail; - - e = tegra_iovmm_domain_init(&gart->domain, &gart->iovmm, - (tegra_iovmm_addr_t)res_remap->start, - (tegra_iovmm_addr_t)res_remap->end+1); - if (e) goto fail; - - gart->regs = gart_regs; - gart->iovmm_base = (tegra_iovmm_addr_t)res_remap->start; - gart->page_count = res_remap->end - res_remap->start + 1; - gart->page_count >>= GART_PAGE_SHIFT; - - gart->savedata = vmalloc(sizeof(u32)*gart->page_count); - if (!gart->savedata) { - pr_err(DRIVER_NAME ": failed to allocate context save area\n"); - e = -ENOMEM; - goto fail; - } - - spin_lock(&gart->pte_lock); - - do_gart_setup(gart, NULL); - gart->enable = 1; - - spin_unlock(&gart->pte_lock); - return 0; - -fail: - if (gart_regs) - iounmap(gart_regs); - if (gart && gart->savedata) - vfree(gart->savedata); - if (gart) - kfree(gart); - return e; -} - -static int __devinit gart_init(void) -{ - return platform_driver_register(&tegra_iovmm_gart_drv); -} - -static void __exit gart_exit(void) -{ - return platform_driver_unregister(&tegra_iovmm_gart_drv); -} - -#define GART_PTE(_pfn) (0x80000000ul | ((_pfn)<iovm_start; - count = iovma->iovm_length >> GART_PAGE_SHIFT; - - for (i=0; iops->lock_makeresident(iovma, i<pte_lock); - - writel(gart_page, gart->regs + GART_ENTRY_ADDR); - writel(GART_PTE(pfn), gart->regs + GART_ENTRY_DATA); - wmb(); - gart_page += 1 << GART_PAGE_SHIFT; - - spin_unlock(&gart->pte_lock); - } - wmb(); - return 0; - -fail: - spin_lock(&gart->pte_lock); - while (i--) { - iovma->ops->release(iovma, i<regs + GART_ENTRY_ADDR); - writel(0, gart->regs + GART_ENTRY_DATA); - wmb(); - } - spin_unlock(&gart->pte_lock); - wmb(); - return -ENOMEM; -} - -static void gart_unmap(struct tegra_iovmm_device *dev, - struct tegra_iovmm_area *iovma, bool decommit) -{ - struct gart_device *gart = container_of(dev, struct gart_device, iovmm); - unsigned long gart_page, count; - unsigned int i; - - count = iovma->iovm_length >> GART_PAGE_SHIFT; - gart_page = iovma->iovm_start; - - spin_lock(&gart->pte_lock); - for (i=0; iops && iovma->ops->release) - iovma->ops->release(iovma, i<regs + GART_ENTRY_ADDR); - writel(0, gart->regs + GART_ENTRY_DATA); - wmb(); - gart_page += 1 << GART_PAGE_SHIFT; - } - spin_unlock(&gart->pte_lock); - wmb(); -} - -static void gart_map_pfn(struct tegra_iovmm_device *dev, - struct tegra_iovmm_area *iovma, tegra_iovmm_addr_t offs, - unsigned long pfn) -{ - struct gart_device *gart = container_of(dev, struct gart_device, iovmm); - - BUG_ON(!pfn_valid(pfn)); - spin_lock(&gart->pte_lock); - writel(offs, gart->regs + GART_ENTRY_ADDR); - writel(GART_PTE(pfn), gart->regs + GART_ENTRY_DATA); - wmb(); - spin_unlock(&gart->pte_lock); - wmb(); -} - -static struct tegra_iovmm_domain *gart_alloc_domain( - struct tegra_iovmm_device *dev, struct tegra_iovmm_client *client) -{ - struct gart_device *gart = container_of(dev, struct gart_device, iovmm); - return &gart->domain; -} - -subsys_initcall(gart_init); -module_exit(gart_exit); diff --git a/arch/arm/mach-tegra/iovmm.c b/arch/arm/mach-tegra/iovmm.c deleted file mode 100644 index 1f9e49902188..000000000000 --- a/arch/arm/mach-tegra/iovmm.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * arch/arm/mach-tegra/iovmm.c - * - * Tegra I/O VM manager - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include - -/* after the best-fit block is located, the remaining pages not needed for - * the allocation will be split into a new free block if the number of - * remaining pages is >= MIN_SPLIT_PAGE. - */ -#define MIN_SPLIT_PAGE (4) -#define MIN_SPLIT_BYTES(_d) (MIN_SPLIT_PAGE<<(_d)->dev->pgsize_bits) - -#define iovmm_start(_b) ((_b)->vm_area.iovm_start) -#define iovmm_length(_b) ((_b)->vm_area.iovm_length) -#define iovmm_end(_b) (iovmm_start(_b) + iovmm_length(_b)) - -/* flags for the block */ -#define BK_free 0 /* indicates free mappings */ -#define BK_map_dirty 1 /* used by demand-loaded mappings */ - -/* flags for the client */ -#define CL_locked 0 - -/* flags for the domain */ -#define DM_map_dirty 0 - -struct tegra_iovmm_block { - struct tegra_iovmm_area vm_area; - atomic_t ref; - unsigned long flags; - unsigned long poison; - struct rb_node free_node; - struct rb_node all_node; -}; - -struct iovmm_share_group { - const char *name; - struct tegra_iovmm_domain *domain; - struct list_head client_list; - struct list_head group_list; - spinlock_t lock; -}; - -static LIST_HEAD(iovmm_devices); -static LIST_HEAD(iovmm_groups); -static DEFINE_MUTEX(iovmm_list_lock); -static struct kmem_cache *iovmm_cache; - -static tegra_iovmm_addr_t iovmm_align_up(struct tegra_iovmm_device *dev, - tegra_iovmm_addr_t addr) -{ - addr += (1<pgsize_bits); - addr--; - addr &= ~((1<pgsize_bits)-1); - return addr; -} - -static tegra_iovmm_addr_t iovmm_align_down(struct tegra_iovmm_device *dev, - tegra_iovmm_addr_t addr) -{ - addr &= ~((1<pgsize_bits)-1); - return addr; -} - -#define iovmprint(fmt, arg...) snprintf(page+len, count-len, fmt, ## arg) - -static void tegra_iovmm_block_stats(struct tegra_iovmm_domain *domain, - unsigned int *num_blocks, unsigned int *num_free, - tegra_iovmm_addr_t *total, tegra_iovmm_addr_t *total_free, - tegra_iovmm_addr_t *max_free) -{ - struct rb_node *n; - struct tegra_iovmm_block *b; - - *num_blocks = 0; - *num_free = 0; - *total = (tegra_iovmm_addr_t)0; - *total_free = (tegra_iovmm_addr_t)0; - *max_free = (tegra_iovmm_addr_t)0; - - spin_lock(&domain->block_lock); - n = rb_first(&domain->all_blocks); - while (n) { - b = rb_entry(n, struct tegra_iovmm_block, all_node); - n = rb_next(n); - (*num_blocks)++; - (*total) += iovmm_length(b); - if (test_bit(BK_free, &b->flags)) { - (*num_free)++; - (*total_free) += iovmm_length(b); - (*max_free) = max_t(tegra_iovmm_addr_t, - (*max_free), iovmm_length(b)); - } - } - spin_unlock(&domain->block_lock); -} - -static int tegra_iovmm_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct iovmm_share_group *grp; - tegra_iovmm_addr_t max_free, total_free, total; - unsigned int num, num_free; - - int len = 0; - - mutex_lock(&iovmm_list_lock); - len += iovmprint("\ngroups\n"); - if (list_empty(&iovmm_groups)) - len += iovmprint("\t\n"); - else { - list_for_each_entry(grp, &iovmm_groups, group_list) { - len += iovmprint("\t%s (device: %s)\n", - (grp->name) ? grp->name : "", - grp->domain->dev->name); - tegra_iovmm_block_stats(grp->domain, &num, - &num_free, &total, &total_free, &max_free); - total >>= 10; - total_free >>= 10; - max_free >>= 10; - len += iovmprint("\t\tsize: %uKiB free: %uKiB " - "largest: %uKiB (%u free / %u total blocks)\n", - total, total_free, max_free, num_free, num); - } - } - mutex_unlock(&iovmm_list_lock); - - *eof = 1; - return len; -} - -static void iovmm_block_put(struct tegra_iovmm_block *b) -{ - BUG_ON(b->poison); - BUG_ON(atomic_read(&b->ref)==0); - if (!atomic_dec_return(&b->ref)) { - b->poison = 0xa5a5a5a5; - kmem_cache_free(iovmm_cache, b); - } -} - -static void iovmm_free_block(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_block *block) -{ - struct tegra_iovmm_block *pred = NULL; /* address-order predecessor */ - struct tegra_iovmm_block *succ = NULL; /* address-order successor */ - struct rb_node **p; - struct rb_node *parent = NULL, *temp; - int pred_free = 0, succ_free = 0; - - iovmm_block_put(block); - - spin_lock(&domain->block_lock); - temp = rb_prev(&block->all_node); - if (temp) - pred = rb_entry(temp, struct tegra_iovmm_block, all_node); - temp = rb_next(&block->all_node); - if (temp) - succ = rb_entry(temp, struct tegra_iovmm_block, all_node); - - if (pred) pred_free = test_bit(BK_free, &pred->flags); - if (succ) succ_free = test_bit(BK_free, &succ->flags); - - if (pred_free && succ_free) { - iovmm_length(pred) += iovmm_length(block); - iovmm_length(pred) += iovmm_length(succ); - rb_erase(&block->all_node, &domain->all_blocks); - rb_erase(&succ->all_node, &domain->all_blocks); - rb_erase(&succ->free_node, &domain->free_blocks); - rb_erase(&pred->free_node, &domain->free_blocks); - iovmm_block_put(block); - iovmm_block_put(succ); - block = pred; - } else if (pred_free) { - iovmm_length(pred) += iovmm_length(block); - rb_erase(&block->all_node, &domain->all_blocks); - rb_erase(&pred->free_node, &domain->free_blocks); - iovmm_block_put(block); - block = pred; - } else if (succ_free) { - iovmm_length(block) += iovmm_length(succ); - rb_erase(&succ->all_node, &domain->all_blocks); - rb_erase(&succ->free_node, &domain->free_blocks); - iovmm_block_put(succ); - } - - p = &domain->free_blocks.rb_node; - while (*p) { - struct tegra_iovmm_block *b; - parent = *p; - b = rb_entry(parent, struct tegra_iovmm_block, free_node); - if (iovmm_length(block) >= iovmm_length(b)) - p = &parent->rb_right; - else - p = &parent->rb_left; - } - rb_link_node(&block->free_node, parent, p); - rb_insert_color(&block->free_node, &domain->free_blocks); - set_bit(BK_free, &block->flags); - spin_unlock(&domain->block_lock); -} - -/* if the best-fit block is larger than the requested size, a remainder - * block will be created and inserted into the free list in its place. - * since all free blocks are stored in two trees the new block needs to be - * linked into both. */ -static void iovmm_split_free_block(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_block *block, unsigned long size) -{ - struct rb_node **p; - struct rb_node *parent = NULL; - struct tegra_iovmm_block *rem; - struct tegra_iovmm_block *b; - - rem = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL); - if (!rem) return; - - spin_lock(&domain->block_lock); - p = &domain->free_blocks.rb_node; - - iovmm_start(rem) = iovmm_start(block) + size; - iovmm_length(rem) = iovmm_length(block) - size; - atomic_set(&rem->ref, 1); - iovmm_length(block) = size; - - while (*p) { - parent = *p; - b = rb_entry(parent, struct tegra_iovmm_block, free_node); - if (iovmm_length(rem) >= iovmm_length(b)) - p = &parent->rb_right; - else - p = &parent->rb_left; - } - set_bit(BK_free, &rem->flags); - rb_link_node(&rem->free_node, parent, p); - rb_insert_color(&rem->free_node, &domain->free_blocks); - - p = &domain->all_blocks.rb_node; - parent = NULL; - while (*p) { - parent = *p; - b = rb_entry(parent, struct tegra_iovmm_block, all_node); - if (iovmm_start(rem) >= iovmm_start(b)) - p = &parent->rb_right; - else - p = &parent->rb_left; - } - rb_link_node(&rem->all_node, parent, p); - rb_insert_color(&rem->all_node, &domain->all_blocks); -} - -static struct tegra_iovmm_block *iovmm_alloc_block( - struct tegra_iovmm_domain *domain, unsigned long size) -{ - struct rb_node *n; - struct tegra_iovmm_block *b, *best; - static int splitting = 0; - - BUG_ON(!size); - size = iovmm_align_up(domain->dev, size); - for (;;) { - spin_lock(&domain->block_lock); - if (!splitting) - break; - spin_unlock(&domain->block_lock); - schedule(); - } - n = domain->free_blocks.rb_node; - best = NULL; - while (n) { - b = rb_entry(n, struct tegra_iovmm_block, free_node); - if (iovmm_length(b) < size) n = n->rb_right; - else if (iovmm_length(b) == size) { - best = b; - break; - } else { - best = b; - n = n->rb_left; - } - } - if (!best) { - spin_unlock(&domain->block_lock); - return NULL; - } - rb_erase(&best->free_node, &domain->free_blocks); - clear_bit(BK_free, &best->flags); - atomic_inc(&best->ref); - if (iovmm_length(best) >= size+MIN_SPLIT_BYTES(domain)) { - splitting = 1; - spin_unlock(&domain->block_lock); - iovmm_split_free_block(domain, best, size); - splitting = 0; - } - - spin_unlock(&domain->block_lock); - - return best; -} - -int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain, - struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start, - tegra_iovmm_addr_t end) -{ - struct tegra_iovmm_block *b; - - b = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL); - if (!b) return -ENOMEM; - - domain->dev = dev; - atomic_set(&domain->clients, 0); - atomic_set(&domain->locks, 0); - atomic_set(&b->ref, 1); - spin_lock_init(&domain->block_lock); - init_rwsem(&domain->map_lock); - init_waitqueue_head(&domain->delay_lock); - iovmm_start(b) = iovmm_align_up(dev, start); - iovmm_length(b) = iovmm_align_down(dev, end) - iovmm_start(b); - set_bit(BK_free, &b->flags); - rb_link_node(&b->free_node, NULL, &domain->free_blocks.rb_node); - rb_insert_color(&b->free_node, &domain->free_blocks); - rb_link_node(&b->all_node, NULL, &domain->all_blocks.rb_node); - rb_insert_color(&b->all_node, &domain->all_blocks); - return 0; -} - -struct tegra_iovmm_area *tegra_iovmm_create_vm( - struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops, - unsigned long size, pgprot_t pgprot) -{ - struct tegra_iovmm_block *b; - struct tegra_iovmm_device *dev; - - if (!client) return NULL; - - dev = client->domain->dev; - - b = iovmm_alloc_block(client->domain, size); - if (!b) return NULL; - - b->vm_area.domain = client->domain; - b->vm_area.pgprot = pgprot; - b->vm_area.ops = ops; - - down_read(&b->vm_area.domain->map_lock); - if (ops && !test_bit(CL_locked, &client->flags)) { - set_bit(BK_map_dirty, &b->flags); - set_bit(DM_map_dirty, &client->domain->flags); - } else if (ops) { - if (dev->ops->map(dev, &b->vm_area)) - pr_err("%s failed to map locked domain\n", __func__); - } - up_read(&b->vm_area.domain->map_lock); - - return &b->vm_area; -} - -void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area, - tegra_iovmm_addr_t vaddr, unsigned long pfn) -{ - struct tegra_iovmm_device *dev = area->domain->dev; - BUG_ON(vaddr & ((1<pgsize_bits)-1)); - BUG_ON(vaddr >= area->iovm_start + area->iovm_length); - BUG_ON(vaddr < area->iovm_start); - BUG_ON(area->ops); - - dev->ops->map_pfn(dev, area, vaddr, pfn); -} - -void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm) -{ - struct tegra_iovmm_block *b; - struct tegra_iovmm_device *dev; - - b = container_of(vm, struct tegra_iovmm_block, vm_area); - dev = vm->domain->dev; - /* if the vm area mapping was deferred, don't unmap it since - * the memory for the page tables it uses may not be allocated */ - down_read(&vm->domain->map_lock); - if (!test_and_clear_bit(BK_map_dirty, &b->flags)) - dev->ops->unmap(dev, vm, false); - up_read(&vm->domain->map_lock); -} - -void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm) -{ - struct tegra_iovmm_block *b; - struct tegra_iovmm_device *dev; - - b = container_of(vm, struct tegra_iovmm_block, vm_area); - dev = vm->domain->dev; - if (!vm->ops) return; - - down_read(&vm->domain->map_lock); - if (vm->ops) { - if (atomic_read(&vm->domain->locks)) - dev->ops->map(dev, vm); - else { - set_bit(BK_map_dirty, &b->flags); - set_bit(DM_map_dirty, &vm->domain->flags); - } - } - up_read(&vm->domain->map_lock); -} - -void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm) -{ - struct tegra_iovmm_block *b; - struct tegra_iovmm_device *dev; - struct tegra_iovmm_domain *domain; - - if (!vm) return; - - b = container_of(vm, struct tegra_iovmm_block, vm_area); - domain = vm->domain; - dev = vm->domain->dev; - down_read(&domain->map_lock); - if (!test_and_clear_bit(BK_map_dirty, &b->flags)) - dev->ops->unmap(dev, vm, true); - iovmm_free_block(domain, b); - up_read(&domain->map_lock); -} - -struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm) -{ - struct tegra_iovmm_block *b; - - BUG_ON(!vm); - b = container_of(vm, struct tegra_iovmm_block, vm_area); - - atomic_inc(&b->ref); - return &b->vm_area; -} - -void tegra_iovmm_area_put(struct tegra_iovmm_area *vm) -{ - struct tegra_iovmm_block *b; - BUG_ON(!vm); - b = container_of(vm, struct tegra_iovmm_block, vm_area); - iovmm_block_put(b); -} - -struct tegra_iovmm_area *tegra_iovmm_find_area_get( - struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr) -{ - struct rb_node *n; - struct tegra_iovmm_block *b = NULL; - - if (!client) return NULL; - - spin_lock(&client->domain->block_lock); - n = client->domain->all_blocks.rb_node; - - while (n) { - b = rb_entry(n, struct tegra_iovmm_block, all_node); - if ((iovmm_start(b) <= addr) && (iovmm_end(b) >= addr)) { - if (test_bit(BK_free, &b->flags)) b = NULL; - break; - } - if (addr > iovmm_start(b)) - n = n->rb_right; - else - n = n->rb_left; - b = NULL; - } - if (b) atomic_inc(&b->ref); - spin_unlock(&client->domain->block_lock); - if (!b) return NULL; - return &b->vm_area; -} - -static int _iovmm_client_lock(struct tegra_iovmm_client *client) -{ - struct tegra_iovmm_device *dev; - struct tegra_iovmm_domain *domain; - int v; - - if (unlikely(!client)) return -ENODEV; - if (unlikely(test_bit(CL_locked, &client->flags))) { - pr_err("attempting to relock client %s\n", client->name); - return 0; - } - - domain = client->domain; - dev = domain->dev; - down_write(&domain->map_lock); - v = atomic_inc_return(&domain->locks); - /* if the device doesn't export the lock_domain function, the device - * must guarantee that any valid domain will be locked. */ - if (v==1 && dev->ops->lock_domain) { - if (dev->ops->lock_domain(dev, domain)) { - atomic_dec(&domain->locks); - up_write(&domain->map_lock); - return -EAGAIN; - } - } - if (test_and_clear_bit(DM_map_dirty, &domain->flags)) { - struct rb_node *n; - struct tegra_iovmm_block *b; - - spin_lock(&domain->block_lock); - n = rb_first(&domain->all_blocks); - while (n) { - b = rb_entry(n, struct tegra_iovmm_block, all_node); - n = rb_next(n); - if (test_bit(BK_free, &b->flags)) - continue; - - if (test_and_clear_bit(BK_map_dirty, &b->flags)) { - if (!b->vm_area.ops) { - pr_err("%s: vm_area ops must exist for lazy maps\n", __func__); - continue; - } - dev->ops->map(dev, &b->vm_area); - } - } - } - set_bit(CL_locked, &client->flags); - up_write(&domain->map_lock); - return 0; -} - -int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client) -{ - return _iovmm_client_lock(client); -} - -int tegra_iovmm_client_lock(struct tegra_iovmm_client *client) -{ - int ret; - - if (!client) return -ENODEV; - - ret = wait_event_interruptible(client->domain->delay_lock, - _iovmm_client_lock(client)!=-EAGAIN); - - if (ret==-ERESTARTSYS) return -EINTR; - - return ret; -} - -void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client) -{ - struct tegra_iovmm_device *dev; - struct tegra_iovmm_domain *domain; - int do_wake = 0; - - if (!client) return; - - if (!test_and_clear_bit(CL_locked, &client->flags)) { - pr_err("unlocking unlocked client %s\n", client->name); - return; - } - - domain = client->domain; - dev = domain->dev; - down_write(&domain->map_lock); - if (!atomic_dec_return(&client->domain->locks)) { - if (dev->ops->unlock_domain) - dev->ops->unlock_domain(dev, domain); - do_wake = 1; - } - up_write(&domain->map_lock); - if (do_wake) wake_up(&domain->delay_lock); -} - -size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client) -{ - struct tegra_iovmm_domain *domain; - struct rb_node *n; - struct tegra_iovmm_block *b; - size_t size = 0; - - if (!client) return 0; - - domain = client->domain; - - spin_lock(&domain->block_lock); - n = rb_first(&domain->all_blocks); - while (n) { - b = rb_entry(n, struct tegra_iovmm_block, all_node); - n = rb_next(n); - size += iovmm_length(b); - } - spin_unlock(&domain->block_lock); - - return size; -} - -void tegra_iovmm_free_client(struct tegra_iovmm_client *client) -{ - struct tegra_iovmm_device *dev; - if (!client) return; - - BUG_ON(!client->domain || !client->domain->dev); - - dev = client->domain->dev; - - if (test_and_clear_bit(CL_locked, &client->flags)) { - pr_err("freeing locked client %s\n", client->name); - if (!atomic_dec_return(&client->domain->locks)) { - down_write(&client->domain->map_lock); - if (dev->ops->unlock_domain) - dev->ops->unlock_domain(dev, client->domain); - up_write(&client->domain->map_lock); - wake_up(&client->domain->delay_lock); - } - } - mutex_lock(&iovmm_list_lock); - if (!atomic_dec_return(&client->domain->clients)) - if (dev->ops->free_domain) - dev->ops->free_domain(dev, client->domain); - list_del(&client->list); - if (list_empty(&client->group->client_list)) { - list_del(&client->group->group_list); - if (client->group->name) kfree(client->group->name); - kfree(client->group); - } - kfree(client->name); - kfree(client); - mutex_unlock(&iovmm_list_lock); -} - -struct tegra_iovmm_client *tegra_iovmm_alloc_client(const char *name, - const char *share_group) -{ - struct tegra_iovmm_client *c = kzalloc(sizeof(*c), GFP_KERNEL); - struct iovmm_share_group *grp = NULL; - struct tegra_iovmm_device *dev; - - if (!c) return NULL; - c->name = kstrdup(name, GFP_KERNEL); - if (!c->name) goto fail; - - mutex_lock(&iovmm_list_lock); - if (share_group) { - list_for_each_entry(grp, &iovmm_groups, group_list) { - if (grp->name && !strcmp(grp->name, share_group)) - break; - } - } - if (!grp || strcmp(grp->name, share_group)) { - grp = kzalloc(sizeof(*grp), GFP_KERNEL); - if (!grp) goto fail_lock; - grp->name = (share_group) ? kstrdup(share_group, GFP_KERNEL) : NULL; - if (share_group && !grp->name) { - kfree(grp); - goto fail_lock; - } - list_for_each_entry(dev, &iovmm_devices, list) { - grp->domain = dev->ops->alloc_domain(dev, c); - if (grp->domain) break; - } - if (!grp->domain) { - pr_err("%s: alloc_domain failed for %s\n", - __func__, c->name); - dump_stack(); - if (grp->name) kfree(grp->name); - kfree(grp); - grp = NULL; - goto fail_lock; - } - spin_lock_init(&grp->lock); - INIT_LIST_HEAD(&grp->client_list); - list_add_tail(&grp->group_list, &iovmm_groups); - } - - atomic_inc(&grp->domain->clients); - c->group = grp; - c->domain = grp->domain; - spin_lock(&grp->lock); - list_add_tail(&c->list, &grp->client_list); - spin_unlock(&grp->lock); - mutex_unlock(&iovmm_list_lock); - return c; - -fail_lock: - mutex_unlock(&iovmm_list_lock); -fail: - if (c) { - if (c->name) kfree(c->name); - kfree(c); - } - return NULL; -} - -int tegra_iovmm_register(struct tegra_iovmm_device *dev) -{ - BUG_ON(!dev); - mutex_lock(&iovmm_list_lock); - if (list_empty(&iovmm_devices)) { - iovmm_cache = KMEM_CACHE(tegra_iovmm_block, 0); - if (!iovmm_cache) { - pr_err("%s: failed to make kmem cache\n", __func__); - mutex_unlock(&iovmm_list_lock); - return -ENOMEM; - } - create_proc_read_entry("iovmminfo", S_IRUGO, NULL, - tegra_iovmm_read_proc, NULL); - } - list_add_tail(&dev->list, &iovmm_devices); - mutex_unlock(&iovmm_list_lock); - printk("%s: added %s\n", __func__, dev->name); - return 0; -} - -int tegra_iovmm_suspend(void) -{ - int rc = 0; - struct tegra_iovmm_device *dev; - - mutex_lock(&iovmm_list_lock); - list_for_each_entry(dev, &iovmm_devices, list) { - - if (!dev->ops->suspend) - continue; - - rc = dev->ops->suspend(dev); - if (rc) { - pr_err("%s: %s suspend returned %d\n", - __func__, dev->name, rc); - mutex_unlock(&iovmm_list_lock); - return rc; - } - } - mutex_unlock(&iovmm_list_lock); - return 0; -} - -void tegra_iovmm_resume(void) -{ - struct tegra_iovmm_device *dev; - - mutex_lock(&iovmm_list_lock); - - list_for_each_entry(dev, &iovmm_devices, list) { - if (dev->ops->resume) - dev->ops->resume(dev); - } - - mutex_unlock(&iovmm_list_lock); -} - -int tegra_iovmm_unregister(struct tegra_iovmm_device *dev) -{ - mutex_lock(&iovmm_list_lock); - list_del(&dev->list); - mutex_unlock(&iovmm_list_lock); - return 0; -} diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 47b7064ae061..1fdbe708d43d 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -4,8 +4,6 @@ * Author: * Colin Cross * - * Copyright (C) 2010, NVIDIA Corporation - * * 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. @@ -18,310 +16,19 @@ */ #include -#include -#include #include #include #include #include -#include #include #include -#include -#include #include "board.h" -#define PMC_CTRL 0x0 -#define PMC_CTRL_LATCH_WAKEUPS (1 << 5) -#define PMC_WAKE_MASK 0xc -#define PMC_WAKE_LEVEL 0x10 -#define PMC_WAKE_STATUS 0x14 -#define PMC_SW_WAKE_STATUS 0x18 -#define PMC_DPD_SAMPLE 0x20 - -static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); - -static u32 tegra_lp0_wake_enb; -static u32 tegra_lp0_wake_level; -static u32 tegra_lp0_wake_level_any; - -static unsigned int tegra_wake_irq_count[32]; - -/* ensures that sufficient time is passed for a register write to - * serialize into the 32KHz domain */ -static void pmc_32kwritel(u32 val, unsigned long offs) -{ - writel(val, pmc + offs); - udelay(130); -} - -int tegra_set_lp0_wake(int irq, int enable) -{ - int wake = tegra_irq_to_wake(irq); - - if (wake < 0) - return -EINVAL; - - if (enable) - tegra_lp0_wake_enb |= 1 << wake; - else - tegra_lp0_wake_enb &= ~(1 << wake); - - return 0; -} - -int tegra_set_lp0_wake_type(int irq, int flow_type) -{ - int wake = tegra_irq_to_wake(irq); - - if (wake < 0) - return 0; - - switch (flow_type) { - case IRQF_TRIGGER_FALLING: - case IRQF_TRIGGER_LOW: - tegra_lp0_wake_level &= ~(1 << wake); - tegra_lp0_wake_level_any &= ~(1 << wake); - break; - case IRQF_TRIGGER_HIGH: - case IRQF_TRIGGER_RISING: - tegra_lp0_wake_level |= 1 << wake; - tegra_lp0_wake_level_any &= ~(1 << wake); - break; - - case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING: - tegra_lp0_wake_level_any |= 1 << wake; - break; - default: - return -EINVAL; - } - - return 0; -} - - -int tegra_set_lp1_wake(int irq, int enable) -{ - return tegra_legacy_irq_set_wake(irq, enable); -} - -void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any) -{ - u32 temp; - u32 status; - u32 lvl; - - wake_level &= wake_enb; - wake_any &= wake_enb; - - wake_level |= (tegra_lp0_wake_level & tegra_lp0_wake_enb); - wake_any |= (tegra_lp0_wake_level_any & tegra_lp0_wake_enb); - - wake_enb |= tegra_lp0_wake_enb; - - pmc_32kwritel(0, PMC_SW_WAKE_STATUS); - temp = readl(pmc + PMC_CTRL); - temp |= PMC_CTRL_LATCH_WAKEUPS; - pmc_32kwritel(temp, PMC_CTRL); - temp &= ~PMC_CTRL_LATCH_WAKEUPS; - pmc_32kwritel(temp, PMC_CTRL); - status = readl(pmc + PMC_SW_WAKE_STATUS); - lvl = readl(pmc + PMC_WAKE_LEVEL); - - /* flip the wakeup trigger for any-edge triggered pads - * which are currently asserting as wakeups */ - lvl ^= status; - lvl &= wake_any; - - wake_level |= lvl; - - writel(wake_level, pmc + PMC_WAKE_LEVEL); - /* Enable DPD sample to trigger sampling pads data and direction - * in which pad will be driven during lp0 mode*/ - writel(0x1, pmc + PMC_DPD_SAMPLE); - - writel(wake_enb, pmc + PMC_WAKE_MASK); -} - -#ifdef CONFIG_PM -static void tegra_irq_handle_wake(void) -{ - int wake; - int irq; - struct irq_desc *desc; - - unsigned long wake_status = readl(pmc + PMC_WAKE_STATUS); - for_each_set_bit(wake, &wake_status, sizeof(wake_status) * 8) { - irq = tegra_wake_to_irq(wake); - if (!irq) { - pr_info("Resume caused by WAKE%d\n", wake); - continue; - } - - desc = irq_to_desc(irq); - if (!desc || !desc->action || !desc->action->name) { - pr_info("Resume caused by WAKE%d, irq %d\n", wake, irq); - continue; - } - - pr_info("Resume caused by WAKE%d, %s\n", wake, - desc->action->name); - - tegra_wake_irq_count[wake]++; - - generic_handle_irq(irq); - } -} -#endif - -static void tegra_mask(unsigned int irq) -{ - gic_mask_irq(irq); - tegra_legacy_mask_irq(irq); -} - -static void tegra_unmask(unsigned int irq) -{ - gic_unmask_irq(irq); - tegra_legacy_unmask_irq(irq); -} - -static int tegra_set_wake(unsigned int irq, unsigned int enable) -{ - int ret; - ret = tegra_set_lp1_wake(irq, enable); - if (ret) - return ret; - - if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0) - return tegra_set_lp0_wake(irq, enable); - - return 0; -} - -static int tegra_set_type(unsigned int irq, unsigned int flow_type) -{ - if (tegra_get_suspend_mode() == TEGRA_SUSPEND_LP0) - return tegra_set_lp0_wake_type(irq, flow_type); - - return 0; -} - -static void tegra_ack(unsigned int irq) -{ - tegra_legacy_force_irq_clr(irq); - gic_ack_irq(irq); -} - -static int tegra_retrigger(unsigned int irq) -{ - tegra_legacy_force_irq_set(irq); - return 1; -} - -static struct irq_chip tegra_irq = { - .name = "PPI", - .ack = tegra_ack, - .mask = tegra_mask, - .unmask = tegra_unmask, - .set_wake = tegra_set_wake, - .set_type = tegra_set_type, -#ifdef CONFIG_SMP - .set_affinity = gic_set_cpu, -#endif - .retrigger = tegra_retrigger, -}; - void __init tegra_init_irq(void) { - unsigned int i; - int irq; - - tegra_init_legacy_irq(); - gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29); gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); - - for (i = 0; i < INT_MAIN_NR; i++) { - irq = INT_PRI_BASE + i; - set_irq_chip(irq, &tegra_irq); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } -} - -#ifdef CONFIG_PM -void tegra_irq_suspend(void) -{ - tegra_legacy_irq_suspend(); -} - -void tegra_irq_resume(void) -{ - tegra_legacy_irq_resume(); - tegra_irq_handle_wake(); } -#endif - -#ifdef CONFIG_DEBUG_FS -static int tegra_wake_irq_debug_show(struct seq_file *s, void *data) -{ - int wake; - int irq; - struct irq_desc *desc; - const char *irq_name; - - seq_printf(s, "wake irq count name\n"); - seq_printf(s, "----------------------\n"); - for (wake = 0; wake < 32; wake++) { - irq = tegra_wake_to_irq(wake); - if (irq < 0) - continue; - - desc = irq_to_desc(irq); - if (tegra_wake_irq_count[wake] == 0 && desc->action == NULL) - continue; - - if (!(desc->status & IRQ_WAKEUP)) - continue; - - irq_name = (desc->action && desc->action->name) ? - desc->action->name : "???"; - - seq_printf(s, "%4d %3d %5d %s\n", - wake, irq, tegra_wake_irq_count[wake], irq_name); - } - return 0; -} - -static int tegra_wake_irq_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_wake_irq_debug_show, NULL); -} - -static const struct file_operations tegra_wake_irq_debug_fops = { - .open = tegra_wake_irq_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init tegra_irq_debug_init(void) -{ - struct dentry *d; - - d = debugfs_create_file("wake_irq", 0755, NULL, NULL, - &tegra_wake_irq_debug_fops); - if (!d) { - pr_info("Failed to create suspend_mode debug file\n"); - return -ENOMEM; - } - - return 0; -} - -late_initcall(tegra_irq_debug_init); -#endif diff --git a/arch/arm/mach-tegra/kfuse.c b/arch/arm/mach-tegra/kfuse.c deleted file mode 100644 index f5de828bb508..000000000000 --- a/arch/arm/mach-tegra/kfuse.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * arch/arm/mach-tegra/kfuse.c - * - * Copyright (C) 2010-2011 NVIDIA Corporation. - * - * 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. - * - */ - -/* The kfuse block stores downstream and upstream HDCP keys for use by HDMI - * module. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "apbio.h" - -/* register definition */ -#define KFUSE_STATE 0x80 -#define KFUSE_STATE_DONE (1u << 16) -#define KFUSE_STATE_CRCPASS (1u << 17) -#define KFUSE_KEYADDR 0x88 -#define KFUSE_KEYADDR_AUTOINC (1u << 16) -#define KFUSE_KEYS 0x8c - -static inline u32 tegra_kfuse_readl(unsigned long offset) -{ - return tegra_apb_readl(TEGRA_KFUSE_BASE + offset); -} - -static inline void tegra_kfuse_writel(u32 value, unsigned long offset) -{ - tegra_apb_writel(value, TEGRA_KFUSE_BASE + offset); -} - -static int wait_for_done(void) -{ - u32 reg; - int retries = 50; - do { - reg = tegra_kfuse_readl(KFUSE_STATE); - if (reg & KFUSE_STATE_DONE); - return 0; - msleep(10); - } while(--retries); - return -ETIMEDOUT; -} - -/* read up to KFUSE_DATA_SZ bytes into dest. - * always starts at the first kfuse. - */ -int tegra_kfuse_read(void *dest, size_t len) -{ - u32 v; - unsigned cnt; - - if (len > KFUSE_DATA_SZ) - return -EINVAL; - - tegra_kfuse_writel(KFUSE_KEYADDR_AUTOINC, KFUSE_KEYADDR); - wait_for_done(); - - if ((tegra_kfuse_readl(KFUSE_STATE) & KFUSE_STATE_CRCPASS) == 0) { - pr_err("kfuse: crc failed\n"); - return -EIO; - } - - for (cnt = 0; cnt < len; cnt += 4) { - v = tegra_kfuse_readl(KFUSE_KEYS); - memcpy(dest + cnt, &v, sizeof v); - } - - return 0; -} diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c deleted file mode 100644 index 5a6197bacbb1..000000000000 --- a/arch/arm/mach-tegra/legacy_irq.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * arch/arm/mach-tegra/legacy_irq.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * 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 -#include -#include -#include -#include - -#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) -#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) -#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) - -#define ICTLR_CPU_IEP_VFIQ 0x08 -#define ICTLR_CPU_IEP_FIR 0x14 -#define ICTLR_CPU_IEP_FIR_SET 0x18 -#define ICTLR_CPU_IEP_FIR_CLR 0x1c - -#define ICTLR_CPU_IER 0x20 -#define ICTLR_CPU_IER_SET 0x24 -#define ICTLR_CPU_IER_CLR 0x28 -#define ICTLR_CPU_IEP_CLASS 0x2C - -#define ICTLR_COP_IER 0x30 -#define ICTLR_COP_IER_SET 0x34 -#define ICTLR_COP_IER_CLR 0x38 -#define ICTLR_COP_IEP_CLASS 0x3c - -#define NUM_ICTLRS 4 - -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), -}; - -static u32 tegra_legacy_wake_mask[4]; -static u32 tegra_legacy_saved_mask[4]; - -/* When going into deep sleep, the CPU is powered down, taking the GIC with it - In order to wake, the wake interrupts need to be enabled in the legacy - interrupt controller. */ -void tegra_legacy_unmask_irq(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET); -} - -void tegra_legacy_mask_irq(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR); -} - -void tegra_legacy_force_irq_set(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET); -} - -void tegra_legacy_force_irq_clr(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR); -} - -int tegra_legacy_force_irq_status(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31))); -} - -void tegra_legacy_select_fiq(unsigned int irq, bool fiq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS); -} - -unsigned long tegra_legacy_vfiq(int nr) -{ - void __iomem *base; - base = ictlr_reg_base[nr]; - return readl(base + ICTLR_CPU_IEP_VFIQ); -} - -unsigned long tegra_legacy_class(int nr) -{ - void __iomem *base; - base = ictlr_reg_base[nr]; - return readl(base + ICTLR_CPU_IEP_CLASS); -} - -int tegra_legacy_irq_set_wake(int irq, int enable) -{ - irq -= 32; - if (enable) - tegra_legacy_wake_mask[irq >> 5] |= 1 << (irq & 31); - else - tegra_legacy_wake_mask[irq >> 5] &= ~(1 << (irq & 31)); - - return 0; -} - -void tegra_legacy_irq_set_lp1_wake_mask(void) -{ - void __iomem *base; - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - base = ictlr_reg_base[i]; - tegra_legacy_saved_mask[i] = readl(base + ICTLR_CPU_IER); - writel(tegra_legacy_wake_mask[i], base + ICTLR_CPU_IER); - } -} - -void tegra_legacy_irq_restore_mask(void) -{ - void __iomem *base; - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - base = ictlr_reg_base[i]; - writel(tegra_legacy_saved_mask[i], base + ICTLR_CPU_IER); - } -} - -void tegra_init_legacy_irq(void) -{ - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel(~0, ictlr + ICTLR_CPU_IER_CLR); - writel(0, ictlr + ICTLR_CPU_IEP_CLASS); - } -} - -#ifdef CONFIG_PM -static u32 cop_ier[NUM_ICTLRS]; -static u32 cpu_ier[NUM_ICTLRS]; -static u32 cpu_iep[NUM_ICTLRS]; - -void tegra_legacy_irq_suspend(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER); - cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS); - cop_ier[i] = readl(ictlr + ICTLR_COP_IER); - writel(~0, ictlr + ICTLR_COP_IER_CLR); - } - local_irq_restore(flags); -} - -void tegra_legacy_irq_resume(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); - writel(~0ul, ictlr + ICTLR_CPU_IER_CLR); - writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); - writel(0, ictlr + ICTLR_COP_IEP_CLASS); - writel(~0ul, ictlr + ICTLR_COP_IER_CLR); - writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET); - } - local_irq_restore(flags); -} -#endif diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c index 6ba38f136199..f81ca7cbbc1f 100644 --- a/arch/arm/mach-tegra/localtimer.c +++ b/arch/arm/mach-tegra/localtimer.c @@ -21,5 +21,5 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt) { evt->irq = IRQ_LOCALTIMER; - twd_timer_setup_scalable(evt, 2500000, 4); + twd_timer_setup(evt); } diff --git a/arch/arm/mach-tegra/mc.c b/arch/arm/mach-tegra/mc.c deleted file mode 100644 index 513ac3f5cf4d..000000000000 --- a/arch/arm/mach-tegra/mc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * arch/arm/mach-tegra/mc.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * 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 -#include - -#include -#include - -static DEFINE_SPINLOCK(tegra_mc_lock); - -void tegra_mc_set_priority(unsigned long client, unsigned long prio) -{ - unsigned long mc_base = IO_TO_VIRT(TEGRA_MC_BASE); - unsigned long reg = client >> 8; - int field = client & 0xff; - unsigned long val; - unsigned long flags; - - spin_lock_irqsave(&tegra_mc_lock, flags); - val = readl(mc_base + reg); - val &= ~(TEGRA_MC_PRIO_MASK << field); - val |= prio << field; - writel(val, mc_base + reg); - spin_unlock_irqrestore(&tegra_mc_lock, flags); -} diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c deleted file mode 100644 index a475367befa3..000000000000 --- a/arch/arm/mach-tegra/pinmux-t2-tables.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * linux/arch/arm/mach-tegra/pinmux-t2-tables.c - * - * Common pinmux configurations for Tegra 2 SoCs - * - * Copyright (C) 2010 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define DRIVE_PINGROUP(pg_name, r) \ - [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \ - .name = #pg_name, \ - .reg = r \ - } - -const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = { - DRIVE_PINGROUP(AO1, 0x868), - DRIVE_PINGROUP(AO2, 0x86c), - DRIVE_PINGROUP(AT1, 0x870), - DRIVE_PINGROUP(AT2, 0x874), - DRIVE_PINGROUP(CDEV1, 0x878), - DRIVE_PINGROUP(CDEV2, 0x87c), - DRIVE_PINGROUP(CSUS, 0x880), - DRIVE_PINGROUP(DAP1, 0x884), - DRIVE_PINGROUP(DAP2, 0x888), - DRIVE_PINGROUP(DAP3, 0x88c), - DRIVE_PINGROUP(DAP4, 0x890), - DRIVE_PINGROUP(DBG, 0x894), - DRIVE_PINGROUP(LCD1, 0x898), - DRIVE_PINGROUP(LCD2, 0x89c), - DRIVE_PINGROUP(SDMMC2, 0x8a0), - DRIVE_PINGROUP(SDMMC3, 0x8a4), - DRIVE_PINGROUP(SPI, 0x8a8), - DRIVE_PINGROUP(UAA, 0x8ac), - DRIVE_PINGROUP(UAB, 0x8b0), - DRIVE_PINGROUP(UART2, 0x8b4), - DRIVE_PINGROUP(UART3, 0x8b8), - DRIVE_PINGROUP(VI1, 0x8bc), - DRIVE_PINGROUP(VI2, 0x8c0), - DRIVE_PINGROUP(XM2A, 0x8c4), - DRIVE_PINGROUP(XM2C, 0x8c8), - DRIVE_PINGROUP(XM2D, 0x8cc), - DRIVE_PINGROUP(XM2CLK, 0x8d0), - DRIVE_PINGROUP(MEMCOMP, 0x8d4), - DRIVE_PINGROUP(SDIO1, 0x8e0), - DRIVE_PINGROUP(CRT, 0x8ec), - DRIVE_PINGROUP(DDC, 0x8f0), - DRIVE_PINGROUP(GMA, 0x8f4), - DRIVE_PINGROUP(GMB, 0x8f8), - DRIVE_PINGROUP(GMC, 0x8fc), - DRIVE_PINGROUP(GMD, 0x900), - DRIVE_PINGROUP(GME, 0x904), - DRIVE_PINGROUP(OWR, 0x908), - DRIVE_PINGROUP(UAD, 0x90c), -}; - -#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe, \ - tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \ - [TEGRA_PINGROUP_ ## pg_name] = { \ - .name = #pg_name, \ - .vddio = TEGRA_VDDIO_ ## vdd, \ - .funcs = { \ - TEGRA_MUX_ ## f0, \ - TEGRA_MUX_ ## f1, \ - TEGRA_MUX_ ## f2, \ - TEGRA_MUX_ ## f3, \ - }, \ - .func_safe = TEGRA_MUX_ ## f_safe, \ - .tri_reg = tri_r, \ - .tri_bit = tri_b, \ - .mux_reg = mux_r, \ - .mux_bit = mux_b, \ - .pupd_reg = pupd_r, \ - .pupd_bit = pupd_b, \ - } - -const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = { - PINGROUP(ATA, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0), - PINGROUP(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2), - PINGROUP(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4), - PINGROUP(ATD, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xA0, 6), - PINGROUP(ATE, NAND, IDE, NAND, GMI, RSVD, IDE, 0x18, 25, 0x80, 12, 0xA0, 8), - PINGROUP(CDEV1, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xA8, 0), - PINGROUP(CDEV2, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xA8, 2), - PINGROUP(CRTP, LCD, CRT, RSVD, RSVD, RSVD, RSVD, 0x20, 14, 0x98, 20, 0xA4, 24), - PINGROUP(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xAC, 24), - PINGROUP(DAP1, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xA0, 10), - PINGROUP(DAP2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2, 0x14, 8, 0x88, 22, 0xA0, 12), - PINGROUP(DAP3, BB, DAP3, RSVD, RSVD, RSVD, DAP3, 0x14, 9, 0x88, 24, 0xA0, 14), - PINGROUP(DAP4, UART, DAP4, RSVD, GMI, RSVD, DAP4, 0x14, 10, 0x88, 26, 0xA0, 16), - PINGROUP(DDC, LCD, I2C2, RSVD, RSVD, RSVD, RSVD4, 0x18, 31, 0x88, 0, 0xB0, 28), - PINGROUP(DTA, VI, RSVD, SDIO2, VI, RSVD, RSVD4, 0x14, 11, 0x84, 20, 0xA0, 18), - PINGROUP(DTB, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xA0, 20), - PINGROUP(DTC, VI, RSVD, RSVD, VI, RSVD, RSVD1, 0x14, 13, 0x84, 26, 0xA0, 22), - PINGROUP(DTD, VI, RSVD, SDIO2, VI, RSVD, RSVD1, 0x14, 14, 0x84, 28, 0xA0, 24), - PINGROUP(DTE, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xA0, 26), - PINGROUP(DTF, VI, I2C3, RSVD, VI, RSVD, RSVD4, 0x20, 12, 0x98, 30, 0xA0, 28), - PINGROUP(GMA, NAND, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xB0, 20), - PINGROUP(GMB, NAND, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xB0, 22), - PINGROUP(GMC, NAND, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xB0, 24), - PINGROUP(GMD, NAND, RSVD, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xB0, 26), - PINGROUP(GME, NAND, RSVD, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8C, 0, 0xA8, 24), - PINGROUP(GPU, UART, PWM, UARTA, GMI, RSVD, RSVD4, 0x14, 16, 0x8C, 4, 0xA4, 20), - PINGROUP(GPU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK, 0x20, 11, 0x98, 28, 0xA4, 6), - PINGROUP(GPV, SD, PCIE, RSVD, RSVD, RSVD, PCIE, 0x14, 17, 0x8C, 2, 0xA0, 30), - PINGROUP(HDINT, LCD, HDMI, RSVD, RSVD, RSVD, HDMI, 0x1C, 23, 0x84, 4, 0xAC, 22), - PINGROUP(I2CP, SYS, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 18, 0x88, 8, 0xA4, 2), - PINGROUP(IRRX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xA8, 22), - PINGROUP(IRTX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xA8, 20), - PINGROUP(KBCA, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xA4, 8), - PINGROUP(KBCB, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xA4, 10), - PINGROUP(KBCC, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xA4, 12), - PINGROUP(KBCD, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xA4, 14), - PINGROUP(KBCE, SYS, KBC, NAND, OWR, RSVD, KBC, 0x14, 26, 0x80, 28, 0xB0, 2), - PINGROUP(KBCF, SYS, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xB0, 0), - PINGROUP(LCSN, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 31, 0x90, 12, 0xAC, 20), - PINGROUP(LD0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 0, 0x94, 0, 0xAC, 12), - PINGROUP(LD1, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 1, 0x94, 2, 0xAC, 12), - PINGROUP(LD10, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 10, 0x94, 20, 0xAC, 12), - PINGROUP(LD11, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 11, 0x94, 22, 0xAC, 12), - PINGROUP(LD12, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 12, 0x94, 24, 0xAC, 12), - PINGROUP(LD13, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 13, 0x94, 26, 0xAC, 12), - PINGROUP(LD14, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 14, 0x94, 28, 0xAC, 12), - PINGROUP(LD15, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 15, 0x94, 30, 0xAC, 12), - PINGROUP(LD16, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 16, 0x98, 0, 0xAC, 12), - PINGROUP(LD17, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 17, 0x98, 2, 0xAC, 12), - PINGROUP(LD2, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 2, 0x94, 4, 0xAC, 12), - PINGROUP(LD3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 3, 0x94, 6, 0xAC, 12), - PINGROUP(LD4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 4, 0x94, 8, 0xAC, 12), - PINGROUP(LD5, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 5, 0x94, 10, 0xAC, 12), - PINGROUP(LD6, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 6, 0x94, 12, 0xAC, 12), - PINGROUP(LD7, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 7, 0x94, 14, 0xAC, 12), - PINGROUP(LD8, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 8, 0x94, 16, 0xAC, 12), - PINGROUP(LD9, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 9, 0x94, 18, 0xAC, 12), - PINGROUP(LDC, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 30, 0x90, 14, 0xAC, 20), - PINGROUP(LDI, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 6, 0x98, 16, 0xAC, 18), - PINGROUP(LHP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 18, 0x98, 10, 0xAC, 16), - PINGROUP(LHP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 19, 0x98, 4, 0xAC, 14), - PINGROUP(LHP2, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 20, 0x98, 6, 0xAC, 14), - PINGROUP(LHS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x20, 7, 0x90, 22, 0xAC, 22), - PINGROUP(LM0, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 24, 0x90, 26, 0xAC, 22), - PINGROUP(LM1, LCD, DISPLAYA, DISPLAYB, RSVD, CRT, RSVD3, 0x1C, 25, 0x90, 28, 0xAC, 22), - PINGROUP(LPP, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 8, 0x98, 14, 0xAC, 18), - PINGROUP(LPW0, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, 0xAC, 20), - PINGROUP(LPW1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 4, 0x90, 2, 0xAC, 20), - PINGROUP(LPW2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, 0xAC, 20), - PINGROUP(LSC0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 27, 0x90, 18, 0xAC, 22), - PINGROUP(LSC1, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 28, 0x90, 20, 0xAC, 20), - PINGROUP(LSCK, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 29, 0x90, 16, 0xAC, 20), - PINGROUP(LSDA, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, 0xAC, 20), - PINGROUP(LSDI, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, DISPLAYA, 0x20, 2, 0x90, 6, 0xAC, 20), - PINGROUP(LSPI, LCD, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, 0xAC, 22), - PINGROUP(LVP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 21, 0x90, 30, 0xAC, 22), - PINGROUP(LVP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 22, 0x98, 8, 0xAC, 16), - PINGROUP(LVS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 26, 0x90, 24, 0xAC, 22), - PINGROUP(OWC, SYS, OWR, RSVD, RSVD, RSVD, OWR, 0x14, 31, 0x84, 8, 0xB0, 30), - PINGROUP(PMC, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, 0x14, 23, 0x98, 18, -1, -1), - PINGROUP(PTA, NAND, I2C2, HDMI, GMI, RSVD, RSVD4, 0x14, 24, 0x98, 22, 0xA4, 4), - PINGROUP(RM, UART, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 25, 0x80, 14, 0xA4, 0), - PINGROUP(SDB, SD, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8C, 10, -1, -1), - PINGROUP(SDC, SD, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8C, 12, 0xAC, 28), - PINGROUP(SDD, SD, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8C, 14, 0xAC, 30), - PINGROUP(SDIO1, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xB0, 18), - PINGROUP(SLXA, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xA4, 22), - PINGROUP(SLXC, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xA4, 26), - PINGROUP(SLXD, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xA4, 28), - PINGROUP(SLXK, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xA4, 30), - PINGROUP(SPDI, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 8, 0x8C, 8, 0xA4, 16), - PINGROUP(SPDO, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 9, 0x8C, 6, 0xA4, 18), - PINGROUP(SPIA, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8C, 30, 0xA8, 4), - PINGROUP(SPIB, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8C, 28, 0xA8, 6), - PINGROUP(SPIC, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8C, 26, 0xA8, 8), - PINGROUP(SPID, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8C, 24, 0xA8, 10), - PINGROUP(SPIE, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8C, 22, 0xA8, 12), - PINGROUP(SPIF, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4, 0x18, 15, 0x8C, 20, 0xA8, 14), - PINGROUP(SPIG, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 16, 0x8C, 18, 0xA8, 16), - PINGROUP(SPIH, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 17, 0x8C, 16, 0xA8, 18), - PINGROUP(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xAC, 0), - PINGROUP(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xAC, 2), - PINGROUP(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4, 0x18, 20, 0x80, 4, 0xAC, 4), - PINGROUP(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xAC, 6), - PINGROUP(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4, 0x18, 22, 0x84, 16, 0xAC, 8), - PINGROUP(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4, 0x18, 23, 0x84, 18, 0xAC, 10), - PINGROUP(UDA, BB, SPI1, RSVD, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xB0, 16), - /* these pin groups only have pullup and pull down control */ - PINGROUP(CK32, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 14), - PINGROUP(DDRC, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xAC, 26), - PINGROUP(PMCA, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 4), - PINGROUP(PMCB, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 6), - PINGROUP(PMCC, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 8), - PINGROUP(PMCD, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 10), - PINGROUP(PMCE, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 12), - PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30), - PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28), -}; - -#ifdef CONFIG_PM -#define TRISTATE_REG_A 0x14 -#define TRISTATE_REG_NUM 4 -#define PIN_MUX_CTL_REG_A 0x80 -#define PIN_MUX_CTL_REG_NUM 8 -#define PULLUPDOWN_REG_A 0xa0 -#define PULLUPDOWN_REG_NUM 5 - -static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM + - PULLUPDOWN_REG_NUM + - ARRAY_SIZE(tegra_soc_drive_pingroups)]; - -static inline unsigned long pg_readl(unsigned long offset) -{ - return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); -} - -static inline void pg_writel(unsigned long value, unsigned long offset) -{ - writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); -} - -void tegra_pinmux_suspend(void) -{ - unsigned int i; - u32 *ctx = pinmux_reg; - - for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++) - *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4); - - for (i = 0; i < PULLUPDOWN_REG_NUM; i++) - *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4); - - for (i = 0; i < TRISTATE_REG_NUM; i++) - *ctx++ = pg_readl(TRISTATE_REG_A + i*4); - - for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++) - *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg); -} - -void tegra_pinmux_resume(void) -{ - unsigned int i; - u32 *ctx = pinmux_reg; - - for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++) - pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4); - - for (i = 0; i < PULLUPDOWN_REG_NUM; i++) - pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4); - - for (i = 0; i < TRISTATE_REG_NUM; i++) - pg_writel(*ctx++, TRISTATE_REG_A + i*4); - - for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++) - pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg); -} -#endif diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c index 3316c49db3cc..13ae10237e84 100644 --- a/arch/arm/mach-tegra/pinmux.c +++ b/arch/arm/mach-tegra/pinmux.c @@ -14,8 +14,7 @@ * */ -#include -#include + #include #include #include @@ -24,6 +23,21 @@ #include #include + +#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x))) +#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x))) +#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x))) + +#define REG_A 0 +#define REG_B 1 +#define REG_C 2 +#define REG_D 3 +#define REG_E 4 +#define REG_F 5 +#define REG_G 6 + +#define REG_N -1 + #define HSM_EN(reg) (((reg) >> 2) & 0x1) #define SCHMT_EN(reg) (((reg) >> 3) & 0x1) #define LPMD(reg) (((reg) >> 4) & 0x3) @@ -32,8 +46,154 @@ #define SLWR(reg) (((reg) >> 28) & 0x3) #define SLWF(reg) (((reg) >> 30) & 0x3) -static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups; -static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups; +struct tegra_pingroup_desc { + const char *name; + int funcs[4]; + s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */ + s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */ + s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */ + s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */ + s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */ + s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */ +}; + +#define PINGROUP(pg_name, f0, f1, f2, f3, \ + tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \ + [TEGRA_PINGROUP_ ## pg_name] = { \ + .name = #pg_name, \ + .funcs = { \ + TEGRA_MUX_ ## f0, \ + TEGRA_MUX_ ## f1, \ + TEGRA_MUX_ ## f2, \ + TEGRA_MUX_ ## f3, \ + }, \ + .tri_reg = REG_ ## tri_r, \ + .tri_bit = tri_b, \ + .mux_reg = REG_ ## mux_r, \ + .mux_bit = mux_b, \ + .pupd_reg = REG_ ## pupd_r, \ + .pupd_bit = pupd_b, \ + } + +static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = { + PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0), + PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2), + PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4), + PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6), + PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8), + PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0), + PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2), + PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24), + PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24), + PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10), + PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12), + PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14), + PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16), + PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28), + PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18), + PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20), + PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22), + PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24), + PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26), + PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28), + PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20), + PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22), + PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24), + PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26), + PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24), + PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20), + PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6), + PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30), + PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22), + PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2), + PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22), + PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20), + PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8), + PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10), + PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12), + PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14), + PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2), + PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0), + PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20), + PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12), + PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12), + PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12), + PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12), + PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12), + PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12), + PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12), + PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12), + PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12), + PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12), + PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12), + PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12), + PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12), + PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12), + PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12), + PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12), + PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12), + PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12), + PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20), + PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18), + PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16), + PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14), + PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14), + PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22), + PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22), + PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22), + PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18), + PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20), + PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20), + PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20), + PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22), + PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20), + PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20), + PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20), + PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20), + PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22), + PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22), + PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16), + PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22), + PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30), + PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1), + PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4), + PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0), + PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1), + PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28), + PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30), + PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18), + PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22), + PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26), + PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28), + PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30), + PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16), + PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18), + PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4), + PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6), + PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8), + PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10), + PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12), + PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14), + PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16), + PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18), + PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0), + PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2), + PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4), + PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6), + PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8), + PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10), + PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16), + /* these pin groups only have pullup and pull down control */ + PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14), + PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26), + PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4), + PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6), + PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8), + PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10), + PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12), + PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30), + PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28), +}; static char *tegra_mux_names[TEGRA_MAX_MUX] = { [TEGRA_MUX_AHB_CLK] = "AHB_CLK", @@ -96,7 +256,48 @@ static char *tegra_mux_names[TEGRA_MAX_MUX] = { [TEGRA_MUX_VI] = "VI", [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK", [TEGRA_MUX_XIO] = "XIO", - [TEGRA_MUX_SAFE] = "", +}; + +struct tegra_drive_pingroup_desc { + const char *name; + s16 reg; +}; + +#define DRIVE_PINGROUP(pg_name, r) \ + [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \ + .name = #pg_name, \ + .reg = r \ + } + +static const struct tegra_drive_pingroup_desc drive_pingroups[TEGRA_MAX_PINGROUP] = { + DRIVE_PINGROUP(AO1, 0x868), + DRIVE_PINGROUP(AO2, 0x86c), + DRIVE_PINGROUP(AT1, 0x870), + DRIVE_PINGROUP(AT2, 0x874), + DRIVE_PINGROUP(CDEV1, 0x878), + DRIVE_PINGROUP(CDEV2, 0x87c), + DRIVE_PINGROUP(CSUS, 0x880), + DRIVE_PINGROUP(DAP1, 0x884), + DRIVE_PINGROUP(DAP2, 0x888), + DRIVE_PINGROUP(DAP3, 0x88c), + DRIVE_PINGROUP(DAP4, 0x890), + DRIVE_PINGROUP(DBG, 0x894), + DRIVE_PINGROUP(LCD1, 0x898), + DRIVE_PINGROUP(LCD2, 0x89c), + DRIVE_PINGROUP(SDMMC2, 0x8a0), + DRIVE_PINGROUP(SDMMC3, 0x8a4), + DRIVE_PINGROUP(SPI, 0x8a8), + DRIVE_PINGROUP(UAA, 0x8ac), + DRIVE_PINGROUP(UAB, 0x8b0), + DRIVE_PINGROUP(UART2, 0x8b4), + DRIVE_PINGROUP(UART3, 0x8b8), + DRIVE_PINGROUP(VI1, 0x8bc), + DRIVE_PINGROUP(VI2, 0x8c0), + DRIVE_PINGROUP(XM2A, 0x8c4), + DRIVE_PINGROUP(XM2C, 0x8c8), + DRIVE_PINGROUP(XM2D, 0x8cc), + DRIVE_PINGROUP(XM2CLK, 0x8d0), + DRIVE_PINGROUP(MEMCOMP, 0x8d4), }; static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = { @@ -180,27 +381,22 @@ static inline void pg_writel(unsigned long value, unsigned long offset) writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); } -static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) +int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func) { int mux = -1; int i; unsigned long reg; unsigned long flags; - enum tegra_pingroup pg = config->pingroup; - enum tegra_mux_func func = config->func; if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) return -ERANGE; - if (pingroups[pg].mux_reg < 0) + if (pingroups[pg].mux_reg == REG_N) return -EINVAL; if (func < 0) return -ERANGE; - if (func == TEGRA_MUX_SAFE) - func = pingroups[pg].func_safe; - if (func & TEGRA_MUX_RSVD) { mux = func & 0x3; } else { @@ -217,10 +413,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) spin_lock_irqsave(&mux_lock, flags); - reg = pg_readl(pingroups[pg].mux_reg); + reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg)); reg &= ~(0x3 << pingroups[pg].mux_bit); reg |= mux << pingroups[pg].mux_bit; - pg_writel(reg, pingroups[pg].mux_reg); + pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg)); spin_unlock_irqrestore(&mux_lock, flags); @@ -236,16 +432,16 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg, if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) return -ERANGE; - if (pingroups[pg].tri_reg < 0) + if (pingroups[pg].tri_reg == REG_N) return -EINVAL; spin_lock_irqsave(&mux_lock, flags); - reg = pg_readl(pingroups[pg].tri_reg); + reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg)); reg &= ~(0x1 << pingroups[pg].tri_bit); if (tristate) reg |= 1 << pingroups[pg].tri_bit; - pg_writel(reg, pingroups[pg].tri_reg); + pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg)); spin_unlock_irqrestore(&mux_lock, flags); @@ -261,7 +457,7 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) return -ERANGE; - if (pingroups[pg].pupd_reg < 0) + if (pingroups[pg].pupd_reg == REG_N) return -EINVAL; if (pupd != TEGRA_PUPD_NORMAL && @@ -272,39 +468,38 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, spin_lock_irqsave(&mux_lock, flags); - reg = pg_readl(pingroups[pg].pupd_reg); + reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg)); reg &= ~(0x3 << pingroups[pg].pupd_bit); reg |= pupd << pingroups[pg].pupd_bit; - pg_writel(reg, pingroups[pg].pupd_reg); + pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg)); spin_unlock_irqrestore(&mux_lock, flags); return 0; } -static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config) +void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup, + enum tegra_mux_func func, + enum tegra_pullupdown pupd, + enum tegra_tristate tristate) { - enum tegra_pingroup pingroup = config->pingroup; - enum tegra_mux_func func = config->func; - enum tegra_pullupdown pupd = config->pupd; - enum tegra_tristate tristate = config->tristate; int err; - if (pingroups[pingroup].mux_reg >= 0) { - err = tegra_pinmux_set_func(config); + if (pingroups[pingroup].mux_reg != REG_N) { + err = tegra_pinmux_set_func(pingroup, func); if (err < 0) pr_err("pinmux: can't set pingroup %s func to %s: %d\n", pingroup_name(pingroup), func_name(func), err); } - if (pingroups[pingroup].pupd_reg >= 0) { + if (pingroups[pingroup].pupd_reg != REG_N) { err = tegra_pinmux_set_pullupdown(pingroup, pupd); if (err < 0) pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n", pingroup_name(pingroup), pupd_name(pupd), err); } - if (pingroups[pingroup].tri_reg >= 0) { + if (pingroups[pingroup].tri_reg != REG_N) { err = tegra_pinmux_set_tristate(pingroup, tristate); if (err < 0) pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n", @@ -312,12 +507,17 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con } } -void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len) + + +void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len) { int i; for (i = 0; i < len; i++) - tegra_pinmux_config_pingroup(&config[i]); + tegra_pinmux_config_pingroup(config[i].pingroup, + config[i].func, + config[i].pupd, + config[i].tristate); } static const char *drive_pinmux_name(enum tegra_drive_pingroup pg) @@ -459,22 +659,8 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg, spin_lock_irqsave(&mux_lock, flags); reg = pg_readl(drive_pingroups[pg].reg); - - /* - * 12 is the wrong offset for pull_up drive strength. This is - * a hack for stingray to only use the correct offset for the - * DDC lines to avoid changing drive strengths across the board - * before cutting a release kernel. This should be updated to - * use the correct offset on the release is cut. - */ - - if (pg == TEGRA_DRIVE_PINGROUP_DDC) { - reg &= ~(0x1f << 20); - reg |= pull_up << 20; - } else { - reg &= ~(0x1f << 12); - reg |= pull_up << 12; - } + reg &= ~(0x1f << 12); + reg |= pull_up << 12; pg_writel(reg, drive_pingroups[pg].reg); spin_unlock_irqrestore(&mux_lock, flags); @@ -598,86 +784,6 @@ void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config, config[i].slew_falling); } -void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config, - int len) -{ - int i; - struct tegra_pingroup_config c; - - for (i = 0; i < len; i++) { - int err; - c = config[i]; - if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) { - WARN_ON(1); - continue; - } - c.func = pingroups[c.pingroup].func_safe; - err = tegra_pinmux_set_func(&c); - if (err < 0) - pr_err("%s: tegra_pinmux_set_func returned %d setting " - "%s to %s\n", __func__, err, - pingroup_name(c.pingroup), func_name(c.func)); - } -} - -void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config, - int len) -{ - int i; - - for (i = 0; i < len; i++) { - int err; - if (config[i].pingroup < 0 || - config[i].pingroup >= TEGRA_MAX_PINGROUP) { - WARN_ON(1); - continue; - } - err = tegra_pinmux_set_func(&config[i]); - if (err < 0) - pr_err("%s: tegra_pinmux_set_func returned %d setting " - "%s to %s\n", __func__, err, - pingroup_name(config[i].pingroup), - func_name(config[i].func)); - } -} - -void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config, - int len, enum tegra_tristate tristate) -{ - int i; - int err; - enum tegra_pingroup pingroup; - - for (i = 0; i < len; i++) { - pingroup = config[i].pingroup; - if (pingroups[pingroup].tri_reg >= 0) { - err = tegra_pinmux_set_tristate(pingroup, tristate); - if (err < 0) - pr_err("pinmux: can't set pingroup %s tristate" - " to %s: %d\n", pingroup_name(pingroup), - tri_name(tristate), err); - } - } -} - -void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config, - int len, enum tegra_pullupdown pupd) -{ - int i; - int err; - enum tegra_pingroup pingroup; - - for (i = 0; i < len; i++) { - pingroup = config[i].pingroup; - if (pingroups[pingroup].pupd_reg >= 0) { - err = tegra_pinmux_set_pullupdown(pingroup, pupd); - if (err < 0) - pr_err("pinmux: can't set pingroup %s pullupdown" - " to %s: %d\n", pingroup_name(pingroup), - pupd_name(pupd), err); - } - } -} #ifdef CONFIG_DEBUG_FS @@ -706,11 +812,11 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) len = strlen(pingroups[i].name); dbg_pad_field(s, 5 - len); - if (pingroups[i].mux_reg < 0) { + if (pingroups[i].mux_reg == REG_N) { seq_printf(s, "TEGRA_MUX_NONE"); len = strlen("NONE"); } else { - mux = (pg_readl(pingroups[i].mux_reg) >> + mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >> pingroups[i].mux_bit) & 0x3; if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); @@ -723,21 +829,21 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused) } dbg_pad_field(s, 13-len); - if (pingroups[i].pupd_reg < 0) { + if (pingroups[i].mux_reg == REG_N) { seq_printf(s, "TEGRA_PUPD_NORMAL"); len = strlen("NORMAL"); } else { - pupd = (pg_readl(pingroups[i].pupd_reg) >> + pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >> pingroups[i].pupd_bit) & 0x3; seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); len = strlen(pupd_name(pupd)); } dbg_pad_field(s, 9 - len); - if (pingroups[i].tri_reg < 0) { + if (pingroups[i].tri_reg == REG_N) { seq_printf(s, "TEGRA_TRI_NORMAL"); } else { - tri = (pg_readl(pingroups[i].tri_reg) >> + tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >> pingroups[i].tri_bit) & 0x1; seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 659c66967fb5..1c0fd92cab39 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -7,8 +7,6 @@ * Copyright (C) 2009 Palm * All Rights Reserved * - * Copyright (C) 2010 NVIDIA 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. @@ -20,59 +18,42 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include -#include #include -#include -#include #include -#include "power.h" - extern void tegra_secondary_startup(void); static DEFINE_SPINLOCK(boot_lock); static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); -#ifdef CONFIG_HOTPLUG_CPU -static DEFINE_PER_CPU(struct completion, cpu_killed); -extern void tegra_hotplug_startup(void); -#endif - -static DECLARE_BITMAP(cpu_init_bits, CONFIG_NR_CPUS) __read_mostly; -const struct cpumask *const cpu_init_mask = to_cpumask(cpu_init_bits); -#define cpu_init_map (*(cpumask_t *)cpu_init_mask) - #define EVP_CPU_RESET_VECTOR \ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) -#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340) #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) void __cpuinit platform_secondary_init(unsigned int cpu) { trace_hardirqs_off(); + + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100); + /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); -#ifdef CONFIG_HOTPLUG_CPU - cpu_set(cpu, cpu_init_map); - INIT_COMPLETION(per_cpu(cpu_killed, cpu)); -#endif spin_unlock(&boot_lock); } @@ -89,30 +70,27 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ spin_lock(&boot_lock); - /* set the reset vector to point to the secondary_startup routine */ -#ifdef CONFIG_HOTPLUG_CPU - if (cpumask_test_cpu(cpu, cpu_init_mask)) - boot_vector = virt_to_phys(tegra_hotplug_startup); - else -#endif - boot_vector = virt_to_phys(tegra_secondary_startup); - smp_wmb(); + /* set the reset vector to point to the secondary_startup routine */ + boot_vector = virt_to_phys(tegra_secondary_startup); old_boot_vector = readl(EVP_CPU_RESET_VECTOR); writel(boot_vector, EVP_CPU_RESET_VECTOR); - /* enable cpu clock on cpu */ + /* enable cpu clock on cpu1 */ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - writel(reg & ~(1<<(8+cpu)), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - reg = 0x1111<= rn */ -.macro wait_until, rn, base, tmp -1002: ldr \tmp, [\base] - sub \tmp, \tmp, \rn - ands \tmp, \tmp, #0x80000000 - dmb - bne 1002b -.endm - -/* Enable Coresight access on cpu */ -.macro enable_coresite, tmp - mov32 \tmp, 0xC5ACCE55 - mcr p14, 0, \tmp, c7, c12, 6 -.endm diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h deleted file mode 100644 index 37992415b9c6..000000000000 --- a/arch/arm/mach-tegra/power.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * arch/arm/mach-tegra/power.h - * - * Declarations for power state transition code - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MACH_TEGRA_POWER_H -#define __MACH_TEGRA_POWER_H - -#include - -#define TEGRA_POWER_SDRAM_SELFREFRESH 0x400 /* SDRAM is in self-refresh */ - -#define TEGRA_POWER_PWRREQ_POLARITY 0x1 /* core power request polarity */ -#define TEGRA_POWER_PWRREQ_OE 0x2 /* core power request enable */ -#define TEGRA_POWER_SYSCLK_POLARITY 0x4 /* sys clk polarity */ -#define TEGRA_POWER_SYSCLK_OE 0x8 /* system clock enable */ -#define TEGRA_POWER_PWRGATE_DIS 0x10 /* power gate disabled */ -#define TEGRA_POWER_EFFECT_LP0 0x40 /* enter LP0 when CPU pwr gated */ -#define TEGRA_POWER_CPU_PWRREQ_POLARITY 0x80 /* CPU power request polarity */ -#define TEGRA_POWER_CPU_PWRREQ_OE 0x100 /* CPU power request enable */ -#define TEGRA_POWER_PMC_SHIFT 8 -#define TEGRA_POWER_PMC_MASK 0x1ff - -/* CPU Context area (1KB per CPU) */ -#define CONTEXT_SIZE_BYTES_SHIFT 10 -#define CONTEXT_SIZE_BYTES (1< - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define PWRGATE_TOGGLE 0x30 -#define PWRGATE_TOGGLE_START (1 << 8) - -#define REMOVE_CLAMPING 0x34 - -#define PWRGATE_STATUS 0x38 - -static DEFINE_SPINLOCK(tegra_powergate_lock); - -static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); - -static u32 pmc_read(unsigned long reg) -{ - return readl(pmc + reg); -} - -static void pmc_write(u32 val, unsigned long reg) -{ - writel(val, pmc + reg); -} - -static int tegra_powergate_set(int id, bool new_state) -{ - bool status; - unsigned long flags; - - spin_lock_irqsave(&tegra_powergate_lock, flags); - - status = pmc_read(PWRGATE_STATUS) & (1 << id); - - if (status == new_state) { - spin_unlock_irqrestore(&tegra_powergate_lock, flags); - return -EINVAL; - } - - pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); - - spin_unlock_irqrestore(&tegra_powergate_lock, flags); - - return 0; -} - -int tegra_powergate_power_on(int id) -{ - if (id < 0 || id >= TEGRA_NUM_POWERGATE) - return -EINVAL; - - return tegra_powergate_set(id, true); -} - -int tegra_powergate_power_off(int id) -{ - if (id < 0 || id >= TEGRA_NUM_POWERGATE) - return -EINVAL; - - return tegra_powergate_set(id, false); -} - -bool tegra_powergate_is_powered(int id) -{ - u32 status; - - if (id < 0 || id >= TEGRA_NUM_POWERGATE) - return -EINVAL; - - status = pmc_read(PWRGATE_STATUS) & (1 << id); - return !!status; -} - -int tegra_powergate_remove_clamping(int id) -{ - u32 mask; - - if (id < 0 || id >= TEGRA_NUM_POWERGATE) - return -EINVAL; - - /* - * Tegra 2 has a bug where PCIE and VDE clamping masks are - * swapped relatively to the partition ids - */ - if (id == TEGRA_POWERGATE_VDEC) - mask = (1 << TEGRA_POWERGATE_PCIE); - else if (id == TEGRA_POWERGATE_PCIE) - mask = (1 << TEGRA_POWERGATE_VDEC); - else - mask = (1 << id); - - pmc_write(mask, REMOVE_CLAMPING); - - return 0; -} - -/* Must be called with clk disabled, and returns with clk enabled */ -static int tegra_powergate_reset_module(struct clk *clk) -{ - int ret; - - tegra_periph_reset_assert(clk); - - udelay(10); - - ret = clk_enable(clk); - if (ret) - return ret; - - udelay(10); - - tegra_periph_reset_deassert(clk); - - return 0; -} - -/* Must be called with clk disabled, and returns with clk enabled */ -int tegra_powergate_sequence_power_up(int id, struct clk *clk) -{ - int ret; - - if (tegra_powergate_is_powered(id)) - return tegra_powergate_reset_module(clk); - - tegra_periph_reset_assert(clk); - - ret = tegra_powergate_power_on(id); - if (ret) - goto err_power; - - ret = clk_enable(clk); - if (ret) - goto err_clk; - - udelay(10); - - ret = tegra_powergate_remove_clamping(id); - if (ret) - goto err_clamp; - - udelay(10); - tegra_periph_reset_deassert(clk); - - return 0; - -err_clamp: - clk_disable(clk); -err_clk: - tegra_powergate_power_off(id); -err_power: - return ret; -} - -#ifdef CONFIG_DEBUG_FS - -static const char *powergate_name[] = { - [TEGRA_POWERGATE_CPU] = "cpu", - [TEGRA_POWERGATE_3D] = "3d", - [TEGRA_POWERGATE_VENC] = "venc", - [TEGRA_POWERGATE_VDEC] = "vdec", - [TEGRA_POWERGATE_PCIE] = "pcie", - [TEGRA_POWERGATE_L2] = "l2", - [TEGRA_POWERGATE_MPE] = "mpe", -}; - -static int powergate_show(struct seq_file *s, void *data) -{ - int i; - - seq_printf(s, " powergate powered\n"); - seq_printf(s, "------------------\n"); - - for (i = 0; i < TEGRA_NUM_POWERGATE; i++) - seq_printf(s, " %9s %7s\n", powergate_name[i], - tegra_powergate_is_powered(i) ? "yes" : "no"); - return 0; -} - -static int powergate_open(struct inode *inode, struct file *file) -{ - return single_open(file, powergate_show, inode->i_private); -} - -static const struct file_operations powergate_fops = { - .open = powergate_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init powergate_debugfs_init(void) -{ - struct dentry *d; - - d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL, - &powergate_fops); - if (!d) - return -ENOMEM; - - return 0; -} - -late_initcall(powergate_debugfs_init); - -#endif diff --git a/arch/arm/mach-tegra/pwm.c b/arch/arm/mach-tegra/pwm.c deleted file mode 100644 index 1328310a404c..000000000000 --- a/arch/arm/mach-tegra/pwm.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * arch/arm/mach-tegra/pwm.c - * - * Tegra pulse-width-modulation controller driver - * - * Copyright (c) 2010, NVIDIA Corporation. - * Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 -#include -#include -#include -#include -#include -#include -#include - -#define PWM_ENABLE (1 << 31) -#define PWM_DUTY_WIDTH 8 -#define PWM_DUTY_SHIFT 16 -#define PWM_SCALE_WIDTH 13 -#define PWM_SCALE_SHIFT 0 - -struct pwm_device { - struct list_head node; - struct platform_device *pdev; - - const char *label; - struct clk *clk; - - int clk_enb; - void __iomem *mmio_base; - - unsigned int in_use; - unsigned int id; -}; - -static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_list); - -static inline int pwm_writel(struct pwm_device *pwm, unsigned long val) -{ - int rc; - - rc = clk_enable(pwm->clk); - if (WARN_ON(rc)) - return rc; - writel(val, pwm->mmio_base); - clk_disable(pwm->clk); - return 0; -} - -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - unsigned long long c; - unsigned long rate, hz; - u32 val = 0; - - /* convert from duty_ns / period_ns to a fixed number of duty - * ticks per (1 << PWM_DUTY_WIDTH) cycles. */ - c = duty_ns * ((1 << PWM_DUTY_WIDTH) - 1); - do_div(c, period_ns); - - val = (u32)c << PWM_DUTY_SHIFT; - - /* compute the prescaler value for which (1 << PWM_DUTY_WIDTH) - * cycles at the PWM clock rate will take period_ns nanoseconds. */ - rate = clk_get_rate(pwm->clk) >> PWM_DUTY_WIDTH; - hz = 1000000000ul / period_ns; - - rate = (rate + (hz / 2)) / hz; - - if (rate >> PWM_SCALE_WIDTH) - return -EINVAL; - - val |= (rate << PWM_SCALE_SHIFT); - - /* the struct clk may be shared across multiple PWM devices, so - * only enable the PWM if this device has been enabled */ - if (pwm->clk_enb) - val |= PWM_ENABLE; - - return pwm_writel(pwm, val); -} -EXPORT_SYMBOL(pwm_config); - -int pwm_enable(struct pwm_device *pwm) -{ - int rc = 0; - - mutex_lock(&pwm_lock); - if (!pwm->clk_enb) { - rc = clk_enable(pwm->clk); - if (!rc) { - u32 val = readl(pwm->mmio_base); - writel(val | PWM_ENABLE, pwm->mmio_base); - pwm->clk_enb = 1; - } - } - mutex_unlock(&pwm_lock); - - return rc; -} -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - if (pwm->clk_enb) { - u32 val = readl(pwm->mmio_base); - writel(val & ~PWM_ENABLE, pwm->mmio_base); - clk_disable(pwm->clk); - pwm->clk_enb = 0; - } else - dev_warn(&pwm->pdev->dev, "%s called on disabled PWM\n", - __func__); - mutex_unlock(&pwm_lock); -} -EXPORT_SYMBOL(pwm_disable); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - struct pwm_device *pwm; - int found = 0; - - mutex_lock(&pwm_lock); - - list_for_each_entry(pwm, &pwm_list, node) { - if (pwm->id == pwm_id) { - found = 1; - break; - } - } - - if (found) { - if (!pwm->in_use) { - pwm->in_use = 1; - pwm->label = label; - } else - pwm = ERR_PTR(-EBUSY); - } else - pwm = ERR_PTR(-ENOENT); - - mutex_unlock(&pwm_lock); - - return pwm; -} -EXPORT_SYMBOL(pwm_request); - -void pwm_free(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - if (pwm->in_use) { - pwm->in_use = 0; - pwm->label = NULL; - } else - dev_warn(&pwm->pdev->dev, "PWM device already freed\n"); - - mutex_unlock(&pwm_lock); -} -EXPORT_SYMBOL(pwm_free); - -static int tegra_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm; - struct resource *r; - int ret; - - pwm = kzalloc(sizeof(*pwm), GFP_KERNEL); - if (!pwm) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - pwm->clk = clk_get(&pdev->dev, NULL); - - if (IS_ERR(pwm->clk)) { - ret = PTR_ERR(pwm->clk); - goto err_free; - } - - pwm->clk_enb = 0; - pwm->in_use = 0; - pwm->id = pdev->id; - pwm->pdev = pdev; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - dev_err(&pdev->dev, "no memory resources defined\n"); - ret = -ENODEV; - goto err_put_clk; - } - - r = request_mem_region(r->start, resource_size(r), pdev->name); - if (!r) { - dev_err(&pdev->dev, "failed to request memory\n"); - ret = -EBUSY; - goto err_put_clk; - } - - pwm->mmio_base = ioremap(r->start, resource_size(r)); - if (!pwm->mmio_base) { - dev_err(&pdev->dev, "failed to ioremap() region\n"); - ret = -ENODEV; - goto err_free_mem; - } - - platform_set_drvdata(pdev, pwm); - - mutex_lock(&pwm_lock); - list_add_tail(&pwm->node, &pwm_list); - mutex_unlock(&pwm_lock); - - return 0; - -err_free_mem: - release_mem_region(r->start, resource_size(r)); -err_put_clk: - clk_put(pwm->clk); -err_free: - kfree(pwm); - return ret; -} - -static int __devexit tegra_pwm_remove(struct platform_device *pdev) -{ - struct pwm_device *pwm = platform_get_drvdata(pdev); - struct resource *r; - int rc; - - if (WARN_ON(!pwm)) - return -ENODEV; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - mutex_lock(&pwm_lock); - if (pwm->in_use) { - mutex_unlock(&pwm_lock); - return -EBUSY; - } - list_del(&pwm->node); - mutex_unlock(&pwm_lock); - - rc = pwm_writel(pwm, 0); - - iounmap(pwm->mmio_base); - release_mem_region(r->start, resource_size(r)); - - if (pwm->clk_enb) - clk_disable(pwm->clk); - - clk_put(pwm->clk); - - kfree(pwm); - return rc; -} - -static struct platform_driver tegra_pwm_driver = { - .driver = { - .name = "tegra_pwm", - }, - .probe = tegra_pwm_probe, - .remove = __devexit_p(tegra_pwm_remove), -}; - -static int __init tegra_pwm_init(void) -{ - return platform_driver_register(&tegra_pwm_driver); -} -subsys_initcall(tegra_pwm_init); - -static void __exit tegra_pwm_exit(void) -{ - platform_driver_unregister(&tegra_pwm_driver); -} -module_exit(tegra_pwm_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("NVIDIA Corporation"); diff --git a/arch/arm/mach-tegra/suspend-t2.c b/arch/arm/mach-tegra/suspend-t2.c deleted file mode 100644 index a6f7ae65fb1f..000000000000 --- a/arch/arm/mach-tegra/suspend-t2.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * arch/arm/mach-tegra/suspend-t2.c - * - * BootROM LP0 scratch register preservation for Tegra 2 - * - * Copyright (c) 2009-2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include - -#include -#include -#include -#include - -#include "gpio-names.h" - -#define PMC_SCRATCH3 0x5c -#define PMC_SCRATCH5 0x64 -#define PMC_SCRATCH6 0x68 -#define PMC_SCRATCH7 0x6c -#define PMC_SCRATCH8 0x70 -#define PMC_SCRATCH9 0x74 -#define PMC_SCRATCH10 0x78 -#define PMC_SCRATCH11 0x7c -#define PMC_SCRATCH12 0x80 -#define PMC_SCRATCH13 0x84 -#define PMC_SCRATCH14 0x88 -#define PMC_SCRATCH15 0x8c -#define PMC_SCRATCH16 0x90 -#define PMC_SCRATCH17 0x94 -#define PMC_SCRATCH18 0x98 -#define PMC_SCRATCH19 0x9c -#define PMC_SCRATCH20 0xa0 -#define PMC_SCRATCH21 0xa4 -#define PMC_SCRATCH22 0xa8 -#define PMC_SCRATCH23 0xac -#define PMC_SCRATCH25 0x100 -#define PMC_SCRATCH35 0x128 -#define PMC_SCRATCH36 0x12c -#define PMC_SCRATCH40 0x13c - -struct pmc_scratch_field { - void __iomem *addr; - unsigned int mask; - int shift_src; - int shift_dst; -}; - -#define field(module, offs, field, dst) \ - { \ - .addr = IO_ADDRESS(TEGRA_##module##_BASE) + offs, \ - .mask = 0xfffffffful >> (31 - ((1?field) - (0?field))), \ - .shift_src = 0?field, \ - .shift_dst = 0?dst, \ - } - -static const struct pmc_scratch_field pllx[] __initdata = { - field(CLK_RESET, 0xe0, 22:20, 17:15), /* PLLX_DIVP */ - field(CLK_RESET, 0xe0, 17:8, 14:5), /* PLLX_DIVN */ - field(CLK_RESET, 0xe0, 4:0, 4:0), /* PLLX_DIVM */ - field(CLK_RESET, 0xe4, 11:8, 25:22), /* PLLX_CPCON */ - field(CLK_RESET, 0xe4, 7:4, 21:18), /* PLLX_LFCON */ - field(APB_MISC, 0x8e4, 27:24, 30:27), /* XM2CFGC_VREF_DQ */ - field(APB_MISC, 0x8c8, 3:3, 26:26), /* XM2CFGC_SCHMT_EN */ - field(APB_MISC, 0x8d0, 2:2, 31:31), /* XM2CLKCFG_PREEMP_EN */ -}; - -static const struct pmc_scratch_field emc_0[] __initdata = { - field(EMC, 0x3c, 4:0, 31:27), /* R2W */ - field(EMC, 0x34, 5:0, 20:15), /* RAS */ - field(EMC, 0x2c, 5:0, 5:0), /* RC */ - field(EMC, 0x30, 8:0, 14:6), /* RFC */ - field(EMC, 0x38, 5:0, 26:21), /* RP */ -}; - -static const struct pmc_scratch_field emc_1[] __initdata = { - field(EMC, 0x44, 4:0, 9:5), /* R2P */ - field(EMC, 0x4c, 5:0, 20:15), /* RD_RCD */ - field(EMC, 0x54, 3:0, 30:27), /* RRD */ - field(EMC, 0x48, 4:0, 14:10), /* W2P */ - field(EMC, 0x40, 4:0, 4:0), /* W2R */ - field(EMC, 0x50, 5:0, 26:21), /* WR_RCD */ -}; - -static const struct pmc_scratch_field emc_2[] __initdata = { - field(EMC, 0x2b8, 2:2, 31:31), /* CLKCHANGE_SR_ENABLE */ - field(EMC, 0x2b8, 10:10, 30:30), /* USE_ADDR_CLK */ - field(EMC, 0x80, 4:0, 29:25), /* PCHG2PDEN */ - field(EMC, 0x64, 3:0, 15:12), /* QRST */ - field(EMC, 0x68, 3:0, 19:16), /* QSAFE */ - field(EMC, 0x60, 3:0, 11:8), /* QUSE */ - field(EMC, 0x6c, 4:0, 24:20), /* RDV */ - field(EMC, 0x58, 3:0, 3:0), /* REXT */ - field(EMC, 0x5c, 3:0, 7:4), /* WDV */ -}; - -static const struct pmc_scratch_field emc_3[] __initdata = { - field(EMC, 0x74, 3:0, 19:16), /* BURST_REFRESH_NUM */ - field(EMC, 0x7c, 3:0, 27:24), /* PDEX2RD */ - field(EMC, 0x78, 3:0, 23:20), /* PDEX2WR */ - field(EMC, 0x70, 4:0, 4:0), /* REFRESH_LO */ - field(EMC, 0x70, 15:5, 15:5), /* REFRESH */ - field(EMC, 0xa0, 3:0, 31:28), /* TCLKSTABLE */ -}; - -static const struct pmc_scratch_field emc_4[] __initdata = { - field(EMC, 0x84, 4:0, 4:0), /* ACT2PDEN */ - field(EMC, 0x88, 4:0, 9:5), /* AR2PDEN */ - field(EMC, 0x8c, 5:0, 15:10), /* RW2PDEN */ - field(EMC, 0x94, 3:0, 31:28), /* TCKE */ - field(EMC, 0x90, 11:0, 27:16), /* TXSR */ -}; - -static const struct pmc_scratch_field emc_5[] __initdata = { - field(EMC, 0x8, 10:10, 30:30), /* AP_REQ_BUSY_CTRL */ - field(EMC, 0x8, 24:24, 31:31), /* CFG_PRIORITY */ - field(EMC, 0x8, 2:2, 26:26), /* FORCE_UPDATE */ - field(EMC, 0x8, 4:4, 27:27), /* MRS_WAIT */ - field(EMC, 0x8, 5:5, 28:28), /* PERIODIC_QRST */ - field(EMC, 0x8, 9:9, 29:29), /* READ_DQM_CTRL */ - field(EMC, 0x8, 0:0, 24:24), /* READ_MUX */ - field(EMC, 0x8, 1:1, 25:25), /* WRITE_MUX */ - field(EMC, 0xa4, 3:0, 9:6), /* TCLKSTOP */ - field(EMC, 0xa8, 13:0, 23:10), /* TREFBW */ - field(EMC, 0x9c, 5:0, 5:0), /* TRPAB */ -}; - -static const struct pmc_scratch_field emc_6[] __initdata = { - field(EMC, 0xfc, 1:0, 1:0), /* DQSIB_DLY_MSB_BYTE_0 */ - field(EMC, 0xfc, 9:8, 3:2), /* DQSIB_DLY_MSB_BYTE_1 */ - field(EMC, 0xfc, 17:16, 5:4), /* DQSIB_DLY_MSB_BYTE_2 */ - field(EMC, 0xfc, 25:24, 7:6), /* DQSIB_DLY_MSB_BYTE_3 */ - field(EMC, 0x110, 1:0, 9:8), /* QUSE_DLY_MSB_BYTE_0 */ - field(EMC, 0x110, 9:8, 11:10), /* QUSE_DLY_MSB_BYTE_1 */ - field(EMC, 0x110, 17:16, 13:12), /* QUSE_DLY_MSB_BYTE_2 */ - field(EMC, 0x110, 25:24, 15:14), /* QUSE_DLY_MSB_BYTE_3 */ - field(EMC, 0xac, 3:0, 25:22), /* QUSE_EXTRA */ - field(EMC, 0x98, 5:0, 21:16), /* TFAW */ - field(APB_MISC, 0x8e4, 5:5, 30:30), /* XM2CFGC_VREF_DQ_EN */ - field(APB_MISC, 0x8e4, 19:16, 29:26), /* XM2CFGC_VREF_DQS */ -}; - -static const struct pmc_scratch_field emc_dqsib_dly[] __initdata = { - field(EMC, 0xf8, 31:0, 31:0), /* DQSIB_DLY_BYTE_0 - DQSIB_DLY_BYTE_3*/ -}; - -static const struct pmc_scratch_field emc_quse_dly[] __initdata = { - field(EMC, 0x10c, 31:0, 31:0), /* QUSE_DLY_BYTE_0 - QUSE_DLY_BYTE_3*/ -}; - -static const struct pmc_scratch_field emc_clktrim[] __initdata = { - field(EMC, 0x2d0, 29:0, 29:0), /* DATA0_CLKTRIM - DATA3_CLKTRIM + - * MCLK_ADDR_CLKTRIM */ -}; - -static const struct pmc_scratch_field emc_autocal_fbio[] __initdata = { - field(EMC, 0x2a4, 29:29, 29:29), /* AUTO_CAL_ENABLE */ - field(EMC, 0x2a4, 30:30, 30:30), /* AUTO_CAL_OVERRIDE */ - field(EMC, 0x2a4, 12:8, 18:14), /* AUTO_CAL_PD_OFFSET */ - field(EMC, 0x2a4, 4:0, 13:9), /* AUTO_CAL_PU_OFFSET */ - field(EMC, 0x2a4, 25:16, 28:19), /* AUTO_CAL_STEP */ - field(EMC, 0xf4, 16:16, 0:0), /* CFG_DEN_EARLY */ - field(EMC, 0x104, 8:8, 8:8), /* CTT_TERMINATION */ - field(EMC, 0x104, 7:7, 7:7), /* DIFFERENTIAL_DQS */ - field(EMC, 0x104, 9:9, 31:31), /* DQS_PULLD */ - field(EMC, 0x104, 1:0, 5:4), /* DRAM_TYPE */ - field(EMC, 0x104, 4:4, 6:6), /* DRAM_WIDTH */ - field(EMC, 0x114, 2:0, 3:1), /* CFG_QUSE_LATE */ -}; - -static const struct pmc_scratch_field emc_autocal_interval[] __initdata = { - field(EMC, 0x2a8, 27:0, 27:0), /* AUTOCAL_INTERVAL */ - field(EMC, 0x2b8, 1:1, 29:29), /* CLKCHANGE_PD_ENABLE */ - field(EMC, 0x2b8, 0:0, 28:28), /* CLKCHANGE_REQ_ENABLE */ - field(EMC, 0x2b8, 9:8, 31:30), /* PIN_CONFIG */ -}; - -static const struct pmc_scratch_field emc_cfgs[] __initdata = { - field(EMC, 0x10, 9:8, 4:3), /* EMEM_BANKWIDTH */ - field(EMC, 0x10, 2:0, 2:0), /* EMEM_COLWIDTH */ - field(EMC, 0x10, 19:16, 8:5), /* EMEM_DEVSIZE */ - field(EMC, 0x10, 25:24, 10:9), /* EMEM_NUMDEV */ - field(EMC, 0xc, 24:24, 21:21), /* AUTO_PRE_RD */ - field(EMC, 0xc, 25:25, 22:22), /* AUTO_PRE_WR */ - field(EMC, 0xc, 16:16, 20:20), /* CLEAR_AP_PREV_SPREQ */ - field(EMC, 0xc, 29:29, 23:23), /* DRAM_ACPD */ - field(EMC, 0xc, 30:30, 24:24), /* DRAM_CLKSTOP_PDSR_ONLY */ - field(EMC, 0xc, 31:31, 25:25), /* DRAM_CLKSTOP */ - field(EMC, 0xc, 15:8, 19:12), /* PRE_IDLE_CYCLES */ - field(EMC, 0xc, 0:0, 11:11), /* PRE_IDLE_EN */ - field(EMC, 0x2bc, 29:28, 29:28), /* CFG_DLL_LOCK_LIMIT */ - field(EMC, 0x2bc, 7:6, 31:30), /* CFG_DLL_MODE */ - field(MC, 0x10c, 0:0, 26:26), /* LL_CTRL */ - field(MC, 0x10c, 1:1, 27:27), /* LL_SEND_BOTH */ -}; - -static const struct pmc_scratch_field emc_adr_cfg1[] __initdata = { - field(EMC, 0x14, 9:8, 9:8), /* EMEM1_BANKWIDTH */ - field(EMC, 0x14, 2:0, 7:5), /* EMEM1_COLWIDTH */ - field(EMC, 0x14, 19:16, 13:10), /* EMEM1_DEVSIZE */ - field(EMC, 0x2dc, 28:24, 4:0), /* TERM_DRVUP */ - field(APB_MISC, 0x8d4, 3:0, 17:14), /* XM2COMP_VREF_SEL */ - field(APB_MISC, 0x8d8, 18:16, 23:21), /* XM2VTTGEN_CAL_DRVDN */ - field(APB_MISC, 0x8d8, 26:24, 20:18), /* XM2VTTGEN_CAL_DRVUP */ - field(APB_MISC, 0x8d8, 1:1, 30:30), /* XM2VTTGEN_SHORT_PWRGND */ - field(APB_MISC, 0x8d8, 0:0, 31:31), /* XM2VTTGEN_SHORT */ - field(APB_MISC, 0x8d8, 14:12, 26:24), /* XM2VTTGEN_VAUXP_LEVEL */ - field(APB_MISC, 0x8d8, 10:8, 29:27), /* XM2VTTGEN_VCLAMP_LEVEL */ -}; - -static const struct pmc_scratch_field emc_digital_dll[] __initdata = { - field(EMC, 0x2bc, 1:1, 23:23), /* DLI_TRIMMER_EN */ - field(EMC, 0x2bc, 0:0, 22:22), /* DLL_EN */ - field(EMC, 0x2bc, 5:5, 27:27), /* DLL_LOWSPEED */ - field(EMC, 0x2bc, 2:2, 24:24), /* DLL_OVERRIDE_EN */ - field(EMC, 0x2bc, 11:8, 31:28), /* DLL_UDSET */ - field(EMC, 0x2bc, 4:4, 26:26), /* PERBYTE_TRIMMER_OVERRIDE */ - field(EMC, 0x2bc, 3:3, 25:25), /* USE_SINGLE_DLL */ - field(MC, 0xc, 21:0, 21:0), /* EMEM_SIZE_KB */ -}; - -static const struct pmc_scratch_field emc_dqs_clktrim[] __initdata = { - field(EMC, 0x2d4, 29:0, 29:0), /* DQS0_CLKTRIM - DQS3 + MCLK*/ - field(APB_MISC, 0x8e4, 3:3, 31:31), /* XM2CFGC_CTT_HIZ_EN */ - field(APB_MISC, 0x8e4, 4:4, 30:30), /* XM2CFGC_VREF_DQS_EN */ -}; - -static const struct pmc_scratch_field emc_dq_clktrim[] __initdata = { - field(EMC, 0x2d8, 29:0, 29:0), - field(APB_MISC, 0x8e4, 2:2, 30:30), /* XM2CFGC_PREEMP_EN */ - field(APB_MISC, 0x8e4, 0:0, 31:31), /* XM2CFGC_RX_FT_REC_EN */ -}; - -static const struct pmc_scratch_field emc_dll_xform_dqs[] __initdata = { - field(EMC, 0x2bc, 25:16, 29:20), /* CFG_DLL_OVERRIDE_VAL */ - field(EMC, 0x2c0, 4:0, 4:0), /* DQS_MULT */ - field(EMC, 0x2c0, 22:8, 19:5), /* DQS_OFFS */ - field(MC, 0x10c, 31:31, 30:30), /* LL_DRAM_INTERLEAVE */ -}; - -static const struct pmc_scratch_field emc_odt_rw[] __initdata = { - field(EMC, 0x2c4, 4:0, 4:0), /* QUSE_MULT */ - field(EMC, 0x2c4, 22:8, 19:5), /* QUSE_OFF */ - field(EMC, 0xb4, 31:31, 29:29), /* DISABLE_ODT_DURING_READ */ - field(EMC, 0xb4, 30:30, 28:28), /* B4_READ */ - field(EMC, 0xb4, 2:0, 27:25), /* RD_DELAY */ - field(EMC, 0xb0, 31:31, 24:24), /* ENABLE_ODT_DURING_WRITE */ - field(EMC, 0xb0, 30:30, 23:23), /* B4_WRITE */ - field(EMC, 0xb0, 2:0, 22:20), /* WR_DELAY */ -}; - -static const struct pmc_scratch_field arbitration_xbar[] __initdata = { - field(AHB_GIZMO, 0xdc, 31:0, 31:0), -}; - -static const struct pmc_scratch_field emc_zcal[] __initdata = { - field(EMC, 0x2e0, 23:0, 23:0), /* ZCAL_REF_INTERVAL */ - field(EMC, 0x2e4, 7:0, 31:24), /* ZCAL_WAIT_CNT */ -}; - -static const struct pmc_scratch_field emc_ctt_term[] __initdata = { - field(EMC, 0x2dc, 19:15, 30:26), /* TERM_DRVDN */ - field(EMC, 0x2dc, 12:8, 25:21), /* TERM_OFFSET */ - field(EMC, 0x2dc, 31:31, 31:31), /* TERM_OVERRIDE */ - field(EMC, 0x2dc, 2:0, 20:18), /* TERM_SLOPE */ - field(EMC, 0x2e8, 23:16, 15:8), /* ZQ_MRW_MA */ - field(EMC, 0x2e8, 7:0, 7:0), /* ZQ_MRW_OP */ -}; - -static const struct pmc_scratch_field xm2_cfgd[] __initdata = { - field(APB_MISC, 0x8e8, 18:16, 11:9), /* CFGD0_DLYIN_TRM */ - field(APB_MISC, 0x8e8, 22:20, 8:6), /* CFGD1_DLYIN_TRM */ - field(APB_MISC, 0x8e8, 26:24, 5:3), /* CFGD2_DLYIN_TRM */ - field(APB_MISC, 0x8e8, 30:28, 2:0), /* CFGD3_DLYIN_TRM */ - field(APB_MISC, 0x8e8, 3:3, 12:12), /* XM2CFGD_CTT_HIZ_EN */ - field(APB_MISC, 0x8e8, 2:2, 13:13), /* XM2CFGD_PREEMP_EN */ - field(APB_MISC, 0x8e8, 0:0, 14:14), /* CM2CFGD_RX_FT_REC_EN */ -}; - -struct pmc_scratch_reg { - const struct pmc_scratch_field *fields; - void __iomem *scratch_addr; - int num_fields; -}; - -#define scratch(offs, field_list) \ - { \ - .scratch_addr = IO_ADDRESS(TEGRA_PMC_BASE) + offs, \ - .fields = field_list, \ - .num_fields = ARRAY_SIZE(field_list), \ - } - -static const struct pmc_scratch_reg scratch[] __initdata = { - scratch(PMC_SCRATCH3, pllx), - scratch(PMC_SCRATCH5, emc_0), - scratch(PMC_SCRATCH6, emc_1), - scratch(PMC_SCRATCH7, emc_2), - scratch(PMC_SCRATCH8, emc_3), - scratch(PMC_SCRATCH9, emc_4), - scratch(PMC_SCRATCH10, emc_5), - scratch(PMC_SCRATCH11, emc_6), - scratch(PMC_SCRATCH12, emc_dqsib_dly), - scratch(PMC_SCRATCH13, emc_quse_dly), - scratch(PMC_SCRATCH14, emc_clktrim), - scratch(PMC_SCRATCH15, emc_autocal_fbio), - scratch(PMC_SCRATCH16, emc_autocal_interval), - scratch(PMC_SCRATCH17, emc_cfgs), - scratch(PMC_SCRATCH18, emc_adr_cfg1), - scratch(PMC_SCRATCH19, emc_digital_dll), - scratch(PMC_SCRATCH20, emc_dqs_clktrim), - scratch(PMC_SCRATCH21, emc_dq_clktrim), - scratch(PMC_SCRATCH22, emc_dll_xform_dqs), - scratch(PMC_SCRATCH23, emc_odt_rw), - scratch(PMC_SCRATCH25, arbitration_xbar), - scratch(PMC_SCRATCH35, emc_zcal), - scratch(PMC_SCRATCH36, emc_ctt_term), - scratch(PMC_SCRATCH40, xm2_cfgd), -}; - -void __init lp0_suspend_init(void) -{ - int i; - - for (i=0; i>= scratch[i].fields[j].shift_src; - v &= scratch[i].fields[j].mask; - v <<= scratch[i].fields[j].shift_dst; - r |= v; - } - - writel(r, scratch[i].scratch_addr); - } -} - -#define NUM_WAKE_EVENTS 31 - -static int tegra_wake_event_irq[NUM_WAKE_EVENTS] = { - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV3), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PB6), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN7), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PA0), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC7), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PAA1), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW3), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW2), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PY6), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ7), - INT_RTC, - INT_KBC, - INT_EXTERNAL_PMU, - -EINVAL, /* TEGRA_USB1_VBUS, */ - -EINVAL, /* TEGRA_USB3_VBUS, */ - -EINVAL, /* TEGRA_USB1_ID, */ - -EINVAL, /* TEGRA_USB3_ID, */ - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI5), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV2), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS5), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ7), - TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2), -}; - -int tegra_irq_to_wake(int irq) -{ - int i; - for (i = 0; i < NUM_WAKE_EVENTS; i++) - if (tegra_wake_event_irq[i] == irq) - return i; - - return -EINVAL; -} - -int tegra_wake_to_irq(int wake) -{ - if (wake < 0) - return -EINVAL; - - if (wake >= NUM_WAKE_EVENTS) - return -EINVAL; - - return tegra_wake_event_irq[wake]; -} diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c deleted file mode 100644 index 146b93a014f3..000000000000 --- a/arch/arm/mach-tegra/suspend.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * arch/arm/mach-tegra/suspend.c - * - * CPU complex suspend & resume functions for Tegra SoCs - * - * Copyright (c) 2009-2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "board.h" -#include "power.h" - -struct suspend_context { - /* - * The next 7 values are referenced by offset in __restart_plls - * in headsmp-t2.S, and should not be moved - */ - u32 pllx_misc; - u32 pllx_base; - u32 pllp_misc; - u32 pllp_base; - u32 pllp_outa; - u32 pllp_outb; - u32 pll_timeout; - - u32 cpu_burst; - u32 clk_csite_src; - u32 twd_ctrl; - u32 twd_load; - u32 cclk_divider; -}; - -volatile struct suspend_context tegra_sctx; - -static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); -#ifdef CONFIG_PM -static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE); -static void __iomem *flow_ctrl = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE); -static void __iomem *evp_reset = IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE)+0x100; -static void __iomem *tmrus = IO_ADDRESS(TEGRA_TMRUS_BASE); -#endif - -#define PMC_CTRL 0x0 -#define PMC_CTRL_LATCH_WAKEUPS (1 << 5) -#define PMC_WAKE_MASK 0xc -#define PMC_WAKE_LEVEL 0x10 -#define PMC_DPAD_ORIDE 0x1C -#define PMC_WAKE_DELAY 0xe0 -#define PMC_DPD_SAMPLE 0x20 - -#define PMC_WAKE_STATUS 0x14 -#define PMC_SW_WAKE_STATUS 0x18 -#define PMC_COREPWRGOOD_TIMER 0x3c -#define PMC_SCRATCH0 0x50 -#define PMC_SCRATCH1 0x54 -#define PMC_CPUPWRGOOD_TIMER 0xc8 -#define PMC_CPUPWROFF_TIMER 0xcc -#define PMC_COREPWROFF_TIMER PMC_WAKE_DELAY -#define PMC_SCRATCH38 0x134 -#define PMC_SCRATCH39 0x138 -#define PMC_SCRATCH41 0x140 - -#define CLK_RESET_CCLK_BURST 0x20 -#define CLK_RESET_CCLK_DIVIDER 0x24 -#define CLK_RESET_PLLC_BASE 0x80 -#define CLK_RESET_PLLM_BASE 0x90 -#define CLK_RESET_PLLX_BASE 0xe0 -#define CLK_RESET_PLLX_MISC 0xe4 -#define CLK_RESET_PLLP_BASE 0xa0 -#define CLK_RESET_PLLP_OUTA 0xa4 -#define CLK_RESET_PLLP_OUTB 0xa8 -#define CLK_RESET_PLLP_MISC 0xac - -#define CLK_RESET_SOURCE_CSITE 0x1d4 - - -#define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28 -#define CLK_RESET_CCLK_BURST_POLICY_PLLM 3 -#define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 - -#define FLOW_CTRL_CPU_CSR 0x8 -#define FLOW_CTRL_CPU1_CSR 0x18 - -#define EMC_MRW_0 0x0e8 -#define EMC_MRW_DEV_SELECTN 30 -#define EMC_MRW_DEV_NONE (3 << EMC_MRW_DEV_SELECTN) - -unsigned long tegra_pgd_phys; /* pgd used by hotplug & LP2 bootup */ -static pgd_t *tegra_pgd; -void *tegra_context_area = NULL; - -static struct clk *tegra_pclk = NULL; -static const struct tegra_suspend_platform_data *pdata = NULL; -static unsigned long wb0_restore = 0; -static enum tegra_suspend_mode current_suspend_mode; - -static unsigned int tegra_time_in_suspend[32]; - -static inline unsigned int time_to_bin(unsigned int time) -{ - return fls(time); -} - -unsigned long tegra_cpu_power_good_time(void) -{ - if (WARN_ON_ONCE(!pdata)) - return 5000; - - return pdata->cpu_timer; -} - -unsigned long tegra_cpu_power_off_time(void) -{ - if (WARN_ON_ONCE(!pdata)) - return 5000; - - return pdata->cpu_off_timer; -} - -enum tegra_suspend_mode tegra_get_suspend_mode(void) -{ - if (!pdata) - return TEGRA_SUSPEND_NONE; - - return pdata->suspend_mode; -} - -static void set_power_timers(unsigned long us_on, unsigned long us_off, - long rate) -{ - static int last_pclk = 0; - unsigned long long ticks; - unsigned long long pclk; - - if (WARN_ON_ONCE(rate <= 0)) - pclk = 100000000; - else - pclk = rate; - - if (rate != last_pclk) { - ticks = (us_on * pclk) + 999999ull; - do_div(ticks, 1000000); - writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER); - - ticks = (us_off * pclk) + 999999ull; - do_div(ticks, 1000000); - writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER); - wmb(); - } - last_pclk = pclk; -} - -static int create_suspend_pgtable(void) -{ - int i; - pmd_t *pmd; - /* arrays of virtual-to-physical mappings which must be - * present to safely boot hotplugged / LP2-idled CPUs. - * tegra_hotplug_startup (hotplug reset vector) is mapped - * VA=PA so that the translation post-MMU is the same as - * pre-MMU, IRAM is mapped VA=PA so that SDRAM self-refresh - * can safely disable the MMU */ - unsigned long addr_v[] = { - PHYS_OFFSET, - IO_IRAM_PHYS, - (unsigned long)tegra_context_area, -#ifdef CONFIG_HOTPLUG_CPU - (unsigned long)virt_to_phys(tegra_hotplug_startup), -#endif - (unsigned long)__cortex_a9_restore, - (unsigned long)virt_to_phys(__shut_off_mmu), - }; - unsigned long addr_p[] = { - PHYS_OFFSET, - IO_IRAM_PHYS, - (unsigned long)virt_to_phys(tegra_context_area), -#ifdef CONFIG_HOTPLUG_CPU - (unsigned long)virt_to_phys(tegra_hotplug_startup), -#endif - (unsigned long)virt_to_phys(__cortex_a9_restore), - (unsigned long)virt_to_phys(__shut_off_mmu), - }; - unsigned int flags = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | - PMD_SECT_WBWA | PMD_SECT_S; - - tegra_pgd = pgd_alloc(&init_mm); - if (!tegra_pgd) - return -ENOMEM; - - for (i=0; i= 0x80000000UL) - cpu_relax(); - } - writel(tegra_sctx.cclk_divider, clk_rst + CLK_RESET_CCLK_DIVIDER); - writel(tegra_sctx.cpu_burst, clk_rst + CLK_RESET_CCLK_BURST); - writel(tegra_sctx.clk_csite_src, clk_rst + CLK_RESET_SOURCE_CSITE); - - /* do not power-gate the CPU when flow controlled */ - reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR); - reg &= ~((1<<5) | (1<<4) | 1); /* clear WFE bitmask */ - reg |= (1<<14); /* write-1-clear event flag */ - writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR); - wmb(); - -#ifdef CONFIG_HAVE_ARM_TWD - writel(tegra_sctx.twd_ctrl, twd_base + 0x8); - writel(tegra_sctx.twd_load, twd_base + 0); -#endif - - gic_dist_restore(0); - get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER); - - enable_irq(INT_SYS_STATS_MON); -} - -static noinline void suspend_cpu_complex(void) -{ - unsigned int reg; - int i; - - disable_irq(INT_SYS_STATS_MON); - - /* switch coresite to clk_m, save off original source */ - tegra_sctx.clk_csite_src = readl(clk_rst + CLK_RESET_SOURCE_CSITE); - writel(3<<30, clk_rst + CLK_RESET_SOURCE_CSITE); - - tegra_sctx.cpu_burst = readl(clk_rst + CLK_RESET_CCLK_BURST); - tegra_sctx.pllx_base = readl(clk_rst + CLK_RESET_PLLX_BASE); - tegra_sctx.pllx_misc = readl(clk_rst + CLK_RESET_PLLX_MISC); - tegra_sctx.pllp_base = readl(clk_rst + CLK_RESET_PLLP_BASE); - tegra_sctx.pllp_outa = readl(clk_rst + CLK_RESET_PLLP_OUTA); - tegra_sctx.pllp_outb = readl(clk_rst + CLK_RESET_PLLP_OUTB); - tegra_sctx.pllp_misc = readl(clk_rst + CLK_RESET_PLLP_MISC); - tegra_sctx.cclk_divider = readl(clk_rst + CLK_RESET_CCLK_DIVIDER); - -#ifdef CONFIG_HAVE_ARM_TWD - tegra_sctx.twd_ctrl = readl(twd_base + 0x8); - tegra_sctx.twd_load = readl(twd_base + 0); - local_timer_stop(); -#endif - - reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR); - /* clear any pending events, set the WFE bitmap to specify just - * CPU0, and clear any pending events for this CPU */ - reg &= ~(1<<5); /* clear CPU1 WFE */ - reg |= (1<<14) | (1<<4) | 1; /* enable CPU0 WFE */ - writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR); - wmb(); - - for (i=1; i> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK; - mode |= TEGRA_POWER_CPU_PWRREQ_OE; - if (pdata->separate_req) - mode |= TEGRA_POWER_PWRREQ_OE; - else - mode &= ~TEGRA_POWER_PWRREQ_OE; - mode &= ~TEGRA_POWER_EFFECT_LP0; - - orig = readl(evp_reset); - writel(virt_to_phys(tegra_lp2_startup), evp_reset); - - set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer, - clk_get_rate_all_locked(tegra_pclk)); - - if (us) - tegra_lp2_set_trigger(us); - - suspend_cpu_complex(); - stop_critical_timings(); - flush_cache_all(); - /* structure is written by reset code, so the L2 lines - * must be invalidated */ - outer_flush_range(__pa(&tegra_sctx),__pa(&tegra_sctx+1)); - barrier(); - - __cortex_a9_save(mode); - /* return from __cortex_a9_restore */ - barrier(); - restore_cpu_complex(); - start_critical_timings(); - - remain = tegra_lp2_timer_remain(); - if (us) - tegra_lp2_set_trigger(0); - - writel(orig, evp_reset); - - return remain; -} - -/* ensures that sufficient time is passed for a register write to - * serialize into the 32KHz domain */ -static void pmc_32kwritel(u32 val, unsigned long offs) -{ - writel(val, pmc + offs); - udelay(130); -} - -static u8 *iram_save = NULL; -static unsigned int iram_save_size = 0; -static void __iomem *iram_code = IO_ADDRESS(TEGRA_IRAM_CODE_AREA); - -static void tegra_suspend_dram(bool do_lp0) -{ - unsigned int mode = TEGRA_POWER_SDRAM_SELFREFRESH; - unsigned long orig, reg; - - orig = readl(evp_reset); - /* copy the reset vector and SDRAM shutdown code into IRAM */ - memcpy(iram_save, iram_code, iram_save_size); - memcpy(iram_code, (void *)__tegra_lp1_reset, iram_save_size); - - set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer, 32768); - - reg = readl(pmc + PMC_CTRL); - mode |= ((reg >> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK); - - if (!do_lp0) { - writel(TEGRA_IRAM_CODE_AREA, evp_reset); - - mode |= TEGRA_POWER_CPU_PWRREQ_OE; - if (pdata->separate_req) - mode |= TEGRA_POWER_PWRREQ_OE; - else - mode &= ~TEGRA_POWER_PWRREQ_OE; - mode &= ~TEGRA_POWER_EFFECT_LP0; - - tegra_legacy_irq_set_lp1_wake_mask(); - } else { - u32 boot_flag = readl(pmc + PMC_SCRATCH0); - pmc_32kwritel(boot_flag | 1, PMC_SCRATCH0); - pmc_32kwritel(wb0_restore, PMC_SCRATCH1); - writel(0x0, pmc + PMC_SCRATCH39); - mode |= TEGRA_POWER_CPU_PWRREQ_OE; - mode |= TEGRA_POWER_PWRREQ_OE; - mode |= TEGRA_POWER_EFFECT_LP0; - - /* for platforms where the core & CPU power requests are - * combined as a single request to the PMU, transition to - * LP0 state by temporarily enabling both requests - */ - if (!pdata->separate_req) { - reg |= ((mode & TEGRA_POWER_PMC_MASK) << - TEGRA_POWER_PMC_SHIFT); - pmc_32kwritel(reg, PMC_CTRL); - mode &= ~TEGRA_POWER_CPU_PWRREQ_OE; - } - - tegra_set_lp0_wake_pads(pdata->wake_enb, pdata->wake_high, - pdata->wake_any); - } - - suspend_cpu_complex(); - flush_cache_all(); -#ifdef CONFIG_CACHE_L2X0 - l2x0_shutdown(); -#endif - - __cortex_a9_save(mode); - restore_cpu_complex(); - - writel(orig, evp_reset); -#ifdef CONFIG_CACHE_L2X0 - l2x0_restart(); -#endif - - if (!do_lp0) { - memcpy(iram_code, iram_save, iram_save_size); - tegra_legacy_irq_restore_mask(); - } else { - /* for platforms where the core & CPU power requests are - * combined as a single request to the PMU, transition out - * of LP0 state by temporarily enabling both requests - */ - if (!pdata->separate_req) { - reg = readl(pmc + PMC_CTRL); - reg |= (TEGRA_POWER_CPU_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); - pmc_32kwritel(reg, PMC_CTRL); - reg &= ~(TEGRA_POWER_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); - writel(reg, pmc + PMC_CTRL); - } - } - - wmb(); -} - -static int tegra_suspend_begin(suspend_state_t state) -{ - return regulator_suspend_prepare(state); -} - -static int tegra_suspend_prepare_late(void) -{ - disable_irq(INT_SYS_STATS_MON); - return tegra_iovmm_suspend(); -} - -static void tegra_suspend_wake(void) -{ - tegra_iovmm_resume(); - enable_irq(INT_SYS_STATS_MON); -} - -static u8 uart_state[5]; - -static int tegra_debug_uart_suspend(void) -{ - void __iomem *uart; - u32 lcr; - - if (TEGRA_DEBUG_UART_BASE == 0) - return 0; - - uart = IO_ADDRESS(TEGRA_DEBUG_UART_BASE); - - lcr = readb(uart + UART_LCR * 4); - - uart_state[0] = lcr; - uart_state[1] = readb(uart + UART_MCR * 4); - - /* DLAB = 0 */ - writeb(lcr & ~UART_LCR_DLAB, uart + UART_LCR * 4); - - uart_state[2] = readb(uart + UART_IER * 4); - - /* DLAB = 1 */ - writeb(lcr | UART_LCR_DLAB, uart + UART_LCR * 4); - - uart_state[3] = readb(uart + UART_DLL * 4); - uart_state[4] = readb(uart + UART_DLM * 4); - - writeb(lcr, uart + UART_LCR * 4); - - return 0; -} - -static void tegra_debug_uart_resume(void) -{ - void __iomem *uart; - u32 lcr; - - if (TEGRA_DEBUG_UART_BASE == 0) - return; - - uart = IO_ADDRESS(TEGRA_DEBUG_UART_BASE); - - lcr = uart_state[0]; - - writeb(uart_state[1], uart + UART_MCR * 4); - - /* DLAB = 0 */ - writeb(lcr & ~UART_LCR_DLAB, uart + UART_LCR * 4); - - writeb(uart_state[2], uart + UART_IER * 4); - - /* DLAB = 1 */ - writeb(lcr | UART_LCR_DLAB, uart + UART_LCR * 4); - - writeb(uart_state[3], uart + UART_DLL * 4); - writeb(uart_state[4], uart + UART_DLM * 4); - - writeb(lcr, uart + UART_LCR * 4); -} - -#define MC_SECURITY_START 0x6c -#define MC_SECURITY_SIZE 0x70 -#define MC_SECURITY_CFG2 0x7c - -static int tegra_suspend_enter(suspend_state_t state) -{ - struct irq_desc *desc; - void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); - void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE); - unsigned long flags; - u32 mc_data[3] = {0, 0, 0}; - int irq; - bool do_lp0 = (current_suspend_mode == TEGRA_SUSPEND_LP0); - bool do_lp2 = (current_suspend_mode == TEGRA_SUSPEND_LP2); - int lp_state; - u64 rtc_before; - u64 rtc_after; - u64 secs; - u32 ms; - - if (do_lp2) - lp_state = 2; - else if (do_lp0) - lp_state = 0; - else - lp_state = 1; - - local_irq_save(flags); - local_fiq_disable(); - - pr_info("Entering suspend state LP%d\n", lp_state); - if (do_lp0) { - tegra_irq_suspend(); - tegra_dma_suspend(); - tegra_debug_uart_suspend(); - tegra_pinmux_suspend(); - tegra_timer_suspend(); - tegra_gpio_suspend(); - tegra_clk_suspend(); - - mc_data[0] = readl(mc + MC_SECURITY_START); - mc_data[1] = readl(mc + MC_SECURITY_SIZE); - mc_data[2] = readl(mc + MC_SECURITY_CFG2); - } - - for_each_irq_desc(irq, desc) { - if ((desc->status & IRQ_WAKEUP) && - (desc->status & IRQ_SUSPENDED)) { - get_irq_chip(irq)->unmask(irq); - } - } - - rtc_before = tegra_rtc_read_ms(); - - if (do_lp2) - tegra_suspend_lp2(0); - else - tegra_suspend_dram(do_lp0); - - rtc_after = tegra_rtc_read_ms(); - - for_each_irq_desc(irq, desc) { - if ((desc->status & IRQ_WAKEUP) && - (desc->status & IRQ_SUSPENDED)) { - get_irq_chip(irq)->mask(irq); - } - } - - /* Clear DPD sample */ - writel(0x0, pmc + PMC_DPD_SAMPLE); - - if (do_lp0) { - writel(mc_data[0], mc + MC_SECURITY_START); - writel(mc_data[1], mc + MC_SECURITY_SIZE); - writel(mc_data[2], mc + MC_SECURITY_CFG2); - - /* trigger emc mode write */ - writel(EMC_MRW_DEV_NONE, emc + EMC_MRW_0); - - tegra_clk_resume(); - tegra_gpio_resume(); - tegra_timer_resume(); - tegra_pinmux_resume(); - tegra_debug_uart_resume(); - tegra_dma_resume(); - tegra_irq_resume(); - } - - secs = rtc_after - rtc_before; - ms = do_div(secs, 1000); - pr_info("Suspended for %llu.%03u seconds\n", secs, ms); - - tegra_time_in_suspend[time_to_bin(secs)]++; - - local_fiq_enable(); - local_irq_restore(flags); - - return 0; -} - -static struct platform_suspend_ops tegra_suspend_ops = { - .valid = suspend_valid_only_mem, - .begin = tegra_suspend_begin, - .prepare_late = tegra_suspend_prepare_late, - .wake = tegra_suspend_wake, - .enter = tegra_suspend_enter, -}; -#endif - -void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat) -{ - u32 reg, mode; - - tegra_pclk = clk_get_sys(NULL, "pclk"); - BUG_ON(!tegra_pclk); - pdata = plat; - (void)reg; - (void)mode; - - if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && tegra_lp0_vec_size) { - wb0_restore = tegra_lp0_vec_start; - } else { - pr_warning("Suspend mode LP0 requested, but missing lp0_vec\n"); - pr_warning("Disabling LP0\n"); - plat->suspend_mode = TEGRA_SUSPEND_LP1; - } - - tegra_context_area = kzalloc(CONTEXT_SIZE_BYTES * NR_CPUS, GFP_KERNEL); - - if (tegra_context_area && create_suspend_pgtable()) { - kfree(tegra_context_area); - tegra_context_area = NULL; - } - -#ifdef CONFIG_PM - iram_save_size = (unsigned long)__tegra_iram_end; - iram_save_size -= (unsigned long)__tegra_lp1_reset; - - iram_save = kmalloc(iram_save_size, GFP_KERNEL); - if (!iram_save) { - pr_err("%s: unable to allocate memory for SDRAM self-refresh " - "LP0/LP1 unavailable\n", __func__); - plat->suspend_mode = TEGRA_SUSPEND_LP2; - } - /* CPU reset vector for LP0 and LP1 */ - writel(virt_to_phys(tegra_lp2_startup), pmc + PMC_SCRATCH41); - - /* Always enable CPU power request; just normal polarity is supported */ - reg = readl(pmc + PMC_CTRL); - BUG_ON(reg & (TEGRA_POWER_CPU_PWRREQ_POLARITY << TEGRA_POWER_PMC_SHIFT)); - reg |= (TEGRA_POWER_CPU_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); - pmc_32kwritel(reg, PMC_CTRL); - - /* Configure core power request and system clock control if LP0 - is supported */ - writel(pdata->core_timer, pmc + PMC_COREPWRGOOD_TIMER); - writel(pdata->core_off_timer, pmc + PMC_COREPWROFF_TIMER); - reg = readl(pmc + PMC_CTRL); - mode = (reg >> TEGRA_POWER_PMC_SHIFT) & TEGRA_POWER_PMC_MASK; - - mode &= ~TEGRA_POWER_SYSCLK_POLARITY; - mode &= ~TEGRA_POWER_PWRREQ_POLARITY; - - if (!pdata->sysclkreq_high) - mode |= TEGRA_POWER_SYSCLK_POLARITY; - if (!pdata->corereq_high) - mode |= TEGRA_POWER_PWRREQ_POLARITY; - - /* configure output inverters while the request is tristated */ - reg |= (mode << TEGRA_POWER_PMC_SHIFT); - pmc_32kwritel(reg, PMC_CTRL); - - /* now enable requests */ - reg |= (TEGRA_POWER_SYSCLK_OE << TEGRA_POWER_PMC_SHIFT); - if (pdata->separate_req) - reg |= (TEGRA_POWER_PWRREQ_OE << TEGRA_POWER_PMC_SHIFT); - writel(reg, pmc + PMC_CTRL); - - if (pdata->suspend_mode == TEGRA_SUSPEND_LP0) - lp0_suspend_init(); - - suspend_set_ops(&tegra_suspend_ops); -#endif - - current_suspend_mode = plat->suspend_mode; -} - -#ifdef CONFIG_DEBUG_FS -static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = { - [TEGRA_SUSPEND_NONE] = "none", - [TEGRA_SUSPEND_LP2] = "lp2", - [TEGRA_SUSPEND_LP1] = "lp1", - [TEGRA_SUSPEND_LP0] = "lp0", -}; - -static int tegra_suspend_debug_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%s\n", tegra_suspend_name[*(int *)s->private]); - return 0; -} - -static int tegra_suspend_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_suspend_debug_show, inode->i_private); -} - -static int tegra_suspend_debug_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - char buf[32]; - int buf_size; - int i; - struct seq_file *s = file->private_data; - enum tegra_suspend_mode *val = s->private; - - memset(buf, 0x00, sizeof(buf)); - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - for (i = 0; i < TEGRA_MAX_SUSPEND_MODE; i++) { - if (!strnicmp(buf, tegra_suspend_name[i], - strlen(tegra_suspend_name[i]))) { - if (i > pdata->suspend_mode) - return -EINVAL; - *val = i; - return count; - } - } - - return -EINVAL; -} - -static const struct file_operations tegra_suspend_debug_fops = { - .open = tegra_suspend_debug_open, - .write = tegra_suspend_debug_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int tegra_suspend_time_debug_show(struct seq_file *s, void *data) -{ - int bin; - seq_printf(s, "time (secs) count\n"); - seq_printf(s, "------------------\n"); - for (bin = 0; bin < 32; bin++) { - if (tegra_time_in_suspend[bin] == 0) - continue; - seq_printf(s, "%4d - %4d %4u\n", - bin ? 1 << (bin - 1) : 0, 1 << bin, - tegra_time_in_suspend[bin]); - } - return 0; -} - -static int tegra_suspend_time_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_suspend_time_debug_show, NULL); -} - -static const struct file_operations tegra_suspend_time_debug_fops = { - .open = tegra_suspend_time_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init tegra_suspend_debug_init(void) -{ - struct dentry *d; - - d = debugfs_create_file("suspend_mode", 0755, NULL, - (void *)¤t_suspend_mode, &tegra_suspend_debug_fops); - if (!d) { - pr_info("Failed to create suspend_mode debug file\n"); - return -ENOMEM; - } - - d = debugfs_create_file("suspend_time", 0755, NULL, NULL, - &tegra_suspend_time_debug_fops); - if (!d) { - pr_info("Failed to create suspend_time debug file\n"); - return -ENOMEM; - } - - return 0; -} - -late_initcall(tegra_suspend_debug_init); -#endif diff --git a/arch/arm/mach-tegra/syncpt.c b/arch/arm/mach-tegra/syncpt.c deleted file mode 100644 index bb649a9fe51a..000000000000 --- a/arch/arm/mach-tegra/syncpt.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * Copyright (C) 2010, NVIDIA Corporation - * - * 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 -#include -#include -#include -#include - -#include -#include - -#define HOST1X_SYNC_OFFSET 0x3000 -#define HOST1X_SYNC_SIZE 0x800 -enum { - HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS = 0x40, - HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE = 0x60 -}; - -static void syncpt_thresh_mask(unsigned int irq) -{ - (void)irq; -} - -static void syncpt_thresh_unmask(unsigned int irq) -{ - (void)irq; -} - -static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc) -{ - void __iomem *sync_regs = get_irq_desc_data(desc); - u32 reg; - int id; - - desc->chip->ack(irq); - - reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS); - - while ((id = __fls(reg)) >= 0) { - reg ^= BIT(id); - generic_handle_irq(id + INT_SYNCPT_THRESH_BASE); - } - - desc->chip->unmask(irq); -} - -static struct irq_chip syncpt_thresh_irq = { - .name = "syncpt", - .mask = syncpt_thresh_mask, - .unmask = syncpt_thresh_unmask -}; - -static int __init syncpt_init_irq(void) -{ - void __iomem *sync_regs; - unsigned int i; - int irq; - - sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET, - HOST1X_SYNC_SIZE); - BUG_ON(!sync_regs); - - writel(0xffffffffUL, - sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE); - writel(0xffffffffUL, - sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS); - - for (i = 0; i < INT_SYNCPT_THRESH_NR; i++) { - irq = INT_SYNCPT_THRESH_BASE + i; - set_irq_chip(irq, &syncpt_thresh_irq); - set_irq_chip_data(irq, sync_regs); - set_irq_handler(irq, handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); - } - if (set_irq_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs)) - BUG(); - set_irq_chained_handler(INT_HOST1X_MPCORE_SYNCPT, - syncpt_thresh_cascade); - - return 0; -} - -core_initcall(syncpt_init_irq); diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index a182f3b06b19..426163231fff 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -23,29 +23,21 @@ #include #include #include -#include +#include #include #include -#include #include "clock.h" -#include "fuse.h" -#include "tegra2_emc.h" #define RST_DEVICES 0x004 #define RST_DEVICES_SET 0x300 #define RST_DEVICES_CLR 0x304 -#define RST_DEVICES_NUM 3 #define CLK_OUT_ENB 0x010 #define CLK_OUT_ENB_SET 0x320 #define CLK_OUT_ENB_CLR 0x324 -#define CLK_OUT_ENB_NUM 3 - -#define CLK_MASK_ARM 0x44 -#define MISC_CLK_ENB 0x48 #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_MASK (3<<30) @@ -53,7 +45,6 @@ #define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) #define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) #define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) -#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) #define OSC_FREQ_DET 0x58 #define OSC_FREQ_DET_TRIG (1<<31) @@ -62,28 +53,18 @@ #define OSC_FREQ_DET_BUSY (1<<31) #define OSC_FREQ_DET_CNT_MASK 0xFFFF -#define PERIPH_CLK_SOURCE_I2S1 0x100 -#define PERIPH_CLK_SOURCE_EMC 0x19c -#define PERIPH_CLK_SOURCE_OSC 0x1fc -#define PERIPH_CLK_SOURCE_NUM \ - ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4) - #define PERIPH_CLK_SOURCE_MASK (3<<30) #define PERIPH_CLK_SOURCE_SHIFT 30 #define PERIPH_CLK_SOURCE_ENABLE (1<<28) -#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF -#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF +#define PERIPH_CLK_SOURCE_DIV_MASK 0xFF #define PERIPH_CLK_SOURCE_DIV_SHIFT 0 -#define SDMMC_CLK_INT_FB_SEL (1 << 23) -#define SDMMC_CLK_INT_FB_DLY_SHIFT 16 -#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT) - #define PLL_BASE 0x0 #define PLL_BASE_BYPASS (1<<31) #define PLL_BASE_ENABLE (1<<30) #define PLL_BASE_REF_ENABLE (1<<29) #define PLL_BASE_OVERRIDE (1<<28) +#define PLL_BASE_LOCK (1<<27) #define PLL_BASE_DIVP_MASK (0x7<<20) #define PLL_BASE_DIVP_SHIFT 20 #define PLL_BASE_DIVN_MASK (0x3FF<<8) @@ -98,8 +79,8 @@ #define PLL_OUT_RESET_DISABLE (1<<0) #define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) - #define PLL_MISC_DCCON_SHIFT 20 +#define PLL_MISC_LOCK_ENABLE (1<<18) #define PLL_MISC_CPCON_SHIFT 8 #define PLL_MISC_CPCON_MASK (0xF<u.periph.clk_num / 32) * 4) -#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8) -#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32)) +#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4) +#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8) +#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32)) #define SUPER_CLK_MUX 0x00 #define SUPER_STATE_SHIFT 28 @@ -136,35 +115,12 @@ #define BUS_CLK_DISABLE (1<<3) #define BUS_CLK_DIV_MASK 0x3 -#define PMC_CTRL 0x0 - #define PMC_CTRL_BLINK_ENB (1 << 7) - -#define PMC_DPD_PADS_ORIDE 0x1c - #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20) - -#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0 -#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff -#define PMC_BLINK_TIMER_ENB (1 << 15) -#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16 -#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff - static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); -static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); - -/* - * Some peripheral clocks share an enable bit, so refcount the enable bits - * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U - */ -static int tegra_periph_clk_enable_refcount[3 * 32]; #define clk_writel(value, reg) \ __raw_writel(value, (u32)reg_clk_base + (reg)) #define clk_readl(reg) \ __raw_readl((u32)reg_clk_base + (reg)) -#define pmc_writel(value, reg) \ - __raw_writel(value, (u32)reg_pmc_base + (reg)) -#define pmc_readl(reg) \ - __raw_readl((u32)reg_pmc_base + (reg)) unsigned long clk_measure_input_freq(void) { @@ -187,38 +143,31 @@ unsigned long clk_measure_input_freq(void) } } -static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate) +static int clk_div71_get_divider(struct clk *c, unsigned long rate) { - s64 divider_u71 = parent_rate * 2; - divider_u71 += rate - 1; - do_div(divider_u71, rate); + unsigned long divider_u71; - if (divider_u71 - 2 < 0) - return 0; + divider_u71 = DIV_ROUND_UP(c->rate * 2, rate); - if (divider_u71 - 2 > 255) + if (divider_u71 - 2 > 255 || divider_u71 - 2 < 0) return -EINVAL; return divider_u71 - 2; } -static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate) +static unsigned long tegra2_clk_recalculate_rate(struct clk *c) { - s64 divider_u16; + unsigned long rate; + rate = c->parent->rate; - divider_u16 = parent_rate; - divider_u16 += rate - 1; - do_div(divider_u16, rate); - - if (divider_u16 - 1 < 0) - return 0; - - if (divider_u16 - 1 > 255) - return -EINVAL; - - return divider_u16 - 1; + if (c->mul != 0 && c->div != 0) + c->rate = rate * c->mul / c->div; + else + c->rate = rate; + return c->rate; } + /* clk_m functions */ static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c) { @@ -270,18 +219,6 @@ static struct clk_ops tegra_clk_m_ops = { .disable = tegra2_clk_m_disable, }; -void tegra2_periph_reset_assert(struct clk *c) -{ - BUG_ON(!c->ops->reset); - c->ops->reset(c, true); -} - -void tegra2_periph_reset_deassert(struct clk *c) -{ - BUG_ON(!c->ops->reset); - c->ops->reset(c, false); -} - /* super clock functions */ /* "super clocks" on tegra have two-stage muxes and a clock skipping * super divider. We will ignore the clock skipping divider, since we @@ -307,6 +244,7 @@ static void tegra2_super_clk_init(struct clk *c) } BUG_ON(sel->input == NULL); c->parent = sel->input; + tegra2_clk_recalculate_rate(c); } static int tegra2_super_clk_enable(struct clk *c) @@ -328,7 +266,6 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p) u32 val; const struct clk_mux_sel *sel; int shift; - val = clk_readl(c->reg + SUPER_CLK_MUX);; BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); @@ -336,122 +273,23 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p) SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; for (sel = c->inputs; sel->input != NULL; sel++) { if (sel->input == p) { + clk_reparent(c, p); val &= ~(SUPER_SOURCE_MASK << shift); val |= sel->value << shift; - - if (c->refcnt) - clk_enable(p); - clk_writel(val, c->reg); - - if (c->refcnt && c->parent) - clk_disable(c->parent); - - clk_reparent(c, p); + c->rate = c->parent->rate; return 0; } } return -EINVAL; } -/* - * Super clocks have "clock skippers" instead of dividers. Dividing using - * a clock skipper does not allow the voltage to be scaled down, so instead - * adjust the rate of the parent clock. This requires that the parent of a - * super clock have no other children, otherwise the rate will change - * underneath the other children. - */ -static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate) -{ - return clk_set_rate(c->parent, rate); -} - static struct clk_ops tegra_super_ops = { .init = tegra2_super_clk_init, .enable = tegra2_super_clk_enable, .disable = tegra2_super_clk_disable, .set_parent = tegra2_super_clk_set_parent, - .set_rate = tegra2_super_clk_set_rate, -}; - -/* virtual cpu clock functions */ -/* some clocks can not be stopped (cpu, memory bus) while the SoC is running. - To change the frequency of these clocks, the parent pll may need to be - reprogrammed, so the clock must be moved off the pll, the pll reprogrammed, - and then the clock moved back to the pll. To hide this sequence, a virtual - clock handles it. - */ -static void tegra2_cpu_clk_init(struct clk *c) -{ -} - -static int tegra2_cpu_clk_enable(struct clk *c) -{ - return 0; -} - -static void tegra2_cpu_clk_disable(struct clk *c) -{ - pr_debug("%s on clock %s\n", __func__, c->name); - - /* oops - don't disable the CPU clock! */ - BUG(); -} - -static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate) -{ - int ret; - /* - * Take an extra reference to the main pll so it doesn't turn - * off when we move the cpu off of it - */ - clk_enable(c->u.cpu.main); - - ret = clk_set_parent(c->parent, c->u.cpu.backup); - if (ret) { - pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name); - goto out; - } - - if (rate == clk_get_rate(c->u.cpu.backup)) - goto out; - - ret = clk_set_rate(c->u.cpu.main, rate); - if (ret) { - pr_err("Failed to change cpu pll to %lu\n", rate); - goto out; - } - - ret = clk_set_parent(c->parent, c->u.cpu.main); - if (ret) { - pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name); - goto out; - } - -out: - clk_disable(c->u.cpu.main); - return ret; -} - -static struct clk_ops tegra_cpu_ops = { - .init = tegra2_cpu_clk_init, - .enable = tegra2_cpu_clk_enable, - .disable = tegra2_cpu_clk_disable, - .set_rate = tegra2_cpu_clk_set_rate, -}; - -/* virtual cop clock functions. Used to acquire the fake 'cop' clock to - * reset the COP block (i.e. AVP) */ -static void tegra2_cop_clk_reset(struct clk *c, bool assert) -{ - unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; - - pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert"); - clk_writel(1 << 1, reg); -} - -static struct clk_ops tegra_cop_ops = { - .reset = tegra2_cop_clk_reset, + .recalculate_rate = tegra2_clk_recalculate_rate, }; /* bus clock functions */ @@ -461,6 +299,7 @@ static void tegra2_bus_clk_init(struct clk *c) c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON; c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1; c->mul = 1; + tegra2_clk_recalculate_rate(c); } static int tegra2_bus_clk_enable(struct clk *c) @@ -481,7 +320,7 @@ static void tegra2_bus_clk_disable(struct clk *c) static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate) { u32 val = clk_readl(c->reg); - unsigned long parent_rate = clk_get_rate(c->parent); + unsigned long parent_rate = c->parent->rate; int i; for (i = 1; i <= 4; i++) { if (rate == parent_rate / i) { @@ -501,98 +340,38 @@ static struct clk_ops tegra_bus_ops = { .enable = tegra2_bus_clk_enable, .disable = tegra2_bus_clk_disable, .set_rate = tegra2_bus_clk_set_rate, + .recalculate_rate = tegra2_clk_recalculate_rate, }; -/* Blink output functions */ - -static void tegra2_blink_clk_init(struct clk *c) -{ - u32 val; - - val = pmc_readl(PMC_CTRL); - c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; - c->mul = 1; - val = pmc_readl(c->reg); - - if (val & PMC_BLINK_TIMER_ENB) { - unsigned int on_off; - - on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & - PMC_BLINK_TIMER_DATA_ON_MASK; - val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; - val &= PMC_BLINK_TIMER_DATA_OFF_MASK; - on_off += val; - /* each tick in the blink timer is 4 32KHz clocks */ - c->div = on_off * 4; - } else { - c->div = 1; - } -} - -static int tegra2_blink_clk_enable(struct clk *c) -{ - u32 val; - - val = pmc_readl(PMC_DPD_PADS_ORIDE); - pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); - - val = pmc_readl(PMC_CTRL); - pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL); - - return 0; +/* PLL Functions */ +static unsigned long tegra2_pll_clk_recalculate_rate(struct clk *c) +{ + u64 rate; + rate = c->parent->rate; + rate *= c->n; + do_div(rate, c->m); + if (c->p == 2) + rate >>= 1; + c->rate = rate; + return c->rate; } -static void tegra2_blink_clk_disable(struct clk *c) +static int tegra2_pll_clk_wait_for_lock(struct clk *c) { - u32 val; - - val = pmc_readl(PMC_CTRL); - pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL); + ktime_t before; - val = pmc_readl(PMC_DPD_PADS_ORIDE); - pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); -} - -static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(c->parent); - if (rate >= parent_rate) { - c->div = 1; - pmc_writel(0, c->reg); - } else { - unsigned int on_off; - u32 val; - - on_off = DIV_ROUND_UP(parent_rate / 8, rate); - c->div = on_off * 8; - - val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) << - PMC_BLINK_TIMER_DATA_ON_SHIFT; - on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK; - on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT; - val |= on_off; - val |= PMC_BLINK_TIMER_ENB; - pmc_writel(val, c->reg); + before = ktime_get(); + while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) { + if (ktime_us_delta(ktime_get(), before) > 5000) { + pr_err("Timed out waiting for lock bit on pll %s", + c->name); + return -1; + } } return 0; } -static struct clk_ops tegra_blink_clk_ops = { - .init = &tegra2_blink_clk_init, - .enable = &tegra2_blink_clk_enable, - .disable = &tegra2_blink_clk_disable, - .set_rate = &tegra2_blink_clk_set_rate, -}; - -/* PLL Functions */ -static int tegra2_pll_clk_wait_for_lock(struct clk *c) -{ - udelay(c->u.pll.lock_delay); - - return 0; -} - static void tegra2_pll_clk_init(struct clk *c) { u32 val = clk_readl(c->reg + PLL_BASE); @@ -601,19 +380,24 @@ static void tegra2_pll_clk_init(struct clk *c) if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { pr_warning("Clock %s has unknown fixed frequency\n", c->name); - c->mul = 1; - c->div = 1; + c->n = 1; + c->m = 0; + c->p = 1; } else if (val & PLL_BASE_BYPASS) { - c->mul = 1; - c->div = 1; + c->n = 1; + c->m = 1; + c->p = 1; } else { - c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; - c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; - if (c->flags & PLLU) - c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; - else - c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1; + c->n = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; + c->m = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; + c->p = (val & PLL_BASE_DIVP_MASK) ? 2 : 1; } + + val = clk_readl(c->reg + PLL_MISC(c)); + if (c->flags & PLL_HAS_CPCON) + c->cpcon = (val & PLL_MISC_CPCON_MASK) >> PLL_MISC_CPCON_SHIFT; + + tegra2_pll_clk_recalculate_rate(c); } static int tegra2_pll_clk_enable(struct clk *c) @@ -626,6 +410,10 @@ static int tegra2_pll_clk_enable(struct clk *c) val |= PLL_BASE_ENABLE; clk_writel(val, c->reg + PLL_BASE); + val = clk_readl(c->reg + PLL_MISC(c)); + val |= PLL_MISC_LOCK_ENABLE; + clk_writel(val, c->reg + PLL_MISC(c)); + tegra2_pll_clk_wait_for_lock(c); return 0; @@ -645,43 +433,41 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) { u32 val; unsigned long input_rate; - const struct clk_pll_freq_table *sel; + const struct clk_pll_table *sel; pr_debug("%s: %s %lu\n", __func__, c->name, rate); + BUG_ON(c->refcnt != 0); - input_rate = clk_get_rate(c->parent); - for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { + input_rate = c->parent->rate; + for (sel = c->pll_table; sel->input_rate != 0; sel++) { if (sel->input_rate == input_rate && sel->output_rate == rate) { - c->mul = sel->n; - c->div = sel->m * sel->p; + c->n = sel->n; + c->m = sel->m; + c->p = sel->p; + c->cpcon = sel->cpcon; val = clk_readl(c->reg + PLL_BASE); if (c->flags & PLL_FIXED) val |= PLL_BASE_OVERRIDE; val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK | PLL_BASE_DIVM_MASK); - val |= (sel->m << PLL_BASE_DIVM_SHIFT) | - (sel->n << PLL_BASE_DIVN_SHIFT); - BUG_ON(sel->p < 1 || sel->p > 2); - if (c->flags & PLLU) { - if (sel->p == 1) - val |= PLLU_BASE_POST_DIV; - } else { - if (sel->p == 2) - val |= 1 << PLL_BASE_DIVP_SHIFT; - } + val |= (c->m << PLL_BASE_DIVM_SHIFT) | + (c->n << PLL_BASE_DIVN_SHIFT); + BUG_ON(c->p > 2); + if (c->p == 2) + val |= 1 << PLL_BASE_DIVP_SHIFT; clk_writel(val, c->reg + PLL_BASE); if (c->flags & PLL_HAS_CPCON) { - val = clk_readl(c->reg + PLL_MISC(c)); - val &= ~PLL_MISC_CPCON_MASK; - val |= sel->cpcon << PLL_MISC_CPCON_SHIFT; + val = c->cpcon << PLL_MISC_CPCON_SHIFT; + val |= PLL_MISC_LOCK_ENABLE; clk_writel(val, c->reg + PLL_MISC(c)); } if (c->state == ON) tegra2_pll_clk_enable(c); + c->rate = rate; return 0; } } @@ -693,21 +479,7 @@ static struct clk_ops tegra_pll_ops = { .enable = tegra2_pll_clk_enable, .disable = tegra2_pll_clk_disable, .set_rate = tegra2_pll_clk_set_rate, -}; - -static void tegra2_pllx_clk_init(struct clk *c) -{ - tegra2_pll_clk_init(c); - - if (tegra_sku_id() == 7) - c->max_rate = 750000000; -} - -static struct clk_ops tegra_pllx_ops = { - .init = tegra2_pllx_clk_init, - .enable = tegra2_pll_clk_enable, - .disable = tegra2_pll_clk_disable, - .set_rate = tegra2_pll_clk_set_rate, + .recalculate_rate = tegra2_pll_clk_recalculate_rate, }; /* Clock divider ops */ @@ -731,6 +503,8 @@ static void tegra2_pll_div_clk_init(struct clk *c) c->div = 1; c->mul = 1; } + + tegra2_clk_recalculate_rate(c); } static int tegra2_pll_div_clk_enable(struct clk *c) @@ -789,11 +563,9 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate) u32 val; u32 new_val; int divider_u71; - unsigned long parent_rate = clk_get_rate(c->parent); - pr_debug("%s: %s %lu\n", __func__, c->name, rate); if (c->flags & DIV_U71) { - divider_u71 = clk_div71_get_divider(parent_rate, rate); + divider_u71 = clk_div71_get_divider(c->parent, rate); if (divider_u71 >= 0) { val = clk_readl(c->reg); new_val = val >> c->reg_shift; @@ -808,38 +580,25 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate) clk_writel(val, c->reg); c->div = divider_u71 + 2; c->mul = 2; + tegra2_clk_recalculate_rate(c); return 0; } } else if (c->flags & DIV_2) { - if (parent_rate == rate * 2) + if (c->parent->rate == rate * 2) { + c->rate = rate; return 0; + } } return -EINVAL; } -static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate) -{ - int divider; - unsigned long parent_rate = clk_get_rate(c->parent); - pr_debug("%s: %s %lu\n", __func__, c->name, rate); - - if (c->flags & DIV_U71) { - divider = clk_div71_get_divider(parent_rate, rate); - if (divider < 0) - return divider; - return DIV_ROUND_UP(parent_rate * 2, divider + 2); - } else if (c->flags & DIV_2) { - return DIV_ROUND_UP(parent_rate, 2); - } - return -EINVAL; -} static struct clk_ops tegra_pll_div_ops = { .init = tegra2_pll_div_clk_init, .enable = tegra2_pll_div_clk_enable, .disable = tegra2_pll_div_clk_disable, .set_rate = tegra2_pll_div_clk_set_rate, - .round_rate = tegra2_pll_div_clk_round_rate, + .recalculate_rate = tegra2_clk_recalculate_rate, }; /* Periph clk ops */ @@ -862,13 +621,9 @@ static void tegra2_periph_clk_init(struct clk *c) } if (c->flags & DIV_U71) { - u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; + u32 divu71 = val & PERIPH_CLK_SOURCE_DIV_MASK; c->div = divu71 + 2; c->mul = 2; - } else if (c->flags & DIV_U16) { - u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; - c->div = divu16 + 1; - c->mul = 1; } else { c->div = 1; c->mul = 1; @@ -882,6 +637,7 @@ static void tegra2_periph_clk_init(struct clk *c) if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_ENB_BIT(c)) c->state = OFF; + tegra2_clk_recalculate_rate(c); } static int tegra2_periph_clk_enable(struct clk *c) @@ -889,10 +645,6 @@ static int tegra2_periph_clk_enable(struct clk *c) u32 val; pr_debug("%s on clock %s\n", __func__, c->name); - tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; - if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) - return 0; - clk_writel(PERIPH_CLK_TO_ENB_BIT(c), CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET)) @@ -912,25 +664,27 @@ static void tegra2_periph_clk_disable(struct clk *c) { pr_debug("%s on clock %s\n", __func__, c->name); - if (c->refcnt) - tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; + clk_writel(PERIPH_CLK_TO_ENB_BIT(c), + CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); +} - if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) +void tegra2_periph_reset_deassert(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + if (!(c->flags & PERIPH_NO_RESET)) clk_writel(PERIPH_CLK_TO_ENB_BIT(c), - CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); + RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); } -static void tegra2_periph_clk_reset(struct clk *c, bool assert) +void tegra2_periph_reset_assert(struct clk *c) { - unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; - - pr_debug("%s %s on clock %s\n", __func__, - assert ? "assert" : "deassert", c->name); + pr_debug("%s on clock %s\n", __func__, c->name); if (!(c->flags & PERIPH_NO_RESET)) clk_writel(PERIPH_CLK_TO_ENB_BIT(c), - base + PERIPH_CLK_TO_ENB_SET_REG(c)); + RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); } + static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) { u32 val; @@ -938,19 +692,12 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) pr_debug("%s: %s %s\n", __func__, c->name, p->name); for (sel = c->inputs; sel->input != NULL; sel++) { if (sel->input == p) { + clk_reparent(c, p); val = clk_readl(c->reg); val &= ~PERIPH_CLK_SOURCE_MASK; val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT; - - if (c->refcnt) - clk_enable(p); - clk_writel(val, c->reg); - - if (c->refcnt && c->parent) - clk_disable(c->parent); - - clk_reparent(c, p); + c->rate = c->parent->rate; return 0; } } @@ -961,57 +708,20 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate) { u32 val; - int divider; - unsigned long parent_rate = clk_get_rate(c->parent); - + int divider_u71; + pr_debug("%s: %lu\n", __func__, rate); if (c->flags & DIV_U71) { - divider = clk_div71_get_divider(parent_rate, rate); - if (divider >= 0) { + divider_u71 = clk_div71_get_divider(c->parent, rate); + if (divider_u71 >= 0) { val = clk_readl(c->reg); - val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; - val |= divider; + val &= ~PERIPH_CLK_SOURCE_DIV_MASK; + val |= divider_u71; clk_writel(val, c->reg); - c->div = divider + 2; + c->div = divider_u71 + 2; c->mul = 2; + tegra2_clk_recalculate_rate(c); return 0; } - } else if (c->flags & DIV_U16) { - divider = clk_div16_get_divider(parent_rate, rate); - if (divider >= 0) { - val = clk_readl(c->reg); - val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK; - val |= divider; - clk_writel(val, c->reg); - c->div = divider + 1; - c->mul = 1; - return 0; - } - } else if (parent_rate <= rate) { - c->div = 1; - c->mul = 1; - return 0; - } - return -EINVAL; -} - -static long tegra2_periph_clk_round_rate(struct clk *c, - unsigned long rate) -{ - int divider; - unsigned long parent_rate = clk_get_rate(c->parent); - pr_debug("%s: %s %lu\n", __func__, c->name, rate); - - if (c->flags & DIV_U71) { - divider = clk_div71_get_divider(parent_rate, rate); - if (divider < 0) - return divider; - - return DIV_ROUND_UP(parent_rate * 2, divider + 2); - } else if (c->flags & DIV_U16) { - divider = clk_div16_get_divider(parent_rate, rate); - if (divider < 0) - return divider; - return DIV_ROUND_UP(parent_rate, divider + 1); } return -EINVAL; } @@ -1022,69 +732,7 @@ static struct clk_ops tegra_periph_clk_ops = { .disable = &tegra2_periph_clk_disable, .set_parent = &tegra2_periph_clk_set_parent, .set_rate = &tegra2_periph_clk_set_rate, - .round_rate = &tegra2_periph_clk_round_rate, - .reset = &tegra2_periph_clk_reset, -}; - -/* The SDMMC controllers have extra bits in the clock source register that - * adjust the delay between the clock and data to compenstate for delays - * on the PCB. */ -void tegra2_sdmmc_tap_delay(struct clk *c, int delay) { - u32 reg; - - delay = clamp(delay, 0, 15); - reg = clk_readl(c->reg); - reg &= ~SDMMC_CLK_INT_FB_DLY_MASK; - reg |= SDMMC_CLK_INT_FB_SEL; - reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT; - clk_writel(reg, c->reg); -} - -/* External memory controller clock ops */ -static void tegra2_emc_clk_init(struct clk *c) -{ - tegra2_periph_clk_init(c); - c->max_rate = clk_get_rate_locked(c); -} - -static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate) -{ - long new_rate = rate; - - new_rate = tegra_emc_round_rate(new_rate); - if (new_rate < 0) - return c->max_rate; - - BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate)); - - return new_rate; -} - -static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate) -{ - int ret; - /* The Tegra2 memory controller has an interlock with the clock - * block that allows memory shadowed registers to be updated, - * and then transfer them to the main registers at the same - * time as the clock update without glitches. */ - ret = tegra_emc_set_rate(rate); - if (ret < 0) - return ret; - - ret = tegra2_periph_clk_set_rate(c, rate); - udelay(1); - - return ret; -} - -static struct clk_ops tegra_emc_clk_ops = { - .init = &tegra2_emc_clk_init, - .enable = &tegra2_periph_clk_enable, - .disable = &tegra2_periph_clk_disable, - .set_parent = &tegra2_periph_clk_set_parent, - .set_rate = &tegra2_emc_clk_set_rate, - .round_rate = &tegra2_emc_clk_round_rate, - .reset = &tegra2_periph_clk_reset, + .recalculate_rate = &tegra2_clk_recalculate_rate, }; /* Clock doubler ops */ @@ -1096,191 +744,24 @@ static void tegra2_clk_double_init(struct clk *c) if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_ENB_BIT(c))) c->state = OFF; + tegra2_clk_recalculate_rate(c); }; -static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate) -{ - if (rate != 2 * clk_get_rate(c->parent)) - return -EINVAL; - c->mul = 2; - c->div = 1; - return 0; -} - static struct clk_ops tegra_clk_double_ops = { .init = &tegra2_clk_double_init, .enable = &tegra2_periph_clk_enable, .disable = &tegra2_periph_clk_disable, - .set_rate = &tegra2_clk_double_set_rate, -}; - -/* Audio sync clock ops */ -static void tegra2_audio_sync_clk_init(struct clk *c) -{ - int source; - const struct clk_mux_sel *sel; - u32 val = clk_readl(c->reg); - c->state = (val & (1<<4)) ? OFF : ON; - source = val & 0xf; - for (sel = c->inputs; sel->input != NULL; sel++) - if (sel->value == source) - break; - BUG_ON(sel->input == NULL); - c->parent = sel->input; -} - -static int tegra2_audio_sync_clk_enable(struct clk *c) -{ - clk_writel(0, c->reg); - return 0; -} - -static void tegra2_audio_sync_clk_disable(struct clk *c) -{ - clk_writel(1, c->reg); -} - -static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p) -{ - u32 val; - const struct clk_mux_sel *sel; - for (sel = c->inputs; sel->input != NULL; sel++) { - if (sel->input == p) { - val = clk_readl(c->reg); - val &= ~0xf; - val |= sel->value; - - if (c->refcnt) - clk_enable(p); - - clk_writel(val, c->reg); - - if (c->refcnt && c->parent) - clk_disable(c->parent); - - clk_reparent(c, p); - return 0; - } - } - - return -EINVAL; -} - -static struct clk_ops tegra_audio_sync_clk_ops = { - .init = tegra2_audio_sync_clk_init, - .enable = tegra2_audio_sync_clk_enable, - .disable = tegra2_audio_sync_clk_disable, - .set_parent = tegra2_audio_sync_clk_set_parent, -}; - -/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */ - -static void tegra2_cdev_clk_init(struct clk *c) -{ - /* We could un-tristate the cdev1 or cdev2 pingroup here; this is - * currently done in the pinmux code. */ - c->state = ON; - if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & - PERIPH_CLK_TO_ENB_BIT(c))) - c->state = OFF; -} - -static int tegra2_cdev_clk_enable(struct clk *c) -{ - clk_writel(PERIPH_CLK_TO_ENB_BIT(c), - CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); - return 0; -} - -static void tegra2_cdev_clk_disable(struct clk *c) -{ - clk_writel(PERIPH_CLK_TO_ENB_BIT(c), - CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); -} - -static struct clk_ops tegra_cdev_clk_ops = { - .init = &tegra2_cdev_clk_init, - .enable = &tegra2_cdev_clk_enable, - .disable = &tegra2_cdev_clk_disable, -}; - -/* shared bus ops */ -/* - * Some clocks may have multiple downstream users that need to request a - * higher clock rate. Shared bus clocks provide a unique shared_bus_user - * clock to each user. The frequency of the bus is set to the highest - * enabled shared_bus_user clock, with a minimum value set by the - * shared bus. - */ -static void tegra_clk_shared_bus_update(struct clk *bus) -{ - struct clk *c; - unsigned long rate = bus->min_rate; - - list_for_each_entry(c, &bus->shared_bus_list, - u.shared_bus_user.node) { - if (c->u.shared_bus_user.enabled) - rate = max(c->u.shared_bus_user.rate, rate); - } - - if (rate != clk_get_rate(bus)) - clk_set_rate(bus, rate); -}; - -static void tegra_clk_shared_bus_init(struct clk *c) -{ - c->max_rate = c->parent->max_rate; - c->u.shared_bus_user.rate = c->parent->max_rate; - c->state = OFF; - c->set = true; - - list_add_tail(&c->u.shared_bus_user.node, - &c->parent->shared_bus_list); -} - -static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate) -{ - c->u.shared_bus_user.rate = rate; - tegra_clk_shared_bus_update(c->parent); - return 0; -} - -static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate) -{ - return clk_round_rate(c->parent, rate); -} - -static int tegra_clk_shared_bus_enable(struct clk *c) -{ - c->u.shared_bus_user.enabled = true; - tegra_clk_shared_bus_update(c->parent); - return 0; -} - -static void tegra_clk_shared_bus_disable(struct clk *c) -{ - c->u.shared_bus_user.enabled = false; - tegra_clk_shared_bus_update(c->parent); -} - -static struct clk_ops tegra_clk_shared_bus_ops = { - .init = tegra_clk_shared_bus_init, - .enable = tegra_clk_shared_bus_enable, - .disable = tegra_clk_shared_bus_disable, - .set_rate = tegra_clk_shared_bus_set_rate, - .round_rate = tegra_clk_shared_bus_round_rate, + .recalculate_rate = &tegra2_clk_recalculate_rate, }; - /* Clock definitions */ static struct clk tegra_clk_32k = { .name = "clk_32k", - .rate = 32768, + .rate = 32678, .ops = NULL, - .max_rate = 32768, }; -static struct clk_pll_freq_table tegra_pll_s_freq_table[] = { +static struct clk_pll_table tegra_pll_s_table[] = { {32768, 12000000, 366, 1, 1, 0}, {32768, 13000000, 397, 1, 1, 0}, {32768, 19200000, 586, 1, 1, 0}, @@ -1292,19 +773,15 @@ static struct clk tegra_pll_s = { .name = "pll_s", .flags = PLL_ALT_MISC_REG, .ops = &tegra_pll_ops, - .parent = &tegra_clk_32k, - .max_rate = 26000000, .reg = 0xf0, - .u.pll = { - .input_min = 32768, - .input_max = 32768, - .cf_min = 0, /* FIXME */ - .cf_max = 0, /* FIXME */ - .vco_min = 12000000, - .vco_max = 26000000, - .freq_table = tegra_pll_s_freq_table, - .lock_delay = 300, - }, + .input_min = 32768, + .input_max = 32768, + .parent = &tegra_clk_32k, + .cf_min = 0, /* FIXME */ + .cf_max = 0, /* FIXME */ + .vco_min = 12000000, + .vco_max = 26000000, + .pll_table = tegra_pll_s_table, }; static struct clk_mux_sel tegra_clk_m_sel[] = { @@ -1312,18 +789,17 @@ static struct clk_mux_sel tegra_clk_m_sel[] = { { .input = &tegra_pll_s, .value = 1}, { 0, 0}, }; - static struct clk tegra_clk_m = { .name = "clk_m", .flags = ENABLE_ON_INIT, .ops = &tegra_clk_m_ops, .inputs = tegra_clk_m_sel, .reg = 0x1fc, + .reg_mask = (1<<28), .reg_shift = 28, - .max_rate = 26000000, }; -static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { +static struct clk_pll_table tegra_pll_c_table[] = { { 0, 0, 0, 0, 0, 0 }, }; @@ -1332,18 +808,14 @@ static struct clk tegra_pll_c = { .flags = PLL_HAS_CPCON, .ops = &tegra_pll_ops, .reg = 0x80, + .input_min = 2000000, + .input_max = 31000000, .parent = &tegra_clk_m, - .max_rate = 600000000, - .u.pll = { - .input_min = 2000000, - .input_max = 31000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 20000000, - .vco_max = 1400000000, - .freq_table = tegra_pll_c_freq_table, - .lock_delay = 300, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_c_table, }; static struct clk tegra_pll_c_out1 = { @@ -1353,18 +825,9 @@ static struct clk tegra_pll_c_out1 = { .parent = &tegra_pll_c, .reg = 0x84, .reg_shift = 0, - .max_rate = 600000000, }; -static struct clk_pll_freq_table tegra_pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 1, 8}, - { 13000000, 666000000, 666, 13, 1, 8}, - { 19200000, 666000000, 555, 16, 1, 8}, - { 26000000, 666000000, 666, 26, 1, 8}, - { 12000000, 600000000, 600, 12, 1, 8}, - { 13000000, 600000000, 600, 13, 1, 8}, - { 19200000, 600000000, 375, 12, 1, 6}, - { 26000000, 600000000, 600, 26, 1, 8}, +static struct clk_pll_table tegra_pll_m_table[] = { { 0, 0, 0, 0, 0, 0 }, }; @@ -1373,18 +836,14 @@ static struct clk tegra_pll_m = { .flags = PLL_HAS_CPCON, .ops = &tegra_pll_ops, .reg = 0x90, + .input_min = 2000000, + .input_max = 31000000, .parent = &tegra_clk_m, - .max_rate = 800000000, - .u.pll = { - .input_min = 2000000, - .input_max = 31000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 20000000, - .vco_max = 1200000000, - .freq_table = tegra_pll_m_freq_table, - .lock_delay = 300, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .pll_table = tegra_pll_m_table, }; static struct clk tegra_pll_m_out1 = { @@ -1394,10 +853,9 @@ static struct clk tegra_pll_m_out1 = { .parent = &tegra_pll_m, .reg = 0x94, .reg_shift = 0, - .max_rate = 600000000, }; -static struct clk_pll_freq_table tegra_pll_p_freq_table[] = { +static struct clk_pll_table tegra_pll_p_table[] = { { 12000000, 216000000, 432, 12, 2, 8}, { 13000000, 216000000, 432, 13, 2, 8}, { 19200000, 216000000, 90, 4, 2, 1}, @@ -1414,18 +872,14 @@ static struct clk tegra_pll_p = { .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, .ops = &tegra_pll_ops, .reg = 0xa0, + .input_min = 2000000, + .input_max = 31000000, .parent = &tegra_clk_m, - .max_rate = 432000000, - .u.pll = { - .input_min = 2000000, - .input_max = 31000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 20000000, - .vco_max = 1400000000, - .freq_table = tegra_pll_p_freq_table, - .lock_delay = 300, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_p_table, }; static struct clk tegra_pll_p_out1 = { @@ -1435,7 +889,6 @@ static struct clk tegra_pll_p_out1 = { .parent = &tegra_pll_p, .reg = 0xa4, .reg_shift = 0, - .max_rate = 432000000, }; static struct clk tegra_pll_p_out2 = { @@ -1445,7 +898,6 @@ static struct clk tegra_pll_p_out2 = { .parent = &tegra_pll_p, .reg = 0xa4, .reg_shift = 16, - .max_rate = 432000000, }; static struct clk tegra_pll_p_out3 = { @@ -1455,7 +907,6 @@ static struct clk tegra_pll_p_out3 = { .parent = &tegra_pll_p, .reg = 0xa8, .reg_shift = 0, - .max_rate = 432000000, }; static struct clk tegra_pll_p_out4 = { @@ -1465,13 +916,13 @@ static struct clk tegra_pll_p_out4 = { .parent = &tegra_pll_p, .reg = 0xa8, .reg_shift = 16, - .max_rate = 432000000, }; -static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { +static struct clk_pll_table tegra_pll_a_table[] = { { 28800000, 56448000, 49, 25, 1, 1}, { 28800000, 73728000, 64, 25, 1, 1}, - { 28800000, 24000000, 5, 6, 1, 1}, + { 28800000, 11289600, 49, 25, 1, 1}, + { 28800000, 12288000, 64, 25, 1, 1}, { 0, 0, 0, 0, 0, 0 }, }; @@ -1480,18 +931,14 @@ static struct clk tegra_pll_a = { .flags = PLL_HAS_CPCON, .ops = &tegra_pll_ops, .reg = 0xb0, + .input_min = 2000000, + .input_max = 31000000, .parent = &tegra_pll_p_out1, - .max_rate = 73728000, - .u.pll = { - .input_min = 2000000, - .input_max = 31000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 20000000, - .vco_max = 1400000000, - .freq_table = tegra_pll_a_freq_table, - .lock_delay = 300, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_a_table, }; static struct clk tegra_pll_a_out0 = { @@ -1501,25 +948,13 @@ static struct clk tegra_pll_a_out0 = { .parent = &tegra_pll_a, .reg = 0xb4, .reg_shift = 0, - .max_rate = 73728000, }; -static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 1, 4}, - { 13000000, 216000000, 216, 13, 1, 4}, - { 19200000, 216000000, 135, 12, 1, 3}, - { 26000000, 216000000, 216, 26, 1, 4}, - - { 12000000, 594000000, 594, 12, 1, 8}, - { 13000000, 594000000, 594, 13, 1, 8}, - { 19200000, 594000000, 495, 16, 1, 8}, - { 26000000, 594000000, 594, 26, 1, 8}, - +static struct clk_pll_table tegra_pll_d_table[] = { { 12000000, 1000000000, 1000, 12, 1, 12}, { 13000000, 1000000000, 1000, 13, 1, 12}, { 19200000, 1000000000, 625, 12, 1, 8}, { 26000000, 1000000000, 1000, 26, 1, 12}, - { 0, 0, 0, 0, 0, 0 }, }; @@ -1528,18 +963,14 @@ static struct clk tegra_pll_d = { .flags = PLL_HAS_CPCON | PLLD, .ops = &tegra_pll_ops, .reg = 0xd0, + .input_min = 2000000, + .input_max = 40000000, .parent = &tegra_clk_m, - .max_rate = 1000000000, - .u.pll = { - .input_min = 2000000, - .input_max = 40000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 40000000, - .vco_max = 1000000000, - .freq_table = tegra_pll_d_freq_table, - .lock_delay = 1000, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 40000000, + .vco_max = 1000000000, + .pll_table = tegra_pll_d_table, }; static struct clk tegra_pll_d_out0 = { @@ -1547,206 +978,79 @@ static struct clk tegra_pll_d_out0 = { .ops = &tegra_pll_div_ops, .flags = DIV_2 | PLLD, .parent = &tegra_pll_d, - .max_rate = 500000000, }; -static struct clk_pll_freq_table tegra_pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 2, 0}, - { 13000000, 480000000, 960, 13, 2, 0}, - { 19200000, 480000000, 200, 4, 2, 0}, - { 26000000, 480000000, 960, 26, 2, 0}, +static struct clk_pll_table tegra_pll_u_table[] = { + { 12000000, 480000000, 960, 12, 1, 0}, + { 13000000, 480000000, 960, 13, 1, 0}, + { 19200000, 480000000, 200, 4, 1, 0}, + { 26000000, 480000000, 960, 26, 1, 0}, { 0, 0, 0, 0, 0, 0 }, }; static struct clk tegra_pll_u = { .name = "pll_u", - .flags = PLLU, + .flags = 0, .ops = &tegra_pll_ops, .reg = 0xc0, + .input_min = 2000000, + .input_max = 40000000, .parent = &tegra_clk_m, - .max_rate = 480000000, - .u.pll = { - .input_min = 2000000, - .input_max = 40000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 480000000, - .vco_max = 960000000, - .freq_table = tegra_pll_u_freq_table, - .lock_delay = 1000, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .pll_table = tegra_pll_u_table, }; -static struct clk_pll_freq_table tegra_pll_x_freq_table[] = { - /* 1 GHz */ +static struct clk_pll_table tegra_pll_x_table[] = { { 12000000, 1000000000, 1000, 12, 1, 12}, { 13000000, 1000000000, 1000, 13, 1, 12}, { 19200000, 1000000000, 625, 12, 1, 8}, { 26000000, 1000000000, 1000, 26, 1, 12}, - - /* 912 MHz */ - { 12000000, 912000000, 912, 12, 1, 12}, - { 13000000, 912000000, 912, 13, 1, 12}, - { 19200000, 912000000, 760, 16, 1, 8}, - { 26000000, 912000000, 912, 26, 1, 12}, - - /* 816 MHz */ - { 12000000, 816000000, 816, 12, 1, 12}, - { 13000000, 816000000, 816, 13, 1, 12}, - { 19200000, 816000000, 680, 16, 1, 8}, - { 26000000, 816000000, 816, 26, 1, 12}, - - /* 760 MHz */ - { 12000000, 760000000, 760, 12, 1, 12}, - { 13000000, 760000000, 760, 13, 1, 12}, - { 19200000, 760000000, 950, 24, 1, 8}, - { 26000000, 760000000, 760, 26, 1, 12}, - - /* 608 MHz */ - { 12000000, 608000000, 608, 12, 1, 12}, - { 13000000, 608000000, 608, 13, 1, 12}, - { 19200000, 608000000, 380, 12, 1, 8}, - { 26000000, 608000000, 608, 26, 1, 12}, - - /* 456 MHz */ - { 12000000, 456000000, 456, 12, 1, 12}, - { 13000000, 456000000, 456, 13, 1, 12}, - { 19200000, 456000000, 380, 16, 1, 8}, - { 26000000, 456000000, 456, 26, 1, 12}, - - /* 312 MHz */ - { 12000000, 312000000, 312, 12, 1, 12}, - { 13000000, 312000000, 312, 13, 1, 12}, - { 19200000, 312000000, 260, 16, 1, 8}, - { 26000000, 312000000, 312, 26, 1, 12}, - + { 12000000, 750000000, 750, 12, 1, 12}, + { 13000000, 750000000, 750, 13, 1, 12}, + { 19200000, 750000000, 625, 16, 1, 8}, + { 26000000, 750000000, 750, 26, 1, 12}, { 0, 0, 0, 0, 0, 0 }, }; static struct clk tegra_pll_x = { .name = "pll_x", .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG, - .ops = &tegra_pllx_ops, + .ops = &tegra_pll_ops, .reg = 0xe0, + .input_min = 2000000, + .input_max = 31000000, .parent = &tegra_clk_m, - .max_rate = 1000000000, - .u.pll = { - .input_min = 2000000, - .input_max = 31000000, - .cf_min = 1000000, - .cf_max = 6000000, - .vco_min = 20000000, - .vco_max = 1200000000, - .freq_table = tegra_pll_x_freq_table, - .lock_delay = 300, - }, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .pll_table = tegra_pll_x_table, }; static struct clk tegra_clk_d = { .name = "clk_d", .flags = PERIPH_NO_RESET, .ops = &tegra_clk_double_ops, + .clk_num = 90, .reg = 0x34, .reg_shift = 12, .parent = &tegra_clk_m, - .max_rate = 52000000, - .u.periph = { - .clk_num = 90, - }, -}; - -/* dap_mclk1, belongs to the cdev1 pingroup. */ -static struct clk tegra_dev1_clk = { - .name = "clk_dev1", - .ops = &tegra_cdev_clk_ops, - .rate = 26000000, - .max_rate = 26000000, - .u.periph = { - .clk_num = 94, - }, -}; - -/* dap_mclk2, belongs to the cdev2 pingroup. */ -static struct clk tegra_dev2_clk = { - .name = "clk_dev2", - .ops = &tegra_cdev_clk_ops, - .rate = 26000000, - .max_rate = 26000000, - .u.periph = { - .clk_num = 93, - }, -}; - -/* initialized before peripheral clocks */ -static struct clk_mux_sel mux_audio_sync_clk[8+1]; -static const struct audio_sources { - const char *name; - int value; -} mux_audio_sync_clk_sources[] = { - { .name = "spdif_in", .value = 0 }, - { .name = "i2s1", .value = 1 }, - { .name = "i2s2", .value = 2 }, - { .name = "pll_a_out0", .value = 4 }, -#if 0 /* FIXME: not implemented */ - { .name = "ac97", .value = 3 }, - { .name = "ext_audio_clk2", .value = 5 }, - { .name = "ext_audio_clk1", .value = 6 }, - { .name = "ext_vimclk", .value = 7 }, -#endif - { 0, 0 } -}; - -static struct clk tegra_clk_audio = { - .name = "audio", - .inputs = mux_audio_sync_clk, - .reg = 0x38, - .max_rate = 73728000, - .ops = &tegra_audio_sync_clk_ops }; +/* FIXME: need tegra_audio static struct clk tegra_clk_audio_2x = { - .name = "audio_2x", + .name = "clk_d", .flags = PERIPH_NO_RESET, - .max_rate = 48000000, .ops = &tegra_clk_double_ops, + .clk_num = 89, .reg = 0x34, .reg_shift = 8, - .parent = &tegra_clk_audio, - .u.periph = { - .clk_num = 89, - }, -}; - -struct clk_lookup tegra_audio_clk_lookups[] = { - { .con_id = "audio", .clk = &tegra_clk_audio }, - { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x } -}; - -/* This is called after peripheral clocks are initialized, as the - * audio_sync clock depends on some of the peripheral clocks. - */ - -static void init_audio_sync_clock_mux(void) -{ - int i; - struct clk_mux_sel *sel = mux_audio_sync_clk; - const struct audio_sources *src = mux_audio_sync_clk_sources; - struct clk_lookup *lookup; - - for (i = 0; src->name; i++, sel++, src++) { - sel->input = tegra_get_clock_by_name(src->name); - if (!sel->input) - pr_err("%s: could not find clk %s\n", __func__, - src->name); - sel->value = src->value; - } - - lookup = tegra_audio_clk_lookups; - for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) { - clk_init(lookup->clk); - clkdev_add(lookup); - } + .parent = &tegra_audio, } +*/ static struct clk_mux_sel mux_cclk[] = { { .input = &tegra_clk_m, .value = 0}, @@ -1773,49 +1077,27 @@ static struct clk_mux_sel mux_sclk[] = { { 0, 0}, }; -static struct clk tegra_clk_cclk = { - .name = "cclk", +static struct clk tegra_clk_cpu = { + .name = "cpu", .inputs = mux_cclk, .reg = 0x20, .ops = &tegra_super_ops, - .max_rate = 1000000000, }; -static struct clk tegra_clk_sclk = { - .name = "sclk", +static struct clk tegra_clk_sys = { + .name = "sys", .inputs = mux_sclk, .reg = 0x28, .ops = &tegra_super_ops, - .max_rate = 240000000, - .min_rate = 120000000, -}; - -static struct clk tegra_clk_virtual_cpu = { - .name = "cpu", - .parent = &tegra_clk_cclk, - .ops = &tegra_cpu_ops, - .max_rate = 1000000000, - .u.cpu = { - .main = &tegra_pll_x, - .backup = &tegra_pll_p, - }, -}; - -static struct clk tegra_clk_cop = { - .name = "cop", - .parent = &tegra_clk_sclk, - .ops = &tegra_cop_ops, - .max_rate = 240000000, }; static struct clk tegra_clk_hclk = { .name = "hclk", .flags = DIV_BUS, - .parent = &tegra_clk_sclk, + .parent = &tegra_clk_sys, .reg = 0x30, .reg_shift = 4, .ops = &tegra_bus_ops, - .max_rate = 240000000, }; static struct clk tegra_clk_pclk = { @@ -1825,15 +1107,6 @@ static struct clk tegra_clk_pclk = { .reg = 0x30, .reg_shift = 0, .ops = &tegra_bus_ops, - .max_rate = 120000000, -}; - -static struct clk tegra_clk_blink = { - .name = "blink", - .parent = &tegra_clk_32k, - .reg = 0x40, - .ops = &tegra_blink_clk_ops, - .max_rate = 32768, }; static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = { @@ -1860,9 +1133,10 @@ static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = { { 0, 0}, }; -static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = { - {.input = &tegra_pll_a_out0, .value = 0}, - {.input = &tegra_clk_audio_2x, .value = 1}, +static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = { + {.input = &tegra_pll_a, .value = 0}, + /* FIXME: no mux defined for tegra_audio + {.input = &tegra_audio, .value = 1},*/ {.input = &tegra_pll_p, .value = 2}, {.input = &tegra_clk_m, .value = 3}, { 0, 0}, @@ -1879,7 +1153,8 @@ static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = { static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = { {.input = &tegra_pll_p, .value = 0}, {.input = &tegra_pll_c, .value = 1}, - {.input = &tegra_clk_audio, .value = 2}, + /* FIXME: no mux defined for tegra_audio + {.input = &tegra_audio, .value = 2},*/ {.input = &tegra_clk_m, .value = 3}, {.input = &tegra_clk_32k, .value = 4}, { 0, 0}, @@ -1912,19 +1187,7 @@ static struct clk_mux_sel mux_clk_32k[] = { { 0, 0}, }; -static struct clk tegra_clk_emc = { - .name = "emc", - .ops = &tegra_emc_clk_ops, - .reg = 0x19c, - .max_rate = 800000000, - .inputs = mux_pllm_pllc_pllp_clkm, - .flags = MUX | DIV_U71 | PERIPH_EMC_ENB, - .u.periph = { - .clk_num = 57, - }, -}; - -#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \ +#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _inputs, _flags) \ { \ .name = _name, \ .lookup = { \ @@ -1932,104 +1195,76 @@ static struct clk tegra_clk_emc = { .con_id = _con, \ }, \ .ops = &tegra_periph_clk_ops, \ + .clk_num = _clk_num, \ .reg = _reg, \ .inputs = _inputs, \ .flags = _flags, \ - .max_rate = _max, \ - .u.periph = { \ - .clk_num = _clk_num, \ - }, \ } -#define SHARED_CLK(_name, _dev, _con, _parent) \ - { \ - .name = _name, \ - .lookup = { \ - .dev_id = _dev, \ - .con_id = _con, \ - }, \ - .ops = &tegra_clk_shared_bus_ops, \ - .parent = _parent, \ - } - -struct clk tegra_list_clks[] = { - PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET), - PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0), - PERIPH_CLK("kfuse", "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0), - PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), - PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), - PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), - PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71), - PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71), - PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0), - PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0), - PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0), - PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */ +struct clk tegra_periph_clks[] = { + PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, mux_clk_32k, PERIPH_NO_RESET), + PERIPH_CLK("timer", "timer", NULL, 5, 0, mux_clk_m, 0), + PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + /* FIXME: spdif has 2 clocks but 1 enable */ + PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, mux_pllp_pllc_pllm, MUX | DIV_U71), + PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71), + PERIPH_CLK("spi", "spi", NULL, 43, 0x114, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("xio", "xio", NULL, 45, 0x120, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("ide", "ide", NULL, 25, 0x144, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + /* FIXME: vfir shares an enable with uartb */ + PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* FIXME: what is la? */ - PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), - PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ - PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16), - PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16), - PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16), - PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16), - PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */ - PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */ - PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ - PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ - PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ - PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */ - PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */ - PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET), - - SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sclk), - SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc), - SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc), - SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc), - SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc), - SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc), - SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc), - SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc), - SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc), - SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc), - SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc), + PERIPH_CLK("la", "la", NULL, 76, 0x1f8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("owr", "owr", NULL, 71, 0x1cc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, mux_pllp_out3, 0), + PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, mux_pllp_out3, 0), + PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, mux_pllp_out3, 0), + PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, mux_pllp_out3, 0), + PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("3d", "3d", NULL, 24, 0x158, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), + PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + /* FIXME: vi and vi_sensor share an enable */ + PERIPH_CLK("vi", "vi", NULL, 20, 0x148, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + /* FIXME: cve and tvo share an enable */ + PERIPH_CLK("cve", "cve", NULL, 49, 0x140, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, mux_clk_m, 0), + PERIPH_CLK("usb2", "usb.1", NULL, 58, 0, mux_clk_m, 0), + PERIPH_CLK("usb3", "usb.2", NULL, 59, 0, mux_clk_m, 0), + PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB), + PERIPH_CLK("dsi", "dsi", NULL, 48, 0, mux_plld, 0), }; #define CLK_DUPLICATE(_name, _dev, _con) \ @@ -2051,23 +1286,6 @@ struct clk_duplicate tegra_clk_duplicates[] = { CLK_DUPLICATE("uartc", "tegra_uart.2", NULL), CLK_DUPLICATE("uartd", "tegra_uart.3", NULL), CLK_DUPLICATE("uarte", "tegra_uart.4", NULL), - CLK_DUPLICATE("usbd", "utmip-pad", NULL), - CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), - CLK_DUPLICATE("usbd", "tegra-otg", NULL), - CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"), - CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"), - CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL), - CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL), - CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL), - CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL), - CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"), - CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"), - CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"), - CLK_DUPLICATE("epp", "tegra_grhost", "epp"), - CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"), - CLK_DUPLICATE("cop", "tegra-avp", "cop"), - CLK_DUPLICATE("vde", "tegra-aes", "vde"), - CLK_DUPLICATE("usbd", "cpcap-otg", NULL), }; #define CLK(dev, con, ck) \ @@ -2077,189 +1295,65 @@ struct clk_duplicate tegra_clk_duplicates[] = { .clk = ck, \ } -struct clk *tegra_ptr_clks[] = { - &tegra_clk_32k, - &tegra_pll_s, - &tegra_clk_m, - &tegra_pll_m, - &tegra_pll_m_out1, - &tegra_pll_c, - &tegra_pll_c_out1, - &tegra_pll_p, - &tegra_pll_p_out1, - &tegra_pll_p_out2, - &tegra_pll_p_out3, - &tegra_pll_p_out4, - &tegra_pll_a, - &tegra_pll_a_out0, - &tegra_pll_d, - &tegra_pll_d_out0, - &tegra_pll_u, - &tegra_pll_x, - &tegra_clk_cclk, - &tegra_clk_sclk, - &tegra_clk_hclk, - &tegra_clk_pclk, - &tegra_clk_d, - &tegra_dev1_clk, - &tegra_dev2_clk, - &tegra_clk_virtual_cpu, - &tegra_clk_blink, - &tegra_clk_cop, - &tegra_clk_emc, +struct clk_lookup tegra_clk_lookups[] = { + /* external root sources */ + CLK(NULL, "32k_clk", &tegra_clk_32k), + CLK(NULL, "pll_s", &tegra_pll_s), + CLK(NULL, "clk_m", &tegra_clk_m), + CLK(NULL, "pll_m", &tegra_pll_m), + CLK(NULL, "pll_m_out1", &tegra_pll_m_out1), + CLK(NULL, "pll_c", &tegra_pll_c), + CLK(NULL, "pll_c_out1", &tegra_pll_c_out1), + CLK(NULL, "pll_p", &tegra_pll_p), + CLK(NULL, "pll_p_out1", &tegra_pll_p_out1), + CLK(NULL, "pll_p_out2", &tegra_pll_p_out2), + CLK(NULL, "pll_p_out3", &tegra_pll_p_out3), + CLK(NULL, "pll_p_out4", &tegra_pll_p_out4), + CLK(NULL, "pll_a", &tegra_pll_a), + CLK(NULL, "pll_a_out0", &tegra_pll_a_out0), + CLK(NULL, "pll_d", &tegra_pll_d), + CLK(NULL, "pll_d_out0", &tegra_pll_d_out0), + CLK(NULL, "pll_u", &tegra_pll_u), + CLK(NULL, "pll_x", &tegra_pll_x), + CLK(NULL, "cpu", &tegra_clk_cpu), + CLK(NULL, "sys", &tegra_clk_sys), + CLK(NULL, "hclk", &tegra_clk_hclk), + CLK(NULL, "pclk", &tegra_clk_pclk), + CLK(NULL, "clk_d", &tegra_clk_d), }; -static void tegra2_init_one_clock(struct clk *c) -{ - clk_init(c); - INIT_LIST_HEAD(&c->shared_bus_list); - if (!c->lookup.dev_id && !c->lookup.con_id) - c->lookup.con_id = c->name; - c->lookup.clk = c; - clkdev_add(&c->lookup); -} - void __init tegra2_init_clocks(void) { int i; + struct clk_lookup *cl; struct clk *c; + struct clk_duplicate *cd; - for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++) - tegra2_init_one_clock(tegra_ptr_clks[i]); - - for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++) - tegra2_init_one_clock(&tegra_list_clks[i]); - - for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { - c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name); - if (!c) { - pr_err("%s: Unknown duplicate clock %s\n", __func__, - tegra_clk_duplicates[i].name); - continue; - } - - tegra_clk_duplicates[i].lookup.clk = c; - clkdev_add(&tegra_clk_duplicates[i].lookup); + for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) { + cl = &tegra_clk_lookups[i]; + clk_init(cl->clk); + clkdev_add(cl); } - init_audio_sync_clock_mux(); -} + for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) { + c = &tegra_periph_clks[i]; + cl = &c->lookup; + cl->clk = c; -#ifdef CONFIG_PM -static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM + - PERIPH_CLK_SOURCE_NUM + 22]; - -void tegra_clk_suspend(void) -{ - unsigned long off, i; - u32 *ctx = clk_rst_suspend; - - *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK; - *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE); - *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); - *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE); - *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a)); - *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE); - *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s)); - *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE); - *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d)); - *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE); - *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u)); - - *ctx++ = clk_readl(tegra_pll_m_out1.reg); - *ctx++ = clk_readl(tegra_pll_a_out0.reg); - *ctx++ = clk_readl(tegra_pll_c_out1.reg); - - *ctx++ = clk_readl(tegra_clk_cclk.reg); - *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER); - - *ctx++ = clk_readl(tegra_clk_sclk.reg); - *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER); - *ctx++ = clk_readl(tegra_clk_pclk.reg); - - *ctx++ = clk_readl(tegra_clk_audio.reg); - - for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC; - off += 4) { - if (off == PERIPH_CLK_SOURCE_EMC) - continue; - *ctx++ = clk_readl(off); + clk_init(cl->clk); + clkdev_add(cl); } - off = RST_DEVICES; - for (i = 0; i < RST_DEVICES_NUM; i++, off += 4) - *ctx++ = clk_readl(off); - - off = CLK_OUT_ENB; - for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4) - *ctx++ = clk_readl(off); - - *ctx++ = clk_readl(MISC_CLK_ENB); - *ctx++ = clk_readl(CLK_MASK_ARM); - - BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend)); -} - -void tegra_clk_resume(void) -{ - unsigned long off, i; - const u32 *ctx = clk_rst_suspend; - u32 val; - - val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK; - val |= *ctx++; - clk_writel(val, OSC_CTRL); - - clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE); - clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); - clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE); - clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a)); - clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE); - clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s)); - clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE); - clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d)); - clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE); - clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u)); - udelay(1000); - - clk_writel(*ctx++, tegra_pll_m_out1.reg); - clk_writel(*ctx++, tegra_pll_a_out0.reg); - clk_writel(*ctx++, tegra_pll_c_out1.reg); - - clk_writel(*ctx++, tegra_clk_cclk.reg); - clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER); - - clk_writel(*ctx++, tegra_clk_sclk.reg); - clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER); - clk_writel(*ctx++, tegra_clk_pclk.reg); - - clk_writel(*ctx++, tegra_clk_audio.reg); - - /* enable all clocks before configuring clock sources */ - clk_writel(0xbffffff9ul, CLK_OUT_ENB); - clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4); - clk_writel(0x77f01bfful, CLK_OUT_ENB + 8); - wmb(); - - for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC; - off += 4) { - if (off == PERIPH_CLK_SOURCE_EMC) - continue; - clk_writel(*ctx++, off); + for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { + cd = &tegra_clk_duplicates[i]; + c = tegra_get_clock_by_name(cd->name); + if (c) { + cl = &cd->lookup; + cl->clk = c; + clkdev_add(cl); + } else { + pr_err("%s: Unknown duplicate clock %s\n", __func__, + cd->name); + } } - wmb(); - - off = RST_DEVICES; - for (i = 0; i < RST_DEVICES_NUM; i++, off += 4) - clk_writel(*ctx++, off); - wmb(); - - off = CLK_OUT_ENB; - for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4) - clk_writel(*ctx++, off); - wmb(); - - clk_writel(*ctx++, MISC_CLK_ENB); - clk_writel(*ctx++, CLK_MASK_ARM); } -#endif diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c deleted file mode 100644 index 9b5397414e03..000000000000 --- a/arch/arm/mach-tegra/tegra2_dvfs.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * arch/arm/mach-tegra/tegra2_dvfs.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include -#include -#include - -#include "clock.h" -#include "dvfs.h" -#include "fuse.h" - -#ifdef CONFIG_TEGRA_CORE_DVFS -static bool tegra_dvfs_core_disabled; -#else -static bool tegra_dvfs_core_disabled = true; -#endif -#ifdef CONFIG_TEGRA_CPU_DVFS -static bool tegra_dvfs_cpu_disabled; -#else -static bool tegra_dvfs_cpu_disabled = true; -#endif - -static const int core_millivolts[MAX_DVFS_FREQS] = - {950, 1000, 1100, 1200, 1275}; -static const int cpu_millivolts[MAX_DVFS_FREQS] = - {750, 775, 800, 825, 875, 900, 925, 975, 1000, 1050, 1100}; - -#define KHZ 1000 -#define MHZ 1000000 - -static struct dvfs_rail tegra2_dvfs_rail_vdd_cpu = { - .reg_id = "vdd_cpu", - .max_millivolts = 1100, - .min_millivolts = 750, - .nominal_millivolts = 1100, -}; - -static struct dvfs_rail tegra2_dvfs_rail_vdd_core = { - .reg_id = "vdd_core", - .max_millivolts = 1275, - .min_millivolts = 950, - .nominal_millivolts = 1200, - .step = 150, /* step vdd_core by 150 mV to allow vdd_aon to follow */ -}; - -static struct dvfs_rail tegra2_dvfs_rail_vdd_aon = { - .reg_id = "vdd_aon", - .max_millivolts = 1275, - .min_millivolts = 950, - .nominal_millivolts = 1200, -#ifndef CONFIG_TEGRA_CORE_DVFS - .disabled = true, -#endif -}; - -/* vdd_core and vdd_aon must be 50 mV higher than vdd_cpu */ -static int tegra2_dvfs_rel_vdd_cpu_vdd_core(struct dvfs_rail *vdd_cpu, - struct dvfs_rail *vdd_core) -{ - if (vdd_cpu->new_millivolts > vdd_cpu->millivolts && - vdd_core->new_millivolts < vdd_cpu->new_millivolts + 50) - return vdd_cpu->new_millivolts + 50; - - if (vdd_core->new_millivolts < vdd_cpu->millivolts + 50) - return vdd_cpu->millivolts + 50; - - return vdd_core->new_millivolts; -} - -/* vdd_aon must be within 170 mV of vdd_core */ -static int tegra2_dvfs_rel_vdd_core_vdd_aon(struct dvfs_rail *vdd_core, - struct dvfs_rail *vdd_aon) -{ - BUG_ON(abs(vdd_aon->millivolts - vdd_core->millivolts) > - vdd_aon->step); - return vdd_core->millivolts; -} - -static struct dvfs_relationship tegra2_dvfs_relationships[] = { - { - /* vdd_core must be 50 mV higher than vdd_cpu */ - .from = &tegra2_dvfs_rail_vdd_cpu, - .to = &tegra2_dvfs_rail_vdd_core, - .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core, - }, - { - /* vdd_aon must be 50 mV higher than vdd_cpu */ - .from = &tegra2_dvfs_rail_vdd_cpu, - .to = &tegra2_dvfs_rail_vdd_aon, - .solve = tegra2_dvfs_rel_vdd_cpu_vdd_core, - }, - { - /* vdd_aon must be within 170 mV of vdd_core */ - .from = &tegra2_dvfs_rail_vdd_core, - .to = &tegra2_dvfs_rail_vdd_aon, - .solve = tegra2_dvfs_rel_vdd_core_vdd_aon, - }, -}; - -static struct dvfs_rail *tegra2_dvfs_rails[] = { - &tegra2_dvfs_rail_vdd_cpu, - &tegra2_dvfs_rail_vdd_core, - &tegra2_dvfs_rail_vdd_aon, -}; - -#define CPU_DVFS(_clk_name, _process_id, _mult, _freqs...) \ - { \ - .clk_name = _clk_name, \ - .cpu_process_id = _process_id, \ - .freqs = {_freqs}, \ - .freqs_mult = _mult, \ - .millivolts = cpu_millivolts, \ - .auto_dvfs = true, \ - .dvfs_rail = &tegra2_dvfs_rail_vdd_cpu, \ - } - -#define CORE_DVFS(_clk_name, _auto, _mult, _freqs...) \ - { \ - .clk_name = _clk_name, \ - .cpu_process_id = -1, \ - .freqs = {_freqs}, \ - .freqs_mult = _mult, \ - .millivolts = core_millivolts, \ - .auto_dvfs = _auto, \ - .dvfs_rail = &tegra2_dvfs_rail_vdd_core, \ - } - -static struct dvfs dvfs_init[] = { - /* Cpu voltages (mV): 750, 775, 800, 825, 875, 900, 925, 975, 1000, 1050, 1100 */ - CPU_DVFS("cpu", 0, MHZ, 314, 314, 314, 456, 456, 608, 608, 760, 817, 912, 1000), - CPU_DVFS("cpu", 1, MHZ, 314, 314, 314, 456, 456, 618, 618, 770, 827, 922, 1000), - CPU_DVFS("cpu", 2, MHZ, 494, 675, 675, 675, 817, 817, 922, 1000), - CPU_DVFS("cpu", 3, MHZ, 730, 760, 845, 845, 1000), - - /* Core voltages (mV): 950, 1000, 1100, 1200, 1275 */ - CORE_DVFS("emc", 1, KHZ, 57000, 333000, 333000, 666000, 666000), - -#if 0 - /* - * The sdhci core calls the clock ops with a spinlock held, which - * conflicts with the sleeping dvfs api. - * For now, boards must ensure that the core voltage does not drop - * below 1V, or that the sdmmc busses are set to 44 MHz or less. - */ - CORE_DVFS("sdmmc1", 1, KHZ, 44000, 52000, 52000, 52000, 52000), - CORE_DVFS("sdmmc2", 1, KHZ, 44000, 52000, 52000, 52000, 52000), - CORE_DVFS("sdmmc3", 1, KHZ, 44000, 52000, 52000, 52000, 52000), - CORE_DVFS("sdmmc4", 1, KHZ, 44000, 52000, 52000, 52000, 52000), -#endif - - CORE_DVFS("ndflash", 1, KHZ, 130000, 150000, 158000, 164000, 164000), - CORE_DVFS("nor", 1, KHZ, 0, 92000, 92000, 92000, 92000), - CORE_DVFS("ide", 1, KHZ, 0, 0, 100000, 100000, 100000), - CORE_DVFS("mipi", 1, KHZ, 0, 40000, 40000, 40000, 60000), - CORE_DVFS("usbd", 1, KHZ, 0, 0, 0, 480000, 480000), - CORE_DVFS("usb2", 1, KHZ, 0, 0, 0, 480000, 480000), - CORE_DVFS("usb3", 1, KHZ, 0, 0, 0, 480000, 480000), - CORE_DVFS("pcie", 1, KHZ, 0, 0, 0, 250000, 250000), - CORE_DVFS("dsi", 1, KHZ, 100000, 100000, 100000, 500000, 500000), - CORE_DVFS("tvo", 1, KHZ, 0, 0, 0, 250000, 250000), - - /* - * The clock rate for the display controllers that determines the - * necessary core voltage depends on a divider that is internal - * to the display block. Disable auto-dvfs on the display clocks, - * and let the display driver call tegra_dvfs_set_rate manually - */ - CORE_DVFS("disp1", 0, KHZ, 158000, 158000, 190000, 190000, 190000), - CORE_DVFS("disp2", 0, KHZ, 158000, 158000, 190000, 190000, 190000), - CORE_DVFS("hdmi", 0, KHZ, 0, 0, 0, 148500, 148500), - - /* - * These clocks technically depend on the core process id, - * but just use the worst case value for now - */ - CORE_DVFS("host1x", 1, KHZ, 104500, 133000, 166000, 166000, 166000), - CORE_DVFS("epp", 1, KHZ, 133000, 171000, 247000, 300000, 300000), - CORE_DVFS("2d", 1, KHZ, 133000, 171000, 247000, 300000, 300000), - CORE_DVFS("3d", 1, KHZ, 114000, 161500, 247000, 300000, 300000), - CORE_DVFS("mpe", 1, KHZ, 104500, 152000, 228000, 250000, 250000), - CORE_DVFS("vi", 1, KHZ, 85000, 100000, 150000, 150000, 150000), - CORE_DVFS("sclk", 1, KHZ, 95000, 133000, 190000, 250000, 250000), - CORE_DVFS("vde", 1, KHZ, 95000, 123500, 209000, 250000, 250000), - /* What is this? */ - CORE_DVFS("NVRM_DEVID_CLK_SRC", 1, MHZ, 480, 600, 800, 1067, 1067), -}; - -int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp) -{ - int ret; - - ret = param_set_bool(arg, kp); - if (ret) - return ret; - - if (tegra_dvfs_core_disabled) - tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core); - else - tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_core); - - return 0; -} - -int tegra_dvfs_disable_cpu_set(const char *arg, const struct kernel_param *kp) -{ - int ret; - - ret = param_set_bool(arg, kp); - if (ret) - return ret; - - if (tegra_dvfs_cpu_disabled) - tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu); - else - tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_cpu); - - return 0; -} - -int tegra_dvfs_disable_get(char *buffer, const struct kernel_param *kp) -{ - return param_get_bool(buffer, kp); -} - -static struct kernel_param_ops tegra_dvfs_disable_core_ops = { - .set = tegra_dvfs_disable_core_set, - .get = tegra_dvfs_disable_get, -}; - -static struct kernel_param_ops tegra_dvfs_disable_cpu_ops = { - .set = tegra_dvfs_disable_cpu_set, - .get = tegra_dvfs_disable_get, -}; - -module_param_cb(disable_core, &tegra_dvfs_disable_core_ops, - &tegra_dvfs_core_disabled, 0644); -module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops, - &tegra_dvfs_cpu_disabled, 0644); - -void __init tegra2_init_dvfs(void) -{ - int i; - struct clk *c; - struct dvfs *d; - int ret; - int cpu_process_id = tegra_cpu_process_id(); - - tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails)); - tegra_dvfs_add_relationships(tegra2_dvfs_relationships, - ARRAY_SIZE(tegra2_dvfs_relationships)); - /* - * VDD_CORE must always be at least 50 mV higher than VDD_CPU - * Fill out cpu_core_millivolts based on cpu_millivolts - */ - for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) { - d = &dvfs_init[i]; - - if (d->cpu_process_id != -1 && - d->cpu_process_id != cpu_process_id) - continue; - - c = tegra_get_clock_by_name(d->clk_name); - - if (!c) { - pr_debug("tegra_dvfs: no clock found for %s\n", - d->clk_name); - continue; - } - - ret = tegra_enable_dvfs_on_clk(c, d); - if (ret) - pr_err("tegra_dvfs: failed to enable dvfs on %s\n", - c->name); - } - - if (tegra_dvfs_core_disabled) - tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core); - - if (tegra_dvfs_cpu_disabled) - tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu); -} diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c deleted file mode 100644 index 47ba71672b86..000000000000 --- a/arch/arm/mach-tegra/tegra2_emc.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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 -#include -#include -#include -#include - -#include - -#include "tegra2_emc.h" - -#define TEGRA_MRR_DIVLD (1<<20) -#define TEGRA_EMC_STATUS 0x02b4 -#define TEGRA_EMC_MRR 0x00ec -static DEFINE_MUTEX(tegra_emc_mrr_lock); - -#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE -static bool emc_enable = true; -#else -static bool emc_enable; -#endif -module_param(emc_enable, bool, 0644); - -static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE); -static const struct tegra_emc_table *tegra_emc_table; -static int tegra_emc_table_size; - -static inline void emc_writel(u32 val, unsigned long addr) -{ - writel(val, emc + addr); -} - -static inline u32 emc_readl(unsigned long addr) -{ - return readl(emc + addr); -} - -/* read LPDDR2 memory modes */ -static int tegra_emc_read_mrr(unsigned long addr) -{ - u32 value; - int count = 100; - - mutex_lock(&tegra_emc_mrr_lock); - do { - emc_readl(TEGRA_EMC_MRR); - } while (--count && (emc_readl(TEGRA_EMC_STATUS) & TEGRA_MRR_DIVLD)); - if (count == 0) { - pr_err("%s: Failed to read memory type\n", __func__); - BUG(); - } - value = (1 << 30) | (addr << 16); - emc_writel(value, TEGRA_EMC_MRR); - - count = 100; - while (--count && !(emc_readl(TEGRA_EMC_STATUS) & TEGRA_MRR_DIVLD)); - if (count == 0) { - pr_err("%s: Failed to read memory type\n", __func__); - BUG(); - } - value = emc_readl(TEGRA_EMC_MRR) & 0xFFFF; - mutex_unlock(&tegra_emc_mrr_lock); - - return value; -} - -static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { - 0x2c, /* RC */ - 0x30, /* RFC */ - 0x34, /* RAS */ - 0x38, /* RP */ - 0x3c, /* R2W */ - 0x40, /* W2R */ - 0x44, /* R2P */ - 0x48, /* W2P */ - 0x4c, /* RD_RCD */ - 0x50, /* WR_RCD */ - 0x54, /* RRD */ - 0x58, /* REXT */ - 0x5c, /* WDV */ - 0x60, /* QUSE */ - 0x64, /* QRST */ - 0x68, /* QSAFE */ - 0x6c, /* RDV */ - 0x70, /* REFRESH */ - 0x74, /* BURST_REFRESH_NUM */ - 0x78, /* PDEX2WR */ - 0x7c, /* PDEX2RD */ - 0x80, /* PCHG2PDEN */ - 0x84, /* ACT2PDEN */ - 0x88, /* AR2PDEN */ - 0x8c, /* RW2PDEN */ - 0x90, /* TXSR */ - 0x94, /* TCKE */ - 0x98, /* TFAW */ - 0x9c, /* TRPAB */ - 0xa0, /* TCLKSTABLE */ - 0xa4, /* TCLKSTOP */ - 0xa8, /* TREFBW */ - 0xac, /* QUSE_EXTRA */ - 0x114, /* FBIO_CFG6 */ - 0xb0, /* ODT_WRITE */ - 0xb4, /* ODT_READ */ - 0x104, /* FBIO_CFG5 */ - 0x2bc, /* CFG_DIG_DLL */ - 0x2c0, /* DLL_XFORM_DQS */ - 0x2c4, /* DLL_XFORM_QUSE */ - 0x2e0, /* ZCAL_REF_CNT */ - 0x2e4, /* ZCAL_WAIT_CNT */ - 0x2a8, /* AUTO_CAL_INTERVAL */ - 0x2d0, /* CFG_CLKTRIM_0 */ - 0x2d4, /* CFG_CLKTRIM_1 */ - 0x2d8, /* CFG_CLKTRIM_2 */ -}; - -/* Select the closest EMC rate that is higher than the requested rate */ -long tegra_emc_round_rate(unsigned long rate) -{ - int i; - int best = -1; - unsigned long distance = ULONG_MAX; - - if (!tegra_emc_table) - return -EINVAL; - - if (!emc_enable) - return -EINVAL; - - pr_debug("%s: %lu\n", __func__, rate); - - /* The EMC clock rate is twice the bus rate, and the bus rate is - * measured in kHz */ - rate = rate / 2 / 1000; - - for (i = 0; i < tegra_emc_table_size; i++) { - if (tegra_emc_table[i].rate >= rate && - (tegra_emc_table[i].rate - rate) < distance) { - distance = tegra_emc_table[i].rate - rate; - best = i; - } - } - - if (best < 0) - return -EINVAL; - - pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate); - - return tegra_emc_table[best].rate * 2 * 1000; -} - -/* The EMC registers have shadow registers. When the EMC clock is updated - * in the clock controller, the shadow registers are copied to the active - * registers, allowing glitchless memory bus frequency changes. - * This function updates the shadow registers for a new clock frequency, - * and relies on the clock lock on the emc clock to avoid races between - * multiple frequency changes */ -int tegra_emc_set_rate(unsigned long rate) -{ - int i; - int j; - - if (!tegra_emc_table) - return -EINVAL; - - /* The EMC clock rate is twice the bus rate, and the bus rate is - * measured in kHz */ - rate = rate / 2 / 1000; - - for (i = 0; i < tegra_emc_table_size; i++) - if (tegra_emc_table[i].rate == rate) - break; - - if (i >= tegra_emc_table_size) - return -EINVAL; - - pr_debug("%s: setting to %lu\n", __func__, rate); - - for (j = 0; j < TEGRA_EMC_NUM_REGS; j++) - emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]); - - emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]); - - return 0; -} - -void tegra_init_emc(const struct tegra_emc_chip *chips, int chips_size) -{ - int i; - int vid; - int rev_id1; - int rev_id2; - int pid; - int chip_matched = -1; - - vid = tegra_emc_read_mrr(5); - rev_id1 = tegra_emc_read_mrr(6); - rev_id2 = tegra_emc_read_mrr(7); - pid = tegra_emc_read_mrr(8); - - for (i = 0; i < chips_size; i++) { - if (chips[i].mem_manufacturer_id >= 0) { - if (chips[i].mem_manufacturer_id != vid) - continue; - } - if (chips[i].mem_revision_id1 >= 0) { - if (chips[i].mem_revision_id1 != rev_id1) - continue; - } - if (chips[i].mem_revision_id2 >= 0) { - if (chips[i].mem_revision_id2 != rev_id2) - continue; - } - if (chips[i].mem_pid >= 0) { - if (chips[i].mem_pid != pid) - continue; - } - - chip_matched = i; - break; - } - - if (chip_matched >= 0) { - pr_info("%s: %s memory found\n", __func__, - chips[chip_matched].description); - tegra_emc_table = chips[chip_matched].table; - tegra_emc_table_size = chips[chip_matched].table_size; - } else { - pr_err("%s: Memory not recognized, memory scaling disabled\n", - __func__); - pr_info("%s: Memory vid = 0x%04x", __func__, vid); - pr_info("%s: Memory rev_id1 = 0x%04x", __func__, rev_id1); - pr_info("%s: Memory rev_id2 = 0x%04x", __func__, rev_id2); - pr_info("%s: Memory pid = 0x%04x", __func__, pid); - } -} diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h deleted file mode 100644 index 4f060f7355d6..000000000000 --- a/arch/arm/mach-tegra/tegra2_emc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross - * - * 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. - * - */ - -#define TEGRA_EMC_NUM_REGS 46 - -struct tegra_emc_table { - unsigned long rate; - u32 regs[TEGRA_EMC_NUM_REGS]; -}; - -struct tegra_emc_chip { - const char *description; - int mem_manufacturer_id; /* LPDDR2 MR5 or -1 to ignore */ - int mem_revision_id1; /* LPDDR2 MR6 or -1 to ignore */ - int mem_revision_id2; /* LPDDR2 MR7 or -1 to ignore */ - int mem_pid; /* LPDDR2 MR8 or -1 to ignore */ - - const struct tegra_emc_table *table; - int table_size; -}; - -int tegra_emc_set_rate(unsigned long rate); -long tegra_emc_round_rate(unsigned long rate); -void tegra_init_emc(const struct tegra_emc_chip *chips, int chips_size); diff --git a/arch/arm/mach-tegra/tegra2_fuse.c b/arch/arm/mach-tegra/tegra2_fuse.c deleted file mode 100644 index 47342911b63e..000000000000 --- a/arch/arm/mach-tegra/tegra2_fuse.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * arch/arm/mach-tegra/tegra2_fuse.c - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * Fuses are one time programmable bits on the chip which are used by - * the chip manufacturer and device manufacturers to store chip/device - * configurations. The fuse bits are encapsulated in a 32 x 64 array. - * If a fuse bit is programmed to 1, it cannot be reverted to 0. Either - * another fuse bit has to be used for the same purpose or a new chip - * needs to be used. - * - * Each and every fuse word has its own shadow word which resides adjacent to - * a particular fuse word. e.g. Fuse words 0-1 form a fuse-shadow pair. - * So in theory we have only 32 fuse words to work with. - * The shadow fuse word is a mirror of the actual fuse word at all times - * and this is maintained while programming a particular fuse. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "fuse.h" - -#define NFUSES 64 -#define STATE_IDLE (0x4 << 16) - -/* since fuse burning is irreversible, use this for testing */ -#define ENABLE_FUSE_BURNING 1 - -/* fuse registers */ -#define FUSE_CTRL 0x000 -#define FUSE_REG_ADDR 0x004 -#define FUSE_REG_READ 0x008 -#define FUSE_REG_WRITE 0x00C -#define FUSE_TIME_PGM 0x01C -#define FUSE_PRIV2INTFC 0x020 -#define FUSE_DIS_PGM 0x02C -#define FUSE_PWR_GOOD_SW 0x034 - -#define BOOT_DEVICE_INFO_EMMC 17 -#define USE_FUSE_TO_SELECT_BOOT_DEVICE 1 - -static u32 fuse_pgm_data[NFUSES / 2]; -static u32 fuse_pgm_mask[NFUSES / 2]; -static u32 tmp_fuse_pgm_data[NFUSES / 2]; -static u32 master_enable; - -DEFINE_MUTEX(fuse_lock); - -static struct fuse_data fuse_info; - -struct param_info { - u32 *addr; - int sz; - u32 start_off; - int start_bit; - int nbits; - int data_offset; -}; - -static struct param_info fuse_info_tbl[] = { - [DEVKEY] = { - .addr = &fuse_info.devkey, - .sz = sizeof(fuse_info.devkey), - .start_off = 0x12, - .start_bit = 8, - .nbits = 32, - .data_offset = 0, - }, - [JTAG_DIS] = { - .addr = &fuse_info.jtag_dis, - .sz = sizeof(fuse_info.jtag_dis), - .start_off = 0x0, - .start_bit = 24, - .nbits = 1, - .data_offset = 1, - }, - [ODM_PROD_MODE] = { - .addr = &fuse_info.odm_prod_mode, - .sz = sizeof(fuse_info.odm_prod_mode), - .start_off = 0x0, - .start_bit = 23, - .nbits = 1, - .data_offset = 2, - }, - [SEC_BOOT_DEV_CFG] = { - .addr = &fuse_info.bootdev_cfg, - .sz = sizeof(fuse_info.bootdev_cfg), - .start_off = 0x14, - .start_bit = 8, - .nbits = 16, - .data_offset = 3, - }, - [SEC_BOOT_DEV_SEL] = { - .addr = &fuse_info.bootdev_sel, - .sz = sizeof(fuse_info.bootdev_sel), - .start_off = 0x14, - .start_bit = 24, - .nbits = 3, - .data_offset = 4, - }, - [SBK] = { - .addr = fuse_info.sbk, - .sz = sizeof(fuse_info.sbk), - .start_off = 0x0A, - .start_bit = 8, - .nbits = 128, - .data_offset = 5, - }, - [SW_RSVD] = { - .addr = &fuse_info.sw_rsvd, - .sz = sizeof(fuse_info.sw_rsvd), - .start_off = 0x14, - .start_bit = 28, - .nbits = 4, - .data_offset = 9, - }, - [IGNORE_DEV_SEL_STRAPS] = { - .addr = &fuse_info.ignore_devsel_straps, - .sz = sizeof(fuse_info.ignore_devsel_straps), - .start_off = 0x14, - .start_bit = 27, - .nbits = 1, - .data_offset = 10, - }, - [ODM_RSVD] = { - .addr = fuse_info.odm_rsvd, - .sz = sizeof(fuse_info.odm_rsvd), - .start_off = 0x16, - .start_bit = 4, - .nbits = 256, - .data_offset = 11, - }, - [SBK_DEVKEY_STATUS] = { - .sz = SBK_DEVKEY_STATUS_SZ, - }, - [MASTER_ENB] = { - .addr = &master_enable, - .sz = sizeof(u8), - .start_off = 0x0, - .start_bit = 0, - .nbits = 1, - }, -}; - -static void wait_for_idle(void) -{ - u32 reg; - - do { - reg = tegra_fuse_readl(FUSE_CTRL); - } while ((reg & (0xF << 16)) != STATE_IDLE); -} - -#define FUSE_READ 0x1 -#define FUSE_WRITE 0x2 -#define FUSE_SENSE 0x3 -#define FUSE_CMD_MASK 0x3 - -static u32 fuse_cmd_read(u32 addr) -{ - u32 reg; - - tegra_fuse_writel(addr, FUSE_REG_ADDR); - reg = tegra_fuse_readl(FUSE_CTRL); - reg &= ~FUSE_CMD_MASK; - reg |= FUSE_READ; - tegra_fuse_writel(reg, FUSE_CTRL); - wait_for_idle(); - - reg = tegra_fuse_readl(FUSE_REG_READ); - return reg; -} - -static void fuse_cmd_write(u32 value, u32 addr) -{ - u32 reg; - - tegra_fuse_writel(addr, FUSE_REG_ADDR); - tegra_fuse_writel(value, FUSE_REG_WRITE); - - reg = tegra_fuse_readl(FUSE_CTRL); - reg &= ~FUSE_CMD_MASK; - reg |= FUSE_WRITE; - tegra_fuse_writel(reg, FUSE_CTRL); - wait_for_idle(); -} - -static void fuse_cmd_sense(void) -{ - u32 reg; - - reg = tegra_fuse_readl(FUSE_CTRL); - reg &= ~FUSE_CMD_MASK; - reg |= FUSE_SENSE; - tegra_fuse_writel(reg, FUSE_CTRL); - wait_for_idle(); -} - -static void fuse_reg_hide(void) -{ - u32 reg = tegra_fuse_readl(0x48); - reg &= ~(1 << 28); - tegra_fuse_writel(reg, 0x48); -} - -static void fuse_reg_unhide(void) -{ - u32 reg = tegra_fuse_readl(0x48); - reg |= (1 << 28); - tegra_fuse_writel(reg, 0x48); -} - -static void get_fuse(enum fuse_io_param io_param, u32 *out) -{ - int start_bit = fuse_info_tbl[io_param].start_bit; - int nbits = fuse_info_tbl[io_param].nbits; - int offset = fuse_info_tbl[io_param].start_off; - u32 *dst = fuse_info_tbl[io_param].addr; - int dst_bit = 0; - int i; - u32 val; - int loops; - - if (out) - dst = out; - - do { - val = fuse_cmd_read(offset); - loops = min(nbits, 32 - start_bit); - for (i = 0; i < loops; i++) { - if (val & (BIT(start_bit + i))) - *dst |= BIT(dst_bit); - else - *dst &= ~BIT(dst_bit); - dst_bit++; - if (dst_bit == 32) { - dst++; - dst_bit = 0; - } - } - nbits -= loops; - offset += 2; - start_bit = 0; - } while (nbits > 0); -} - -int tegra_fuse_read(enum fuse_io_param io_param, u32 *data, int size) -{ - int ret = 0, nbits; - u32 sbk[4], devkey = 0; - - if (!data) - return -EINVAL; - - if (size != fuse_info_tbl[io_param].sz) { - pr_err("%s: size mismatch(%d), %d vs %d\n", __func__, - (int)io_param, size, fuse_info_tbl[io_param].sz); - return -EINVAL; - } - - mutex_lock(&fuse_lock); - fuse_reg_unhide(); - fuse_cmd_sense(); - - if (io_param == SBK_DEVKEY_STATUS) { - *data = 0; - - get_fuse(SBK, sbk); - get_fuse(DEVKEY, &devkey); - nbits = sizeof(sbk) * BITS_PER_BYTE; - if (find_first_bit((unsigned long *)sbk, nbits) != nbits) - *data = 1; - else if (devkey) - *data = 1; - } else { - get_fuse(io_param, data); - } - - fuse_reg_hide(); - mutex_unlock(&fuse_lock); - return ret; -} - -static bool fuse_odm_prod_mode(void) -{ - u32 odm_prod_mode = 0; - - get_fuse(ODM_PROD_MODE, &odm_prod_mode); - return (odm_prod_mode ? true : false); -} - -static void set_fuse(enum fuse_io_param io_param, u32 *data) -{ - int i, start_bit = fuse_info_tbl[io_param].start_bit; - int nbits = fuse_info_tbl[io_param].nbits, loops; - int offset = fuse_info_tbl[io_param].start_off >> 1; - int src_bit = 0; - u32 val; - - do { - val = *data; - loops = min(nbits, 32 - start_bit); - for (i = 0; i < loops; i++) { - fuse_pgm_mask[offset] |= BIT(start_bit + i); - if (val & BIT(src_bit)) - fuse_pgm_data[offset] |= BIT(start_bit + i); - else - fuse_pgm_data[offset] &= ~BIT(start_bit + i); - src_bit++; - if (src_bit == 32) { - data++; - val = *data; - src_bit = 0; - } - } - nbits -= loops; - offset++; - start_bit = 0; - } while (nbits > 0); -} - -static void populate_fuse_arrs(struct fuse_data *info, u32 flags) -{ - u32 data = 0; - u32 *src = (u32 *)info; - int i; - - memset(fuse_pgm_data, 0, sizeof(fuse_pgm_data)); - memset(fuse_pgm_mask, 0, sizeof(fuse_pgm_mask)); - - /* enable program bit */ - data = 1; - set_fuse(MASTER_ENB, &data); - - if ((flags & FLAGS_ODMRSVD)) { - set_fuse(ODM_RSVD, info->odm_rsvd); - flags &= ~FLAGS_ODMRSVD; - } - - /* do not burn any more if secure mode is set */ - if (fuse_odm_prod_mode()) - goto out; - - for_each_set_bit(i, (unsigned long *)&flags, MAX_PARAMS) - set_fuse(i, src + fuse_info_tbl[i].data_offset); - -out: - pr_debug("ready to program"); -} - -static void fuse_power_enable(void) -{ -#if ENABLE_FUSE_BURNING - tegra_fuse_writel(0x1, FUSE_PWR_GOOD_SW); - udelay(1); -#endif -} - -static void fuse_power_disable(void) -{ -#if ENABLE_FUSE_BURNING - tegra_fuse_writel(0, FUSE_PWR_GOOD_SW); - udelay(1); -#endif -} - -static void fuse_program_array(int pgm_cycles) -{ - u32 reg, fuse_val[2]; - u32 *data = tmp_fuse_pgm_data, addr = 0, *mask = fuse_pgm_mask; - int i = 0; - - fuse_reg_unhide(); - fuse_cmd_sense(); - - /* get the first 2 fuse bytes */ - fuse_val[0] = fuse_cmd_read(0); - fuse_val[1] = fuse_cmd_read(1); - - fuse_power_enable(); - - /* - * The fuse macro is a high density macro. Fuses are - * burned using an addressing mechanism, so no need to prepare - * the full list, but more write to control registers are needed. - * The only bit that can be written at first is bit 0, a special write - * protection bit by assumptions all other bits are at 0 - * - * The programming pulse must have a precise width of - * [9000, 11000] ns. - */ - if (pgm_cycles > 0) { - reg = pgm_cycles; - tegra_fuse_writel(reg, FUSE_TIME_PGM); - } - fuse_val[0] = (0x1 & ~fuse_val[0]); - fuse_val[1] = (0x1 & ~fuse_val[1]); - fuse_cmd_write(fuse_val[0], 0); - fuse_cmd_write(fuse_val[1], 1); - - fuse_power_disable(); - - /* - * this will allow programming of other fuses - * and the reading of the existing fuse values - */ - fuse_cmd_sense(); - - /* Clear out all bits that have already been burned or masked out */ - memcpy(data, fuse_pgm_data, sizeof(fuse_pgm_data)); - - for (addr = 0; addr < NFUSES; addr += 2, data++, mask++) { - reg = fuse_cmd_read(addr); - pr_debug("%d: 0x%x 0x%x 0x%x\n", addr, (u32)(*data), - ~reg, (u32)(*mask)); - *data = (*data & ~reg) & *mask; - } - - fuse_power_enable(); - - /* - * Finally loop on all fuses, program the non zero ones. - * Words 0 and 1 are written last and they contain control fuses. We - * need to invalidate after writing to a control word (with the exception - * of the master enable). This is also the reason we write them last. - */ - for (i = ARRAY_SIZE(fuse_pgm_data) - 1; i >= 0; i--) { - if (tmp_fuse_pgm_data[i]) { - fuse_cmd_write(tmp_fuse_pgm_data[i], i * 2); - fuse_cmd_write(tmp_fuse_pgm_data[i], (i * 2) + 1); - } - - if (i < 2) { - fuse_power_disable(); - fuse_cmd_sense(); - fuse_power_enable(); - } - } - - /* Read all data into the chip options */ - tegra_fuse_writel(0x1, FUSE_PRIV2INTFC); - udelay(1); - tegra_fuse_writel(0, FUSE_PRIV2INTFC); - - while (!(tegra_fuse_readl(FUSE_CTRL) & (1 << 30))); - - fuse_reg_hide(); - fuse_power_disable(); -} - -static int fuse_set(enum fuse_io_param io_param, u32 *param, int size) -{ - int i, nwords = size / sizeof(u32); - u32 *data; - - if (io_param > MAX_PARAMS) - return -EINVAL; - - data = (u32*)kzalloc(size, GFP_KERNEL); - if (!data) { - pr_err("failed to alloc %d bytes\n", nwords); - return -ENOMEM; - } - - get_fuse(io_param, data); - - for (i = 0; i < nwords; i++) { - if ((data[i] | param[i]) != param[i]) { - pr_info("hw_val: 0x%x, sw_val: 0x%x, final: 0x%x\n", - data[i], param[i], (data[i] | param[i])); - param[i] = (data[i] | param[i]); - } - } - kfree(data); - return 0; -} - -int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags) -{ - u32 reg; - int i = 0; - - mutex_lock(&fuse_lock); - reg = tegra_fuse_readl(FUSE_DIS_PGM); - mutex_unlock(&fuse_lock); - if (reg) { - pr_err("fuse programming disabled"); - return -EACCES; - } - - if (fuse_odm_prod_mode() && (flags != FLAGS_ODMRSVD)) { - pr_err("reserved odm fuses are allowed in secure mode"); - return -EPERM; - } - - if ((flags & FLAGS_ODM_PROD_MODE) && - (flags & (FLAGS_SBK | FLAGS_DEVKEY))) { - pr_err("odm production mode and sbk/devkey not allowed"); - return -EPERM; - } - - mutex_lock(&fuse_lock); - memcpy(&fuse_info, pgm_data, sizeof(fuse_info)); - for_each_set_bit(i, (unsigned long *)&flags, MAX_PARAMS) { - fuse_set((u32)i, fuse_info_tbl[i].addr, - fuse_info_tbl[i].sz); - } - - populate_fuse_arrs(&fuse_info, flags); - fuse_program_array(0); - - /* disable program bit */ - reg = 0; - set_fuse(MASTER_ENB, ®); - - memset(&fuse_info, 0, sizeof(fuse_info)); - mutex_unlock(&fuse_lock); - - return 0; -} - -void tegra_fuse_program_disable(void) -{ - mutex_lock(&fuse_lock); - tegra_fuse_writel(0x1, FUSE_DIS_PGM); - mutex_unlock(&fuse_lock); -} - -static int tegra_fuse_program_sdmmc(void) -{ - int ret_val = 0; - u32 boot_cfg_value = 0; - u32 boot_strap_value = 0; - - struct fuse_data emmc_data; - - emmc_data.ignore_devsel_straps = USE_FUSE_TO_SELECT_BOOT_DEVICE; - emmc_data.bootdev_cfg = BOOT_DEVICE_INFO_EMMC; - - tegra_fuse_read(IGNORE_DEV_SEL_STRAPS, &boot_strap_value, - sizeof(boot_strap_value)); - tegra_fuse_read(SEC_BOOT_DEV_CFG, &boot_cfg_value, - sizeof(boot_cfg_value)); - if ((boot_strap_value == USE_FUSE_TO_SELECT_BOOT_DEVICE) && - (boot_cfg_value == BOOT_DEVICE_INFO_EMMC)) { - pr_err("Boot info fuses already programmed!\n"); - return ret_val; - } - ret_val = tegra_fuse_program(&emmc_data, - FLAGS_SEC_BOOT_DEV_CFG | - FLAGS_IGNORE_DEV_SEL_STRAPS); - if (ret_val < 0) - pr_err("Unable to program emmc fuse\n"); - return ret_val; -} - -static int tegra_fuse_verify_odm_production(void) -{ - int ret_val = 0; - u32 fuse = 0; - if (tegra_fuse_read(ODM_PROD_MODE, &fuse, sizeof(fuse)) == 0) { - pr_info("%s: Production ODM FUSE value: %x\n", __func__, fuse); - ret_val = (int)fuse; - } - return ret_val; -} - -static int tegra_fuse_verify_sbk(void) -{ - int ret_val = 0; - u32 fuse = 0; - if (tegra_fuse_read(SBK_DEVKEY_STATUS, (void *)&fuse, - SBK_DEVKEY_STATUS_SZ) == 0) { - pr_info("%s: SBK_DEVKEY_FUSE value: %x\n", - __func__, fuse); - ret_val = (int)fuse; - } - pr_info("SBK_DEVKEY_FUSE verify is done\n"); - return ret_val; -} - -static int tegra_fuse_get_uid(void *data) -{ - u64 uid = 0ULL; - u32 ub, lb; - - uid = tegra_chip_uid(); - lb = uid & 0xFFFFFFFF; - ub = uid >> 32; - snprintf((char *)data, SIZE_OF_UID, "%08X%08X", ub, lb); - return 0; -} - - -static int tegra_fuse_program_sbk_fuse(void *data) -{ - int ret_val = 0; - struct fuse_data sbk_req_data; - - memcpy(sbk_req_data.sbk, data, SIZE_OF_SBK); - - ret_val = tegra_fuse_verify_sbk(); - if (ret_val > 0) { - pr_err("SBK has been programmed already!\n"); - return ret_val; - } - - ret_val = tegra_fuse_program(&sbk_req_data, FLAGS_SBK); - pr_info("tegra_fuse_read return value %d\n ", ret_val); - return ret_val; -} - -long tegra_fuse_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long ioctl_param) -{ - int ret_val = 0; - u32 sbk_buff[4]; - u32 uid_buff[4]; - - switch (ioctl_num) { - case TEGRA_FUSE_IOCTL_PROGRAM_SBK: - if (copy_from_user((void *)sbk_buff, - (void __user *)ioctl_param, - SIZE_OF_SBK)) { - return -EFAULT; - } - ret_val = tegra_fuse_program_sbk_fuse(sbk_buff); - break; - - case TEGRA_FUSE_IOCTL_GET_UID: - tegra_fuse_get_uid(uid_buff); - if (copy_to_user((void __user *)ioctl_param, - (void *)uid_buff, SIZE_OF_UID)) { - ret_val = -EFAULT; - } - break; - - case TEGRA_FUSE_IOCTL_PROGRAM_SDMMC: - ret_val = tegra_fuse_program_sdmmc(); - break; - - case TEGRA_FUSE_IOCTL_VERIFY_SBK: - ret_val = tegra_fuse_verify_sbk(); - break; - - case TEGRA_FUSE_IOCTL_VERIFY_PROD_ODM: - ret_val = tegra_fuse_verify_odm_production(); - break; - - default: - ret_val = -EFAULT; - break; - } - return ret_val; -} - -static const struct file_operations tegra_fuse_fops = { - .unlocked_ioctl = tegra_fuse_ioctl, -}; - -static struct miscdevice tegra_fuse_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "tegra_fuse", - .fops = &tegra_fuse_fops, -}; - -static int __init tegra_fuse_program_init(void) -{ - int rtn; - - mutex_init(&fuse_lock); - - rtn = misc_register(&tegra_fuse_device); - if (rtn < 0) { - pr_err("Failed to register misc device %d\n", rtn); - return rtn; - } - - return 0; -} - -module_init(tegra_fuse_program_init); diff --git a/arch/arm/mach-tegra/tegra2_save.S b/arch/arm/mach-tegra/tegra2_save.S deleted file mode 100644 index 91f2ba038363..000000000000 --- a/arch/arm/mach-tegra/tegra2_save.S +++ /dev/null @@ -1,413 +0,0 @@ -/* - * arch/arm/mach-tegra/tegra2_save.S - * - * CPU state save & restore routines for CPU hotplug - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "power.h" - -/* .section ".cpuinit.text", "ax"*/ - -#define TTB_FLAGS 0x6A @ IRGN_WBWA, OC_RGN_WBWA, S, NOS - -#define EMC_CFG 0xc -#define EMC_ADR_CFG 0x10 -#define EMC_REFRESH 0x70 -#define EMC_NOP 0xdc -#define EMC_SELF_REF 0xe0 -#define EMC_REQ_CTRL 0x2b0 -#define EMC_EMC_STATUS 0x2b4 - -#define PMC_CTRL 0x0 -#define PMC_CTRL_BFI_SHIFT 8 -#define PMC_CTRL_BFI_WIDTH 9 -#define PMC_SCRATCH38 0x134 -#define PMC_SCRATCH41 0x140 - -#define CLK_RESET_CCLK_BURST 0x20 -#define CLK_RESET_CCLK_DIVIDER 0x24 -#define CLK_RESET_SCLK_BURST 0x28 -#define CLK_RESET_SCLK_DIVIDER 0x2c - -#define CLK_RESET_PLLC_BASE 0x80 -#define CLK_RESET_PLLM_BASE 0x90 -#define CLK_RESET_PLLP_BASE 0xa0 - -#define FLOW_CTRL_HALT_CPU_EVENTS 0x0 - -#include "power-macros.S" - -.macro emc_device_mask, rd, base - ldr \rd, [\base, #EMC_ADR_CFG] - tst \rd, #(0x3<<24) - moveq \rd, #(0x1<<8) @ just 1 device - movne \rd, #(0x3<<8) @ 2 devices -.endm - -/* - * - * __tear_down_master( r8 = context_pa, sp = power state ) - * - * Set the clock burst policy to the selected wakeup source - * Enable CPU power-request mode in the PMC - * Put the CPU in wait-for-event mode on the flow controller - * Trigger the PMC state machine to put the CPU in reset - */ -ENTRY(__tear_down_master) -__tear_down_master: -#ifdef CONFIG_CACHE_L2X0 - /* clean out the dirtied L2 lines, since all power transitions - * cause the cache state to get invalidated (although LP1 & LP2 - * preserve the data in the L2, the control words (L2X0_CTRL, - * L2X0_AUX_CTRL, etc.) need to be cleaned to L3 so that they - * will be visible on reboot. skip this for LP0, since the L2 cache - * will be shutdown before we reach this point */ - tst sp, #TEGRA_POWER_EFFECT_LP0 - bne __l2_clean_done - mov32 r0, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT) - add r3, r8, #(CONTEXT_SIZE_BYTES) - bic r8, r8, #0x1f - add r3, r3, #0x1f -11: str r8, [r0, #L2X0_CLEAN_LINE_PA] - add r8, r8, #32 - cmp r8, r3 - blo 11b -12: ldr r1, [r0, #L2X0_CLEAN_LINE_PA] - tst r1, #1 - bne 12b - mov r1, #0 - str r1, [r0, #L2X0_CACHE_SYNC] -13: ldr r1, [r0, #L2X0_CACHE_SYNC] - tst r1, #1 - bne 13b -__l2_clean_done: -#endif - - tst sp, #TEGRA_POWER_SDRAM_SELFREFRESH - - /* preload all the address literals that are needed for the - * CPU power-gating process, to avoid loads from SDRAM (which are - * not supported once SDRAM is put into self-refresh. - * LP0 / LP1 use physical address, since the MMU needs to be - * disabled before putting SDRAM into self-refresh to avoid - * memory access due to page table walks */ - mov32 r0, (IO_APB_VIRT-IO_APB_PHYS) - mov32 r4, TEGRA_PMC_BASE - mov32 r0, (IO_PPSB_VIRT-IO_PPSB_PHYS) - mov32 r5, TEGRA_CLK_RESET_BASE - mov32 r6, TEGRA_FLOW_CTRL_BASE - mov32 r7, TEGRA_TMRUS_BASE - - /* change page table pointer to tegra_pgd_phys, so that IRAM - * and MMU shut-off will be mapped virtual == physical */ - adr r3, __tear_down_master_data - ldr r3, [r3] @ &tegra_pgd_phys - ldr r3, [r3] - orr r3, r3, #TTB_FLAGS - mov r2, #0 - mcr p15, 0, r2, c13, c0, 1 @ reserved context - isb - mcr p15, 0, r3, c2, c0, 0 @ TTB 0 - isb - - /* Obtain LP1 information. - * R10 = LP1 branch target */ - mov32 r2, __tegra_lp1_reset - mov32 r3, __tear_down_master_sdram - sub r2, r3, r2 - mov32 r3, (TEGRA_IRAM_CODE_AREA) - add r10, r2, r3 - - mov32 r3, __shut_off_mmu - - /* R9 = LP2 branch target */ - mov32 r9, __tear_down_master_pll_cpu - - /* Convert the branch targets - * to physical addresses */ - sub r3, r3, #(PAGE_OFFSET - PHYS_OFFSET) - sub r9, r9, #(PAGE_OFFSET - PHYS_OFFSET) - movne r9, r10 - bx r3 -ENDPROC(__tear_down_master) - .type __tear_down_master_data, %object -__tear_down_master_data: - .long tegra_pgd_phys - .size __tear_down_master_data, . - __tear_down_master_data - -/* START OF ROUTINES COPIED TO IRAM */ -/* - * __tegra_lp1_reset - * - * reset vector for LP1 restore; copied into IRAM during suspend. - * brings the system back up to a safe starting point (SDRAM out of - * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP, - * system clock running on the same PLL that it suspended at), and - * jumps to tegra_lp2_startup to restore PLLX and virtual addressing. - * physical address of tegra_lp2_startup expected to be stored in - * PMC_SCRATCH41 - */ - .align L1_CACHE_SHIFT -ENTRY(__tegra_lp1_reset) -__tegra_lp1_reset: - /* the CPU and system bus are running at 32KHz and executing from - * IRAM when this code is executed; immediately switch to CLKM and - * enable PLLP. */ - mov32 r0, TEGRA_CLK_RESET_BASE - mov r1, #(1<<28) - str r1, [r0, #CLK_RESET_SCLK_BURST] - str r1, [r0, #CLK_RESET_CCLK_BURST] - mov r1, #0 - str r1, [r0, #CLK_RESET_SCLK_DIVIDER] - str r1, [r0, #CLK_RESET_CCLK_DIVIDER] - - ldr r1, [r0, #CLK_RESET_PLLM_BASE] - tst r1, #(1<<30) - orreq r1, r1, #(1<<30) - streq r1, [r0, #CLK_RESET_PLLM_BASE] - ldr r1, [r0, #CLK_RESET_PLLP_BASE] - tst r1, #(1<<30) - orreq r1, r1, #(1<<30) - streq r1, [r0, #CLK_RESET_PLLP_BASE] - ldr r1, [r0, #CLK_RESET_PLLC_BASE] - tst r1, #(1<<30) - orreq r1, r1, #(1<<30) - streq r1, [r0, #CLK_RESET_PLLC_BASE] - mov32 r7, TEGRA_TMRUS_BASE - ldr r1, [r7] - - /* since the optimized settings are still in SDRAM, there is - * no need to store them back into the IRAM-local __lp1_pad_area */ - add r2, pc, #__lp1_pad_area-(.+8) -padload:ldmia r2!, {r3-r4} - cmp r3, #0 - beq padload_done - str r4, [r3] - b padload -padload_done: - ldr r2, [r7] - add r2, r2, #0x4 @ 4uS delay for DRAM pad restoration - wait_until r2, r7, r3 - add r1, r1, #0xff @ 255uS delay for PLL stabilization - wait_until r1, r7, r3 - - str r4, [r0, #CLK_RESET_SCLK_BURST] - mov32 r4, ((1<<28) | (4)) @ burst policy is PLLP - str r4, [r0, #CLK_RESET_CCLK_BURST] - - mov32 r0, TEGRA_EMC_BASE - ldr r1, [r0, #EMC_CFG] - bic r1, r1, #(1<<31) @ disable DRAM_CLK_STOP - str r1, [r0, #EMC_CFG] - - mov r1, #0 - str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh - mov r1, #1 - str r1, [r0, #EMC_NOP] - str r1, [r0, #EMC_NOP] - str r1, [r0, #EMC_REFRESH] - - emc_device_mask r1, r0 - -exit_selfrefresh_loop: - ldr r2, [r0, #EMC_EMC_STATUS] - ands r2, r2, r1 - bne exit_selfrefresh_loop - - mov r1, #0 - str r1, [r0, #EMC_REQ_CTRL] - - mov32 r0, TEGRA_PMC_BASE - ldr r0, [r0, #PMC_SCRATCH41] - mov pc, r0 -ENDPROC(__tegra_lp1_reset) - -/* - * __tear_down_master_sdram - * - * disables MMU, data cache, and puts SDRAM into self-refresh. - * must execute from IRAM. - */ - .align L1_CACHE_SHIFT -__tear_down_master_sdram: - mov32 r1, TEGRA_EMC_BASE - mov r2, #3 - str r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests - -emcidle:ldr r2, [r1, #EMC_EMC_STATUS] - tst r2, #4 - beq emcidle - - mov r2, #1 - str r2, [r1, #EMC_SELF_REF] - - emc_device_mask r2, r1 - -emcself:ldr r3, [r1, #EMC_EMC_STATUS] - and r3, r3, r2 - cmp r3, r2 - bne emcself @ loop until DDR in self-refresh - - add r2, pc, #__lp1_pad_area-(.+8) - -padsave:ldm r2, {r0-r1} - cmp r0, #0 - beq padsave_done - ldr r3, [r0] - str r1, [r0] - str r3, [r2, #4] - add r2, r2, #8 - b padsave -padsave_done: - - ldr r0, [r5, #CLK_RESET_SCLK_BURST] - str r0, [r2, #4] - dsb - b __tear_down_master_pll_cpu -ENDPROC(__tear_down_master_sdram) - - .align L1_CACHE_SHIFT - .type __lp1_pad_area, %object -__lp1_pad_area: - .word TEGRA_APB_MISC_BASE + 0x8c8 /* XM2CFGCPADCTRL */ - .word 0x8 - .word TEGRA_APB_MISC_BASE + 0x8cc /* XM2CFGDPADCTRL */ - .word 0x8 - .word TEGRA_APB_MISC_BASE + 0x8d0 /* XM2CLKCFGPADCTRL */ - .word 0x0 - .word TEGRA_APB_MISC_BASE + 0x8d4 /* XM2COMPPADCTRL */ - .word 0x8 - .word TEGRA_APB_MISC_BASE + 0x8d8 /* XM2VTTGENPADCTRL */ - .word 0x5500 - .word TEGRA_APB_MISC_BASE + 0x8e4 /* XM2CFGCPADCTRL2 */ - .word 0x08080040 - .word TEGRA_APB_MISC_BASE + 0x8e8 /* XM2CFGDPADCTRL2 */ - .word 0x0 - .word 0x0 /* end of list */ - .word 0x0 /* sclk_burst_policy */ - .size __lp1_pad_area, . - __lp1_pad_area - - .align L1_CACHE_SHIFT -__tear_down_master_pll_cpu: - ldr r0, [r4, #PMC_CTRL] - bfi r0, sp, #PMC_CTRL_BFI_SHIFT, #PMC_CTRL_BFI_WIDTH - str r0, [r4, #PMC_CTRL] - tst sp, #TEGRA_POWER_SDRAM_SELFREFRESH - - /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */ - moveq r0, #(2<<28) /* burst policy = run mode */ - orreq r0, r0, #(4<<4) /* use PLLP in run mode burst */ - streq r0, [r5, #CLK_RESET_CCLK_BURST] - moveq r0, #0 - streq r0, [r5, #CLK_RESET_CCLK_DIVIDER] - beq __cclk_burst_set - - /* in other modes, set system & CPU burst policies to 32KHz. - * start by jumping to CLKM to safely disable PLLs, then jump - * to CLKS */ - mov r0, #(1<<28) - str r0, [r5, #CLK_RESET_SCLK_BURST] - str r0, [r5, #CLK_RESET_CCLK_BURST] - mov r0, #0 - str r0, [r5, #CLK_RESET_CCLK_DIVIDER] - str r0, [r5, #CLK_RESET_SCLK_DIVIDER] - - /* 2 us delay between changing sclk and disabling PLLs */ - wait_for_us r1, r7, r9 - add r1, r1, #2 - wait_until r1, r7, r9 - - /* switch to CLKS */ - mov r0, #0 /* burst policy = 32KHz */ - str r0, [r5, #CLK_RESET_SCLK_BURST] - - /* disable PLLP, PLLM, PLLC in LP0 and LP1 states */ - ldr r0, [r5, #CLK_RESET_PLLM_BASE] - bic r0, r0, #(1<<30) - str r0, [r5, #CLK_RESET_PLLM_BASE] - ldr r0, [r5, #CLK_RESET_PLLP_BASE] - bic r0, r0, #(1<<30) - str r0, [r5, #CLK_RESET_PLLP_BASE] - ldr r0, [r5, #CLK_RESET_PLLC_BASE] - bic r0, r0, #(1<<30) - str r0, [r5, #CLK_RESET_PLLC_BASE] - -__cclk_burst_set: - mov r0, #(4<<29) /* STOP_UNTIL_IRQ */ - orr r0, r0, #(1<<10) | (1<<8) /* IRQ_0, FIQ_0 */ - ldr r1, [r7] - str r1, [r4, #PMC_SCRATCH38] - dsb - str r0, [r6, #FLOW_CTRL_HALT_CPU_EVENTS] - dsb - ldr r0, [r6, #FLOW_CTRL_HALT_CPU_EVENTS] /* memory barrier */ - -halted: dsb - wfe /* CPU should be power gated here */ - isb - b halted -ENDPROC(__tear_down_master_pll_cpu) - -/* - * __put_cpu_in_reset(cpu_nr) - * - * puts the specified CPU in wait-for-event mode on the flow controller - * and puts the CPU in reset - */ -ENTRY(__put_cpu_in_reset) -__put_cpu_in_reset: - cmp r0, #0 - subne r1, r0, #1 - movne r1, r1, lsl #3 - addne r1, r1, #0x14 - moveq r1, #0 @ r1 = CPUx_HALT_EVENTS register offset - mov32 r7, (TEGRA_FLOW_CTRL_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT) - mov r2, #(0x2<<29) - str r2, [r7, r1] @ put flow controller in wait event mode - isb - dsb - movw r1, 0x1011 - mov r1, r1, lsl r0 - mov32 r7, (TEGRA_CLK_RESET_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT) - str r1, [r7, #0x340] @ put slave CPU in reset - isb - dsb - b . -ENDPROC(__put_cpu_in_reset) - -/* dummy symbol for end of IRAM */ - .align L1_CACHE_SHIFT -ENTRY(__tegra_iram_end) -__tegra_iram_end: - b . -ENDPROC(__tegra_iram_end) diff --git a/arch/arm/mach-tegra/tegra_fiq_debugger.c b/arch/arm/mach-tegra/tegra_fiq_debugger.c deleted file mode 100644 index 29e3119b0edd..000000000000 --- a/arch/arm/mach-tegra/tegra_fiq_debugger.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * arch/arm/mach-tegra/fiq_debugger.c - * - * Serial Debugger Interface for Tegra - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -struct tegra_fiq_debugger { - struct fiq_debugger_pdata pdata; - void __iomem *debug_port_base; - bool break_seen; -}; - -static inline void tegra_write(struct tegra_fiq_debugger *t, - unsigned int val, unsigned int off) -{ - __raw_writeb(val, t->debug_port_base + off * 4); -} - -static inline unsigned int tegra_read(struct tegra_fiq_debugger *t, - unsigned int off) -{ - return __raw_readb(t->debug_port_base + off * 4); -} - -static inline unsigned int tegra_read_lsr(struct tegra_fiq_debugger *t) -{ - unsigned int lsr; - - lsr = tegra_read(t, UART_LSR); - if (lsr & UART_LSR_BI) - t->break_seen = true; - - return lsr; -} - -static int debug_port_init(struct platform_device *pdev) -{ - struct tegra_fiq_debugger *t; - t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata); - - if (tegra_read(t, UART_LSR) & UART_LSR_DR) - (void)tegra_read(t, UART_RX); - /* enable rx and lsr interrupt */ - tegra_write(t, UART_IER_RLSI | UART_IER_RDI, UART_IER); - /* interrupt on every character */ - tegra_write(t, 0, UART_IIR); - - return 0; -} - -static int debug_getc(struct platform_device *pdev) -{ - unsigned int lsr; - struct tegra_fiq_debugger *t; - t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata); - - lsr = tegra_read_lsr(t); - - if (lsr & UART_LSR_BI || t->break_seen) { - t->break_seen = false; - return FIQ_DEBUGGER_BREAK; - } - - if (lsr & UART_LSR_DR) - return tegra_read(t, UART_RX); - - return FIQ_DEBUGGER_NO_CHAR; -} - -static void debug_putc(struct platform_device *pdev, unsigned int c) -{ - struct tegra_fiq_debugger *t; - t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata); - - while (!(tegra_read_lsr(t) & UART_LSR_THRE)) - cpu_relax(); - - tegra_write(t, c, UART_TX); -} - -static void debug_flush(struct platform_device *pdev) -{ - struct tegra_fiq_debugger *t; - t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata); - - while (!(tegra_read_lsr(t) & UART_LSR_TEMT)) - cpu_relax(); -} - -static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on) -{ - if (on) - tegra_fiq_enable(irq); - else - tegra_fiq_disable(irq); -} - -static int tegra_fiq_debugger_id; - -void tegra_serial_debug_init(unsigned int base, int irq, - struct clk *clk, int signal_irq, int wakeup_irq) -{ - struct tegra_fiq_debugger *t; - struct platform_device *pdev; - struct resource *res; - int res_count; - - t = kzalloc(sizeof(struct tegra_fiq_debugger), GFP_KERNEL); - if (!t) { - pr_err("Failed to allocate for fiq debugger\n"); - return; - } - - t->pdata.uart_init = debug_port_init; - t->pdata.uart_getc = debug_getc; - t->pdata.uart_putc = debug_putc; - t->pdata.uart_flush = debug_flush; - t->pdata.fiq_enable = fiq_enable; - - t->debug_port_base = ioremap(base, PAGE_SIZE); - if (!t->debug_port_base) { - pr_err("Failed to ioremap for fiq debugger\n"); - goto out1; - } - - res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL); - if (!res) { - pr_err("Failed to alloc fiq debugger resources\n"); - goto out2; - } - - pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); - if (!pdev) { - pr_err("Failed to alloc fiq debugger platform device\n"); - goto out3; - }; - - res[0].flags = IORESOURCE_IRQ; - res[0].start = irq; - res[0].end = irq; - res[0].name = "fiq"; - - res[1].flags = IORESOURCE_IRQ; - res[1].start = signal_irq; - res[1].end = signal_irq; - res[1].name = "signal"; - res_count = 2; - - if (wakeup_irq >= 0) { - res[2].flags = IORESOURCE_IRQ; - res[2].start = wakeup_irq; - res[2].end = wakeup_irq; - res[2].name = "wakeup"; - res_count++; - } - - pdev->name = "fiq_debugger"; - pdev->id = tegra_fiq_debugger_id++; - pdev->dev.platform_data = &t->pdata; - pdev->resource = res; - pdev->num_resources = res_count; - - if (platform_device_register(pdev)) { - pr_err("Failed to register fiq debugger\n"); - goto out4; - } - - return; - -out4: - kfree(pdev); -out3: - kfree(res); -out2: - iounmap(t->debug_port_base); -out1: - kfree(t); -} diff --git a/arch/arm/mach-tegra/tegra_i2s_audio.c b/arch/arm/mach-tegra/tegra_i2s_audio.c deleted file mode 100644 index 1bae833f4f2a..000000000000 --- a/arch/arm/mach-tegra/tegra_i2s_audio.c +++ /dev/null @@ -1,1963 +0,0 @@ -/* - * arch/arm/mach-tegra/tegra_i2s_audio.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Iliyan Malchev - * - * 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. - * - */ - -/* TODO: - -- replace make I2S_MAX_NUM_BUFS configurable through an ioctl -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "clock.h" - -#define PCM_BUFFER_MAX_SIZE_ORDER PAGE_SHIFT - -#define TEGRA_AUDIO_DSP_NONE 0 -#define TEGRA_AUDIO_DSP_PCM 1 -#define TEGRA_AUDIO_DSP_NETWORK 2 -#define TEGRA_AUDIO_DSP_TDM 3 - -#define I2S_MAX_NUM_BUFS 4 -#define I2S_DEFAULT_TX_NUM_BUFS 2 -#define I2S_DEFAULT_RX_NUM_BUFS 2 - -/* per stream (input/output) */ -struct audio_stream { - int opened; - struct mutex lock; - - bool active; /* is DMA in progress? */ - int num_bufs; - void *buffer[I2S_MAX_NUM_BUFS]; - dma_addr_t buf_phy[I2S_MAX_NUM_BUFS]; - struct completion comp[I2S_MAX_NUM_BUFS]; - struct tegra_dma_req dma_req[I2S_MAX_NUM_BUFS]; - int last_queued; - - int i2s_fifo_atn_level; - - struct tegra_dma_channel *dma_chan; - bool stop; - struct completion stop_completion; - spinlock_t dma_req_lock; - - struct work_struct allow_suspend_work; - struct wake_lock wake_lock; - char wake_lock_name[100]; -}; - -/* per i2s controller */ -struct audio_driver_state { - struct list_head next; - - struct platform_device *pdev; - struct tegra_audio_platform_data *pdata; - phys_addr_t i2s_phys; - unsigned long i2s_base; - - unsigned long dma_req_sel; - - int irq; - struct tegra_audio_in_config in_config; - - struct miscdevice misc_out; - struct miscdevice misc_out_ctl; - struct audio_stream out; - - struct miscdevice misc_in; - struct miscdevice misc_in_ctl; - struct audio_stream in; - - /* Control for whole I2S (Data format, etc.) */ - struct miscdevice misc_ctl; - unsigned int bit_format; -}; - -static inline bool pending_buffer_requests(struct audio_stream *stream) -{ - int i; - for (i = 0; i < stream->num_bufs; i++) - if (!completion_done(&stream->comp[i])) - return true; - return false; -} - -static inline int buf_size(struct audio_stream *s __attribute__((unused))) -{ - return 1 << PCM_BUFFER_MAX_SIZE_ORDER; -} - -static inline struct audio_driver_state *ads_from_misc_out(struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, misc_out); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_misc_out_ctl( - struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, - misc_out_ctl); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_misc_in(struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, misc_in); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_misc_in_ctl( - struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, - misc_in_ctl); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_misc_ctl( - struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, - misc_ctl); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_out( - struct audio_stream *aos) -{ - return container_of(aos, struct audio_driver_state, out); -} - -static inline struct audio_driver_state *ads_from_in( - struct audio_stream *ais) -{ - return container_of(ais, struct audio_driver_state, in); -} - -static inline void prevent_suspend(struct audio_stream *as) -{ - pr_debug("%s\n", __func__); - cancel_work_sync(&as->allow_suspend_work); - wake_lock(&as->wake_lock); -} - -static void allow_suspend_worker(struct work_struct *w) -{ - struct audio_stream *as = container_of(w, - struct audio_stream, allow_suspend_work); - pr_debug("%s\n", __func__); - wake_unlock(&as->wake_lock); -} - -static inline void allow_suspend(struct audio_stream *as) -{ - schedule_work(&as->allow_suspend_work); -} - -#define I2S_I2S_FIFO_TX_BUSY I2S_I2S_STATUS_FIFO1_BSY -#define I2S_I2S_FIFO_TX_QS I2S_I2S_STATUS_QS_FIFO1 -#define I2S_I2S_FIFO_TX_ERR I2S_I2S_STATUS_FIFO1_ERR - -#define I2S_I2S_FIFO_RX_BUSY I2S_I2S_STATUS_FIFO2_BSY -#define I2S_I2S_FIFO_RX_QS I2S_I2S_STATUS_QS_FIFO2 -#define I2S_I2S_FIFO_RX_ERR I2S_I2S_STATUS_FIFO2_ERR - -#define I2S_FIFO_ERR (I2S_I2S_STATUS_FIFO1_ERR | I2S_I2S_STATUS_FIFO2_ERR) - -static inline void i2s_writel(unsigned long base, u32 val, u32 reg) -{ - writel(val, base + reg); -} - -static inline u32 i2s_readl(unsigned long base, u32 reg) -{ - return readl(base + reg); -} - -static inline void i2s_fifo_write(unsigned long base, int fifo, u32 data) -{ - i2s_writel(base, data, fifo ? I2S_I2S_FIFO2_0 : I2S_I2S_FIFO1_0); -} - -static inline u32 i2s_fifo_read(unsigned long base, int fifo) -{ - return i2s_readl(base, fifo ? I2S_I2S_FIFO2_0 : I2S_I2S_FIFO1_0); -} - -static int i2s_set_channel_bit_count(unsigned long base, - int sampling, int bitclk) -{ - u32 val; - int bitcnt = bitclk / (2 * sampling) - 1; - - if (bitcnt < 0 || bitcnt >= 1<<11) { - pr_err("%s: bit count %d is out of bounds\n", __func__, - bitcnt); - return -EINVAL; - } - - val = bitcnt; - if (bitclk % (2 * sampling)) { - pr_info("%s: enabling non-symmetric mode\n", __func__); - val |= I2S_I2S_TIMING_NON_SYM_ENABLE; - } - - pr_debug("%s: I2S_I2S_TIMING_0 = %08x\n", __func__, val); - i2s_writel(base, val, I2S_I2S_TIMING_0); - return 0; -} - -static void i2s_set_fifo_mode(unsigned long base, int fifo, int tx) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (fifo == 0) { - val &= ~I2S_I2S_CTRL_FIFO1_RX_ENABLE; - val |= (!tx) ? I2S_I2S_CTRL_FIFO1_RX_ENABLE : 0; - } else { - val &= ~I2S_I2S_CTRL_FIFO2_TX_ENABLE; - val |= tx ? I2S_I2S_CTRL_FIFO2_TX_ENABLE : 0; - } - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -static int i2s_fifo_set_attention_level(unsigned long base, - int fifo, unsigned level) -{ - u32 val; - - if (level > I2S_FIFO_ATN_LVL_TWELVE_SLOTS) { - pr_err("%s: invalid fifo level selector %d\n", __func__, - level); - return -EINVAL; - } - - val = i2s_readl(base, I2S_I2S_FIFO_SCR_0); - - if (!fifo) { - val &= ~I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK; - val |= level << I2S_FIFO1_ATN_LVL_SHIFT; - } else { - val &= ~I2S_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK; - val |= level << I2S_FIFO2_ATN_LVL_SHIFT; - } - - i2s_writel(base, val, I2S_I2S_FIFO_SCR_0); - return 0; -} - -static void i2s_fifo_enable(unsigned long base, int fifo, int on) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (!fifo) { - val &= ~I2S_I2S_CTRL_FIFO1_ENABLE; - val |= on ? I2S_I2S_CTRL_FIFO1_ENABLE : 0; - } else { - val &= ~I2S_I2S_CTRL_FIFO2_ENABLE; - val |= on ? I2S_I2S_CTRL_FIFO2_ENABLE : 0; - } - - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -#if 0 -static bool i2s_is_fifo_enabled(unsigned long base, int fifo) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (!fifo) - return !!(val & I2S_I2S_CTRL_FIFO1_ENABLE); - return !!(val & I2S_I2S_CTRL_FIFO2_ENABLE); -} -#endif - -static void i2s_fifo_clear(unsigned long base, int fifo) -{ - u32 val = i2s_readl(base, I2S_I2S_FIFO_SCR_0); - if (!fifo) { - val &= ~I2S_I2S_FIFO_SCR_FIFO1_CLR; - val |= I2S_I2S_FIFO_SCR_FIFO1_CLR; -#if 0 - /* Per Nvidia, reduces pop on the next run. */ - if (!(val & I2S_I2S_CTRL_FIFO1_RX_ENABLE)) { - int cnt = 16; - while (cnt--) - i2s_writel(base, 0, I2S_I2S_FIFO1_0); - } -#endif - } else { - val &= ~I2S_I2S_FIFO_SCR_FIFO2_CLR; - val |= I2S_I2S_FIFO_SCR_FIFO2_CLR; - } - - i2s_writel(base, val, I2S_I2S_FIFO_SCR_0); -} - -static void i2s_set_master(unsigned long base, int master) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - val &= ~I2S_I2S_CTRL_MASTER_ENABLE; - val |= master ? I2S_I2S_CTRL_MASTER_ENABLE : 0; - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -static int i2s_set_dsp_mode(unsigned long base, unsigned int mode) -{ - u32 val; - if (mode > TEGRA_AUDIO_DSP_TDM) { - pr_err("%s: invalid mode %d.\n", __func__, mode); - return -EINVAL; - } - if (mode == TEGRA_AUDIO_DSP_TDM) { - pr_err("TEGRA_AUDIO_DSP_TDM not implemented.\n"); - return -EINVAL; - } - - /* Disable unused modes */ - if (mode != TEGRA_AUDIO_DSP_PCM) { - /* Disable PCM mode */ - val = i2s_readl(base, I2S_I2S_PCM_CTRL_0); - val &= ~(I2S_I2S_PCM_CTRL_TRM_MODE | - I2S_I2S_PCM_CTRL_RCV_MODE); - i2s_writel(base, val, I2S_I2S_PCM_CTRL_0); - } - if (mode != TEGRA_AUDIO_DSP_NETWORK) { - /* Disable Network mode */ - val = i2s_readl(base, I2S_I2S_NW_CTRL_0); - val &= ~(I2S_I2S_NW_CTRL_TRM_TLPHY_MODE | - I2S_I2S_NW_CTRL_RCV_TLPHY_MODE); - i2s_writel(base, val, I2S_I2S_NW_CTRL_0); - } - - /* Enable the selected mode. */ - switch (mode) { - case TEGRA_AUDIO_DSP_NETWORK: - /* Set DSP Network (Telephony) Mode */ - val = i2s_readl(base, I2S_I2S_NW_CTRL_0); - val |= I2S_I2S_NW_CTRL_TRM_TLPHY_MODE | - I2S_I2S_NW_CTRL_RCV_TLPHY_MODE; - i2s_writel(base, val, I2S_I2S_NW_CTRL_0); - break; - case TEGRA_AUDIO_DSP_PCM: - /* Set DSP PCM Mode */ - val = i2s_readl(base, I2S_I2S_PCM_CTRL_0); - val |= I2S_I2S_PCM_CTRL_TRM_MODE | - I2S_I2S_PCM_CTRL_RCV_MODE; - i2s_writel(base, val, I2S_I2S_PCM_CTRL_0); - break; - } - - return 0; -} - -static int i2s_set_bit_format(unsigned long base, unsigned fmt) -{ - u32 val; - - if (fmt > I2S_BIT_FORMAT_DSP) { - pr_err("%s: invalid bit-format selector %d\n", __func__, fmt); - return -EINVAL; - } - - val = i2s_readl(base, I2S_I2S_CTRL_0); - val &= ~I2S_I2S_CTRL_BIT_FORMAT_MASK; - val |= fmt << I2S_BIT_FORMAT_SHIFT; - i2s_writel(base, val, I2S_I2S_CTRL_0); - /* For DSP format, select DSP PCM mode. */ - /* PCM mode and Network Mode slot 0 are effectively identical. */ - if (fmt == I2S_BIT_FORMAT_DSP) - i2s_set_dsp_mode(base, TEGRA_AUDIO_DSP_PCM); - else - i2s_set_dsp_mode(base, TEGRA_AUDIO_DSP_NONE); - - return 0; -} - -static int i2s_set_bit_size(unsigned long base, unsigned bit_size) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - val &= ~I2S_I2S_CTRL_BIT_SIZE_MASK; - - if (bit_size > I2S_BIT_SIZE_32) { - pr_err("%s: invalid bit_size selector %d\n", __func__, - bit_size); - return -EINVAL; - } - - val |= bit_size << I2S_BIT_SIZE_SHIFT; - - i2s_writel(base, val, I2S_I2S_CTRL_0); - return 0; -} - -static int i2s_set_fifo_format(unsigned long base, unsigned fmt) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - val &= ~I2S_I2S_CTRL_FIFO_FORMAT_MASK; - - if (fmt > I2S_FIFO_32 && fmt != I2S_FIFO_PACKED) { - pr_err("%s: invalid fmt selector %d\n", __func__, fmt); - return -EINVAL; - } - - val |= fmt << I2S_FIFO_SHIFT; - - i2s_writel(base, val, I2S_I2S_CTRL_0); - return 0; -} - -static void i2s_set_left_right_control_polarity(unsigned long base, - int high_low) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - val &= ~I2S_I2S_CTRL_L_R_CTRL; - val |= high_low ? I2S_I2S_CTRL_L_R_CTRL : 0; - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -#if 0 -static void i2s_set_fifo_irq_on_err(unsigned long base, int fifo, int on) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (!fifo) { - val &= ~I2S_I2S_IE_FIFO1_ERR; - val |= on ? I2S_I2S_IE_FIFO1_ERR : 0; - } else { - val &= ~I2S_I2S_IE_FIFO2_ERR; - val |= on ? I2S_I2S_IE_FIFO2_ERR : 0; - } - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -static void i2s_set_fifo_irq_on_qe(unsigned long base, int fifo, int on) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (!fifo) { - val &= ~I2S_I2S_QE_FIFO1; - val |= on ? I2S_I2S_QE_FIFO1 : 0; - } else { - val &= ~I2S_I2S_QE_FIFO2; - val |= on ? I2S_I2S_QE_FIFO2 : 0; - } - i2s_writel(base, val, I2S_I2S_CTRL_0); -} -#endif - -static void i2s_enable_fifos(unsigned long base, int on) -{ - u32 val = i2s_readl(base, I2S_I2S_CTRL_0); - if (on) - val |= I2S_I2S_QE_FIFO1 | I2S_I2S_QE_FIFO2 | - I2S_I2S_IE_FIFO1_ERR | I2S_I2S_IE_FIFO2_ERR; - else - val &= ~(I2S_I2S_QE_FIFO1 | I2S_I2S_QE_FIFO2 | - I2S_I2S_IE_FIFO1_ERR | I2S_I2S_IE_FIFO2_ERR); - - i2s_writel(base, val, I2S_I2S_CTRL_0); -} - -static inline u32 i2s_get_status(unsigned long base) -{ - return i2s_readl(base, I2S_I2S_STATUS_0); -} - -static inline u32 i2s_get_control(unsigned long base) -{ - return i2s_readl(base, I2S_I2S_CTRL_0); -} - -static inline void i2s_ack_status(unsigned long base) -{ - return i2s_writel(base, i2s_readl(base, I2S_I2S_STATUS_0), - I2S_I2S_STATUS_0); -} - -static inline u32 i2s_get_fifo_scr(unsigned long base) -{ - return i2s_readl(base, I2S_I2S_FIFO_SCR_0); -} - -static inline phys_addr_t i2s_get_fifo_phy_base(unsigned long phy_base, - int fifo) -{ - return phy_base + (fifo ? I2S_I2S_FIFO2_0 : I2S_I2S_FIFO1_0); -} - -static inline u32 i2s_get_fifo_full_empty_count(unsigned long base, int fifo) -{ - u32 val = i2s_readl(base, I2S_I2S_FIFO_SCR_0); - - if (!fifo) - val = val >> I2S_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT; - else - val = val >> I2S_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT; - - return val & I2S_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK; -} - -static int i2s_configure(struct platform_device *pdev) -{ - struct tegra_audio_platform_data *pdata = pdev->dev.platform_data; - struct audio_driver_state *state = pdata->driver_data; - bool master; - struct clk *i2s_clk; - int master_clk; - - /* dev_info(&pdev->dev, "%s\n", __func__); */ - - if (!state) - return -ENOMEM; - - /* disable interrupts from I2S */ - i2s_enable_fifos(state->i2s_base, 0); - i2s_fifo_clear(state->i2s_base, I2S_FIFO_TX); - i2s_fifo_clear(state->i2s_base, I2S_FIFO_RX); - i2s_set_left_right_control_polarity(state->i2s_base, 0); /* default */ - - i2s_clk = clk_get(&pdev->dev, NULL); - if (!i2s_clk) { - dev_err(&pdev->dev, "%s: could not get i2s clock\n", - __func__); - return -EIO; - } - - master = state->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP ? - state->pdata->dsp_master : state->pdata->i2s_master; - - - master_clk = state->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP ? - state->pdata->dsp_master_clk : - state->pdata->i2s_master_clk; -#define I2S_CLK_TO_BITCLK_RATIO 2 /* Todo, Bitclk based on 2X clock? */ - if (master) - i2s_set_channel_bit_count(state->i2s_base, master_clk, - clk_get_rate(i2s_clk)*I2S_CLK_TO_BITCLK_RATIO); - i2s_set_master(state->i2s_base, master); - - i2s_set_fifo_mode(state->i2s_base, I2S_FIFO_TX, 1); - i2s_set_fifo_mode(state->i2s_base, I2S_FIFO_RX, 0); - - if (state->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP) - i2s_set_bit_format(state->i2s_base, I2S_BIT_FORMAT_DSP); - else - i2s_set_bit_format(state->i2s_base, state->pdata->mode); - i2s_set_bit_size(state->i2s_base, state->pdata->bit_size); - i2s_set_fifo_format(state->i2s_base, state->pdata->fifo_fmt); - - return 0; -} - -static int init_stream_buffer(struct audio_stream *, int); - -static int setup_dma(struct audio_driver_state *, int); -static void tear_down_dma(struct audio_driver_state *, int); -static void stop_dma_playback(struct audio_stream *); -static int start_dma_recording(struct audio_stream *, int); -static void stop_dma_recording(struct audio_stream *); - -struct sound_ops { - int (*setup)(struct audio_driver_state *, int); - void (*tear_down)(struct audio_driver_state *, int); - void (*stop_playback)(struct audio_stream *); - int (*start_recording)(struct audio_stream *, int); - void (*stop_recording)(struct audio_stream *); -}; - -static const struct sound_ops dma_sound_ops = { - .setup = setup_dma, - .tear_down = tear_down_dma, - .stop_playback = stop_dma_playback, - .start_recording = start_dma_recording, - .stop_recording = stop_dma_recording, -}; - -static const struct sound_ops *sound_ops = &dma_sound_ops; - -static int start_recording_if_necessary(struct audio_stream *ais, int size) -{ - int rc = 0; - unsigned long flags; - prevent_suspend(ais); - spin_lock_irqsave(&ais->dma_req_lock, flags); - if (!ais->stop && !pending_buffer_requests(ais)) { - /* pr_debug("%s: starting recording\n", __func__); */ - rc = sound_ops->start_recording(ais, size); - if (rc) { - pr_err("%s start_recording() failed\n", __func__); - allow_suspend(ais); - } - } - spin_unlock_irqrestore(&ais->dma_req_lock, flags); - return rc; -} - -static bool stop_playback_if_necessary(struct audio_stream *aos) -{ - unsigned long flags; - spin_lock_irqsave(&aos->dma_req_lock, flags); - pr_debug("%s\n", __func__); - if (!pending_buffer_requests(aos)) { - pr_debug("%s: no more data to play back\n", __func__); - sound_ops->stop_playback(aos); - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - allow_suspend(aos); - return true; - } - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - - return false; -} - -/* playback and recording */ -static bool wait_till_stopped(struct audio_stream *as) -{ - int rc; - pr_debug("%s: wait for completion\n", __func__); - rc = wait_for_completion_timeout( - &as->stop_completion, HZ); - if (!rc) - pr_err("%s: wait timed out", __func__); - if (rc < 0) - pr_err("%s: wait error %d\n", __func__, rc); - allow_suspend(as); - pr_debug("%s: done: %d\n", __func__, rc); - return true; -} - -/* Ask for playback and recording to stop. The _nosync means that - * as->lock has to be locked by the caller. - */ -static void request_stop_nosync(struct audio_stream *as) -{ - int i; - pr_debug("%s\n", __func__); - if (!as->stop) { - as->stop = true; - if (pending_buffer_requests(as)) - wait_till_stopped(as); - for (i = 0; i < as->num_bufs; i++) { - init_completion(&as->comp[i]); - complete(&as->comp[i]); - } - } - if (!tegra_dma_is_empty(as->dma_chan)) - pr_err("%s: DMA not empty!\n", __func__); - /* Stop the DMA then dequeue anything that's in progress. */ - tegra_dma_cancel(as->dma_chan); - as->active = false; /* applies to recording only */ - pr_debug("%s: done\n", __func__); -} - -static void setup_dma_tx_request(struct tegra_dma_req *req, - struct audio_stream *aos); - -static void setup_dma_rx_request(struct tegra_dma_req *req, - struct audio_stream *ais); - -static int setup_dma(struct audio_driver_state *ads, int mask) -{ - int rc, i; - pr_info("%s\n", __func__); - - if (mask & TEGRA_AUDIO_ENABLE_TX) { - /* setup audio playback */ - for (i = 0; i < ads->out.num_bufs; i++) { - ads->out.buf_phy[i] = dma_map_single(&ads->pdev->dev, - ads->out.buffer[i], - 1 << PCM_BUFFER_MAX_SIZE_ORDER, - DMA_TO_DEVICE); - BUG_ON(!ads->out.buf_phy[i]); - setup_dma_tx_request(&ads->out.dma_req[i], &ads->out); - ads->out.dma_req[i].source_addr = ads->out.buf_phy[i]; - } - ads->out.dma_chan = tegra_dma_allocate_channel( - TEGRA_DMA_MODE_CONTINUOUS_SINGLE); - if (!ads->out.dma_chan) { - pr_err("%s: error alloc output DMA channel: %ld\n", - __func__, PTR_ERR(ads->out.dma_chan)); - rc = -ENODEV; - goto fail_tx; - } - } - - if (mask & TEGRA_AUDIO_ENABLE_RX) { - /* setup audio recording */ - for (i = 0; i < ads->in.num_bufs; i++) { - ads->in.buf_phy[i] = dma_map_single(&ads->pdev->dev, - ads->in.buffer[i], - 1 << PCM_BUFFER_MAX_SIZE_ORDER, - DMA_FROM_DEVICE); - BUG_ON(!ads->in.buf_phy[i]); - setup_dma_rx_request(&ads->in.dma_req[i], &ads->in); - ads->in.dma_req[i].dest_addr = ads->in.buf_phy[i]; - } - ads->in.dma_chan = tegra_dma_allocate_channel( - TEGRA_DMA_MODE_CONTINUOUS_SINGLE); - if (!ads->in.dma_chan) { - pr_err("%s: error allocating input DMA channel: %ld\n", - __func__, PTR_ERR(ads->in.dma_chan)); - rc = -ENODEV; - goto fail_rx; - } - } - - return 0; - -fail_rx: - if (mask & TEGRA_AUDIO_ENABLE_RX) { - for (i = 0; i < ads->in.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->in.buf_phy[i], - 1 << PCM_BUFFER_MAX_SIZE_ORDER, - DMA_FROM_DEVICE); - ads->in.buf_phy[i] = 0; - } - tegra_dma_free_channel(ads->in.dma_chan); - ads->in.dma_chan = 0; - } -fail_tx: - if (mask & TEGRA_AUDIO_ENABLE_TX) { - for (i = 0; i < ads->out.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->out.buf_phy[i], - 1 << PCM_BUFFER_MAX_SIZE_ORDER, - DMA_TO_DEVICE); - ads->out.buf_phy[i] = 0; - } - tegra_dma_free_channel(ads->out.dma_chan); - ads->out.dma_chan = 0; - } - - return rc; -} - -static void tear_down_dma(struct audio_driver_state *ads, int mask) -{ - int i; - pr_info("%s\n", __func__); - - if (mask & TEGRA_AUDIO_ENABLE_TX) { - tegra_dma_free_channel(ads->out.dma_chan); - for (i = 0; i < ads->out.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->out.buf_phy[i], - buf_size(&ads->out), - DMA_TO_DEVICE); - ads->out.buf_phy[i] = 0; - } - } - ads->out.dma_chan = NULL; - - if (mask & TEGRA_AUDIO_ENABLE_RX) { - tegra_dma_free_channel(ads->in.dma_chan); - for (i = 0; i < ads->in.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->in.buf_phy[i], - buf_size(&ads->in), - DMA_FROM_DEVICE); - ads->in.buf_phy[i] = 0; - } - } - ads->in.dma_chan = NULL; -} - -static void dma_tx_complete_callback(struct tegra_dma_req *req) -{ - unsigned long flags; - struct audio_stream *aos = req->dev; - unsigned req_num; - - spin_lock_irqsave(&aos->dma_req_lock, flags); - - req_num = req - aos->dma_req; - pr_debug("%s: completed buffer %d size %d\n", __func__, - req_num, req->bytes_transferred); - BUG_ON(req_num >= aos->num_bufs); - - complete(&aos->comp[req_num]); - - if (!pending_buffer_requests(aos)) { - pr_debug("%s: Playback underflow\n", __func__); - complete(&aos->stop_completion); - } - - spin_unlock_irqrestore(&aos->dma_req_lock, flags); -} - -static void dma_rx_complete_callback(struct tegra_dma_req *req) -{ - unsigned long flags; - struct audio_stream *ais = req->dev; - unsigned req_num; - - spin_lock_irqsave(&ais->dma_req_lock, flags); - - req_num = req - ais->dma_req; - pr_debug("%s: completed buffer %d size %d\n", __func__, - req_num, req->bytes_transferred); - BUG_ON(req_num >= ais->num_bufs); - - complete(&ais->comp[req_num]); - - if (!pending_buffer_requests(ais)) - pr_debug("%s: Capture overflow\n", __func__); - - spin_unlock_irqrestore(&ais->dma_req_lock, flags); -} - -static void setup_dma_tx_request(struct tegra_dma_req *req, - struct audio_stream *aos) -{ - struct audio_driver_state *ads = ads_from_out(aos); - - memset(req, 0, sizeof(*req)); - - req->complete = dma_tx_complete_callback; - req->dev = aos; - req->to_memory = false; - req->dest_addr = i2s_get_fifo_phy_base(ads->i2s_phys, I2S_FIFO_TX); - req->dest_wrap = 4; - if (ads->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP) - req->dest_bus_width = ads->pdata->dsp_bus_width; - else - req->dest_bus_width = ads->pdata->i2s_bus_width; - req->source_bus_width = 32; - req->source_wrap = 0; - req->req_sel = ads->dma_req_sel; -} - -static void setup_dma_rx_request(struct tegra_dma_req *req, - struct audio_stream *ais) -{ - struct audio_driver_state *ads = ads_from_in(ais); - - memset(req, 0, sizeof(*req)); - - req->complete = dma_rx_complete_callback; - req->dev = ais; - req->to_memory = true; - req->source_addr = i2s_get_fifo_phy_base(ads->i2s_phys, I2S_FIFO_RX); - req->source_wrap = 4; - if (ads->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP) - req->source_bus_width = ads->pdata->dsp_bus_width; - else - req->source_bus_width = ads->pdata->i2s_bus_width; - req->dest_bus_width = 32; - req->dest_wrap = 0; - req->req_sel = ads->dma_req_sel; -} - -static int start_playback(struct audio_stream *aos, - struct tegra_dma_req *req) -{ - int rc; - unsigned long flags; - struct audio_driver_state *ads = ads_from_out(aos); - - pr_debug("%s: (writing %d)\n", - __func__, req->size); - - spin_lock_irqsave(&aos->dma_req_lock, flags); -#if 0 - i2s_fifo_clear(ads->i2s_base, I2S_FIFO_TX); -#endif - i2s_fifo_set_attention_level(ads->i2s_base, - I2S_FIFO_TX, aos->i2s_fifo_atn_level); - - i2s_fifo_enable(ads->i2s_base, I2S_FIFO_TX, 1); - - rc = tegra_dma_enqueue_req(aos->dma_chan, req); - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - - if (rc) - pr_err("%s: could not enqueue TX DMA req\n", __func__); - return rc; -} - -/* Called with aos->dma_req_lock taken. */ -static void stop_dma_playback(struct audio_stream *aos) -{ - int spin = 0; - struct audio_driver_state *ads = ads_from_out(aos); - pr_debug("%s\n", __func__); - i2s_fifo_enable(ads->i2s_base, I2S_FIFO_TX, 0); - while ((i2s_get_status(ads->i2s_base) & I2S_I2S_FIFO_TX_BUSY) && - spin < 100) { - udelay(10); - if (spin++ > 50) - pr_info("%s: spin %d\n", __func__, spin); - } - if (spin == 100) - pr_warn("%s: spinny\n", __func__); -} - -/* This function may be called from either interrupt or process context. */ -/* Called with ais->dma_req_lock taken. */ -static int start_dma_recording(struct audio_stream *ais, int size) -{ - int i; - struct audio_driver_state *ads = ads_from_in(ais); - - pr_debug("%s\n", __func__); - - BUG_ON(pending_buffer_requests(ais)); - - for (i = 0; i < ais->num_bufs; i++) { - init_completion(&ais->comp[i]); - ais->dma_req[i].dest_addr = ais->buf_phy[i]; - ais->dma_req[i].size = size; - tegra_dma_enqueue_req(ais->dma_chan, &ais->dma_req[i]); - } - - ais->last_queued = ais->num_bufs - 1; - -#if 0 - i2s_fifo_clear(ads->i2s_base, I2S_FIFO_RX); -#endif - i2s_fifo_set_attention_level(ads->i2s_base, - I2S_FIFO_RX, ais->i2s_fifo_atn_level); - i2s_fifo_enable(ads->i2s_base, I2S_FIFO_RX, 1); - return 0; -} - -static void stop_dma_recording(struct audio_stream *ais) -{ - int spin = 0; - struct audio_driver_state *ads = ads_from_in(ais); - pr_debug("%s\n", __func__); - tegra_dma_cancel(ais->dma_chan); - i2s_fifo_enable(ads->i2s_base, I2S_FIFO_RX, 0); - i2s_fifo_clear(ads->i2s_base, I2S_FIFO_RX); - while ((i2s_get_status(ads->i2s_base) & I2S_I2S_FIFO_RX_BUSY) && - spin < 100) { - udelay(10); - if (spin++ > 50) - pr_info("%s: spin %d\n", __func__, spin); - } - if (spin == 100) - pr_warn("%s: spinny\n", __func__); -} - -static irqreturn_t i2s_interrupt(int irq, void *data) -{ - struct audio_driver_state *ads = data; - u32 status = i2s_get_status(ads->i2s_base); - - pr_debug("%s: %08x\n", __func__, status); - - if (status & I2S_FIFO_ERR) - i2s_ack_status(ads->i2s_base); - - pr_debug("%s: done %08x\n", __func__, i2s_get_status(ads->i2s_base)); - return IRQ_HANDLED; -} - -static ssize_t tegra_audio_write(struct file *file, - const char __user *buf, size_t size, loff_t *off) -{ - ssize_t rc = 0; - int out_buf; - struct tegra_dma_req *req; - struct audio_driver_state *ads = ads_from_misc_out(file); - - mutex_lock(&ads->out.lock); - - if (!IS_ALIGNED(size, 4) || size < 4 || size > buf_size(&ads->out)) { - pr_err("%s: invalid user size %d\n", __func__, size); - rc = -EINVAL; - goto done; - } - - pr_debug("%s: write %d bytes\n", __func__, size); - - if (ads->out.stop) { - pr_debug("%s: playback has been cancelled\n", __func__); - goto done; - } - - /* Decide which buf is next. */ - out_buf = (ads->out.last_queued + 1) % ads->out.num_bufs; - req = &ads->out.dma_req[out_buf]; - - /* Wait for the buffer to be emptied (complete). The maximum timeout - * value could be calculated dynamically based on buf_size(&ads->out). - * For a buffer size of 16k, at 44.1kHz/stereo/16-bit PCM, you would - * have ~93ms. - */ - pr_debug("%s: waiting for buffer %d\n", __func__, out_buf); - rc = wait_for_completion_interruptible_timeout( - &ads->out.comp[out_buf], HZ); - if (!rc) { - pr_err("%s: timeout", __func__); - rc = -ETIMEDOUT; - goto done; - } else if (rc < 0) { - pr_err("%s: wait error %d", __func__, rc); - goto done; - } - - /* Fill the buffer and enqueue it. */ - pr_debug("%s: acquired buffer %d, copying data\n", __func__, out_buf); - rc = copy_from_user(ads->out.buffer[out_buf], buf, size); - if (rc) { - rc = -EFAULT; - goto done; - } - - prevent_suspend(&ads->out); - - req->size = size; - dma_sync_single_for_device(NULL, - req->source_addr, req->size, DMA_TO_DEVICE); - ads->out.last_queued = out_buf; - init_completion(&ads->out.stop_completion); - - rc = start_playback(&ads->out, req); - if (!rc) - rc = size; - else - allow_suspend(&ads->out); - -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static long tegra_audio_out_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = 0; - struct audio_driver_state *ads = ads_from_misc_out_ctl(file); - struct audio_stream *aos = &ads->out; - - mutex_lock(&aos->lock); - - switch (cmd) { - case TEGRA_AUDIO_OUT_FLUSH: - if (pending_buffer_requests(aos)) { - pr_debug("%s: flushing\n", __func__); - request_stop_nosync(aos); - pr_debug("%s: flushed\n", __func__); - } - if (stop_playback_if_necessary(aos)) - pr_debug("%s: done (stopped)\n", __func__); - aos->stop = false; - break; - case TEGRA_AUDIO_OUT_SET_NUM_BUFS: { - unsigned int num; - if (copy_from_user(&num, (const void __user *)arg, - sizeof(num))) { - rc = -EFAULT; - break; - } - if (!num || num > I2S_MAX_NUM_BUFS) { - pr_err("%s: invalid buffer count %d\n", __func__, num); - rc = -EINVAL; - break; - } - if (pending_buffer_requests(aos)) { - pr_err("%s: playback in progress\n", __func__); - rc = -EBUSY; - break; - } - rc = init_stream_buffer(aos, num); - if (rc < 0) - break; - aos->num_bufs = num; - sound_ops->tear_down(ads, TEGRA_AUDIO_ENABLE_TX); - sound_ops->setup(ads, TEGRA_AUDIO_ENABLE_TX); - pr_debug("%s: num buf set to %d\n", __func__, num); - } - break; - case TEGRA_AUDIO_OUT_GET_NUM_BUFS: - if (copy_to_user((void __user *)arg, - &aos->num_bufs, sizeof(aos->num_bufs))) - rc = -EFAULT; - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&aos->lock); - return rc; -} - -static long tegra_audio_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = 0; - struct audio_driver_state *ads = ads_from_misc_ctl(file); - unsigned int mode; - bool dma_restart = false; - - mutex_lock(&ads->out.lock); - mutex_lock(&ads->in.lock); - - switch (cmd) { - case TEGRA_AUDIO_SET_BIT_FORMAT: - if (copy_from_user(&mode, (const void __user *)arg, - sizeof(mode))) { - rc = -EFAULT; - goto done; - } - dma_restart = (mode != ads->bit_format); - switch (mode) { - case TEGRA_AUDIO_BIT_FORMAT_DEFAULT: - i2s_set_bit_format(ads->i2s_base, ads->pdata->mode); - ads->bit_format = mode; - break; - case TEGRA_AUDIO_BIT_FORMAT_DSP: - i2s_set_bit_format(ads->i2s_base, I2S_BIT_FORMAT_DSP); - ads->bit_format = mode; - break; - default: - pr_err("%s: Invald PCM mode %d", __func__, mode); - rc = -EINVAL; - goto done; - } - break; - case TEGRA_AUDIO_GET_BIT_FORMAT: - if (copy_to_user((void __user *)arg, &ads->bit_format, - sizeof(mode))) - rc = -EFAULT; - goto done; - } - - if (dma_restart) { - pr_debug("%s: Restarting DMA due to configuration change.\n", - __func__); - if (pending_buffer_requests(&ads->out) || ads->in.active) { - pr_err("%s: dma busy, cannot restart.\n", __func__); - rc = -EBUSY; - goto done; - } - sound_ops->tear_down(ads, ads->pdata->mask); - i2s_configure(ads->pdev); - sound_ops->setup(ads, ads->pdata->mask); - } - -done: - mutex_unlock(&ads->in.lock); - mutex_unlock(&ads->out.lock); - return rc; -} - -static long tegra_audio_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = 0; - struct audio_driver_state *ads = ads_from_misc_in_ctl(file); - struct audio_stream *ais = &ads->in; - - mutex_lock(&ais->lock); - - switch (cmd) { - case TEGRA_AUDIO_IN_START: - pr_debug("%s: start recording\n", __func__); - ais->stop = false; - break; - case TEGRA_AUDIO_IN_STOP: - pr_debug("%s: stop recording\n", __func__); - if (ais->active) { - /* Clean up DMA/I2S, and complete the completion */ - sound_ops->stop_recording(ais); - complete(&ais->stop_completion); - /* Set stop flag and allow suspend. */ - request_stop_nosync(ais); - } - break; - case TEGRA_AUDIO_IN_SET_CONFIG: { - struct tegra_audio_in_config cfg; - - if (ais->active) { - pr_err("%s: recording in progress\n", __func__); - rc = -EBUSY; - break; - } - if (copy_from_user(&cfg, (const void __user *)arg, - sizeof(cfg))) { - rc = -EFAULT; - break; - } - - if (cfg.stereo && !ads->pdata->stereo_capture) { - pr_err("%s: not capable of stereo capture.", - __func__); - rc = -EINVAL; - } - if (!rc) { - pr_info("%s: setting input sampling rate to %d, %s\n", - __func__, cfg.rate, - cfg.stereo ? "stereo" : "mono"); - ads->in_config = cfg; - ads->in_config.stereo = !!ads->in_config.stereo; - } - } - break; - case TEGRA_AUDIO_IN_GET_CONFIG: - if (copy_to_user((void __user *)arg, &ads->in_config, - sizeof(ads->in_config))) - rc = -EFAULT; - break; - case TEGRA_AUDIO_IN_SET_NUM_BUFS: { - unsigned int num; - if (copy_from_user(&num, (const void __user *)arg, - sizeof(num))) { - rc = -EFAULT; - break; - } - if (!num || num > I2S_MAX_NUM_BUFS) { - pr_err("%s: invalid buffer count %d\n", __func__, - num); - rc = -EINVAL; - break; - } - if (ais->active || pending_buffer_requests(ais)) { - pr_err("%s: recording in progress\n", __func__); - rc = -EBUSY; - break; - } - rc = init_stream_buffer(ais, num); - if (rc < 0) - break; - ais->num_bufs = num; - sound_ops->tear_down(ads, TEGRA_AUDIO_ENABLE_RX); - sound_ops->setup(ads, TEGRA_AUDIO_ENABLE_RX); - } - break; - case TEGRA_AUDIO_IN_GET_NUM_BUFS: - if (copy_to_user((void __user *)arg, - &ais->num_bufs, sizeof(ais->num_bufs))) - rc = -EFAULT; - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&ais->lock); - return rc; -} - -static ssize_t tegra_audio_read(struct file *file, char __user *buf, - size_t size, loff_t *off) -{ - ssize_t rc; - ssize_t nr = 0; - int in_buf; - struct tegra_dma_req *req; - struct audio_driver_state *ads = ads_from_misc_in(file); - - mutex_lock(&ads->in.lock); - - if (!IS_ALIGNED(size, 4) || size < 4 || size > buf_size(&ads->in)) { - pr_err("%s: invalid size %d.\n", __func__, size); - rc = -EINVAL; - goto done; - } - - pr_debug("%s: size %d\n", __func__, size); - - /* If we want recording to stop immediately after it gets cancelled, - * then we do not want to wait for the fifo to get drained. - */ - if (ads->in.stop) { - pr_debug("%s: recording has been cancelled\n", __func__); - rc = 0; - goto done; - } - - /* This function calls prevent_suspend() internally */ - rc = start_recording_if_necessary(&ads->in, size); - if (rc < 0 && rc != -EALREADY) { - pr_err("%s: could not start recording\n", __func__); - goto done; - } - - ads->in.active = true; - - /* Note that when tegra_audio_read() is called for the first time (or - * when all the buffers are empty), then it queues up all - * ads->in.num_bufs buffers, and in_buf is set to zero below. - */ - in_buf = (ads->in.last_queued + 1) % ads->in.num_bufs; - - /* Wait for the buffer to be filled (complete). The maximum timeout - * value could be calculated dynamically based on buf_size(&ads->in). - * For a buffer size of 16k, at 44.1kHz/stereo/16-bit PCM, you would - * have ~93ms. - */ - rc = wait_for_completion_interruptible_timeout( - &ads->in.comp[in_buf], HZ); - if (!rc) { - pr_err("%s: timeout", __func__); - rc = -ETIMEDOUT; - goto done; - } else if (rc < 0) { - pr_err("%s: wait error %d", __func__, rc); - goto done; - } - - req = &ads->in.dma_req[in_buf]; - - nr = size > req->size ? req->size : size; - req->size = size; - dma_sync_single_for_cpu(NULL, ads->in.dma_req[in_buf].dest_addr, - ads->in.dma_req[in_buf].size, DMA_FROM_DEVICE); - rc = copy_to_user(buf, ads->in.buffer[in_buf], nr); - if (rc) { - rc = -EFAULT; - goto done; - } - - init_completion(&ads->in.stop_completion); - - ads->in.last_queued = in_buf; - rc = tegra_dma_enqueue_req(ads->in.dma_chan, req); - /* We've successfully enqueued this request before. */ - BUG_ON(rc); - - rc = nr; - *off += nr; -done: - mutex_unlock(&ads->in.lock); - pr_debug("%s: done %d\n", __func__, rc); - return rc; -} - -static int tegra_audio_out_open(struct inode *inode, struct file *file) -{ - int rc = 0; - int i; - struct audio_driver_state *ads = ads_from_misc_out(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->out.lock); - - if (ads->out.opened) { - rc = -EBUSY; - goto done; - } - - ads->out.opened = 1; - ads->out.stop = false; - - for (i = 0; i < I2S_MAX_NUM_BUFS; i++) { - init_completion(&ads->out.comp[i]); - /* TX buf rest state is unqueued, complete. */ - complete(&ads->out.comp[i]); - } - -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static int tegra_audio_out_release(struct inode *inode, struct file *file) -{ - struct audio_driver_state *ads = ads_from_misc_out(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->out.lock); - ads->out.opened = 0; - request_stop_nosync(&ads->out); - if (stop_playback_if_necessary(&ads->out)) - pr_debug("%s: done (stopped)\n", __func__); - allow_suspend(&ads->out); - mutex_unlock(&ads->out.lock); - pr_debug("%s: done\n", __func__); - return 0; -} - -static int tegra_audio_in_open(struct inode *inode, struct file *file) -{ - int rc = 0; - int i; - struct audio_driver_state *ads = ads_from_misc_in(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->in.lock); - if (ads->in.opened) { - rc = -EBUSY; - goto done; - } - - ads->in.opened = 1; - ads->in.stop = false; - - for (i = 0; i < I2S_MAX_NUM_BUFS; i++) { - init_completion(&ads->in.comp[i]); - /* RX buf rest state is unqueued, complete. */ - complete(&ads->in.comp[i]); - } - -done: - mutex_unlock(&ads->in.lock); - return rc; -} - -static int tegra_audio_in_release(struct inode *inode, struct file *file) -{ - struct audio_driver_state *ads = ads_from_misc_in(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->in.lock); - ads->in.opened = 0; - if (ads->in.active) { - sound_ops->stop_recording(&ads->in); - complete(&ads->in.stop_completion); - request_stop_nosync(&ads->in); - } - allow_suspend(&ads->in); - mutex_unlock(&ads->in.lock); - pr_debug("%s: done\n", __func__); - return 0; -} - -static const struct file_operations tegra_audio_out_fops = { - .owner = THIS_MODULE, - .open = tegra_audio_out_open, - .release = tegra_audio_out_release, - .write = tegra_audio_write, -}; - -static const struct file_operations tegra_audio_in_fops = { - .owner = THIS_MODULE, - .open = tegra_audio_in_open, - .read = tegra_audio_read, - .release = tegra_audio_in_release, -}; - -static int tegra_audio_ctl_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int tegra_audio_ctl_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations tegra_audio_out_ctl_fops = { - .owner = THIS_MODULE, - .open = tegra_audio_ctl_open, - .release = tegra_audio_ctl_release, - .unlocked_ioctl = tegra_audio_out_ioctl, -}; - -static const struct file_operations tegra_audio_in_ctl_fops = { - .owner = THIS_MODULE, - .open = tegra_audio_ctl_open, - .release = tegra_audio_ctl_release, - .unlocked_ioctl = tegra_audio_in_ioctl, -}; - -static const struct file_operations tegra_audio_ctl_fops = { - .owner = THIS_MODULE, - .open = tegra_audio_ctl_open, - .release = tegra_audio_ctl_release, - .unlocked_ioctl = tegra_audio_ioctl, -}; - -static int init_stream_buffer(struct audio_stream *s, int num) -{ - int i, j; - pr_debug("%s (num %d)\n", __func__, num); - - for (i = 0; i < num; i++) { - kfree(s->buffer[i]); - s->buffer[i] = - kmalloc((1 << PCM_BUFFER_MAX_SIZE_ORDER), - GFP_KERNEL | GFP_DMA); - if (!s->buffer[i]) { - pr_err("%s: could not allocate buffer\n", __func__); - for (j = i - 1; j >= 0; j--) { - kfree(s->buffer[j]); - s->buffer[j] = 0; - } - return -ENOMEM; - } - } - return 0; -} - - -static int setup_misc_device(struct miscdevice *misc, - const struct file_operations *fops, - const char *fmt, ...) -{ - int rc = 0; - va_list args; - const int sz = 64; - - va_start(args, fmt); - - memset(misc, 0, sizeof(*misc)); - misc->minor = MISC_DYNAMIC_MINOR; - misc->name = kmalloc(sz, GFP_KERNEL); - if (!misc->name) { - rc = -ENOMEM; - goto done; - } - - vsnprintf((char *)misc->name, sz, fmt, args); - misc->fops = fops; - if (misc_register(misc)) { - pr_err("%s: could not register %s\n", __func__, misc->name); - kfree(misc->name); - rc = -EIO; - goto done; - } - -done: - va_end(args); - return rc; -} - -static ssize_t dma_toggle_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "dma\n"); -} - -static ssize_t dma_toggle_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - pr_err("%s: Not implemented.", __func__); - return 0; -} - -static DEVICE_ATTR(dma_toggle, 0644, dma_toggle_show, dma_toggle_store); - -static ssize_t __attr_fifo_atn_read(char *buf, int atn_lvl) -{ - switch (atn_lvl) { - case I2S_FIFO_ATN_LVL_ONE_SLOT: - strncpy(buf, "1\n", 2); - return 2; - case I2S_FIFO_ATN_LVL_FOUR_SLOTS: - strncpy(buf, "4\n", 2); - return 2; - case I2S_FIFO_ATN_LVL_EIGHT_SLOTS: - strncpy(buf, "8\n", 2); - return 2; - case I2S_FIFO_ATN_LVL_TWELVE_SLOTS: - strncpy(buf, "12\n", 3); - return 3; - default: - BUG_ON(1); - return -EIO; - } -} - -static ssize_t __attr_fifo_atn_write(struct audio_driver_state *ads, - struct audio_stream *as, - int *fifo_lvl, - const char *buf, size_t size) -{ - int lvl; - - if (size > 3) { - pr_err("%s: buffer size %d too big\n", __func__, size); - return -EINVAL; - } - - if (sscanf(buf, "%d", &lvl) != 1) { - pr_err("%s: invalid input string [%s]\n", __func__, buf); - return -EINVAL; - } - - switch (lvl) { - case 1: - lvl = I2S_FIFO_ATN_LVL_ONE_SLOT; - break; - case 4: - lvl = I2S_FIFO_ATN_LVL_FOUR_SLOTS; - break; - case 8: - lvl = I2S_FIFO_ATN_LVL_EIGHT_SLOTS; - break; - case 12: - lvl = I2S_FIFO_ATN_LVL_TWELVE_SLOTS; - break; - default: - pr_err("%s: invalid attention level %d\n", __func__, lvl); - return -EINVAL; - } - - *fifo_lvl = lvl; - pr_info("%s: fifo level %d\n", __func__, *fifo_lvl); - - return size; -} - -static ssize_t tx_fifo_atn_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - return __attr_fifo_atn_read(buf, ads->out.i2s_fifo_atn_level); -} - -static ssize_t tx_fifo_atn_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - ssize_t rc; - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - mutex_lock(&ads->out.lock); - if (pending_buffer_requests(&ads->out)) { - pr_err("%s: playback in progress.\n", __func__); - rc = -EBUSY; - goto done; - } - rc = __attr_fifo_atn_write(ads, &ads->out, - &ads->out.i2s_fifo_atn_level, - buf, count); -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static DEVICE_ATTR(tx_fifo_atn, 0644, tx_fifo_atn_show, tx_fifo_atn_store); - -static ssize_t rx_fifo_atn_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - return __attr_fifo_atn_read(buf, ads->in.i2s_fifo_atn_level); -} - -static ssize_t rx_fifo_atn_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - ssize_t rc; - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - mutex_lock(&ads->in.lock); - if (ads->in.active) { - pr_err("%s: recording in progress.\n", __func__); - rc = -EBUSY; - goto done; - } - rc = __attr_fifo_atn_write(ads, &ads->in, - &ads->in.i2s_fifo_atn_level, - buf, count); -done: - mutex_unlock(&ads->in.lock); - return rc; -} - -static DEVICE_ATTR(rx_fifo_atn, 0644, rx_fifo_atn_show, rx_fifo_atn_store); - -static int tegra_audio_probe(struct platform_device *pdev) -{ - int rc, i; - struct resource *res; - struct clk *i2s_clk, *dap_mclk; - struct audio_driver_state *state; - - pr_info("%s\n", __func__); - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->pdev = pdev; - state->pdata = pdev->dev.platform_data; - state->pdata->driver_data = state; - BUG_ON(!state->pdata); - - if (!(state->pdata->mask & - (TEGRA_AUDIO_ENABLE_TX | TEGRA_AUDIO_ENABLE_RX))) { - dev_err(&pdev->dev, "neither tx nor rx is enabled!\n"); - return -EIO; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mem resource!\n"); - return -ENODEV; - } - - if (!request_mem_region(res->start, resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "memory region already claimed!\n"); - return -ENOMEM; - } - - state->i2s_phys = res->start; - state->i2s_base = (unsigned long)ioremap(res->start, - res->end - res->start + 1); - if (!state->i2s_base) { - dev_err(&pdev->dev, "cannot remap iomem!\n"); - return -EIO; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "no dma resource!\n"); - return -ENODEV; - } - state->dma_req_sel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, "no irq resource!\n"); - return -ENODEV; - } - state->irq = res->start; - - i2s_clk = clk_get(&pdev->dev, NULL); - if (!i2s_clk) { - dev_err(&pdev->dev, "%s: could not get i2s clock\n", - __func__); - return -EIO; - } - - clk_set_rate(i2s_clk, state->pdata->i2s_clk_rate); - if (clk_enable(i2s_clk)) { - dev_err(&pdev->dev, "%s: failed to enable i2s clock\n", - __func__); - return -EIO; - } - pr_info("%s: i2s_clk rate %ld\n", __func__, clk_get_rate(i2s_clk)); - - dap_mclk = tegra_get_clock_by_name(state->pdata->dap_clk); - if (!dap_mclk) { - dev_err(&pdev->dev, "%s: could not get DAP clock\n", - __func__); - return -EIO; - } - clk_enable(dap_mclk); - - rc = i2s_configure(pdev); - if (rc < 0) - return rc; - - if ((state->pdata->mask & TEGRA_AUDIO_ENABLE_TX)) { - state->out.opened = 0; - state->out.active = false; - mutex_init(&state->out.lock); - init_completion(&state->out.stop_completion); - spin_lock_init(&state->out.dma_req_lock); - state->out.dma_chan = NULL; - state->out.i2s_fifo_atn_level = I2S_FIFO_ATN_LVL_FOUR_SLOTS; - state->out.num_bufs = I2S_DEFAULT_TX_NUM_BUFS; - for (i = 0; i < I2S_MAX_NUM_BUFS; i++) { - init_completion(&state->out.comp[i]); - /* TX buf rest state is unqueued, complete. */ - complete(&state->out.comp[i]); - state->out.buffer[i] = 0; - state->out.buf_phy[i] = 0; - } - state->out.last_queued = 0; - rc = init_stream_buffer(&state->out, state->out.num_bufs); - if (rc < 0) - return rc; - - INIT_WORK(&state->out.allow_suspend_work, allow_suspend_worker); - - snprintf(state->out.wake_lock_name, - sizeof(state->out.wake_lock_name), - "i2s.%d-audio-out", state->pdev->id); - wake_lock_init(&state->out.wake_lock, WAKE_LOCK_SUSPEND, - state->out.wake_lock_name); - - rc = setup_misc_device(&state->misc_out, - &tegra_audio_out_fops, - "audio%d_out", state->pdev->id); - if (rc < 0) - return rc; - - rc = setup_misc_device(&state->misc_out_ctl, - &tegra_audio_out_ctl_fops, - "audio%d_out_ctl", state->pdev->id); - if (rc < 0) - return rc; - } - - if ((state->pdata->mask & TEGRA_AUDIO_ENABLE_RX)) { - state->in.opened = 0; - state->in.active = false; - mutex_init(&state->in.lock); - init_completion(&state->in.stop_completion); - spin_lock_init(&state->in.dma_req_lock); - state->in.dma_chan = NULL; - state->in.i2s_fifo_atn_level = I2S_FIFO_ATN_LVL_FOUR_SLOTS; - state->in.num_bufs = I2S_DEFAULT_RX_NUM_BUFS; - for (i = 0; i < I2S_MAX_NUM_BUFS; i++) { - init_completion(&state->in.comp[i]); - /* RX buf rest state is unqueued, complete. */ - complete(&state->in.comp[i]); - state->in.buffer[i] = 0; - state->in.buf_phy[i] = 0; - } - state->in.last_queued = 0; - rc = init_stream_buffer(&state->in, state->in.num_bufs); - if (rc < 0) - return rc; - - INIT_WORK(&state->in.allow_suspend_work, allow_suspend_worker); - - snprintf(state->in.wake_lock_name, - sizeof(state->in.wake_lock_name), - "i2s.%d-audio-in", state->pdev->id); - wake_lock_init(&state->in.wake_lock, WAKE_LOCK_SUSPEND, - state->in.wake_lock_name); - - rc = setup_misc_device(&state->misc_in, - &tegra_audio_in_fops, - "audio%d_in", state->pdev->id); - if (rc < 0) - return rc; - - rc = setup_misc_device(&state->misc_in_ctl, - &tegra_audio_in_ctl_fops, - "audio%d_in_ctl", state->pdev->id); - if (rc < 0) - return rc; - } - - if (request_irq(state->irq, i2s_interrupt, - IRQF_DISABLED, state->pdev->name, state) < 0) { - dev_err(&pdev->dev, - "%s: could not register handler for irq %d\n", - __func__, state->irq); - return -EIO; - } - - rc = setup_misc_device(&state->misc_ctl, - &tegra_audio_ctl_fops, - "audio%d_ctl", state->pdev->id); - if (rc < 0) - return rc; - - sound_ops->setup(state, state->pdata->mask); - - rc = device_create_file(&pdev->dev, &dev_attr_dma_toggle); - if (rc < 0) { - dev_err(&pdev->dev, "%s: could not create sysfs entry %s: %d\n", - __func__, dev_attr_dma_toggle.attr.name, rc); - return rc; - } - - rc = device_create_file(&pdev->dev, &dev_attr_tx_fifo_atn); - if (rc < 0) { - dev_err(&pdev->dev, "%s: could not create sysfs entry %s: %d\n", - __func__, dev_attr_tx_fifo_atn.attr.name, rc); - return rc; - } - - rc = device_create_file(&pdev->dev, &dev_attr_rx_fifo_atn); - if (rc < 0) { - dev_err(&pdev->dev, "%s: could not create sysfs entry %s: %d\n", - __func__, dev_attr_rx_fifo_atn.attr.name, rc); - return rc; - } - - state->in_config.rate = 11025; - state->in_config.stereo = false; - - return 0; -} - -#ifdef CONFIG_PM -static int tegra_audio_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - /* dev_info(&pdev->dev, "%s\n", __func__); */ - return 0; -} - -static int tegra_audio_resume(struct platform_device *pdev) -{ - return i2s_configure(pdev); -} -#endif /* CONFIG_PM */ - -static struct platform_driver tegra_audio_driver = { - .driver = { - .name = "i2s", - .owner = THIS_MODULE, - }, - .probe = tegra_audio_probe, -#ifdef CONFIG_PM - .suspend = tegra_audio_suspend, - .resume = tegra_audio_resume, -#endif -}; - -static int __init tegra_audio_init(void) -{ - return platform_driver_register(&tegra_audio_driver); -} - -module_init(tegra_audio_init); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-tegra/tegra_spdif_audio.c b/arch/arm/mach-tegra/tegra_spdif_audio.c deleted file mode 100644 index 6613d3d5edeb..000000000000 --- a/arch/arm/mach-tegra/tegra_spdif_audio.c +++ /dev/null @@ -1,1186 +0,0 @@ -/* - * arch/arm/mach-tegra/tegra_spdif_audio.c - * - * S/PDIF audio driver for NVIDIA Tegra SoCs - * - * Copyright (c) 2008-2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "clock.h" - -#define PCM_BUFFER_MAX_SIZE_ORDER (PAGE_SHIFT) - -#define SPDIF_MAX_NUM_BUFS 4 -/* Todo: Add IOCTL to configure the number of buffers. */ -#define SPDIF_DEFAULT_TX_NUM_BUFS 2 -#define SPDIF_DEFAULT_RX_NUM_BUFS 2 -/* per stream (input/output) */ -struct audio_stream { - int opened; - struct mutex lock; - - bool active; /* is DMA in progress? */ - int num_bufs; - void *buffer[SPDIF_MAX_NUM_BUFS]; - dma_addr_t buf_phy[SPDIF_MAX_NUM_BUFS]; - struct completion comp[SPDIF_MAX_NUM_BUFS]; - struct tegra_dma_req dma_req[SPDIF_MAX_NUM_BUFS]; - int last_queued; - - int spdif_fifo_atn_level; - - struct tegra_dma_channel *dma_chan; - bool stop; - struct completion stop_completion; - spinlock_t dma_req_lock; - - struct work_struct allow_suspend_work; - struct wake_lock wake_lock; - char wake_lock_name[100]; -}; - -struct audio_driver_state { - struct list_head next; - - struct platform_device *pdev; - struct tegra_audio_platform_data *pdata; - phys_addr_t spdif_phys; - unsigned long spdif_base; - - unsigned long dma_req_sel; - bool fifo_init; - - int irq; - - struct miscdevice misc_out; - struct miscdevice misc_out_ctl; - struct audio_stream out; -}; - -static inline bool pending_buffer_requests(struct audio_stream *stream) -{ - int i; - for (i = 0; i < stream->num_bufs; i++) - if (!completion_done(&stream->comp[i])) - return true; - return false; -} - -static inline int buf_size(struct audio_stream *s __attribute__((unused))) -{ - return 1 << PCM_BUFFER_MAX_SIZE_ORDER; -} - -static inline struct audio_driver_state *ads_from_misc_out(struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, misc_out); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_misc_out_ctl( - struct file *file) -{ - struct miscdevice *m = file->private_data; - struct audio_driver_state *ads = - container_of(m, struct audio_driver_state, - misc_out_ctl); - BUG_ON(!ads); - return ads; -} - -static inline struct audio_driver_state *ads_from_out( - struct audio_stream *aos) -{ - return container_of(aos, struct audio_driver_state, out); -} - -static inline void prevent_suspend(struct audio_stream *as) -{ - pr_debug("%s\n", __func__); - cancel_work_sync(&as->allow_suspend_work); - wake_lock(&as->wake_lock); -} - -static void allow_suspend_worker(struct work_struct *w) -{ - struct audio_stream *as = container_of(w, - struct audio_stream, allow_suspend_work); - pr_debug("%s\n", __func__); - wake_unlock(&as->wake_lock); -} - -static inline void allow_suspend(struct audio_stream *as) -{ - schedule_work(&as->allow_suspend_work); -} - -#define I2S_I2S_FIFO_TX_BUSY I2S_I2S_STATUS_FIFO1_BSY -#define I2S_I2S_FIFO_TX_QS I2S_I2S_STATUS_QS_FIFO1 -#define I2S_I2S_FIFO_TX_ERR I2S_I2S_STATUS_FIFO1_ERR - -#define I2S_I2S_FIFO_RX_BUSY I2S_I2S_STATUS_FIFO2_BSY -#define I2S_I2S_FIFO_RX_QS I2S_I2S_STATUS_QS_FIFO2 -#define I2S_I2S_FIFO_RX_ERR I2S_I2S_STATUS_FIFO2_ERR - -#define I2S_FIFO_ERR (I2S_I2S_STATUS_FIFO1_ERR | I2S_I2S_STATUS_FIFO2_ERR) - - -static inline void spdif_writel(unsigned long base, u32 val, u32 reg) -{ - writel(val, base + reg); -} - -static inline u32 spdif_readl(unsigned long base, u32 reg) -{ - return readl(base + reg); -} - -static inline void spdif_fifo_write(unsigned long base, u32 data) -{ - spdif_writel(base, data, SPDIF_DATA_OUT_0); -} - -static int spdif_fifo_set_attention_level(unsigned long base, - unsigned level) -{ - u32 val; - - if (level > SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS) { - pr_err("%s: invalid fifo level selector %d\n", __func__, - level); - return -EINVAL; - } - - val = spdif_readl(base, SPDIF_DATA_FIFO_CSR_0); - - val &= ~SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_MASK; - val |= level << SPDIF_DATA_FIFO_CSR_0_TX_ATN_LVL_SHIFT; - - - spdif_writel(base, val, SPDIF_DATA_FIFO_CSR_0); - return 0; -} - -static void spdif_fifo_enable(unsigned long base, int on) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - val &= ~(SPDIF_CTRL_0_TX_EN | SPDIF_CTRL_0_TC_EN | SPDIF_CTRL_0_TU_EN); - val |= on ? (SPDIF_CTRL_0_TX_EN) : 0; - val |= on ? (SPDIF_CTRL_0_TC_EN) : 0; - - spdif_writel(base, val, SPDIF_CTRL_0); -} -#if 0 -static bool spdif_is_fifo_enabled(unsigned long base) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - return !!(val & SPDIF_CTRL_0_TX_EN); -} -#endif - -static void spdif_fifo_clear(unsigned long base) -{ - u32 val = spdif_readl(base, SPDIF_DATA_FIFO_CSR_0); - val &= ~(SPDIF_DATA_FIFO_CSR_0_TX_CLR | SPDIF_DATA_FIFO_CSR_0_TU_CLR); - val |= SPDIF_DATA_FIFO_CSR_0_TX_CLR | SPDIF_DATA_FIFO_CSR_0_TU_CLR; - spdif_writel(base, val, SPDIF_DATA_FIFO_CSR_0); -} - - -static int spdif_set_bit_mode(unsigned long base, unsigned mode) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - val &= ~SPDIF_CTRL_0_BIT_MODE_MASK; - - if (mode > SPDIF_BIT_MODE_MODERAW) { - pr_err("%s: invalid bit_size selector %d\n", __func__, - mode); - return -EINVAL; - } - - val |= mode << SPDIF_CTRL_0_BIT_MODE_SHIFT; - - spdif_writel(base, val, SPDIF_CTRL_0); - return 0; -} - -static int spdif_set_fifo_packed(unsigned long base, unsigned on) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - val &= ~SPDIF_CTRL_0_PACK; - val |= on ? SPDIF_CTRL_0_PACK : 0; - spdif_writel(base, val, SPDIF_CTRL_0); - return 0; -} - -#if 0 -static void spdif_set_fifo_irq_on_err(unsigned long base, int on) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - val &= ~SPDIF_CTRL_0_IE_TXE; - val |= on ? SPDIF_CTRL_0_IE_TXE : 0; - spdif_writel(base, val, SPDIF_CTRL_0); -} -#endif - - -static void spdif_enable_fifos(unsigned long base, int on) -{ - u32 val = spdif_readl(base, SPDIF_CTRL_0); - if (on) - val |= SPDIF_CTRL_0_TX_EN | SPDIF_CTRL_0_TC_EN | - SPDIF_CTRL_0_IE_TXE; - else - val &= ~(SPDIF_CTRL_0_TX_EN | SPDIF_CTRL_0_TC_EN | - SPDIF_CTRL_0_IE_TXE); - - spdif_writel(base, val, SPDIF_CTRL_0); -} - -static inline u32 spdif_get_status(unsigned long base) -{ - return spdif_readl(base, SPDIF_STATUS_0); -} - -static inline u32 spdif_get_control(unsigned long base) -{ - return spdif_readl(base, SPDIF_CTRL_0); -} - -static inline void spdif_ack_status(unsigned long base) -{ - return spdif_writel(base, spdif_readl(base, SPDIF_STATUS_0), - SPDIF_STATUS_0); -} - -static inline u32 spdif_get_fifo_scr(unsigned long base) -{ - return spdif_readl(base, SPDIF_DATA_FIFO_CSR_0); -} - -static inline phys_addr_t spdif_get_fifo_phy_base(unsigned long phy_base) -{ - return phy_base + SPDIF_DATA_OUT_0; -} - -static inline u32 spdif_get_fifo_full_empty_count(unsigned long base) -{ - u32 val = spdif_readl(base, SPDIF_DATA_FIFO_CSR_0); - val = val >> SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_SHIFT; - return val & SPDIF_DATA_FIFO_CSR_0_TD_EMPTY_COUNT_MASK; -} - - -static int spdif_set_sample_rate(struct audio_driver_state *state, - unsigned int sample_rate) -{ - unsigned int clock_freq = 0; - struct clk *spdif_clk; - - unsigned int ch_sta[] = { - 0x0, /* 44.1, default values */ - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - }; - - switch (sample_rate) { - case 32000: - clock_freq = 4096000; /* 4.0960 MHz */ - ch_sta[0] = 0x3 << 24; - ch_sta[1] = 0xC << 4; - break; - case 44100: - clock_freq = 5644800; /* 5.6448 MHz */ - ch_sta[0] = 0x0; - ch_sta[1] = 0xF << 4; - break; - case 48000: - clock_freq = 6144000; /* 6.1440MHz */ - ch_sta[0] = 0x2 << 24; - ch_sta[1] = 0xD << 4; - break; - case 88200: - clock_freq = 11289600; /* 11.2896 MHz */ - break; - case 96000: - clock_freq = 12288000; /* 12.288 MHz */ - break; - case 176400: - clock_freq = 22579200; /* 22.5792 MHz */ - break; - case 192000: - clock_freq = 24576000; /* 24.5760 MHz */ - break; - default: - return -1; - } - - spdif_clk = clk_get(&state->pdev->dev, NULL); - if (!spdif_clk) { - dev_err(&state->pdev->dev, "%s: could not get spdif clock\n", - __func__); - return -EIO; - } - - clk_set_rate(spdif_clk, clock_freq); - if (clk_enable(spdif_clk)) { - dev_err(&state->pdev->dev, - "%s: failed to enable spdif_clk clock\n", __func__); - return -EIO; - } - pr_info("%s: spdif_clk rate %ld\n", __func__, clk_get_rate(spdif_clk)); - - spdif_writel(state->spdif_base, ch_sta[0], SPDIF_CH_STA_TX_A_0); - spdif_writel(state->spdif_base, ch_sta[1], SPDIF_CH_STA_TX_B_0); - spdif_writel(state->spdif_base, ch_sta[2], SPDIF_CH_STA_TX_C_0); - spdif_writel(state->spdif_base, ch_sta[3], SPDIF_CH_STA_TX_D_0); - spdif_writel(state->spdif_base, ch_sta[4], SPDIF_CH_STA_TX_E_0); - spdif_writel(state->spdif_base, ch_sta[5], SPDIF_CH_STA_TX_F_0); - - return 0; -} - -static int init_stream_buffer(struct audio_stream *, int); - -static int setup_dma(struct audio_driver_state *); -static void tear_down_dma(struct audio_driver_state *); -static void stop_dma_playback(struct audio_stream *); - - -struct sound_ops { - int (*setup)(struct audio_driver_state *); - void (*tear_down)(struct audio_driver_state *); - void (*stop_playback)(struct audio_stream *); -}; - -static const struct sound_ops dma_sound_ops = { - .setup = setup_dma, - .tear_down = tear_down_dma, - .stop_playback = stop_dma_playback, -}; - -static const struct sound_ops *sound_ops = &dma_sound_ops; - - - -static bool stop_playback_if_necessary(struct audio_stream *aos) -{ - unsigned long flags; - spin_lock_irqsave(&aos->dma_req_lock, flags); - pr_debug("%s\n", __func__); - if (!pending_buffer_requests(aos)) { - pr_debug("%s: no more data to play back\n", __func__); - sound_ops->stop_playback(aos); - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - allow_suspend(aos); - return true; - } - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - - return false; -} - -/* playback */ -static bool wait_till_stopped(struct audio_stream *as) -{ - int rc; - pr_debug("%s: wait for completion\n", __func__); - rc = wait_for_completion_timeout( - &as->stop_completion, HZ); - if (!rc) - pr_err("%s: wait timed out", __func__); - if (rc < 0) - pr_err("%s: wait error %d\n", __func__, rc); - allow_suspend(as); - pr_debug("%s: done: %d\n", __func__, rc); - return true; -} - -/* Ask for playback to stop. The _nosync means that - * as->lock has to be locked by the caller. - */ -static void request_stop_nosync(struct audio_stream *as) -{ - int i; - pr_debug("%s\n", __func__); - if (!as->stop) { - as->stop = true; - if (pending_buffer_requests(as)) - wait_till_stopped(as); - for (i = 0; i < as->num_bufs; i++) { - init_completion(&as->comp[i]); - complete(&as->comp[i]); - } - } - if (!tegra_dma_is_empty(as->dma_chan)) - pr_err("%s: DMA not empty!\n", __func__); - /* Stop the DMA then dequeue anything that's in progress. */ - tegra_dma_cancel(as->dma_chan); - as->active = false; /* applies to recording only */ - pr_debug("%s: done\n", __func__); -} - -static void setup_dma_tx_request(struct tegra_dma_req *req, - struct audio_stream *aos); - -static int setup_dma(struct audio_driver_state *ads) -{ - int rc, i; - pr_info("%s\n", __func__); - - /* setup audio playback */ - for (i = 0; i < ads->out.num_bufs; i++) { - ads->out.buf_phy[i] = dma_map_single(&ads->pdev->dev, - ads->out.buffer[i], - buf_size(&ads->out), - DMA_TO_DEVICE); - BUG_ON(!ads->out.buf_phy[i]); - setup_dma_tx_request(&ads->out.dma_req[i], &ads->out); - ads->out.dma_req[i].source_addr = ads->out.buf_phy[i]; - } - ads->out.dma_chan = - tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_SINGLE); - if (!ads->out.dma_chan) { - pr_err("%s: error alloc output DMA channel: %ld\n", - __func__, PTR_ERR(ads->out.dma_chan)); - rc = -ENODEV; - goto fail_tx; - } - return 0; - - -fail_tx: - - for (i = 0; i < ads->out.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->out.buf_phy[i], - buf_size(&ads->out), - DMA_TO_DEVICE); - ads->out.buf_phy[i] = 0; - } - tegra_dma_free_channel(ads->out.dma_chan); - ads->out.dma_chan = 0; - - - return rc; -} - -static void tear_down_dma(struct audio_driver_state *ads) -{ - int i; - pr_info("%s\n", __func__); - - - tegra_dma_free_channel(ads->out.dma_chan); - for (i = 0; i < ads->out.num_bufs; i++) { - dma_unmap_single(&ads->pdev->dev, ads->out.buf_phy[i], - buf_size(&ads->out), - DMA_TO_DEVICE); - ads->out.buf_phy[i] = 0; - } - - ads->out.dma_chan = NULL; -} - -static void dma_tx_complete_callback(struct tegra_dma_req *req) -{ - struct audio_stream *aos = req->dev; - unsigned req_num; - - req_num = req - aos->dma_req; - pr_debug("%s: completed buffer %d size %d\n", __func__, - req_num, req->bytes_transferred); - BUG_ON(req_num >= aos->num_bufs); - - complete(&aos->comp[req_num]); - - if (!pending_buffer_requests(aos)) { - pr_debug("%s: Playback underflow", __func__); - complete(&aos->stop_completion); - } -} - - -static void setup_dma_tx_request(struct tegra_dma_req *req, - struct audio_stream *aos) -{ - struct audio_driver_state *ads = ads_from_out(aos); - - memset(req, 0, sizeof(*req)); - - req->complete = dma_tx_complete_callback; - req->dev = aos; - req->to_memory = false; - req->dest_addr = spdif_get_fifo_phy_base(ads->spdif_phys); - req->dest_bus_width = 32; - req->dest_wrap = 4; - req->source_wrap = 0; - req->source_bus_width = 32; - req->req_sel = ads->dma_req_sel; -} - - -static int start_playback(struct audio_stream *aos, - struct tegra_dma_req *req) -{ - int rc; - unsigned long flags; - struct audio_driver_state *ads = ads_from_out(aos); - - pr_debug("%s: (writing %d)\n", - __func__, req->size); - - spin_lock_irqsave(&aos->dma_req_lock, flags); -#if 0 - spdif_fifo_clear(ads->spdif_base); -#endif - - spdif_fifo_set_attention_level(ads->spdif_base, - ads->out.spdif_fifo_atn_level); - - if (ads->fifo_init) { - spdif_set_bit_mode(ads->spdif_base, SPDIF_BIT_MODE_MODE16BIT); - spdif_set_fifo_packed(ads->spdif_base, 1); - ads->fifo_init = false; - } - - spdif_fifo_enable(ads->spdif_base, 1); - - rc = tegra_dma_enqueue_req(aos->dma_chan, req); - spin_unlock_irqrestore(&aos->dma_req_lock, flags); - - if (rc) - pr_err("%s: could not enqueue TX DMA req\n", __func__); - return rc; -} - -/* Called with aos->dma_req_lock taken. */ -static void stop_dma_playback(struct audio_stream *aos) -{ - int spin = 0; - struct audio_driver_state *ads = ads_from_out(aos); - pr_debug("%s\n", __func__); - spdif_fifo_enable(ads->spdif_base, 0); - while ((spdif_get_status(ads->spdif_base) & SPDIF_STATUS_0_TX_BSY) && - spin < 100) { - udelay(10); - if (spin++ > 50) - pr_info("%s: spin %d\n", __func__, spin); - } - if (spin == 100) - pr_warn("%s: spinny\n", __func__); - ads->fifo_init = true; -} - - - -static irqreturn_t spdif_interrupt(int irq, void *data) -{ - struct audio_driver_state *ads = data; - u32 status = spdif_get_status(ads->spdif_base); - - pr_debug("%s: %08x\n", __func__, status); - -/* if (status & SPDIF_STATUS_0_TX_ERR) */ - spdif_ack_status(ads->spdif_base); - - pr_debug("%s: done %08x\n", __func__, - spdif_get_status(ads->spdif_base)); - return IRQ_HANDLED; -} - -static ssize_t tegra_spdif_write(struct file *file, - const char __user *buf, size_t size, loff_t *off) -{ - ssize_t rc = 0; - int out_buf; - struct tegra_dma_req *req; - struct audio_driver_state *ads = ads_from_misc_out(file); - - mutex_lock(&ads->out.lock); - - if (!IS_ALIGNED(size, 4) || size < 4 || size > buf_size(&ads->out)) { - pr_err("%s: invalid user size %d\n", __func__, size); - rc = -EINVAL; - goto done; - } - - pr_debug("%s: write %d bytes\n", __func__, size); - - if (ads->out.stop) { - pr_debug("%s: playback has been cancelled\n", __func__); - goto done; - } - - /* Decide which buf is next. */ - out_buf = (ads->out.last_queued + 1) % ads->out.num_bufs; - req = &ads->out.dma_req[out_buf]; - - /* Wait for the buffer to be emptied (complete). The maximum timeout - * value could be calculated dynamically based on buf_size(&ads->out). - * For a buffer size of 16k, at 44.1kHz/stereo/16-bit PCM, you would - * have ~93ms. - */ - pr_debug("%s: waiting for buffer %d\n", __func__, out_buf); - rc = wait_for_completion_interruptible_timeout( - &ads->out.comp[out_buf], HZ); - if (!rc) { - pr_err("%s: timeout", __func__); - rc = -ETIMEDOUT; - goto done; - } else if (rc < 0) { - pr_err("%s: wait error %d", __func__, rc); - goto done; - } - - /* Fill the buffer and enqueue it. */ - pr_debug("%s: acquired buffer %d, copying data\n", __func__, out_buf); - rc = copy_from_user(ads->out.buffer[out_buf], buf, size); - if (rc) { - rc = -EFAULT; - goto done; - } - - prevent_suspend(&ads->out); - - req->size = size; - dma_sync_single_for_device(NULL, - req->source_addr, req->size, DMA_TO_DEVICE); - ads->out.last_queued = out_buf; - init_completion(&ads->out.stop_completion); - - rc = start_playback(&ads->out, req); - if (!rc) - rc = size; - else - allow_suspend(&ads->out); - -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static long tegra_spdif_out_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = 0; - struct audio_driver_state *ads = ads_from_misc_out_ctl(file); - struct audio_stream *aos = &ads->out; - - mutex_lock(&aos->lock); - - switch (cmd) { - case TEGRA_AUDIO_OUT_FLUSH: - if (pending_buffer_requests(aos)) { - pr_debug("%s: flushing\n", __func__); - request_stop_nosync(aos); - pr_debug("%s: flushed\n", __func__); - } - if (stop_playback_if_necessary(aos)) - pr_debug("%s: done (stopped)\n", __func__); - aos->stop = false; - break; - case TEGRA_AUDIO_OUT_SET_NUM_BUFS: { - unsigned int num; - if (copy_from_user(&num, (const void __user *)arg, - sizeof(num))) { - rc = -EFAULT; - break; - } - if (!num || num > SPDIF_MAX_NUM_BUFS) { - pr_err("%s: invalid buffer count %d\n", __func__, num); - rc = -EINVAL; - break; - } - if (pending_buffer_requests(aos)) { - pr_err("%s: playback in progress\n", __func__); - rc = -EBUSY; - break; - } - rc = init_stream_buffer(aos, num); - if (rc < 0) - break; - aos->num_bufs = num; - sound_ops->setup(ads); - } - break; - case TEGRA_AUDIO_OUT_GET_NUM_BUFS: - if (copy_to_user((void __user *)arg, - &aos->num_bufs, sizeof(aos->num_bufs))) - rc = -EFAULT; - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&aos->lock); - return rc; -} - - -static int tegra_spdif_out_open(struct inode *inode, struct file *file) -{ - int rc = 0; - int i; - struct audio_driver_state *ads = ads_from_misc_out(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->out.lock); - - if (ads->out.opened) { - rc = -EBUSY; - goto done; - } - - ads->out.opened = 1; - ads->out.stop = false; - - for (i = 0; i < SPDIF_MAX_NUM_BUFS; i++) { - init_completion(&ads->out.comp[i]); - /* TX buf rest state is unqueued, complete. */ - complete(&ads->out.comp[i]); - } - -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static int tegra_spdif_out_release(struct inode *inode, struct file *file) -{ - struct audio_driver_state *ads = ads_from_misc_out(file); - - pr_debug("%s\n", __func__); - - mutex_lock(&ads->out.lock); - ads->out.opened = 0; - request_stop_nosync(&ads->out); - if (stop_playback_if_necessary(&ads->out)) - pr_debug("%s: done (stopped)\n", __func__); - allow_suspend(&ads->out); - mutex_unlock(&ads->out.lock); - pr_debug("%s: done\n", __func__); - return 0; -} - - -static const struct file_operations tegra_spdif_out_fops = { - .owner = THIS_MODULE, - .open = tegra_spdif_out_open, - .release = tegra_spdif_out_release, - .write = tegra_spdif_write, -}; - -static int tegra_spdif_ctl_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int tegra_spdif_ctl_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations tegra_spdif_out_ctl_fops = { - .owner = THIS_MODULE, - .open = tegra_spdif_ctl_open, - .release = tegra_spdif_ctl_release, - .unlocked_ioctl = tegra_spdif_out_ioctl, -}; - -static int init_stream_buffer(struct audio_stream *s, int num) -{ - int i, j; - pr_debug("%s (num %d)\n", __func__, num); - - for (i = 0; i < num; i++) { - kfree(s->buffer[i]); - s->buffer[i] = - kmalloc(buf_size(s), GFP_KERNEL | GFP_DMA); - if (!s->buffer[i]) { - pr_err("%s: could not allocate buffer\n", __func__); - for (j = i - 1; j >= 0; j--) { - kfree(s->buffer[j]); - s->buffer[j] = 0; - } - return -ENOMEM; - } - } - return 0; -} - - -static int setup_misc_device(struct miscdevice *misc, - const struct file_operations *fops, - const char *fmt, ...) -{ - int rc = 0; - va_list args; - const int sz = 64; - - va_start(args, fmt); - - memset(misc, 0, sizeof(*misc)); - misc->minor = MISC_DYNAMIC_MINOR; - misc->name = kmalloc(sz, GFP_KERNEL); - if (!misc->name) { - rc = -ENOMEM; - goto done; - } - - vsnprintf((char *)misc->name, sz, fmt, args); - misc->fops = fops; - if (misc_register(misc)) { - pr_err("%s: could not register %s\n", __func__, misc->name); - kfree(misc->name); - rc = -EIO; - goto done; - } - -done: - va_end(args); - return rc; -} - -static ssize_t dma_toggle_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "dma\n"); -} - -static ssize_t dma_toggle_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - pr_err("%s: Not implemented.", __func__); - return 0; -} - -static DEVICE_ATTR(dma_toggle, 0644, dma_toggle_show, dma_toggle_store); - -static ssize_t __attr_fifo_atn_read(char *buf, int atn_lvl) -{ - switch (atn_lvl) { - case SPDIF_FIFO_ATN_LVL_ONE_SLOT: - strncpy(buf, "1\n", 2); - return 2; - case SPDIF_FIFO_ATN_LVL_FOUR_SLOTS: - strncpy(buf, "4\n", 2); - return 2; - case SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS: - strncpy(buf, "8\n", 2); - return 2; - case SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS: - strncpy(buf, "12\n", 3); - return 3; - default: - BUG_ON(1); - return -EIO; - } -} - -static ssize_t __attr_fifo_atn_write(struct audio_driver_state *ads, - struct audio_stream *as, - int *fifo_lvl, - const char *buf, size_t size) -{ - int lvl; - - if (size > 3) { - pr_err("%s: buffer size %d too big\n", __func__, size); - return -EINVAL; - } - - if (sscanf(buf, "%d", &lvl) != 1) { - pr_err("%s: invalid input string [%s]\n", __func__, buf); - return -EINVAL; - } - - switch (lvl) { - case 1: - lvl = SPDIF_FIFO_ATN_LVL_ONE_SLOT; - break; - case 4: - lvl = SPDIF_FIFO_ATN_LVL_FOUR_SLOTS; - break; - case 8: - lvl = SPDIF_FIFO_ATN_LVL_EIGHT_SLOTS; - break; - case 12: - lvl = SPDIF_FIFO_ATN_LVL_TWELVE_SLOTS; - break; - default: - pr_err("%s: invalid attention level %d\n", __func__, lvl); - return -EINVAL; - } - - *fifo_lvl = lvl; - pr_info("%s: fifo level %d\n", __func__, *fifo_lvl); - - return size; -} - -static ssize_t tx_fifo_atn_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - return __attr_fifo_atn_read(buf, ads->out.spdif_fifo_atn_level); -} - -static ssize_t tx_fifo_atn_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - ssize_t rc; - struct tegra_audio_platform_data *pdata = dev->platform_data; - struct audio_driver_state *ads = pdata->driver_data; - mutex_lock(&ads->out.lock); - if (pending_buffer_requests(&ads->out)) { - pr_err("%s: playback in progress.\n", __func__); - rc = -EBUSY; - goto done; - } - rc = __attr_fifo_atn_write(ads, &ads->out, - &ads->out.spdif_fifo_atn_level, - buf, count); -done: - mutex_unlock(&ads->out.lock); - return rc; -} - -static DEVICE_ATTR(tx_fifo_atn, 0644, tx_fifo_atn_show, tx_fifo_atn_store); - - -static int spdif_configure(struct platform_device *pdev) -{ - struct tegra_audio_platform_data *pdata = pdev->dev.platform_data; - struct audio_driver_state *state = pdata->driver_data; - - if (!state) - return -ENOMEM; - - /* disable interrupts from SPDIF */ - spdif_writel(state->spdif_base, 0x0, SPDIF_CTRL_0); - spdif_fifo_clear(state->spdif_base); - spdif_enable_fifos(state->spdif_base, 0); - - spdif_set_bit_mode(state->spdif_base, SPDIF_BIT_MODE_MODE16BIT); - spdif_set_fifo_packed(state->spdif_base, 1); - - spdif_fifo_set_attention_level(state->spdif_base, - state->out.spdif_fifo_atn_level); - - spdif_set_sample_rate(state, 44100); - - state->fifo_init = true; - return 0; -} - -static int tegra_spdif_probe(struct platform_device *pdev) -{ - int rc, i; - struct resource *res; - struct audio_driver_state *state; - - pr_info("%s\n", __func__); - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->pdev = pdev; - state->pdata = pdev->dev.platform_data; - state->pdata->driver_data = state; - BUG_ON(!state->pdata); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mem resource!\n"); - return -ENODEV; - } - - if (!request_mem_region(res->start, resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "memory region already claimed!\n"); - return -ENOMEM; - } - - state->spdif_phys = res->start; - state->spdif_base = (unsigned long)ioremap(res->start, - res->end - res->start + 1); - if (!state->spdif_base) { - dev_err(&pdev->dev, "cannot remap iomem!\n"); - return -EIO; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "no dma resource!\n"); - return -ENODEV; - } - state->dma_req_sel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, "no irq resource!\n"); - return -ENODEV; - } - state->irq = res->start; - - rc = spdif_configure(pdev); - if (rc < 0) - return rc; - - state->out.opened = 0; - state->out.active = false; - mutex_init(&state->out.lock); - init_completion(&state->out.stop_completion); - spin_lock_init(&state->out.dma_req_lock); - state->out.dma_chan = NULL; - state->out.num_bufs = SPDIF_DEFAULT_TX_NUM_BUFS; - for (i = 0; i < SPDIF_MAX_NUM_BUFS; i++) { - init_completion(&state->out.comp[i]); - /* TX buf rest state is unqueued, complete. */ - complete(&state->out.comp[i]); - state->out.buffer[i] = 0; - state->out.buf_phy[i] = 0; - } - state->out.last_queued = 0; - rc = init_stream_buffer(&state->out, state->out.num_bufs); - if (rc < 0) - return rc; - - INIT_WORK(&state->out.allow_suspend_work, allow_suspend_worker); - snprintf(state->out.wake_lock_name, sizeof(state->out.wake_lock_name), - "tegra-audio-spdif"); - wake_lock_init(&state->out.wake_lock, WAKE_LOCK_SUSPEND, - state->out.wake_lock_name); - - if (request_irq(state->irq, spdif_interrupt, - IRQF_DISABLED, state->pdev->name, state) < 0) { - dev_err(&pdev->dev, - "%s: could not register handler for irq %d\n", - __func__, state->irq); - return -EIO; - } - - rc = setup_misc_device(&state->misc_out, - &tegra_spdif_out_fops, - "spdif_out"); - if (rc < 0) - return rc; - - rc = setup_misc_device(&state->misc_out_ctl, - &tegra_spdif_out_ctl_fops, - "spdif_out_ctl"); - if (rc < 0) - return rc; - - sound_ops->setup(state); - - rc = device_create_file(&pdev->dev, &dev_attr_dma_toggle); - if (rc < 0) { - dev_err(&pdev->dev, "%s: could not create sysfs entry %s: %d\n", - __func__, dev_attr_dma_toggle.attr.name, rc); - return rc; - } - - rc = device_create_file(&pdev->dev, &dev_attr_tx_fifo_atn); - if (rc < 0) { - dev_err(&pdev->dev, "%s: could not create sysfs entry %s: %d\n", - __func__, dev_attr_tx_fifo_atn.attr.name, rc); - return rc; - } - - return 0; -} - -#ifdef CONFIG_PM -static int tegra_spdif_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - /* dev_info(&pdev->dev, "%s\n", __func__); */ - return 0; -} - -static int tegra_spdif_resume(struct platform_device *pdev) -{ - return spdif_configure(pdev); -} -#endif /* CONFIG_PM */ - -static struct platform_driver tegra_spdif_driver = { - .driver = { - .name = "spdif_out", - .owner = THIS_MODULE, - }, - .probe = tegra_spdif_probe, -#ifdef CONFIG_PM - .suspend = tegra_spdif_suspend, - .resume = tegra_spdif_resume, -#endif -}; - -static int __init tegra_spdif_init(void) -{ - return platform_driver_register(&tegra_spdif_driver); -} - -module_init(tegra_spdif_init); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index 632c58e3e399..2f420210d406 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -33,15 +33,9 @@ #include #include -#include #include "board.h" #include "clock.h" -#include "power.h" - -#define RTC_SECONDS 0x08 -#define RTC_SHADOW_SECONDS 0x0c -#define RTC_MILLISECONDS 0x10 #define TIMERUS_CNTR_1US 0x10 #define TIMERUS_USEC_CFG 0x14 @@ -55,18 +49,15 @@ #define TIMER_PTV 0x0 #define TIMER_PCR 0x4 +struct tegra_timer; + static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE); -static void __iomem *rtc_base = IO_ADDRESS(TEGRA_RTC_BASE); #define timer_writel(value, reg) \ __raw_writel(value, (u32)timer_reg_base + (reg)) #define timer_readl(reg) \ __raw_readl((u32)timer_reg_base + (reg)) -static u64 tegra_sched_clock_offset; -static u64 tegra_sched_clock_suspend_val; -static u64 tegra_sched_clock_suspend_rtc; - static int tegra_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { @@ -101,7 +92,7 @@ static void tegra_timer_set_mode(enum clock_event_mode mode, static cycle_t tegra_clocksource_read(struct clocksource *cs) { - return timer_readl(TIMERUS_CNTR_1US); + return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US)); } static struct clock_event_device tegra_clockevent = { @@ -116,66 +107,14 @@ static struct clocksource tegra_clocksource = { .name = "timer_us", .rating = 300, .read = tegra_clocksource_read, - .mask = CLOCKSOURCE_MASK(32), + .mask = 0x7FFFFFFFFFFFFFFFULL, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; unsigned long long sched_clock(void) { - return tegra_sched_clock_offset + - cnt32_to_63(timer_readl(TIMERUS_CNTR_1US)) * NSEC_PER_USEC; -} - -static void tegra_sched_clock_suspend(void) -{ - tegra_sched_clock_suspend_val = sched_clock(); - tegra_sched_clock_suspend_rtc = tegra_rtc_read_ms(); -} - -static void tegra_sched_clock_resume(void) -{ - u64 rtc_offset_ms = tegra_rtc_read_ms() - tegra_sched_clock_suspend_rtc; - tegra_sched_clock_offset = tegra_sched_clock_suspend_val + - rtc_offset_ms * NSEC_PER_MSEC - - (sched_clock() - tegra_sched_clock_offset); -} - -/* - * tegra_rtc_read - Reads the Tegra RTC registers - * Care must be taken that this funciton is not called while the - * tegra_rtc driver could be executing to avoid race conditions - * on the RTC shadow register - */ -u64 tegra_rtc_read_ms(void) -{ - u32 ms = readl(rtc_base + RTC_MILLISECONDS); - u32 s = readl(rtc_base + RTC_SHADOW_SECONDS); - return (u64)s * MSEC_PER_SEC + ms; -} - -/* - * read_persistent_clock - Return time from a persistent clock. - * - * Reads the time from a source which isn't disabled during PM, the - * 32k sync timer. Convert the cycles elapsed since last read into - * nsecs and adds to a monotonically increasing timespec. - * Care must be taken that this funciton is not called while the - * tegra_rtc driver could be executing to avoid race conditions - * on the RTC shadow register - */ -static struct timespec persistent_ts; -static u64 persistent_ms, last_persistent_ms; -void read_persistent_clock(struct timespec *ts) -{ - u64 delta; - struct timespec *tsp = &persistent_ts; - - last_persistent_ms = persistent_ms; - persistent_ms = tegra_rtc_read_ms(); - delta = persistent_ms - last_persistent_ms; - - timespec_add_ns(tsp, delta * NSEC_PER_MSEC); - *ts = *tsp; + return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource), + tegra_clocksource.mult, tegra_clocksource.shift); } static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) @@ -194,20 +133,6 @@ static struct irqaction tegra_timer_irq = { .irq = INT_TMR3, }; -static irqreturn_t tegra_lp2wake_interrupt(int irq, void *dev_id) -{ - timer_writel(1<<30, TIMER4_BASE + TIMER_PCR); - return IRQ_HANDLED; -} - -static struct irqaction tegra_lp2wake_irq = { - .name = "timer_lp2wake", - .flags = IRQF_DISABLED, - .handler = tegra_lp2wake_interrupt, - .dev_id = NULL, - .irq = INT_TMR4, -}; - static void __init tegra_init_timer(void) { unsigned long rate = clk_measure_input_freq(); @@ -245,12 +170,6 @@ static void __init tegra_init_timer(void) BUG(); } - ret = setup_irq(tegra_lp2wake_irq.irq, &tegra_lp2wake_irq); - if (ret) { - printk(KERN_ERR "Failed to register LP2 timer IRQ: %d\n", ret); - BUG(); - } - clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5); tegra_clockevent.max_delta_ns = clockevent_delta2ns(0x1fffffff, &tegra_clockevent); @@ -266,31 +185,3 @@ static void __init tegra_init_timer(void) struct sys_timer tegra_timer = { .init = tegra_init_timer, }; - -void tegra_lp2_set_trigger(unsigned long cycles) -{ - timer_writel(0, TIMER4_BASE + TIMER_PTV); - if (cycles) { - u32 reg = 0x80000000ul | min(0x1ffffffful, cycles); - timer_writel(reg, TIMER4_BASE + TIMER_PTV); - } -} -EXPORT_SYMBOL(tegra_lp2_set_trigger); - -unsigned long tegra_lp2_timer_remain(void) -{ - return timer_readl(TIMER4_BASE + TIMER_PCR) & 0x1ffffffful; -} - -static u32 usec_config; -void tegra_timer_suspend(void) -{ - tegra_sched_clock_suspend(); - usec_config = timer_readl(TIMERUS_USEC_CFG); -} - -void tegra_timer_resume(void) -{ - timer_writel(usec_config, TIMERUS_USEC_CFG); - tegra_sched_clock_resume(); -} diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c deleted file mode 100644 index ef07efd11b19..000000000000 --- a/arch/arm/mach-tegra/usb_phy.c +++ /dev/null @@ -1,869 +0,0 @@ -/* - * arch/arm/mach-tegra/usb_phy.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * Benoit Goby - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ULPI_VIEWPORT 0x170 -#define ULPI_WAKEUP (1 << 31) -#define ULPI_RUN (1 << 30) -#define ULPI_RD_WR (1 << 29) - -#define USB_PORTSC1 0x184 -#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) -#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26) -#define USB_PORTSC1_PHCD (1 << 23) -#define USB_PORTSC1_WKOC (1 << 22) -#define USB_PORTSC1_WKDS (1 << 21) -#define USB_PORTSC1_WKCN (1 << 20) -#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16) -#define USB_PORTSC1_PP (1 << 12) -#define USB_PORTSC1_SUSP (1 << 7) -#define USB_PORTSC1_PE (1 << 2) -#define USB_PORTSC1_CCS (1 << 0) - -#define USB_SUSP_CTRL 0x400 -#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) -#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) -#define USB_SUSP_CLR (1 << 5) -#define USB_CLKEN (1 << 6) -#define USB_PHY_CLK_VALID (1 << 7) -#define UTMIP_RESET (1 << 11) -#define UHSIC_RESET (1 << 11) -#define UTMIP_PHY_ENABLE (1 << 12) -#define ULPI_PHY_ENABLE (1 << 13) -#define USB_SUSP_SET (1 << 14) -#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) - -#define USB1_LEGACY_CTRL 0x410 -#define USB1_NO_LEGACY_MODE (1 << 0) -#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) -#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ - (1 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) -#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) - -#define ULPI_TIMING_CTRL_0 0x424 -#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) -#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) - -#define ULPI_TIMING_CTRL_1 0x428 -#define ULPI_DATA_TRIMMER_LOAD (1 << 0) -#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) -#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) -#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) -#define ULPI_DIR_TRIMMER_LOAD (1 << 24) -#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) - -#define UTMIP_PLL_CFG1 0x804 -#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) - -#define UTMIP_XCVR_CFG0 0x808 -#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) -#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) -#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) -#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) -#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) -#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) -#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) - -#define UTMIP_BIAS_CFG0 0x80c -#define UTMIP_OTGPD (1 << 11) -#define UTMIP_BIASPD (1 << 10) - -#define UTMIP_HSRX_CFG0 0x810 -#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) -#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) - -#define UTMIP_HSRX_CFG1 0x814 -#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UTMIP_TX_CFG0 0x820 -#define UTMIP_FS_PREABMLE_J (1 << 19) -#define UTMIP_HS_DISCON_DISABLE (1 << 8) - -#define UTMIP_MISC_CFG0 0x824 -#define UTMIP_DPDM_OBSERVE (1 << 26) -#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) -#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) -#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) -#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) - -#define UTMIP_MISC_CFG1 0x828 -#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) -#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) - -#define UTMIP_DEBOUNCE_CFG0 0x82c -#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) - -#define UTMIP_BAT_CHRG_CFG0 0x830 -#define UTMIP_PD_CHRG (1 << 0) - -#define UTMIP_SPARE_CFG0 0x834 -#define FUSE_SETUP_SEL (1 << 3) - -#define UTMIP_XCVR_CFG1 0x838 -#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) -#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) -#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) -#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) - -#define UTMIP_BIAS_CFG1 0x83c -#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) - -static DEFINE_SPINLOCK(utmip_pad_lock); -static int utmip_pad_count; - -struct tegra_xtal_freq { - int freq; - u8 enable_delay; - u8 stable_count; - u8 active_delay; - u8 xtal_freq_count; - u16 debounce; -}; - -static const struct tegra_xtal_freq tegra_freq_table[] = { - { - .freq = 12000000, - .enable_delay = 0x02, - .stable_count = 0x2F, - .active_delay = 0x04, - .xtal_freq_count = 0x76, - .debounce = 0x7530, - }, - { - .freq = 13000000, - .enable_delay = 0x02, - .stable_count = 0x33, - .active_delay = 0x05, - .xtal_freq_count = 0x7F, - .debounce = 0x7EF4, - }, - { - .freq = 19200000, - .enable_delay = 0x03, - .stable_count = 0x4B, - .active_delay = 0x06, - .xtal_freq_count = 0xBB, - .debounce = 0xBB80, - }, - { - .freq = 26000000, - .enable_delay = 0x04, - .stable_count = 0x66, - .active_delay = 0x09, - .xtal_freq_count = 0xFE, - .debounce = 0xFDE8, - }, -}; - -static struct tegra_utmip_config utmip_default[] = { - [0] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_lsfslew = 1, - .xcvr_lsrslew = 1, - }, - [2] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static inline bool phy_is_ulpi(struct tegra_usb_phy *phy) -{ - return (phy->instance == 1); -} - -static int utmip_pad_open(struct tegra_usb_phy *phy) -{ - phy->pad_clk = clk_get_sys("utmip-pad", NULL); - if (IS_ERR(phy->pad_clk)) { - pr_err("%s: can't get utmip pad clock\n", __func__); - return PTR_ERR(phy->pad_clk); - } - - if (phy->instance == 0) { - phy->pad_regs = phy->regs; - } else { - phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); - if (!phy->pad_regs) { - pr_err("%s: can't remap usb registers\n", __func__); - clk_put(phy->pad_clk); - return -ENOMEM; - } - } - return 0; -} - -static void utmip_pad_close(struct tegra_usb_phy *phy) -{ - if (phy->instance != 0) - iounmap(phy->pad_regs); - clk_put(phy->pad_clk); -} - -static void utmip_pad_power_on(struct tegra_usb_phy *phy) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - clk_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - if (utmip_pad_count++ == 0) { - val = readl(base + UTMIP_BIAS_CFG0); - val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); - writel(val, base + UTMIP_BIAS_CFG0); - } - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable(phy->pad_clk); -} - -static int utmip_pad_power_off(struct tegra_usb_phy *phy) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - if (!utmip_pad_count) { - pr_err("%s: utmip pad already powered off\n", __func__); - return -EINVAL; - } - - clk_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - if (--utmip_pad_count == 0) { - val = readl(base + UTMIP_BIAS_CFG0); - val |= UTMIP_OTGPD | UTMIP_BIASPD; - writel(val, base + UTMIP_BIAS_CFG0); - } - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable(phy->pad_clk); - - return 0; -} - -static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result) -{ - unsigned long timeout = 2500; - do { - if ((readl(reg) & mask) == result) - return 0; - udelay(1); - timeout--; - } while (timeout); - return -1; -} - -static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->instance == 0) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - } - - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - } - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->instance == 0) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - } - - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - } - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static int utmi_phy_power_on(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_utmip_config *config = phy->config; - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - if (phy->instance == 0) { - val = readl(base + USB1_LEGACY_CTRL); - val |= USB1_NO_LEGACY_MODE; - writel(val, base + USB1_LEGACY_CTRL); - } - - val = readl(base + UTMIP_TX_CFG0); - val &= ~UTMIP_FS_PREABMLE_J; - writel(val, base + UTMIP_TX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG0); - val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); - val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); - val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); - writel(val, base + UTMIP_HSRX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG1); - val &= ~UTMIP_HS_SYNC_START_DLY(~0); - val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); - writel(val, base + UTMIP_HSRX_CFG1); - - val = readl(base + UTMIP_DEBOUNCE_CFG0); - val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); - val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); - writel(val, base + UTMIP_DEBOUNCE_CFG0); - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; - writel(val, base + UTMIP_MISC_CFG0); - - val = readl(base + UTMIP_MISC_CFG1); - val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0)); - val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) | - UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count); - writel(val, base + UTMIP_MISC_CFG1); - - val = readl(base + UTMIP_PLL_CFG1); - val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); - val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | - UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); - writel(val, base + UTMIP_PLL_CFG1); - - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); - writel(val, base + USB_SUSP_CTRL); - } - - utmip_pad_power_on(phy); - - val = readl(base + UTMIP_XCVR_CFG0); - val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | - UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) | - UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) | - UTMIP_XCVR_HSSLEW_MSB(~0)); - val |= UTMIP_XCVR_SETUP(config->xcvr_setup); - val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); - val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); - writel(val, base + UTMIP_XCVR_CFG0); - - val = readl(base + UTMIP_XCVR_CFG1); - val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); - val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); - writel(val, base + UTMIP_XCVR_CFG1); - - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val &= ~UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - val = readl(base + UTMIP_BIAS_CFG1); - val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); - val |= UTMIP_BIAS_PDTRK_COUNT(0x5); - writel(val, base + UTMIP_BIAS_CFG1); - - if (phy->instance == 0) { - val = readl(base + UTMIP_SPARE_CFG0); - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) - val &= ~FUSE_SETUP_SEL; - else - val |= FUSE_SETUP_SEL; - writel(val, base + UTMIP_SPARE_CFG0); - } - - if (phy->instance == 2) { - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - } - - val = readl(base + USB_SUSP_CTRL); - val &= ~UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - if (phy->instance == 0) { - val = readl(base + USB1_LEGACY_CTRL); - val &= ~USB1_VBUS_SENSE_CTL_MASK; - val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; - writel(val, base + USB1_LEGACY_CTRL); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - } - - utmi_phy_clk_enable(phy); - - if (phy->instance == 2) { - val = readl(base + USB_PORTSC1); - val &= ~USB_PORTSC1_PTS(~0); - writel(val, base + USB_PORTSC1); - } - - return 0; -} - -static void utmi_phy_power_off(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - utmi_phy_clk_disable(phy); - - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); - val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); - writel(val, base + USB_SUSP_CTRL); - } - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val |= UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - val = readl(base + UTMIP_XCVR_CFG0); - val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | - UTMIP_FORCE_PDZI_POWERDOWN; - writel(val, base + UTMIP_XCVR_CFG0); - - val = readl(base + UTMIP_XCVR_CFG1); - val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN; - writel(val, base + UTMIP_XCVR_CFG1); - - utmip_pad_power_off(phy); -} - -static void utmi_phy_preresume(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_TX_CFG0); - val |= UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); -} - -static void utmi_phy_postresume(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_TX_CFG0); - val &= ~UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); -} - -static void utmi_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; - else - val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; - writel(val, base + UTMIP_MISC_CFG0); - udelay(1); - - val = readl(base + UTMIP_MISC_CFG0); - val |= UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -} - -static void utmi_phy_restore_end(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -} - -static void ulpi_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - unsigned long val; - void __iomem *base = phy->regs; - - /*Tristate ulpi interface before USB controller resume*/ - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, TEGRA_TRI_TRISTATE); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, TEGRA_TRI_TRISTATE); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, TEGRA_TRI_TRISTATE); - - val = readl(base + ULPI_TIMING_CTRL_0); - val &= ~ULPI_OUTPUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); -} - -static void ulpi_phy_restore_end(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, TEGRA_TRI_NORMAL); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, TEGRA_TRI_NORMAL); - tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, TEGRA_TRI_NORMAL); -} - -static int ulpi_phy_power_on(struct tegra_usb_phy *phy) -{ - int ret; - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_ulpi_config *config = phy->config; - - clk_enable(phy->clk); - msleep(1); - - if (!phy->initialized) { - phy->initialized = 1; - gpio_direction_output(config->reset_gpio, 0); - msleep(5); - gpio_direction_output(config->reset_gpio, 1); - } - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_RESET; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - - val = readl(base + USB_SUSP_CTRL); - val |= ULPI_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_CLKEN, USB_CLKEN) < 0) - pr_err("%s: timeout waiting for AHB clock\n", __func__); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - val = 0; - writel(val, base + ULPI_TIMING_CTRL_1); - - val |= ULPI_DATA_TRIMMER_SEL(4); - val |= ULPI_STPDIRNXT_TRIMMER_SEL(4); - val |= ULPI_DIR_TRIMMER_SEL(4); - writel(val, base + ULPI_TIMING_CTRL_1); - udelay(10); - - val |= ULPI_DATA_TRIMMER_LOAD; - val |= ULPI_STPDIRNXT_TRIMMER_LOAD; - val |= ULPI_DIR_TRIMMER_LOAD; - writel(val, base + ULPI_TIMING_CTRL_1); - - /* Fix VbusInvalid due to floating VBUS */ - ret = otg_io_write(phy->ulpi, 0x40, 0x08); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; - } - - ret = otg_io_write(phy->ulpi, 0x80, 0x0B); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; - } - - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN; - writel(val, base + USB_PORTSC1); - - return 0; -} - -static void ulpi_phy_power_off(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - int ret; - - /* Disable VbusValid, SessEnd comparators */ - ret = otg_io_write(phy->ulpi, 0x00, 0x0D); - if (ret) - pr_err("%s: ulpi write 0x0D failed\n", __func__); - - ret = otg_io_write(phy->ulpi, 0x00, 0x10); - if (ret) - pr_err("%s: ulpi write 0x10 failed\n", __func__); - - /* Disable IdFloat comparator */ - ret = otg_io_write(phy->ulpi, 0x00, 0x19); - if (ret) - pr_err("%s: ulpi write 0x19 failed\n", __func__); - - ret = otg_io_write(phy->ulpi, 0x00, 0x1D); - if (ret) - pr_err("%s: ulpi write 0x1D failed\n", __func__); - - /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB - * Controller to immediately bring the ULPI PHY out of low power - */ - val = readl(base + USB_PORTSC1); - val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); - writel(val, base + USB_PORTSC1); - - /* Put the PHY in the low power mode */ - val = readl(base + USB_PORTSC1); - val |= USB_PORTSC1_PHCD; - writel(val, base + USB_PORTSC1); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) - pr_err("%s: timeout waiting for phy to stop\n", __func__); - - clk_disable(phy->clk); -} - -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode) -{ - struct tegra_usb_phy *phy; - struct tegra_ulpi_config *ulpi_config; - unsigned long parent_rate; - int i; - int err; - - phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); - if (!phy) - return ERR_PTR(-ENOMEM); - - phy->instance = instance; - phy->regs = regs; - phy->config = config; - phy->mode = phy_mode; - phy->initialized = 0; - - if (!phy->config) { - if (phy_is_ulpi(phy)) { - pr_err("%s: ulpi phy configuration missing", __func__); - err = -EINVAL; - goto err0; - } else { - phy->config = &utmip_default[instance]; - } - } - - phy->pll_u = clk_get_sys(NULL, "pll_u"); - if (IS_ERR(phy->pll_u)) { - pr_err("Can't get pll_u clock\n"); - err = PTR_ERR(phy->pll_u); - goto err0; - } - clk_enable(phy->pll_u); - - parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); - for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { - if (tegra_freq_table[i].freq == parent_rate) { - phy->freq = &tegra_freq_table[i]; - break; - } - } - if (!phy->freq) { - pr_err("invalid pll_u parent rate %ld\n", parent_rate); - err = -EINVAL; - goto err1; - } - - if (phy_is_ulpi(phy)) { - ulpi_config = config; - phy->clk = clk_get_sys(NULL, ulpi_config->clk); - if (IS_ERR(phy->clk)) { - pr_err("%s: can't get ulpi clock\n", __func__); - err = -ENXIO; - goto err1; - } - tegra_gpio_enable(ulpi_config->reset_gpio); - gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); - gpio_direction_output(ulpi_config->reset_gpio, 0); - phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); - phy->ulpi->io_priv = regs + ULPI_VIEWPORT; - } else { - err = utmip_pad_open(phy); - if (err < 0) - goto err1; - } - - return phy; - -err1: - clk_disable(phy->pll_u); - clk_put(phy->pll_u); -err0: - kfree(phy); - return ERR_PTR(err); -} - -int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) -{ - if (phy_is_ulpi(phy)) - return ulpi_phy_power_on(phy); - else - return utmi_phy_power_on(phy); -} - -void tegra_usb_phy_power_off(struct tegra_usb_phy *phy) -{ - if (phy_is_ulpi(phy)) - ulpi_phy_power_off(phy); - else - utmi_phy_power_off(phy); -} - -void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_preresume(phy); -} - -void tegra_usb_phy_postresume(struct tegra_usb_phy *phy) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_postresume(phy); -} - -void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_restore_start(phy, port_speed); - else - ulpi_phy_restore_start(phy, port_speed); -} - -void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_restore_end(phy); - else - ulpi_phy_restore_end(phy); -} - -void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_clk_disable(phy); -} - -void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) -{ - if (!phy_is_ulpi(phy)) - utmi_phy_clk_enable(phy); -} - -void tegra_usb_phy_close(struct tegra_usb_phy *phy) -{ - if (phy_is_ulpi(phy)) - clk_put(phy->clk); - else - utmip_pad_close(phy); - clk_disable(phy->pll_u); - clk_put(phy->pll_u); - kfree(phy); -} diff --git a/arch/arm/mach-tegra/wakeups-t2.h b/arch/arm/mach-tegra/wakeups-t2.h deleted file mode 100644 index f674b040a214..000000000000 --- a/arch/arm/mach-tegra/wakeups-t2.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * arch/arm/mach-tegra/wakeups-t2.h - * - * Declarations of Tegra 2 LP0 wakeup sources - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MACH_TEGRA_WAKEUPS_T2_H -#define __MACH_TEGRA_WAKEUPS_T2_H - -#define TEGRA_WAKE_GPIO_PO5 (1 << 0) -#define TEGRA_WAKE_GPIO_PV3 (1 << 1) -#define TEGRA_WAKE_GPIO_PL1 (1 << 2) -#define TEGRA_WAKE_GPIO_PB6 (1 << 3) -#define TEGRA_WAKE_GPIO_PN7 (1 << 4) -#define TEGRA_WAKE_GPIO_PA0 (1 << 5) -#define TEGRA_WAKE_GPIO_PU5 (1 << 6) -#define TEGRA_WAKE_GPIO_PU6 (1 << 7) -#define TEGRA_WAKE_GPIO_PC7 (1 << 8) -#define TEGRA_WAKE_GPIO_PS2 (1 << 9) -#define TEGRA_WAKE_GPIO_PAA1 (1 << 10) -#define TEGRA_WAKE_GPIO_PW3 (1 << 11) -#define TEGRA_WAKE_GPIO_PW2 (1 << 12) -#define TEGRA_WAKE_GPIO_PY6 (1 << 13) -#define TEGRA_WAKE_GPIO_PV6 (1 << 14) -#define TEGRA_WAKE_GPIO_PJ7 (1 << 15) -#define TEGRA_WAKE_RTC_ALARM (1 << 16) -#define TEGRA_WAKE_KBC_EVENT (1 << 17) -#define TEGRA_WAKE_PWR_INT (1 << 18) -#define TEGRA_WAKE_USB1_VBUS (1 << 19) -#define TEGRA_WAKE_USB3_VBUS (1 << 20) -#define TEGRA_WAKE_USB1_ID (1 << 21) -#define TEGRA_WAKE_USB3_ID (1 << 22) -#define TEGRA_WAKE_GPIO_PI5 (1 << 23) -#define TEGRA_WAKE_GPIO_PV2 (1 << 24) -#define TEGRA_WAKE_GPIO_PS4 (1 << 25) -#define TEGRA_WAKE_GPIO_PS5 (1 << 26) -#define TEGRA_WAKE_GPIO_PS0 (1 << 27) -#define TEGRA_WAKE_GPIO_PQ6 (1 << 28) -#define TEGRA_WAKE_GPIO_PQ7 (1 << 29) -#define TEGRA_WAKE_GPIO_PN2 (1 << 30) - -#endif diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index cc6f9d6193dd..a0a2928ae4dd 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -779,13 +779,6 @@ config CACHE_L2X0 help This option enables the L2x0 PrimeCell. -config CACHE_PL310 - bool - depends on CACHE_L2X0 - default y if CPU_V7 - help - This option enables support for the PL310 cache controller. - config CACHE_TAUROS2 bool "Enable the Tauros2 L2 cache controller" depends on (ARCH_DOVE || ARCH_MMP) diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 9abfa5d2b750..9982eb385c0f 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -26,44 +26,16 @@ #define CACHE_LINE_SIZE 32 static void __iomem *l2x0_base; +static DEFINE_SPINLOCK(l2x0_lock); static uint32_t l2x0_way_mask; /* Bitmask of active ways */ -bool l2x0_disabled; -static inline void cache_wait_always(void __iomem *reg, unsigned long mask) +static inline void cache_wait(void __iomem *reg, unsigned long mask) { /* wait for the operation to complete */ while (readl_relaxed(reg) & mask) ; } -#ifdef CONFIG_CACHE_PL310 - -static inline void cache_wait(void __iomem *reg, unsigned long mask) -{ - /* cache operations are atomic */ -} - -#define _l2x0_lock(lock, flags) ((void)(flags)) -#define _l2x0_unlock(lock, flags) ((void)(flags)) - -#define block_end(start, end) (end) - -#define L2CC_TYPE "PL310/L2C-310" - -#else /* !CONFIG_CACHE_PL310 */ - -#define cache_wait cache_wait_always - -static DEFINE_SPINLOCK(l2x0_lock); -#define _l2x0_lock(lock, flags) spin_lock_irqsave(lock, flags) -#define _l2x0_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) - -#define block_end(start, end) ((start) + min((end) - (start), 4096UL)) - -#define L2CC_TYPE "L2x0" - -#endif /* CONFIG_CACHE_PL310 */ - static inline void cache_sync(void) { void __iomem *base = l2x0_base; @@ -126,9 +98,9 @@ static void l2x0_cache_sync(void) { unsigned long flags; - _l2x0_lock(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); } static inline void l2x0_inv_all(void) @@ -136,23 +108,11 @@ static inline void l2x0_inv_all(void) unsigned long flags; /* invalidate all ways */ - _l2x0_lock(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); - cache_wait_always(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); + cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); -} - -static inline void l2x0_flush_all(void) -{ - unsigned long flags; - - /* flush all ways */ - _l2x0_lock(&l2x0_lock, flags); - writel(0xff, l2x0_base + L2X0_CLEAN_INV_WAY); - cache_wait_always(l2x0_base + L2X0_CLEAN_INV_WAY, 0xff); - cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) @@ -160,7 +120,7 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - _l2x0_lock(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); debug_writel(0x03); @@ -177,7 +137,7 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) } while (start < end) { - unsigned long blk_end = block_end(start, end); + unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { l2x0_inv_line(start); @@ -185,13 +145,13 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) } if (blk_end < end) { - _l2x0_unlock(&l2x0_lock, flags); - _l2x0_lock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_INV_LINE_PA, 1); cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) @@ -199,10 +159,10 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - _l2x0_lock(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - unsigned long blk_end = block_end(start, end); + unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { l2x0_clean_line(start); @@ -210,13 +170,13 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) } if (blk_end < end) { - _l2x0_unlock(&l2x0_lock, flags); - _l2x0_lock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_LINE_PA, 1); cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) @@ -224,10 +184,10 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - _l2x0_lock(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - unsigned long blk_end = block_end(start, end); + unsigned long blk_end = start + min(end - start, 4096UL); debug_writel(0x03); while (start < blk_end) { @@ -237,57 +197,23 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) debug_writel(0x00); if (blk_end < end) { - _l2x0_unlock(&l2x0_lock, flags); - _l2x0_lock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); - _l2x0_unlock(&l2x0_lock, flags); + spin_unlock_irqrestore(&l2x0_lock, flags); } -void l2x0_shutdown(void) -{ - unsigned long flags; - - if (l2x0_disabled) - return; - - BUG_ON(num_online_cpus() > 1); - - local_irq_save(flags); - - if (readl(l2x0_base + L2X0_CTRL) & 1) { - int m; - /* lockdown all ways, all masters to prevent new line - * allocation during maintenance */ - for (m=0; m<8; m++) { - writel(l2x0_way_mask, - l2x0_base + L2X0_LOCKDOWN_WAY_D + (m*8)); - writel(l2x0_way_mask, - l2x0_base + L2X0_LOCKDOWN_WAY_I + (m*8)); - } - l2x0_flush_all(); - writel(0, l2x0_base + L2X0_CTRL); - /* unlock cache ways */ - for (m=0; m<8; m++) { - writel(0, l2x0_base + L2X0_LOCKDOWN_WAY_D + (m*8)); - writel(0, l2x0_base + L2X0_LOCKDOWN_WAY_I + (m*8)); - } - } - - local_irq_restore(flags); -} - -static void l2x0_enable(__u32 aux_val, __u32 aux_mask) +void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) { __u32 aux; __u32 cache_id; int ways; const char *type; - if (l2x0_disabled) - return; + l2x0_base = base; cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); @@ -333,36 +259,12 @@ static void l2x0_enable(__u32 aux_val, __u32 aux_mask) writel_relaxed(1, l2x0_base + L2X0_CTRL); } - /*printk(KERN_INFO "%s cache controller enabled\n", type); - printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", - ways, cache_id, aux);*/ -} - -void l2x0_restart(void) -{ - l2x0_enable(0, ~0ul); -} - -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) -{ - if (l2x0_disabled) { - pr_info(L2CC_TYPE " cache controller disabled\n"); - return; - } - - l2x0_base = base; - - l2x0_enable(aux_val, aux_mask); - outer_cache.inv_range = l2x0_inv_range; outer_cache.clean_range = l2x0_clean_range; outer_cache.flush_range = l2x0_flush_range; outer_cache.sync = l2x0_cache_sync; -} -static int __init l2x0_disable(char *unused) -{ - l2x0_disabled = 1; - return 0; + printk(KERN_INFO "%s cache controller enabled\n", type); + printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", + ways, cache_id, aux); } -early_param("nol2x0", l2x0_disable); diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 2528afc1248f..86aa689ef1aa 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -196,10 +196,6 @@ 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 @@ -208,10 +204,6 @@ 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 @@ -219,6 +211,10 @@ 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 @@ -226,10 +222,6 @@ 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 @@ -264,18 +256,12 @@ v6_dma_clean_range: * - end - virtual end address of region */ ENTRY(v6_dma_flush_range) -#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT - sub r2, r1, r0 - cmp r2, #CONFIG_CACHE_FLUSH_RANGE_LIMIT - bhi v6_dma_flush_dcache_all -#endif - -#ifdef CONFIG_DMA_CACHE_RWFO - ldrb r2, [r0] @ read for ownership - strb r2, [r0] @ write for ownership -#endif 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 +#endif #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line #else @@ -283,27 +269,11 @@ 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 mov pc, lr -#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT -v6_dma_flush_dcache_all: - mov r0, #0 -#ifdef HARVARD_CACHE - mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate -#else - mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate -#endif - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mov pc, lr -#endif - /* * dma_map_area(start, size, dir) * - start - kernel virtual start address diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 74e71052da12..9b906dec1ca1 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -65,30 +65,6 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address, return ret; } -#if USE_SPLIT_PTLOCKS -/* - * If we are using split PTE locks, then we need to take the page - * lock here. Otherwise we are using shared mm->page_table_lock - * which is already locked, thus cannot take it. - */ -static inline void do_pte_lock(spinlock_t *ptl) -{ - /* - * Use nested version here to indicate that we are already - * holding one similar spinlock. - */ - spin_lock_nested(ptl, SINGLE_DEPTH_NESTING); -} - -static inline void do_pte_unlock(spinlock_t *ptl) -{ - spin_unlock(ptl); -} -#else /* !USE_SPLIT_PTLOCKS */ -static inline void do_pte_lock(spinlock_t *ptl) {} -static inline void do_pte_unlock(spinlock_t *ptl) {} -#endif /* USE_SPLIT_PTLOCKS */ - static int adjust_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { @@ -113,11 +89,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address, */ ptl = pte_lockptr(vma->vm_mm, pmd); pte = pte_offset_map_nested(pmd, address); - do_pte_lock(ptl); + spin_lock(ptl); ret = do_adjust_pte(vma, address, pfn, pte); - do_pte_unlock(ptl); + spin_unlock(ptl); pte_unmap_nested(pte); return ret; @@ -192,8 +168,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, return; mapping = page_mapping(page); +#ifndef CONFIG_SMP if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) __flush_dcache_page(mapping, page); +#endif if (mapping) { if (cache_is_vivt()) make_coherent(mapping, vma, addr, ptep, pfn); diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index e0758968e9f8..c6844cb9b508 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "mm.h" @@ -247,10 +246,12 @@ void flush_dcache_page(struct page *page) mapping = page_mapping(page); - if (!cache_ops_need_broadcast() && - !PageHighMem(page) && mapping && !mapping_mapped(mapping)) +#ifndef CONFIG_SMP + if (!PageHighMem(page) && mapping && !mapping_mapped(mapping)) set_bit(PG_dcache_dirty, &page->flags); - else { + else +#endif + { __flush_dcache_page(mapping, page); if (mapping && cache_is_vivt()) __flush_dcache_aliases(mapping, page); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index de77de72e277..7185b00650fe 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -147,8 +147,8 @@ static void __init find_limits(struct meminfo *mi, } } -static void __init arm_bootmem_init(unsigned long start_pfn, - unsigned long end_pfn) +static void __init arm_bootmem_init(struct meminfo *mi, + unsigned long start_pfn, unsigned long end_pfn) { unsigned int boot_pages; phys_addr_t bitmap; @@ -171,35 +171,27 @@ static void __init arm_bootmem_init(unsigned long start_pfn, pgdat = NODE_DATA(0); init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); - /* Free the lowmem regions from memblock into bootmem. */ - for (i = 0; i < memblock.memory.cnt; i++) { - unsigned long start = memblock_start_pfn(&memblock.memory, i); - unsigned long end = memblock_end_pfn(&memblock.memory, i); - - if (end >= end_pfn) - end = end_pfn; - if (start >= end) - break; - - free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT); + for_each_bank(i, mi) { + struct membank *bank = &mi->bank[i]; + if (!bank->highmem) + free_bootmem(bank_phys_start(bank), bank_phys_size(bank)); } - /* Reserve the lowmem memblock reserved regions in bootmem. */ + /* + * Reserve the memblock reserved regions in bootmem. + */ for (i = 0; i < memblock.reserved.cnt; i++) { - unsigned long start = memblock_start_pfn(&memblock.reserved, i); - unsigned long size = memblock_size_bytes(&memblock.reserved, i); - - if (start >= end_pfn) - break; - if (start + PFN_UP(size) > end_pfn) - size = (end_pfn - start) << PAGE_SHIFT; - - reserve_bootmem(__pfn_to_phys(start), size, BOOTMEM_DEFAULT); + phys_addr_t start = memblock_start_pfn(&memblock.reserved, i); + if (start >= start_pfn && + memblock_end_pfn(&memblock.reserved, i) <= end_pfn) + reserve_bootmem_node(pgdat, __pfn_to_phys(start), + memblock_size_bytes(&memblock.reserved, i), + BOOTMEM_DEFAULT); } } -static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, - unsigned long max_high) +static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min, + unsigned long max_low, unsigned long max_high) { unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; int i; @@ -224,23 +216,13 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, * holes = node_size - sum(bank_sizes) */ memcpy(zhole_size, zone_size, sizeof(zhole_size)); - for (i = 0; i < memblock.memory.cnt; i++) { - unsigned long start = memblock_start_pfn(&memblock.memory, i); - unsigned long end = memblock_end_pfn(&memblock.memory, i); - - if (start < max_low) { - unsigned long low_end = min(end, max_low); - - zhole_size[0] -= low_end - start; - } - + for_each_bank(i, mi) { + int idx = 0; #ifdef CONFIG_HIGHMEM - if (end > max_low) { - unsigned long high_start = max(start, max_low); - - zhole_size[ZONE_HIGHMEM] -= end - high_start; - } + if (mi->bank[i].highmem) + idx = ZONE_HIGHMEM; #endif + zhole_size[idx] -= bank_pfn_size(&mi->bank[i]); } /* @@ -328,7 +310,7 @@ void __init bootmem_init(void) find_limits(mi, &min, &max_low, &max_high); - arm_bootmem_init(min, max_low); + arm_bootmem_init(mi, min, max_low); /* * Sparsemem tries to allocate bootmem in memory_present(), @@ -346,7 +328,7 @@ void __init bootmem_init(void) * the sparse mem_map arrays initialized by sparse_init() * for memmap_init_zone(), otherwise all PFNs are invalid. */ - arm_bootmem_free(min, max_low, max_high); + arm_bootmem_free(mi, min, max_low, max_high); high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; @@ -440,57 +422,6 @@ static void __init free_unused_memmap(struct meminfo *mi) } } -static void __init free_highpages(void) -{ -#ifdef CONFIG_HIGHMEM - unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET; - int i, j; - - /* set highmem page free */ - for (i = j = 0; i < memblock.memory.cnt; i++) { - unsigned long start = memblock_start_pfn(&memblock.memory, i); - unsigned long end = memblock_end_pfn(&memblock.memory, i); - - /* Ignore complete lowmem entries */ - if (end <= max_low) - continue; - - /* Truncate partial highmem entries */ - if (start < max_low) - start = max_low; - - /* Find and exclude any reserved regions */ - for (; j < memblock.reserved.cnt; j++) { - unsigned long res_start; - unsigned long res_end; - - res_start = memblock_start_pfn(&memblock.reserved, j); - res_end = res_start + PFN_UP(memblock_size_bytes(&memblock.reserved, j)); - - if (res_end < start) - continue; - if (res_start < start) - res_start = start; - if (res_start > end) - res_start = end; - if (res_end > end) - res_end = end; - if (res_start != start) - totalhigh_pages += free_area(start, res_start, - NULL); - start = res_end; - if (start == end) - break; - } - - /* And now free anything which remains */ - if (start < end) - totalhigh_pages += free_area(start, end, NULL); - } - totalram_pages += totalhigh_pages; -#endif -} - /* * mem_init() marks the free areas in the mem_map and tells us how much * memory is free. This is done after various parts of the system have @@ -519,7 +450,16 @@ void __init mem_init(void) __phys_to_pfn(__pa(swapper_pg_dir)), NULL); #endif - free_highpages(); +#ifdef CONFIG_HIGHMEM + /* set highmem page free */ + for_each_bank (i, &meminfo) { + unsigned long start = bank_pfn_start(&meminfo.bank[i]); + unsigned long end = bank_pfn_end(&meminfo.bank[i]); + if (start >= max_low_pfn + PHYS_PFN_OFFSET) + totalhigh_pages += free_area(start, end, NULL); + } + totalram_pages += totalhigh_pages; +#endif reserved_pages = free_pages = 0; @@ -549,10 +489,9 @@ void __init mem_init(void) */ printk(KERN_INFO "Memory:"); num_physpages = 0; - for (i = 0; i < memblock.memory.cnt; i++) { - unsigned long pages = memblock_size_pages(&memblock.memory, i); - num_physpages += pages; - printk(" %luMB", pages >> (20 - PAGE_SHIFT)); + for (i = 0; i < meminfo.nr_banks; i++) { + num_physpages += bank_pfn_size(&meminfo.bank[i]); + printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20); } printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 16314854323a..cd6ef4facc15 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -867,7 +867,6 @@ static void __init sanity_check_meminfo(void) static inline void prepare_page_table(void) { unsigned long addr; - phys_addr_t end; /* * Clear out all the mappings below the kernel image. @@ -882,19 +881,11 @@ static inline void prepare_page_table(void) for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) pmd_clear(pmd_off_k(addr)); - /* - * Find the end of the first block of lowmem. This is complicated - * when we use memblock. - */ - end = memblock.memory.region[0].base + memblock.memory.region[0].size; - if (end >= lowmem_end_addr) - end = lowmem_end_addr; - /* * Clear out all the kernel space mappings, except for the first * memory bank, up to the end of the vmalloc region. */ - for (addr = __phys_to_virt(end); + for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0])); addr < VMALLOC_END; addr += PGDIR_SIZE) pmd_clear(pmd_off_k(addr)); } @@ -1011,27 +1002,29 @@ static void __init kmap_init(void) #endif } +static inline void map_memory_bank(struct membank *bank) +{ + struct map_desc map; + + map.pfn = bank_pfn_start(bank); + map.virtual = __phys_to_virt(bank_phys_start(bank)); + map.length = bank_phys_size(bank); + map.type = MT_MEMORY; + + create_mapping(&map); +} + static void __init map_lowmem(void) { + struct meminfo *mi = &meminfo; int i; /* Map all the lowmem memory banks. */ - for (i = 0; i < memblock.memory.cnt; i++) { - phys_addr_t start = memblock.memory.region[i].base; - phys_addr_t end = start + memblock.memory.region[i].size; - struct map_desc map; - - if (end >= lowmem_end_addr) - end = lowmem_end_addr; - if (start >= end) - break; - - map.pfn = __phys_to_pfn(start); - map.virtual = __phys_to_virt(start); - map.length = end - start; - map.type = MT_MEMORY; + for (i = 0; i < mi->nr_banks; i++) { + struct membank *bank = &mi->bank[i]; - create_mapping(&map); + if (!bank->highmem) + map_memory_bank(bank); } } diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 6da85e3f0632..7d63beaf9745 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -107,7 +107,7 @@ .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK .long PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED - .long PTE_EXT_TEX(4) | PTE_BUFFERABLE @ L_PTE_MT_INNER_WB + .long 0x00 @ unused .long 0x00 @ L_PTE_MT_MINICACHE (not present) .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC .long 0x00 @ unused diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 8cdf3bf26719..197f21bed5e9 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -302,12 +302,8 @@ __v7_setup: * NS1 = PRRR[19] = 1 - normal shareable property * NOS = PRRR[24+n] = 1 - not outer shareable */ - ldr r5, =0xff0a89a8 @ PRRR -#ifdef CONFIG_SMP - ldr r6, =0xc0e0c4e0 @ NMRR -#else - ldr r6, =0x40e044e0 -#endif + ldr r5, =0xff0a81a8 @ PRRR + ldr r6, =0x40e040e0 @ NMRR mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR #endif diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index b5dc61a22bf2..361a51e49030 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -373,7 +373,7 @@ cpu_xsc3_mt_table: .long PTE_EXT_TEX(5) | PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED - .long PTE_EXT_TEX(4) | PTE_BUFFERABLE @ L_PTE_MT_INNER_WB (not present?) + .long 0x00 @ unused .long 0x00 @ L_PTE_MT_MINICACHE (not present) .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC (not present?) .long 0x00 @ unused diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 69518395e710..14075979bcba 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -469,7 +469,7 @@ cpu_xscale_mt_table: .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED - .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_INNER_WB + .long 0x00 @ unused .long PTE_EXT_TEX(1) | PTE_CACHEABLE @ L_PTE_MT_MINICACHE .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC .long 0x00 @ unused diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index f5c5b8da9a87..ec7eddf9e525 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -997,17 +996,11 @@ void omap_start_dma(int 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. + * Errata: On ES2.0 BUFFERING disable must be set. + * This will always fail on ES1.0 */ - if (cpu_is_omap2420() || - (cpu_is_omap2430() && (omap_type() == OMAP2430_REV_ES1_0))) - l |= OMAP_DMA_CCR_BUFFERING_DISABLE; + if (cpu_is_omap24xx()) + l |= OMAP_DMA_CCR_EN; l |= OMAP_DMA_CCR_EN; dma_write(l, CCR(lch)); @@ -1025,39 +1018,8 @@ void omap_stop_dma(int lch) 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)) { - int i = 0; - u32 sys_cf; - - /* Configure No-Standby */ - l = dma_read(OCP_SYSCONFIG); - sys_cf = l; - l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK; - l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE); - dma_write(l , OCP_SYSCONFIG); - - l = dma_read(CCR(lch)); - l &= ~OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); - - /* Wait for sDMA FIFO drain */ - l = 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)); - } - 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); - } else { - l &= ~OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); - } + l &= ~OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h index cf66f85a011c..af3a03941add 100644 --- a/arch/arm/plat-omap/include/plat/dma.h +++ b/arch/arm/plat-omap/include/plat/dma.h @@ -335,10 +335,6 @@ #define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11) #define OMAP_DMA_CCR_EN (1 << 7) -#define OMAP_DMA_CCR_RD_ACTIVE (1 << 9) -#define OMAP_DMA_CCR_WR_ACTIVE (1 << 10) -#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24) -#define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25) #define OMAP_DMA_DATA_TYPE_S8 0x00 #define OMAP_DMA_DATA_TYPE_S16 0x01 diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index c1a978402583..4fa9903b83cf 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -10,7 +10,7 @@ * * Basic entry code, called from the kernel's undefined instruction trap. * r0 = faulted instruction - * r2 = faulted PC+4 + * r5 = faulted PC+4 * r9 = successful return * r10 = thread_info structure * lr = failure return @@ -26,7 +26,6 @@ ENTRY(do_vfp) str r11, [r10, #TI_PREEMPT] #endif enable_irq - str r2, [sp, #S_PC] @ update regs->ARM_pc for Thumb 2 case ldr r4, .LCvfp ldr r11, [r10, #TI_CPU] @ CPU number add r10, r10, #TI_VFPSTATE @ r10 = workspace diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index b07d990bbed8..592c7079de88 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -72,16 +72,12 @@ export MMU DTB all: linux.bin -# With make 3.82 we cannot mix normal and wildcard targets -BOOT_TARGETS1 = linux.bin linux.bin.gz -BOOT_TARGETS2 = simpleImage.% +BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.% archclean: $(Q)$(MAKE) $(clean)=$(boot) -$(BOOT_TARGETS1): vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -$(BOOT_TARGETS2): vmlinux +$(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ define archhelp diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5c0a3575877c..5742bb4d78f4 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 - * Copyright 2010, Lars-Peter Clausen + * Copyright 2010, Lars-Petrer Clausen * * 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(6), + QI_LB60_GPIO_KEYIN(7), QI_LB60_GPIO_KEYIN8, }; diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index 3fee685de4df..8eff48e20dba 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -169,11 +169,9 @@ static int p970_marked_instr_event(u64 event) switch (unit) { case PM_VPU: mask = 0x4c; /* byte 0 bits 2,3,6 */ - break; case PM_LSU0: /* byte 2 bits 0,2,3,4,6; all of byte 1 */ mask = 0x085dff00; - break; case PM_LSU1L: mask = 0x50 << 24; /* byte 3 bits 4,6 */ break; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1eb64ba43a08..09dffe6efa46 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1122,7 +1122,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, else #endif /* CONFIG_PPC_HAS_HASH_64K */ rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize, - subpage_protection(mm, ea)); + subpage_protection(pgdir, ea)); /* Dump some info in case of hash insertion failure, they should * never happen so it is really useful to know if/when they do diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 1995c1712fc8..ac151399ef34 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -95,6 +95,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck); static int notrace s390_revalidate_registers(struct mci *mci) { int kill_task; + u64 tmpclock; u64 zero; void *fpt_save_area, *fpt_creg_save_area; @@ -213,10 +214,11 @@ static int notrace s390_revalidate_registers(struct mci *mci) : "0", "cc"); #endif /* Revalidate clock comparator register */ - if (S390_lowcore.clock_comparator == -1) - set_clock_comparator(S390_lowcore.mcck_clock); - else - set_clock_comparator(S390_lowcore.clock_comparator); + asm volatile( + " stck 0(%1)\n" + " sckc 0(%1)" + : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); + /* Check if old PSW is valid */ if (!mci->wp) /* diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index c1e326cedea5..3479f1b0d4e0 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -566,23 +565,6 @@ 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 */ @@ -591,6 +573,5 @@ 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/lib/delay.c b/arch/s390/lib/delay.c index 7c37ec359ec2..752b362bf651 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -29,21 +29,17 @@ static void __udelay_disabled(unsigned long long usecs) { unsigned long mask, cr0, cr0_saved; u64 clock_saved; - u64 end; - mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; - end = get_clock() + (usecs << 12); clock_saved = local_tick_disable(); + set_clock_comparator(get_clock() + (usecs << 12)); __ctl_store(cr0_saved, 0, 0); cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; __ctl_load(cr0 , 0, 0); + mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; lockdep_off(); - do { - set_clock_comparator(end); - trace_hardirqs_on(); - __load_psw_mask(mask); - local_irq_disable(); - } while (get_clock() < end); + trace_hardirqs_on(); + __load_psw_mask(mask); + local_irq_disable(); lockdep_on(); __ctl_load(cr0_saved, 0, 0); local_tick_enable(clock_saved); diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index ae717e3c26d6..be201fdc97aa 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h @@ -19,10 +19,9 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs); -asmlinkage int sys_execve(const char __user *ufilename, - const char __user *const __user *uargv, - const char __user *const __user *uenvp, - unsigned long r7, struct pt_regs __regs); +asmlinkage int sys_execve(const char __user *ufilename, char __user * __user *uargv, + char __user * __user *uenvp, unsigned long r7, + struct pt_regs __regs); asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs); diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index f61a5017878f..963e1a45c35f 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h @@ -37,7 +37,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, const char *buf, int nbytes); + int (*v2_dev_write)(int d, 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 618a5bd4660d..33e31ce6b31f 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -60,6 +60,25 @@ extern char *prom_getbootargs(void); 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. */ @@ -102,8 +121,19 @@ extern int prom_getrev(void); /* Get the prom firmware revision. */ extern int prom_getprev(void); -/* Write a buffer of characters to the console. */ -extern void prom_console_write_buf(const char *buf, int len); +/* 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); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); @@ -208,6 +238,7 @@ extern int prom_node_has_property(int node, char *property); extern int prom_setprop(int node, const char *prop_name, char *prop_value, int value_size); +extern int prom_pathtoinode(char *path); extern int 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 209463d62626..3e0b2d62303d 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -67,6 +67,27 @@ 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. */ @@ -88,14 +109,33 @@ 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); -/* Write a buffer of characters to the console. */ -extern void prom_console_write_buf(const char *buf, int len); +/* 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); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); @@ -238,7 +278,9 @@ extern int prom_finddevice(const char *name); extern int prom_setprop(int node, const char *prop_name, char *prop_value, int value_size); +extern int prom_pathtoinode(const char *path); extern int 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 dcefd2211552..6a7b4dbc8e09 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 / HZ) - 1))); + (((1000000 / 100) - 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/HZ) - 1))); + LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 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 816c0fa12dc0..1b8c073adb44 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -6,6 +6,7 @@ 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 diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 48863108a44c..5340264b78f5 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -16,26 +16,63 @@ 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. */ -static int prom_nbputchar(const char *buf) +int +prom_nbputchar(char c) { + 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))(*buf); + i = (*(romvec->pv_nbputchar))(c); break; case PROM_V2: case PROM_V3: - if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, - buf, 0x1) == 1) + outc = c; + if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1) i = 0; + else + i = -1; break; default: + i = -1; break; }; restore_current(); @@ -43,14 +80,18 @@ static int prom_nbputchar(const char *buf) return i; /* Ugh, we could spin forever on unsupported proms ;( */ } -void prom_console_write_buf(const char *buf, int len) +/* Blocking version of get character routine above. */ +char +prom_getchar(void) { - while (len) { - int n = prom_nbputchar(buf); - if (n) - continue; - len--; - buf++; - } + int character; + while((character = prom_nbgetchar()) == -1) ; + return (char) character; } +/* 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 ed39e75828bd..10322dc2f557 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -15,34 +15,85 @@ extern int prom_stdin, prom_stdout; -static int __prom_console_write_buf(const char *buf, int len) +/* 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) +{ + 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]; - int ret; + char outc; + + outc = c; args[0] = (unsigned long) "write"; args[1] = 3; args[2] = 1; args[3] = (unsigned int) prom_stdout; - args[4] = (unsigned long) buf; - args[5] = (unsigned int) len; + args[4] = (unsigned long) &outc; + args[5] = 1; args[6] = (unsigned long) -1; p1275_cmd_direct(args); - ret = (int) args[6]; - if (ret < 0) + if (args[6] == 1) + return 0; + else return -1; - return ret; } -void prom_console_write_buf(const char *buf, int len) +/* Blocking version of get character routine above. */ +char +prom_getchar(void) +{ + int character; + while((character = prom_nbgetchar()) == -1) ; + return (char) character; +} + +/* Blocking version of put character routine above. */ +void +prom_putchar(char c) { - while (len) { - int n = __prom_console_write_buf(buf, len); - if (n < 0) - continue; - len -= n; - buf += len; - } + 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); } diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c new file mode 100644 index 000000000000..9c5d4687242a --- /dev/null +++ b/arch/sparc/prom/devops_32.c @@ -0,0 +1,87 @@ +/* + * devops.c: Device operations using the PROM. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#include +#include +#include + +#include +#include + +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 new file mode 100644 index 000000000000..a017119e7ef1 --- /dev/null +++ b/arch/sparc/prom/devops_64.c @@ -0,0 +1,67 @@ +/* + * 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 +#include +#include + +#include +#include + +/* 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/misc_64.c b/arch/sparc/prom/misc_64.c index 2fdcebf9a5df..6cb1581d6aef 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -18,7 +18,7 @@ #include #include -static int prom_service_exists(const char *service_name) +int prom_service_exists(const char *service_name) { unsigned long args[5]; @@ -150,6 +150,20 @@ 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/printf.c b/arch/sparc/prom/printf.c index d9682f06b3b0..ca869266b9f3 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c @@ -15,45 +15,22 @@ #include #include -#include #include #include -#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) { - unsigned int dest_len; - unsigned long flags; - char *dest; - - dest = console_write_buf; - raw_spin_lock_irqsave(&console_write_lock, flags); + char 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; - } + while (n != 0) { + --n; + if ((ch = *buf++) == '\n') + prom_putchar('\r'); + prom_putchar(ch); } - 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 71e7f080a576..b21592f8e3fe 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c @@ -341,3 +341,18 @@ int 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 + */ +int prom_pathtoinode(char *path) +{ + int node, 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 8327b1b68f4b..9d3f9137a43a 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -374,6 +374,24 @@ inline int prom_inst2pkg(int inst) return node; } +/* Return 'node' assigned to a particular prom 'path' + * FIXME: Should work for v0 as well + */ +int +prom_pathtoinode(const char *path) +{ + int node, 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/kernel/process.c b/arch/tile/kernel/process.c index aaf6282bacc3..84c29111756c 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -211,13 +211,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, childregs->regs[0] = 0; /* return value is zero */ 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. diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1664cce7b0ac..7f7338c90784 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -727,9 +727,6 @@ struct winch { static void free_winch(struct winch *winch, int free_irq_ok) { - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); - list_del(&winch->list); if (winch->pid != -1) @@ -738,6 +735,8 @@ static void free_winch(struct winch *winch, int free_irq_ok) os_close_file(winch->fd); if (winch->stack != 0) free_stack(winch->stack, 0); + if (free_irq_ok) + free_irq(WINCH_IRQ, winch); kfree(winch); } diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 9a873d765615..ec6378550671 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -22,7 +22,7 @@ SECTIONS _text = .; _stext = .; __init_begin = .; - INIT_TEXT_SECTION(0) + INIT_TEXT_SECTION(PAGE_SIZE) . = ALIGN(PAGE_SIZE); .text : diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6e3359d6a839..dec5678fc17f 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv) long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); - long long remain, max = UM_NSEC_PER_SEC / UM_HZ; + int remain, max = UM_NSEC_PER_SEC / UM_HZ; if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0) printk(UM_KERN_ERR "disable_timer - setitimer failed, " diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index f857bd39cdfb..3f76523589af 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -152,7 +152,7 @@ #define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */ #define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */ #define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */ -#define X86_FEATURE_XOP (6*32+11) /* extended AVX instructions */ +#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */ #define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */ #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ #define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 6a45ec41ec26..30a3e9776123 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -206,7 +206,6 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) extern void iounmap(volatile void __iomem *addr); -extern void set_iounmap_nonlazy(void); #ifdef __KERNEL__ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6986312bb670..c52e2eb40a1e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -79,7 +79,7 @@ #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 80 +#define KVM_MAX_CPUID_ENTRIES 40 #define KVM_NR_FIXED_MTRR_REGION 88 #define KVM_NR_VAR_MTRR 8 diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h index 33fc2966beb7..16350740edf6 100644 --- a/arch/x86/include/asm/mrst.h +++ b/arch/x86/include/asm/mrst.h @@ -26,7 +26,7 @@ enum mrst_cpu_type { }; extern enum mrst_cpu_type __mrst_cpu_chip; -static inline enum mrst_cpu_type mrst_identify_cpu(void) +static enum mrst_cpu_type mrst_identify_cpu(void) { return __mrst_cpu_chip; } diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f358241e4121..325b7bdbebaa 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -764,6 +764,29 @@ extern unsigned long idle_halt; extern unsigned long idle_nomwait; extern bool c1e_detected; +/* + * on systems with caches, caches must be flashed as the absolute + * last instruction before going into a suspended halt. Otherwise, + * dirty data can linger in the cache and become stale on resume, + * leading to strange errors. + * + * perform a variety of operations to guarantee that the compiler + * will not reorder instructions. wbinvd itself is serializing + * so the processor will not reorder. + * + * Systems without cache can just go into halt. + */ +static inline void wbinvd_halt(void) +{ + mb(); + /* check for clflush to determine if wbinvd is legal */ + if (cpu_has_clflush) + asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory"); + else + while (1) + halt(); +} + extern void enable_sep_cpu(void); extern int sysenter_setup(void); diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 4c2f63c7fc1b..4cfc90824068 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -50,7 +50,7 @@ struct smp_ops { void (*smp_prepare_cpus)(unsigned max_cpus); void (*smp_cpus_done)(unsigned max_cpus); - void (*stop_other_cpus)(int wait); + void (*smp_send_stop)(void); void (*smp_send_reschedule)(int cpu); int (*cpu_up)(unsigned cpu); @@ -73,12 +73,7 @@ extern struct smp_ops smp_ops; static inline void smp_send_stop(void) { - smp_ops.stop_other_cpus(0); -} - -static inline void stop_other_cpus(void) -{ - smp_ops.stop_other_cpus(1); + smp_ops.smp_send_stop(); } static inline void smp_prepare_boot_cpu(void) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index e0f220e158c1..e3b534cda49a 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1340,14 +1340,6 @@ 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 4d90327853b7..5c5b8f3dddb5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1397,7 +1397,6 @@ int setup_ioapic_entry(int apic_id, int irq, irte.dlvry_mode = apic->irq_delivery_mode; irte.vector = vector; irte.dest_id = IRTE_DEST(destination); - irte.redir_hint = 1; /* Set source-id of interrupt request */ set_ioapic_sid(&irte, apic_id); @@ -3349,7 +3348,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, irte.dlvry_mode = apic->irq_delivery_mode; irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); - irte.redir_hint = 1; /* Set source-id of interrupt request */ if (pdev) @@ -3626,7 +3624,6 @@ static int dmar_msi_set_affinity(unsigned int irq, 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 fac49a845064..83e9be4778e2 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -76,6 +76,13 @@ 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/amd.c b/arch/x86/kernel/cpu/amd.c index 81fa3cb12f39..ba5f62f45f01 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -305,7 +305,8 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) /* use socket ID also for last level cache */ per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; /* fixup topology information on multi-node processors */ - amd_fixup_dcm(c); + if ((c->x86 == 0x10) && (c->x86_model == 9)) + amd_fixup_dcm(c); #endif } diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index a2baafb2fe6d..cd8da247dda1 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -701,7 +701,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) per_cpu(acfreq_data, policy->cpu) = NULL; acpi_processor_unregister_performance(data->acpi_data, policy->cpu); - kfree(data->freq_table); kfree(data); } diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index ac140c7be396..c5f59d071425 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -827,7 +827,7 @@ int __init amd_special_default_mtrr(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) return 0; - if (boot_cpu_data.x86 < 0xf) + if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) return 0; /* In case some hypervisor doesn't pass SYSCFG through: */ if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 46d58448c3af..c2897b7b4a3b 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -52,7 +52,7 @@ static __initconst const u64 amd_hw_cache_event_ids [ C(DTLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */ - [ C(RESULT_MISS) ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */ + [ C(RESULT_MISS) ] = 0x0046, /* L1 DTLB and L2 DLTB Miss */ }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = 0, @@ -66,7 +66,7 @@ static __initconst const u64 amd_hw_cache_event_ids [ C(ITLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes */ - [ C(RESULT_MISS) ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */ + [ C(RESULT_MISS) ] = 0x0085, /* Instr. fetch ITLB misses */ }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = -1, diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 994828899e09..045b36cada65 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -34,7 +34,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE); + vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); if (!vaddr) return -ENOMEM; @@ -46,7 +46,6 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, } else memcpy(buf, vaddr + offset, csize); - set_iounmap_nonlazy(); iounmap(vaddr); return csize; } diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 42c594254507..ff15c9dcc25d 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -433,10 +433,6 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) dr6_p = (unsigned long *)ERR_PTR(args->err); dr6 = *dr6_p; - /* If it's a single step, TRAP bits are random */ - if (dr6 & DR_STEP) - return NOTIFY_DONE; - /* Do an early return if no trap bits are set in DR6 */ if ((dr6 & DR_TRAP_BITS) == 0) return NOTIFY_DONE; diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 2573689bda77..356170262a93 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c @@ -364,7 +364,8 @@ 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) { - vfree(mc); + if (mc) + vfree(mc); mc = vmalloc(mc_size); if (!mc) break; @@ -373,11 +374,13 @@ 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)) { - vfree(new_mc); + if (new_mc) + vfree(new_mc); new_rev = mc_header.rev; new_mc = mc; mc = NULL; /* trigger new vmalloc */ @@ -387,10 +390,12 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, leftover -= mc_size; } - vfree(mc); + if (mc) + vfree(mc); if (leftover) { - vfree(new_mc); + if (new_mc) + vfree(new_mc); state = UCODE_ERROR; goto out; } @@ -400,7 +405,8 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, goto out; } - vfree(uci->mc); + if (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/olpc.c b/arch/x86/kernel/olpc.c index a2bd899b2b83..0e0cdde519be 100644 --- a/arch/x86/kernel/olpc.c +++ b/arch/x86/kernel/olpc.c @@ -114,7 +114,6 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, unsigned long flags; int ret = -EIO; int i; - int restarts = 0; spin_lock_irqsave(&ec_lock, flags); @@ -170,9 +169,7 @@ restart: if (wait_on_obf(0x6c, 1)) { printk(KERN_ERR "olpc-ec: timeout waiting for" " EC to provide data!\n"); - if (restarts++ < 10) - goto restart; - goto err; + goto restart; } outbuf[i] = inb(0x68); pr_devel("olpc-ec: received 0x%x\n", outbuf[i]); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 76a0d715a031..e3af342fe83a 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -641,7 +641,7 @@ void native_machine_shutdown(void) /* O.K Now that I'm on the appropriate processor, * stop all of the others. */ - stop_other_cpus(); + smp_send_stop(); #endif lapic_shutdown(); diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 513deac7228d..d801210945d6 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -159,10 +159,10 @@ asmlinkage void smp_reboot_interrupt(void) irq_exit(); } -static void native_stop_other_cpus(int wait) +static void native_smp_send_stop(void) { unsigned long flags; - unsigned long timeout; + unsigned long wait; if (reboot_force) return; @@ -179,12 +179,9 @@ static void native_stop_other_cpus(int wait) if (num_online_cpus() > 1) { apic->send_IPI_allbutself(REBOOT_VECTOR); - /* - * Don't wait longer than a second if the caller - * didn't ask us to wait. - */ - timeout = USEC_PER_SEC; - while (num_online_cpus() > 1 && (wait || timeout--)) + /* Don't wait longer than a second */ + wait = USEC_PER_SEC; + while (num_online_cpus() > 1 && wait--) udelay(1); } @@ -230,7 +227,7 @@ struct smp_ops smp_ops = { .smp_prepare_cpus = native_smp_prepare_cpus, .smp_cpus_done = native_smp_cpus_done, - .stop_other_cpus = native_stop_other_cpus, + .smp_send_stop = native_smp_send_stop, .smp_send_reschedule = native_smp_send_reschedule, .cpu_up = native_cpu_up, diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 016179e5ba09..8b3bfc4dd708 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1383,94 +1383,11 @@ void play_dead_common(void) local_irq_disable(); } -#define MWAIT_SUBSTATE_MASK 0xf -#define MWAIT_SUBSTATE_SIZE 4 - -#define CPUID_MWAIT_LEAF 5 -#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1 - -/* - * We need to flush the caches before going to sleep, lest we have - * dirty data in our caches when we come back up. - */ -static inline void mwait_play_dead(void) -{ - unsigned int eax, ebx, ecx, edx; - unsigned int highest_cstate = 0; - unsigned int highest_subcstate = 0; - int i; - void *mwait_ptr; - - if (!cpu_has(¤t_cpu_data, X86_FEATURE_MWAIT)) - return; - if (!cpu_has(¤t_cpu_data, X86_FEATURE_CLFLSH)) - return; - if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) - return; - - eax = CPUID_MWAIT_LEAF; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - - /* - * eax will be 0 if EDX enumeration is not valid. - * Initialized below to cstate, sub_cstate value when EDX is valid. - */ - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) { - eax = 0; - } else { - edx >>= MWAIT_SUBSTATE_SIZE; - for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { - if (edx & MWAIT_SUBSTATE_MASK) { - highest_cstate = i; - highest_subcstate = edx & MWAIT_SUBSTATE_MASK; - } - } - eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | - (highest_subcstate - 1); - } - - /* - * This should be a memory location in a cache line which is - * unlikely to be touched by other processors. The actual - * content is immaterial as it is not actually modified in any way. - */ - mwait_ptr = ¤t_thread_info()->flags; - - wbinvd(); - - while (1) { - /* - * The CLFLUSH is a workaround for erratum AAI65 for - * the Xeon 7400 series. It's not clear it is actually - * needed, but it should be harmless in either case. - * The WBINVD is insufficient due to the spurious-wakeup - * case where we return around the loop. - */ - clflush(mwait_ptr); - __monitor(mwait_ptr, 0, 0); - mb(); - __mwait(eax, 0); - } -} - -static inline void hlt_play_dead(void) -{ - if (current_cpu_data.x86 >= 4) - wbinvd(); - - while (1) { - native_halt(); - } -} - void native_play_dead(void) { play_dead_common(); tboot_shutdown(TB_SHUTDOWN_WFS); - - mwait_play_dead(); /* Only returns on failure */ - hlt_play_dead(); + wbinvd_halt(); } #else /* ... !CONFIG_HOTPLUG_CPU */ diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9f4edeb21323..60788dee0f8a 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -575,7 +575,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) if (regs->flags & X86_VM_MASK) { handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); return; } diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 61fb98519622..5ffb5622f793 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -551,14 +551,8 @@ cannot_handle: int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno) { if (VMPI.is_vm86pus) { - if ((trapno == 3) || (trapno == 1)) { - KVM86->regs32->ax = VM86_TRAP + (trapno << 8); - /* setting this flag forces the code in entry_32.S to - call save_v86_state() and change the stack pointer - to KVM86->regs32 */ - set_thread_flag(TIF_IRET); - return 0; - } + if ((trapno == 3) || (trapno == 1)) + return_to_32bit(regs, VM86_TRAP + (trapno << 8)); do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs)); return 0; } diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 547128546cc3..9c253bd65e24 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -394,8 +394,7 @@ 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_align(xstate_size, - __alignof__(struct xsave_struct)); + init_xstate_buf = alloc_bootmem(xstate_size); init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; clts(); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index e7c3f3bd08fc..8a3f9f64f86f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -88,14 +88,6 @@ struct nested_state { /* A VMEXIT is required but not yet emulated */ bool exit_required; - /* - * If we vmexit during an instruction emulation we need this to restore - * the l1 guest rip after the emulation - */ - unsigned long vmexit_rip; - unsigned long vmexit_rsp; - unsigned long vmexit_rax; - /* cache for intercepts of the guest */ u16 intercept_cr_read; u16 intercept_cr_write; @@ -1214,12 +1206,8 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) if (old == new) { /* cr0 write with ts and mp unchanged */ svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; - if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) { - svm->nested.vmexit_rip = kvm_rip_read(vcpu); - svm->nested.vmexit_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP); - svm->nested.vmexit_rax = kvm_register_read(vcpu, VCPU_REGS_RAX); + if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) return; - } } } @@ -2411,23 +2399,6 @@ static int emulate_on_interception(struct vcpu_svm *svm) return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; } -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); - - if (svm->nested.vmexit_rip) { - kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip); - kvm_register_write(vcpu, VCPU_REGS_RSP, svm->nested.vmexit_rsp); - kvm_register_write(vcpu, VCPU_REGS_RAX, svm->nested.vmexit_rax); - svm->nested.vmexit_rip = 0; - } - - return r == EMULATE_DONE; -} - static int cr8_write_interception(struct vcpu_svm *svm) { struct kvm_run *kvm_run = svm->vcpu.run; @@ -2701,7 +2672,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_READ_CR4] = emulate_on_interception, [SVM_EXIT_READ_CR8] = emulate_on_interception, [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, - [SVM_EXIT_WRITE_CR0] = cr0_write_interception, + [SVM_EXIT_WRITE_CR0] = emulate_on_interception, [SVM_EXIT_WRITE_CR3] = emulate_on_interception, [SVM_EXIT_WRITE_CR4] = emulate_on_interception, [SVM_EXIT_WRITE_CR8] = cr8_write_interception, @@ -3281,7 +3252,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) 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); @@ -3289,6 +3259,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) #else loadsegment(gs, gs_selector); #endif + kvm_load_ldt(ldt_selector); reload_tss(vcpu); @@ -3383,14 +3354,6 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) { switch (func) { - case 0x00000001: - /* Mask out xsave bit as long as it is not supported by SVM */ - entry->ecx &= ~(bit(X86_FEATURE_XSAVE)); - break; - case 0x80000001: - if (nested) - entry->ecx |= (1 << 2); /* Set SVM bit */ - break; case 0x8000000A: entry->eax = 1; /* SVM revision 1 */ entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b3986fec7e68..7bddfab12013 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -828,9 +828,10 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) #endif #ifdef CONFIG_X86_64 - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); - if (is_long_mode(&vmx->vcpu)) + if (is_long_mode(&vmx->vcpu)) { + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + } #endif for (i = 0; i < vmx->save_nmsrs; ++i) kvm_set_shared_msr(vmx->guest_msrs[i].index, @@ -845,23 +846,23 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) ++vmx->vcpu.stat.host_state_reload; vmx->host_state.loaded = 0; -#ifdef CONFIG_X86_64 - if (is_long_mode(&vmx->vcpu)) - rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); -#endif + if (vmx->host_state.fs_reload_needed) + loadsegment(fs, vmx->host_state.fs_sel); if (vmx->host_state.gs_ldt_reload_needed) { kvm_load_ldt(vmx->host_state.ldt_sel); #ifdef CONFIG_X86_64 load_gs_index(vmx->host_state.gs_sel); + wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); #else loadsegment(gs, vmx->host_state.gs_sel); #endif } - if (vmx->host_state.fs_reload_needed) - loadsegment(fs, vmx->host_state.fs_sel); reload_tss(); #ifdef CONFIG_X86_64 - wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); + if (is_long_mode(&vmx->vcpu)) { + rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); + } #endif if (current_thread_info()->status & TS_USEDFPU) clts(); @@ -4248,6 +4249,11 @@ 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; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a5746de6f402..3a09c625d526 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -153,6 +153,11 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { u64 __read_mostly host_xcr0; +static inline u32 bit(int bitno) +{ + return 1 << (bitno & 31); +} + static void kvm_on_user_return(struct user_return_notifier *urn) { unsigned slot; @@ -1989,9 +1994,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, 0 /* Reserved, AES */ | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX); /* cpuid 0x80000001.ecx */ const u32 kvm_supported_word6_x86_features = - F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ | + F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ | F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) | - F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) | + F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(SSE5) | 0 /* SKINIT */ | 0 /* WDT */; /* all calls to cpuid_count() should be made on the same cpu */ @@ -2300,7 +2305,6 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, !kvm_exception_is_soft(vcpu->arch.exception.nr); events->exception.nr = vcpu->arch.exception.nr; events->exception.has_error_code = vcpu->arch.exception.has_error_code; - events->exception.pad = 0; events->exception.error_code = vcpu->arch.exception.error_code; events->interrupt.injected = @@ -2314,14 +2318,12 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, events->nmi.injected = vcpu->arch.nmi_injected; events->nmi.pending = vcpu->arch.nmi_pending; events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); - events->nmi.pad = 0; events->sipi_vector = vcpu->arch.sipi_vector; events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR | KVM_VCPUEVENT_VALID_SHADOW); - memset(&events->reserved, 0, sizeof(events->reserved)); } static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, @@ -2364,7 +2366,6 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, dbgregs->dr6 = vcpu->arch.dr6; dbgregs->dr7 = vcpu->arch.dr7; dbgregs->flags = 0; - memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); } static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, @@ -2848,7 +2849,6 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) sizeof(ps->channels)); ps->flags = kvm->arch.vpit->pit_state.flags; mutex_unlock(&kvm->arch.vpit->pit_state.lock); - memset(&ps->reserved, 0, sizeof(ps->reserved)); return r; } @@ -2912,6 +2912,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_memslots *slots, *old_slots; unsigned long *dirty_bitmap; + spin_lock(&kvm->mmu_lock); + kvm_mmu_slot_remove_write_access(kvm, log->slot); + spin_unlock(&kvm->mmu_lock); + r = -ENOMEM; dirty_bitmap = vmalloc(n); if (!dirty_bitmap) @@ -2933,10 +2937,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; kfree(old_slots); - spin_lock(&kvm->mmu_lock); - kvm_mmu_slot_remove_write_access(kvm, log->slot); - spin_unlock(&kvm->mmu_lock); - r = -EFAULT; if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { vfree(dirty_bitmap); @@ -3229,7 +3229,6 @@ long kvm_arch_vm_ioctl(struct file *filp, now_ns = timespec_to_ns(&now); user_ns.clock = kvm->arch.kvmclock_offset + now_ns; user_ns.flags = 0; - memset(&user_ns.pad, 0, sizeof(user_ns.pad)); r = -EFAULT; if (copy_to_user(argp, &user_ns, sizeof(user_ns))) @@ -5112,8 +5111,6 @@ 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.cr3); mmu_reset_needed = 1; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 0bf327453499..b7a404722d2b 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -65,11 +65,6 @@ 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); diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 42623310c968..b67a6b5aa8d4 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -484,29 +484,21 @@ static int __init_ibs_nmi(void) return 0; } -/* - * 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 - */ - +/* initialize the APIC for the IBS interrupts if available */ static void init_ibs(void) { - preempt_disable(); - ibs_caps = get_ibs_caps(); + if (!ibs_caps) - goto out; + return; - if (__init_ibs_nmi() < 0) + if (__init_ibs_nmi()) { ibs_caps = 0; - else - printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); + return; + } -out: - preempt_enable(); + printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", + (unsigned)ibs_caps); } static int (*create_arch_files)(struct super_block *sb, struct dentry *root); diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index b6552b189bcd..4a2afa1bac51 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 = -m64 -Wl,-soname=linux-vdso.so.1 \ +VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -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 = -m32 -Wl,-soname=linux-gate.so.1 +VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -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 0f6cd146f1ee..7d46c8441418 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1017,6 +1017,10 @@ static void xen_reboot(int reason) { struct sched_shutdown r = { .reason = reason }; +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r)) BUG(); } diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index f4d010031465..25f232b18a82 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -400,9 +400,9 @@ static void stop_self(void *v) BUG(); } -static void xen_stop_other_cpus(int wait) +static void xen_smp_send_stop(void) { - smp_call_function(stop_self, NULL, wait); + smp_call_function(stop_self, NULL, 0); } static void xen_smp_send_reschedule(int cpu) @@ -470,7 +470,7 @@ static const struct smp_ops xen_smp_ops __initdata = { .cpu_disable = xen_cpu_disable, .play_dead = xen_play_dead, - .stop_other_cpus = xen_stop_other_cpus, + .smp_send_stop = xen_smp_send_stop, .smp_send_reschedule = xen_smp_send_reschedule, .send_call_func_ipi = xen_smp_send_call_function_ipi, diff --git a/block/blk-core.c b/block/blk-core.c index 677f57445fd9..32a1c123dfb3 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1612,12 +1612,11 @@ void submit_bio(int rw, struct bio *bio) if (unlikely(block_dump)) { char b[BDEVNAME_SIZE]; - printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n", + printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n", current->comm, task_pid_nr(current), (rw & WRITE) ? "WRITE" : "READ", (unsigned long long)bio->bi_sector, - bdevname(bio->bi_bdev, b), - count); + bdevname(bio->bi_bdev, b)); } } diff --git a/block/blk-map.c b/block/blk-map.c index 267a57b77099..ade0a08c9099 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -205,8 +205,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, 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 c24bf43d51f0..eafc94f68d79 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 = blk_queue_cluster(q); + cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); 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 (!blk_queue_cluster(q)) + if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) 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 = blk_queue_cluster(q); + cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); /* * for each bio in rq diff --git a/block/blk-settings.c b/block/blk-settings.c index ea9430d3d7d2..a234f4bf1d6f 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -125,7 +125,7 @@ void blk_set_default_limits(struct queue_limits *lim) lim->alignment_offset = 0; lim->io_opt = 0; lim->misaligned = 0; - lim->cluster = 1; + lim->no_cluster = 0; } EXPORT_SYMBOL(blk_set_default_limits); @@ -343,7 +343,7 @@ EXPORT_SYMBOL(blk_queue_logical_block_size); * hardware can operate on without reverting to read-modify-write * operations. */ -void blk_queue_physical_block_size(struct request_queue *q, unsigned int size) +void blk_queue_physical_block_size(struct request_queue *q, unsigned short size) { q->limits.physical_block_size = size; @@ -468,6 +468,15 @@ 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); @@ -538,7 +547,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->cluster &= b->cluster; + t->no_cluster |= b->no_cluster; t->discard_zeroes_data &= b->discard_zeroes_data; /* Physical block size a multiple of the logical block size? */ @@ -634,6 +643,7 @@ 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]; @@ -644,6 +654,17 @@ 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 a26c930db346..0749b89c6885 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -114,7 +114,7 @@ static ssize_t queue_max_segments_show(struct request_queue *q, char *page) static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) { - if (blk_queue_cluster(q)) + if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) return queue_var_show(queue_max_segment_size(q), (page)); return queue_var_show(PAGE_CACHE_SIZE, (page)); diff --git a/block/genhd.c b/block/genhd.c index c26acf69af5a..59a2db6fecef 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -541,15 +541,13 @@ void add_disk(struct gendisk *disk) disk->major = MAJOR(devt); disk->first_minor = MINOR(devt); - /* Register BDI before referencing it from bdev */ - bdi = &disk->queue->backing_dev_info; - bdi_register_dev(bdi, disk_devt(disk)); - blk_register_region(disk_devt(disk), disk->minors, NULL, exact_match, exact_lock, disk); register_disk(disk); blk_register_queue(disk); + bdi = &disk->queue->backing_dev_info; + bdi_register_dev(bdi, disk_devt(disk)); retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, "bdi"); WARN_ON(retval); @@ -1008,22 +1006,6 @@ static void disk_release(struct device *dev) free_part_stats(&disk->part0); kfree(disk); } - -static int disk_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct gendisk *disk = dev_to_disk(dev); - struct disk_part_iter piter; - struct hd_struct *part; - int cnt = 0; - - disk_part_iter_init(&piter, disk, 0); - while((part = disk_part_iter_next(&piter))) - cnt++; - disk_part_iter_exit(&piter); - add_uevent_var(env, "NPARTS=%u", cnt); - return 0; -} - struct class block_class = { .name = "block", }; @@ -1042,7 +1024,6 @@ static struct device_type disk_type = { .groups = disk_attr_groups, .release = disk_release, .devnode = block_devnode, - .uevent = disk_uevent, }; #ifdef CONFIG_PROC_FS diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 4f4230b79bb6..a8b5a10eb5b0 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -321,47 +321,33 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; size_t iov_data_len; - struct sg_iovec *sg_iov; - struct iovec *iov; - int i; + struct sg_iovec *iov; - sg_iov = kmalloc(size, GFP_KERNEL); - if (!sg_iov) { + iov = kmalloc(size, GFP_KERNEL); + if (!iov) { ret = -ENOMEM; goto out; } - if (copy_from_user(sg_iov, hdr->dxferp, size)) { - kfree(sg_iov); + if (copy_from_user(iov, hdr->dxferp, size)) { + kfree(iov); ret = -EFAULT; goto out; } - /* - * Sum up the vecs, making sure they don't overflow - */ - iov = (struct iovec *) sg_iov; - iov_data_len = 0; - for (i = 0; i < hdr->iovec_count; i++) { - if (iov_data_len + iov[i].iov_len < iov_data_len) { - kfree(sg_iov); - ret = -EINVAL; - goto out; - } - iov_data_len += iov[i].iov_len; - } - /* SG_IO howto says that the shorter of the two wins */ + iov_data_len = iov_length((struct iovec *)iov, + hdr->iovec_count); if (hdr->dxfer_len < iov_data_len) { - hdr->iovec_count = iov_shorten(iov, + hdr->iovec_count = iov_shorten((struct iovec *)iov, hdr->iovec_count, hdr->dxfer_len); iov_data_len = hdr->dxfer_len; } - ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count, + ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, iov_data_len, GFP_KERNEL); - kfree(sg_iov); + kfree(iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, GFP_KERNEL); diff --git a/drivers/Kconfig b/drivers/Kconfig index 6781b709cac5..a2b902f4d437 100755 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -88,8 +88,6 @@ source "drivers/memstick/Kconfig" source "drivers/leds/Kconfig" -source "drivers/switch/Kconfig" - source "drivers/accessibility/Kconfig" source "drivers/infiniband/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index d7f34f1a6cab..a2aea53a75ed 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -95,7 +95,6 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/ -obj-$(CONFIG_SWITCH) += switch/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 6b0b5d08d97a..d555b374e314 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -300,25 +300,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. - * - * Note 10/2010: Except for the Scope() op. This opcode does - * not actually create a new object, it refers to an existing - * object. However, for Scope(), we want to indeed open a - * new scope. */ - if (op->common.aml_opcode != AML_SCOPE_OP) { - status = - acpi_ds_load2_begin_op(walk_state, NULL); - } else { - status = - acpi_ds_scope_stack_push(op->named.node, - op->named.node-> - type, walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } + status = acpi_ds_load2_begin_op(walk_state, NULL); } + break; case AML_CLASS_EXECUTE: diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 4c0a0a37d46e..98417201e9ce 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -98,7 +98,6 @@ enum { * due to bad math. */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, - ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, }; struct acpi_battery { @@ -413,8 +412,6 @@ static int acpi_battery_get_info(struct acpi_battery *battery) result = extract_package(battery, buffer.pointer, info_offsets, ARRAY_SIZE(info_offsets)); kfree(buffer.pointer); - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) - battery->full_charge_capacity = battery->design_capacity; return result; } @@ -451,10 +448,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->rate_now != -1) battery->rate_now = abs((s16)battery->rate_now); - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) - && battery->capacity_now >= 0 && battery->capacity_now <= 100) - battery->capacity_now = (battery->capacity_now * - battery->full_charge_capacity) / 100; return result; } @@ -568,33 +561,6 @@ static void acpi_battery_quirks(struct acpi_battery *battery) } } -/* - * According to the ACPI spec, some kinds of primary batteries can - * report percentage battery remaining capacity directly to OS. - * In this case, it reports the Last Full Charged Capacity == 100 - * and BatteryPresentRate == 0xFFFFFFFF. - * - * Now we found some battery reports percentage remaining capacity - * even if it's rechargeable. - * https://bugzilla.kernel.org/show_bug.cgi?id=15979 - * - * Handle this correctly so that they won't break userspace. - */ -static void acpi_battery_quirks2(struct acpi_battery *battery) -{ - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) - return ; - - if (battery->full_charge_capacity == 100 && - battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && - battery->capacity_now >=0 && battery->capacity_now <= 100) { - set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags); - battery->full_charge_capacity = battery->design_capacity; - battery->capacity_now = (battery->capacity_now * - battery->full_charge_capacity) / 100; - } -} - static int acpi_battery_update(struct acpi_battery *battery) { int result, old_present = acpi_battery_present(battery); @@ -620,9 +586,7 @@ static int acpi_battery_update(struct acpi_battery *battery) if (!battery->bat.dev) sysfs_add_battery(battery); #endif - result = acpi_battery_get_state(battery); - acpi_battery_quirks2(battery); - return result; + return acpi_battery_get_state(battery); } /* -------------------------------------------------------------------------- diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d68bd61072bb..310e3b9749cb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -935,12 +935,6 @@ static int __init acpi_bus_init(void) goto error1; } - /* - * _PDC control method may load dynamic SSDT tables, - * and we need to install the table handler before that. - */ - acpi_sysfs_init(); - acpi_early_processor_set_pdc(); /* @@ -1032,6 +1026,7 @@ static int __init acpi_init(void) acpi_scan_init(); acpi_ec_init(); acpi_power_init(); + acpi_sysfs_init(); acpi_debugfs_init(); acpi_sleep_proc_init(); acpi_wakeup_device_init(); diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 74c4a398604a..7de27d49c4b9 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -79,7 +79,7 @@ int __init acpi_debugfs_init(void) if (!acpi_dir) goto err; - cm_dentry = debugfs_create_file("custom_method", S_IWUSR, + cm_dentry = debugfs_create_file("custom_method", S_IWUGO, acpi_dir, NULL, &cm_fops); if (!cm_dentry) goto err; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7bff18b33089..f31291ba94d0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -929,9 +929,6 @@ 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/ata/ahci.h b/drivers/ata/ahci.h index d1a0f5bfdfeb..e5fdeebf9ef0 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -72,7 +72,6 @@ enum { AHCI_CMD_RESET = (1 << 8), AHCI_CMD_CLR_BUSY = (1 << 10), - RX_FIS_PIO_SETUP = 0x20, /* offset of PIO Setup FIS data */ RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 137514dbbf65..8eea309ea212 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1830,24 +1830,12 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; - u8 *rx_fis = pp->rx_fis; + u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; if (pp->fbs_enabled) - rx_fis += qc->dev->link->pmp * 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); + d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; + ata_tf_from_fis(d2h_fis, &qc->result_tf); return true; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7bb6787de550..a89172c100f5 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2577,11 +2577,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) * * If door lock fails, always clear sdev->locked to * avoid this infinite loop. - * - * This may happen before SCSI scan is complete. Make - * sure qc->dev->sdev isn't NULL before dereferencing. */ - if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) + if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) qc->dev->sdev->locked = 0; qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c55988b4f900..e30c537cce32 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1532,10 +1532,11 @@ 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_IDLE: - return ata_sff_idle_irq(ap); - default: + case HSM_ST: + case HSM_ST_LAST: break; + default: + return ata_sff_idle_irq(ap); } /* check main status, clearing INTRQ if needed */ diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index c51b8d25cfa8..4730c42a5ee5 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -538,7 +538,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) return 0; } -static void svia_configure(struct pci_dev *pdev, int board_id) +static void svia_configure(struct pci_dev *pdev) { u8 tmp8; @@ -577,7 +577,7 @@ static void svia_configure(struct pci_dev *pdev, int board_id) } /* - * vt6420/1 has problems talking to some drives. The following + * vt6421 has problems talking to some drives. The following * is the fix from Joseph Chan . * * When host issues HOLD, device may send up to 20DW of data @@ -596,9 +596,8 @@ static void svia_configure(struct pci_dev *pdev, int board_id) * * https://bugzilla.kernel.org/show_bug.cgi?id=15173 * http://article.gmane.org/gmane.linux.ide/46352 - * http://thread.gmane.org/gmane.linux.kernel/1062139 */ - if (board_id == vt6420 || board_id == vt6421) { + if (pdev->device == 0x3249) { pci_read_config_byte(pdev, 0x52, &tmp8); tmp8 |= 1 << 2; pci_write_config_byte(pdev, 0x52, tmp8); @@ -653,7 +652,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - svia_configure(pdev, board_id); + svia_configure(pdev); pci_set_master(pdev); return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1ba3de8015b5..276d5a701dc3 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "../base.h" #include "power.h" @@ -46,12 +45,6 @@ LIST_HEAD(dpm_list); static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; -static void dpm_drv_timeout(unsigned long data); -struct dpm_drv_wd_data { - struct device *dev; - struct task_struct *tsk; -}; - /* * Set once the preparation of devices for a PM transition has started, reset * before starting to resume devices. Protected by dpm_list_mtx. @@ -531,9 +524,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) TRACE_DEVICE(dev); TRACE_RESUME(0); - if (dev->parent && (dev->parent->power.status >= DPM_OFF || - dev->parent->power.status == DPM_RESUMING)) - dpm_wait(dev->parent, async); + dpm_wait(dev->parent, async); device_lock(dev); dev->power.status = DPM_RESUMING; @@ -593,30 +584,6 @@ static bool is_async(struct device *dev) && !pm_trace_is_enabled(); } -/** - * dpm_drv_timeout - Driver suspend / resume watchdog handler - * @data: struct device which timed out - * - * Called when a driver has timed out suspending or resuming. - * There's not much we can do here to recover so - * BUG() out for a crash-dump - * - */ -static void dpm_drv_timeout(unsigned long data) -{ - struct dpm_drv_wd_data *wd_data = (void *)data; - struct device *dev = wd_data->dev; - struct task_struct *tsk = wd_data->tsk; - - printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev), - (dev->driver ? dev->driver->name : "no driver")); - - printk(KERN_EMERG "dpm suspend stack:\n"); - show_stack(tsk, NULL); - - BUG(); -} - /** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. @@ -873,19 +840,8 @@ static int async_error; static int __device_suspend(struct device *dev, pm_message_t state, bool async) { int error = 0; - struct timer_list timer; - struct dpm_drv_wd_data data; dpm_wait_for_children(dev, async); - - data.dev = dev; - data.tsk = get_current(); - init_timer_on_stack(&timer); - timer.expires = jiffies + HZ * 12; - timer.function = dpm_drv_timeout; - timer.data = (unsigned long)&data; - add_timer(&timer); - device_lock(dev); if (async_error) @@ -927,10 +883,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) End: device_unlock(dev); - - del_timer_sync(&timer); - destroy_timer_on_stack(&timer); - complete_all(&dev->power.completion); return error; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index d773397575db..ab735a605cf3 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -71,7 +71,7 @@ struct blk_shadow { static const struct block_device_operations xlvbd_block_fops; -#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) +#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) /* * We have one of these per vbd, whether ide, scsi or 'other'. They diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 24fe2f37de8e..3182186449ee 100755 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -263,16 +263,9 @@ static int hci_uart_tty_open(struct tty_struct *tty) BT_DBG("tty %p", tty); - /* FIXME: This btw is bogus, nothing requires the old ldisc to clear - the pointer */ if (hu) return -EEXIST; - /* Error if the tty has no write op instead of leaving an exploitable - hole */ - if (tty->ops->write == NULL) - return -EOPNOTSUPP; - if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { BT_ERR("Can't allocate control structure"); return -ENFILE; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 0a0880332f20..3d44ec724c17 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -88,19 +88,6 @@ config VT_HW_CONSOLE_BINDING information. For framebuffer console users, please refer to . -config DEVMEM - bool "Memory device driver" - default y - help - The memory driver provides two character devices, mem and kmem, which - provide access to the system's memory. The mem device is a view of - physical memory, and each byte in the device corresponds to the - matching physical address. The kmem device is the same as mem, but - the addresses correspond to the kernel's virtual address space rather - than physical memory. These devices are standard parts of a Linux - system and most users should say Y here. You might say N if very - security conscience or memory is tight. - config DEVKMEM bool "/dev/kmem virtual device support" default y @@ -1132,10 +1119,6 @@ config DEVPORT depends on ISA || PCI default y -config DCC_TTY - tristate "DCC tty driver" - depends on ARM - source "drivers/s390/char/Kconfig" config RAMOOPS diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 720d6e8142cd..dc9641660605 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -109,7 +109,6 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ -obj-$(CONFIG_DCC_TTY) += dcc_tty.o obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_RAMOOPS) += ramoops.o diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 47350deb0e01..cd18493c9527 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1049,7 +1049,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_G45_HB), ID(PCI_DEVICE_ID_INTEL_G41_HB), ID(PCI_DEVICE_ID_INTEL_B43_HB), - ID(PCI_DEVICE_ID_INTEL_B43_1_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 6ea3bf6e5b1a..75e0a3497888 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -534,7 +534,7 @@ static void intel_i830_init_gtt_entries(void) pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); - if (IS_G33 || IS_I965) { + if (IS_I965) { u32 pgetbl_ctl; pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); @@ -567,6 +567,22 @@ static void intel_i830_init_gtt_entries(void) size = 512; } size += 4; /* add in BIOS popup space */ + } else if (IS_G33 && !IS_PINEVIEW) { + /* G33's GTT size defined in gmch_ctrl */ + switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { + case G33_PGETBL_SIZE_1M: + size = 1024; + break; + case G33_PGETBL_SIZE_2M: + size = 2048; + break; + default: + dev_info(&agp_bridge->dev->dev, + "unknown page table size 0x%x, assuming 512KB\n", + (gmch_ctrl & G33_PGETBL_SIZE_MASK)); + size = 512; + } + size += 4; } else if (IS_G4X || IS_PINEVIEW) { /* On 4 series hardware, GTT stolen is separate from graphics * stolen, ignore it in stolen gtt entries counting. However, @@ -1241,31 +1257,24 @@ static int intel_i915_get_gtt_size(void) int size; if (IS_G33) { - u32 pgetbl_ctl; - pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); + u16 gmch_ctrl; - switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { - case I965_PGETBL_SIZE_128KB: - size = 128; - break; - case I965_PGETBL_SIZE_256KB: - size = 256; - break; - case I965_PGETBL_SIZE_512KB: + /* G33's GTT size defined in gmch_ctrl */ + pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: size = 512; break; - case I965_PGETBL_SIZE_1MB: + case I830_GMCH_GMS_STOLEN_1024: size = 1024; break; - case I965_PGETBL_SIZE_2MB: - size = 2048; - break; - case I965_PGETBL_SIZE_1_5MB: - size = 1024 + 512; + case I830_GMCH_GMS_STOLEN_8192: + size = 8*1024; break; default: - dev_info(&intel_private.pcidev->dev, - "unknown page table size, assuming 512KB\n"); + dev_info(&agp_bridge->dev->dev, + "unknown page table size 0x%x, assuming 512KB\n", + (gmch_ctrl & I830_GMCH_GMS_MASK)); size = 512; } } else { @@ -1297,14 +1306,6 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); - temp &= 0xfff80000; - - intel_private.registers = ioremap(temp, 128 * 4096); - if (!intel_private.registers) { - iounmap(intel_private.gtt); - return -ENOMEM; - } - gtt_map_size = intel_i915_get_gtt_size(); intel_private.gtt = ioremap(temp2, gtt_map_size); @@ -1313,6 +1314,14 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) intel_private.gtt_total_size = gtt_map_size / 4; + temp &= 0xfff80000; + + intel_private.registers = ioremap(temp, 128 * 4096); + if (!intel_private.registers) { + iounmap(intel_private.gtt); + return -ENOMEM; + } + temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ diff --git a/drivers/char/dcc_tty.c b/drivers/char/dcc_tty.c deleted file mode 100644 index a787accdcb14..000000000000 --- a/drivers/char/dcc_tty.c +++ /dev/null @@ -1,326 +0,0 @@ -/* drivers/char/dcc_tty.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 -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("DCC TTY Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -static spinlock_t g_dcc_tty_lock = SPIN_LOCK_UNLOCKED; -static struct hrtimer g_dcc_timer; -static char g_dcc_buffer[16]; -static int g_dcc_buffer_head; -static int g_dcc_buffer_count; -static unsigned g_dcc_write_delay_usecs = 1; -static struct tty_driver *g_dcc_tty_driver; -static struct tty_struct *g_dcc_tty; -static int g_dcc_tty_open_count; - -static void dcc_poll_locked(void) -{ - char ch; - int rch; - int written; - - while (g_dcc_buffer_count) { - ch = g_dcc_buffer[g_dcc_buffer_head]; - asm( - "mrc 14, 0, r15, c0, c1, 0\n" - "mcrcc 14, 0, %1, c0, c5, 0\n" - "movcc %0, #1\n" - "movcs %0, #0\n" - : "=r" (written) - : "r" (ch) - ); - if (written) { - if (ch == '\n') - g_dcc_buffer[g_dcc_buffer_head] = '\r'; - else { - g_dcc_buffer_head = (g_dcc_buffer_head + 1) % ARRAY_SIZE(g_dcc_buffer); - g_dcc_buffer_count--; - if (g_dcc_tty) - tty_wakeup(g_dcc_tty); - } - g_dcc_write_delay_usecs = 1; - } else { - if (g_dcc_write_delay_usecs > 0x100) - break; - g_dcc_write_delay_usecs <<= 1; - udelay(g_dcc_write_delay_usecs); - } - } - - if (g_dcc_tty && !test_bit(TTY_THROTTLED, &g_dcc_tty->flags)) { - asm( - "mrc 14, 0, %0, c0, c1, 0\n" - "tst %0, #(1 << 30)\n" - "moveq %0, #-1\n" - "mrcne 14, 0, %0, c0, c5, 0\n" - : "=r" (rch) - ); - if (rch >= 0) { - ch = rch; - tty_insert_flip_string(g_dcc_tty, &ch, 1); - tty_flip_buffer_push(g_dcc_tty); - } - } - - - if (g_dcc_buffer_count) - hrtimer_start(&g_dcc_timer, ktime_set(0, g_dcc_write_delay_usecs * NSEC_PER_USEC), HRTIMER_MODE_REL); - else - hrtimer_start(&g_dcc_timer, ktime_set(0, 20 * NSEC_PER_MSEC), HRTIMER_MODE_REL); -} - -static int dcc_tty_open(struct tty_struct * tty, struct file * filp) -{ - int ret; - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - if (g_dcc_tty == NULL || g_dcc_tty == tty) { - g_dcc_tty = tty; - g_dcc_tty_open_count++; - ret = 0; - } else - ret = -EBUSY; - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - - printk("dcc_tty_open, tty %p, f_flags %x, returned %d\n", tty, filp->f_flags, ret); - - return ret; -} - -static void dcc_tty_close(struct tty_struct * tty, struct file * filp) -{ - printk("dcc_tty_close, tty %p, f_flags %x\n", tty, filp->f_flags); - if (g_dcc_tty == tty) { - if (--g_dcc_tty_open_count == 0) - g_dcc_tty = NULL; - } -} - -static int dcc_write(const unsigned char *buf_start, int count) -{ - const unsigned char *buf = buf_start; - unsigned long irq_flags; - int copy_len; - int space_left; - int tail; - - if (count < 1) - return 0; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - do { - tail = (g_dcc_buffer_head + g_dcc_buffer_count) % ARRAY_SIZE(g_dcc_buffer); - copy_len = ARRAY_SIZE(g_dcc_buffer) - tail; - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - if (copy_len > space_left) - copy_len = space_left; - if (copy_len > count) - copy_len = count; - memcpy(&g_dcc_buffer[tail], buf, copy_len); - g_dcc_buffer_count += copy_len; - buf += copy_len; - count -= copy_len; - if (copy_len < count && copy_len < space_left) { - space_left -= copy_len; - copy_len = count; - if (copy_len > space_left) { - copy_len = space_left; - } - memcpy(g_dcc_buffer, buf, copy_len); - buf += copy_len; - count -= copy_len; - g_dcc_buffer_count += copy_len; - } - dcc_poll_locked(); - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - } while(count && space_left); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return buf - buf_start; -} - -static int dcc_tty_write(struct tty_struct * tty, const unsigned char *buf, int count) -{ - int ret; - /* printk("dcc_tty_write %p, %d\n", buf, count); */ - ret = dcc_write(buf, count); - if (ret != count) - printk("dcc_tty_write %p, %d, returned %d\n", buf, count, ret); - return ret; -} - -static int dcc_tty_write_room(struct tty_struct *tty) -{ - int space_left; - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - space_left = ARRAY_SIZE(g_dcc_buffer) - g_dcc_buffer_count; - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return space_left; -} - -static int dcc_tty_chars_in_buffer(struct tty_struct *tty) -{ - int ret; - asm( - "mrc 14, 0, %0, c0, c1, 0\n" - "mov %0, %0, LSR #30\n" - "and %0, %0, #1\n" - : "=r" (ret) - ); - return ret; -} - -static void dcc_tty_unthrottle(struct tty_struct * tty) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - dcc_poll_locked(); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); -} - -static enum hrtimer_restart dcc_tty_timer_func(struct hrtimer *timer) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&g_dcc_tty_lock, irq_flags); - dcc_poll_locked(); - spin_unlock_irqrestore(&g_dcc_tty_lock, irq_flags); - return HRTIMER_NORESTART; -} - -void dcc_console_write(struct console *co, const char *b, unsigned count) -{ -#if 1 - dcc_write(b, count); -#else - /* blocking printk */ - while (count > 0) { - int written; - written = dcc_write(b, count); - if (written) { - b += written; - count -= written; - } - } -#endif -} - -static struct tty_driver *dcc_console_device(struct console *c, int *index) -{ - *index = 0; - return g_dcc_tty_driver; -} - -static int __init dcc_console_setup(struct console *co, char *options) -{ - if (co->index != 0) - return -ENODEV; - return 0; -} - - -static struct console dcc_console = -{ - .name = "ttyDCC", - .write = dcc_console_write, - .device = dcc_console_device, - .setup = dcc_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static struct tty_operations dcc_tty_ops = { - .open = dcc_tty_open, - .close = dcc_tty_close, - .write = dcc_tty_write, - .write_room = dcc_tty_write_room, - .chars_in_buffer = dcc_tty_chars_in_buffer, - .unthrottle = dcc_tty_unthrottle, -}; - -static int __init dcc_tty_init(void) -{ - int ret; - - hrtimer_init(&g_dcc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - g_dcc_timer.function = dcc_tty_timer_func; - - g_dcc_tty_driver = alloc_tty_driver(1); - if (!g_dcc_tty_driver) { - printk(KERN_ERR "dcc_tty_probe: alloc_tty_driver failed\n"); - ret = -ENOMEM; - goto err_alloc_tty_driver_failed; - } - g_dcc_tty_driver->owner = THIS_MODULE; - g_dcc_tty_driver->driver_name = "dcc"; - g_dcc_tty_driver->name = "ttyDCC"; - g_dcc_tty_driver->major = 0; // auto assign - g_dcc_tty_driver->minor_start = 0; - g_dcc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - g_dcc_tty_driver->subtype = SERIAL_TYPE_NORMAL; - g_dcc_tty_driver->init_termios = tty_std_termios; - g_dcc_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(g_dcc_tty_driver, &dcc_tty_ops); - ret = tty_register_driver(g_dcc_tty_driver); - if (ret) { - printk(KERN_ERR "dcc_tty_probe: tty_register_driver failed, %d\n", ret); - goto err_tty_register_driver_failed; - } - tty_register_device(g_dcc_tty_driver, 0, NULL); - - register_console(&dcc_console); - hrtimer_start(&g_dcc_timer, ktime_set(0, 0), HRTIMER_MODE_REL); - - return 0; - -err_tty_register_driver_failed: - put_tty_driver(g_dcc_tty_driver); - g_dcc_tty_driver = NULL; -err_alloc_tty_driver_failed: - return ret; -} - -static void __exit dcc_tty_exit(void) -{ - int ret; - - tty_unregister_device(g_dcc_tty_driver, 0); - ret = tty_unregister_driver(g_dcc_tty_driver); - if (ret < 0) { - printk(KERN_ERR "dcc_tty_remove: tty_unregister_driver failed, %d\n", ret); - } else { - put_tty_driver(g_dcc_tty_driver); - } - g_dcc_tty_driver = NULL; -} - -module_init(dcc_tty_init); -module_exit(dcc_tty_exit); - - diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index f8e7d89ceb2c..a0a1829d3198 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -479,21 +479,6 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) if (irq) { unsigned long irq_flags; - if (devp->hd_flags & HPET_SHARED_IRQ) { - /* - * To prevent the interrupt handler from seeing an - * unwanted interrupt status bit, program the timer - * so that it will not fire in the near future ... - */ - writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK, - &timer->hpet_config); - write_counter(read_counter(&hpet->hpet_mc), - &timer->hpet_compare); - /* ... and clear any left-over status. */ - isr = 1 << (devp - devp->hd_hpets->hp_dev); - writel(isr, &hpet->hpet_isr); - } - sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : IRQF_DISABLED; @@ -985,8 +970,6 @@ static int hpet_acpi_add(struct acpi_device *device) return -ENODEV; if (!data.hd_address || !data.hd_nirqs) { - if (data.hd_address) - iounmap(data.hd_address); printk("%s: no address or irqs in _CRS\n", __func__); return -ENODEV; } diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 501f115333ed..7bd7c45b53ef 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1665,17 +1665,6 @@ static int check_hotmod_int_op(const char *curr, const char *option, return 0; } -static struct smi_info *smi_info_alloc(void) -{ - struct smi_info *info = kzalloc(sizeof(*info), GFP_KERNEL); - - if (info) { - spin_lock_init(&info->si_lock); - spin_lock_init(&info->msg_lock); - } - return info; -} - static int hotmod_handler(const char *val, struct kernel_param *kp) { char *str = kstrdup(val, GFP_KERNEL); @@ -1790,7 +1779,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) } if (op == HM_ADD) { - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { rv = -ENOMEM; goto out; @@ -1855,7 +1844,7 @@ static __devinit void hardcode_find_bmc(void) if (!ports[i] && !addrs[i]) continue; - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return; @@ -2039,7 +2028,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) return -ENODEV; } - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); return -ENOMEM; @@ -2149,7 +2138,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, if (!acpi_dev) return -ENODEV; - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -2330,7 +2319,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) { struct smi_info *info; - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_ERR PFX "Could not allocate SI data\n"); return; @@ -2437,7 +2426,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; struct smi_info *info; - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -2578,7 +2567,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, return -EINVAL; } - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { dev_err(&dev->dev, @@ -3025,7 +3014,7 @@ static __devinit void default_find_bmc(void) if (check_legacy_ioport(ipmi_defaults[i].port)) continue; #endif - info = smi_info_alloc(); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return; @@ -3150,6 +3139,9 @@ static int try_smi_init(struct smi_info *new_smi) goto out_err; } + spin_lock_init(&(new_smi->si_lock)); + spin_lock_init(&(new_smi->msg_lock)); + /* Do low-level detection first. */ if (new_smi->handlers->detect(new_smi->si_sm)) { if (new_smi->addr_source) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 91091b0f1a32..1f528fad3516 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -59,7 +59,6 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) } #endif -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) #ifdef CONFIG_STRICT_DEVMEM static inline int range_is_allowed(unsigned long pfn, unsigned long size) { @@ -85,9 +84,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) return 1; } #endif -#endif -#ifdef CONFIG_DEVMEM void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) { } @@ -214,9 +211,6 @@ static ssize_t write_mem(struct file *file, const char __user *buf, *ppos += written; return written; } -#endif /* CONFIG_DEVMEM */ - -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) int __weak phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, unsigned long size, pgprot_t *vma_prot) @@ -338,7 +332,6 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) } return 0; } -#endif /* CONFIG_DEVMEM */ #ifdef CONFIG_DEVKMEM static int mmap_kmem(struct file *file, struct vm_area_struct *vma) @@ -703,8 +696,6 @@ static loff_t null_lseek(struct file *file, loff_t offset, int orig) return file->f_pos = 0; } -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) - /* * The memory devices use the full 32/64 bits of the offset, and so we cannot * check against negative addresses: they are ok. The return value is weird, @@ -738,14 +729,10 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) return ret; } -#endif - -#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) static int open_port(struct inode * inode, struct file * filp) { return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } -#endif #define zero_lseek null_lseek #define full_lseek null_lseek @@ -755,7 +742,6 @@ static int open_port(struct inode * inode, struct file * filp) #define open_kmem open_mem #define open_oldmem open_mem -#ifdef CONFIG_DEVMEM static const struct file_operations mem_fops = { .llseek = memory_lseek, .read = read_mem, @@ -764,7 +750,6 @@ static const struct file_operations mem_fops = { .open = open_mem, .get_unmapped_area = get_unmapped_area_mem, }; -#endif #ifdef CONFIG_DEVKMEM static const struct file_operations kmem_fops = { @@ -854,9 +839,7 @@ static const struct memdev { const struct file_operations *fops; struct backing_dev_info *dev_info; } devlist[] = { -#ifdef CONFIG_DEVMEM [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi }, -#endif #ifdef CONFIG_DEVKMEM [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi }, #endif diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c index 0e62674072eb..04ef3ef0a422 100644 --- a/drivers/char/n_gsm.c +++ b/drivers/char/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 >> 7); /* bits 7 - 15 */ - *--dp = (msg->len & 127) << 1; /* bits 0 - 6 */ + *--dp = (msg->len >> 6) | EA; + *--dp = (msg->len & 127) << 1; } } @@ -968,8 +968,6 @@ 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/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 45f9fad4f5dc..9ecd6bef5d3b 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -4127,8 +4127,6 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (cmd != SIOCWANDEV) return hdlc_ioctl(dev, ifr, cmd); - memset(&new_line, 0, size); - switch(ifr->ifr_settings.type) { case IF_GET_IFACE: /* return current sync_serial_settings */ diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 9445f48c692f..74f00b5ffa36 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c @@ -27,6 +27,7 @@ #include #define RAMOOPS_KERNMSG_HDR "====" +#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) #define RECORD_SIZE 4096 @@ -62,8 +63,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, hdr_size; - char *buf, *buf_orig; + int res; + char *buf; struct timeval timestamp; /* Only dump oopses if dump_oops is set */ @@ -71,8 +72,6 @@ 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; @@ -80,9 +79,8 @@ 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; - 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); + l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE)); + l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy); s2_start = l2 - l2_cpy; s1_start = l1 - l1_cpy; diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index d8210ca00720..cc1e9850d655 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -413,8 +413,7 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { - struct tty_buffer *head, *tail = tty->buf.tail; - int seen_tail = 0; + struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { int count; char *char_buf; @@ -424,15 +423,6 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; - /* - There's a possibility tty might get new buffer - added during the unlock window below. We could - end up spinning in here forever hogging the CPU - completely. To avoid this let's have a rest each - time we processed the tail buffer. - */ - if (tail == head) - seen_tail = 1; tty->buf.head = head->next; tty_buffer_free(tty, head); continue; @@ -442,7 +432,7 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room || seen_tail) { + if (!tty->receive_room) { schedule_delayed_work(&tty->buf.work, 1); break; } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e0f7f4b8c286..613c852ee0fe 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -553,9 +553,6 @@ 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 */ @@ -575,10 +572,6 @@ 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); @@ -616,6 +609,7 @@ 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,7 +635,6 @@ 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(); @@ -1311,9 +1304,7 @@ static int tty_reopen(struct tty_struct *tty) { struct tty_driver *driver = tty->driver; - if (test_bit(TTY_CLOSING, &tty->flags) || - test_bit(TTY_HUPPING, &tty->flags) || - test_bit(TTY_LDISC_CHANGING, &tty->flags)) + if (test_bit(TTY_CLOSING, &tty->flags)) return -EIO; if (driver->type == TTY_DRIVER_TYPE_PTY && diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 4214d58276f7..412f9775d19c 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c @@ -47,7 +47,6 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; @@ -84,7 +83,6 @@ static void put_ldisc(struct tty_ldisc *ld) return; } local_irq_restore(flags); - wake_up(&tty_ldisc_idle); } /** @@ -454,8 +452,6 @@ 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; @@ -534,23 +530,6 @@ static int tty_ldisc_halt(struct tty_struct *tty) return cancel_delayed_work_sync(&tty->buf.work); } -/** - * tty_ldisc_wait_idle - wait for the ldisc to become idle - * @tty: tty to wait for - * - * Wait for the line discipline to become idle. The discipline must - * have been halted for this to guarantee it remains idle. - */ -static int tty_ldisc_wait_idle(struct tty_struct *tty) -{ - int ret; - ret = wait_event_interruptible_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, 5 * HZ); - if (ret < 0) - return ret; - return ret > 0 ? 0 : -EBUSY; -} - /** * tty_set_ldisc - set line discipline * @tty: the terminal to set @@ -655,17 +634,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) flush_scheduled_work(); - retval = tty_ldisc_wait_idle(tty); - tty_lock(); mutex_lock(&tty->ldisc_mutex); - - /* handle wait idle failure locked */ - if (retval) { - tty_ldisc_put(new_ldisc); - goto enable; - } - if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ @@ -699,7 +669,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_put(o_ldisc); -enable: /* * Allow ldisc referencing to occur again */ @@ -745,12 +714,9 @@ static void tty_reset_termios(struct tty_struct *tty) * state closed */ -static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) +static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) { - struct tty_ldisc *ld = tty_ldisc_get(ldisc); - - if (IS_ERR(ld)) - return -1; + struct tty_ldisc *ld; tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); @@ -758,10 +724,10 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) /* * Switch the line discipline back */ + ld = tty_ldisc_get(ldisc); + BUG_ON(IS_ERR(ld)); tty_ldisc_assign(tty, ld); tty_set_termios_ldisc(tty, ldisc); - - return 0; } /** @@ -836,16 +802,13 @@ void tty_ldisc_hangup(struct tty_struct *tty) a FIXME */ if (tty->ldisc) { /* Not yet closed */ if (reset == 0) { - - if (!tty_ldisc_reinit(tty, tty->termios->c_line)) - err = tty_ldisc_open(tty, tty->ldisc); - else - err = 1; + tty_ldisc_reinit(tty, tty->termios->c_line); + err = tty_ldisc_open(tty, tty->ldisc); } /* If the re-open fails or we reset then go to N_TTY. The N_TTY open cannot fail */ if (reset || err) { - BUG_ON(tty_ldisc_reinit(tty, N_TTY)); + tty_ldisc_reinit(tty, N_TTY); WARN_ON(tty_ldisc_open(tty, tty->ldisc)); } tty_ldisc_enable(tty); diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 6b68a0fb4611..38df8c19e74c 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -503,7 +503,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, struct kbd_struct * kbd; unsigned int console; unsigned char ucval; - unsigned int uival; void __user *up = (void __user *)arg; int i, perm; int ret = 0; @@ -658,7 +657,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGETMODE: - uival = vc->vc_mode; + ucval = vc->vc_mode; goto setint; case KDMAPDISP: @@ -696,7 +695,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGKBMODE: - uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : + ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : K_XLATE); @@ -718,9 +717,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGKBMETA: - uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); + ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); setint: - ret = put_user(uival, (int __user *)arg); + ret = put_user(ucval, (int __user *)arg); break; case KDGETKEYCODE: @@ -950,7 +949,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, for (i = 0; i < MAX_NR_CONSOLES; ++i) if (! VT_IS_IN_USE(i)) break; - uival = i < MAX_NR_CONSOLES ? (i+1) : -1; + ucval = i < MAX_NR_CONSOLES ? (i+1) : -1; goto setint; /* diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index cd3464b77b60..a8c8d9c19d74 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -110,16 +110,6 @@ config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE Be aware that not all cpufreq drivers support the conservative governor. If unsure have a look at the help section of the driver. Fallback governor will be the performance governor. - -config CPU_FREQ_DEFAULT_GOV_INTERACTIVE - bool "interactive" - select CPU_FREQ_GOV_INTERACTIVE - help - Use the CPUFreq governor 'interactive' as default. This allows - you to get a full dynamic cpu frequency capable system by simply - loading your cpufreq low-level hardware driver, using the - 'interactive' governor for latency-sensitive workloads. - endchoice config CPU_FREQ_GOV_PERFORMANCE @@ -177,12 +167,6 @@ config CPU_FREQ_GOV_ONDEMAND If in doubt, say N. -config CPU_FREQ_GOV_INTERACTIVE - tristate "'interactive' cpufreq policy governor" - help - 'interactive' - This driver adds a dynamic cpufreq policy governor - designed for latency-sensitive workloads. - config CPU_FREQ_GOV_CONSERVATIVE tristate "'conservative' cpufreq governor" depends on CPU_FREQ diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 30629f7dc747..71fc3b4173f1 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o -obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o # CPUfreq cross-arch helpers obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c deleted file mode 100644 index 81783286cad2..000000000000 --- a/drivers/cpufreq/cpufreq_interactive.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_interactive.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Author: Mike Chan (mike@android.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static void (*pm_idle_old)(void); -static atomic_t active_count = ATOMIC_INIT(0); - -struct cpufreq_interactive_cpuinfo { - struct timer_list cpu_timer; - int timer_idlecancel; - u64 time_in_idle; - u64 idle_exit_time; - u64 timer_run_time; - int idling; - u64 freq_change_time; - u64 freq_change_time_in_idle; - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *freq_table; - unsigned int target_freq; - int governor_enabled; -}; - -static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo); - -/* Workqueues handle frequency scaling */ -static struct task_struct *up_task; -static struct workqueue_struct *down_wq; -static struct work_struct freq_scale_down_work; -static cpumask_t up_cpumask; -static spinlock_t up_cpumask_lock; -static cpumask_t down_cpumask; -static spinlock_t down_cpumask_lock; - -/* Go to max speed when CPU load at or above this value. */ -#define DEFAULT_GO_MAXSPEED_LOAD 85 -static unsigned long go_maxspeed_load; - -/* - * The minimum amount of time to spend at a frequency before we can ramp down. - */ -#define DEFAULT_MIN_SAMPLE_TIME 80000; -static unsigned long min_sample_time; - -#define DEBUG 0 -#define BUFSZ 128 - -#if DEBUG -#include - -struct dbgln { - int cpu; - unsigned long jiffy; - unsigned long run; - char buf[BUFSZ]; -}; - -#define NDBGLNS 256 - -static struct dbgln dbgbuf[NDBGLNS]; -static int dbgbufs; -static int dbgbufe; -static struct proc_dir_entry *dbg_proc; -static spinlock_t dbgpr_lock; - -static u64 up_request_time; -static unsigned int up_max_latency; - -static void dbgpr(char *fmt, ...) -{ - va_list args; - int n; - unsigned long flags; - - spin_lock_irqsave(&dbgpr_lock, flags); - n = dbgbufe; - va_start(args, fmt); - vsnprintf(dbgbuf[n].buf, BUFSZ, fmt, args); - va_end(args); - dbgbuf[n].cpu = smp_processor_id(); - dbgbuf[n].run = nr_running(); - dbgbuf[n].jiffy = jiffies; - - if (++dbgbufe >= NDBGLNS) - dbgbufe = 0; - - if (dbgbufe == dbgbufs) - if (++dbgbufs >= NDBGLNS) - dbgbufs = 0; - - spin_unlock_irqrestore(&dbgpr_lock, flags); -} - -static void dbgdump(void) -{ - int i, j; - unsigned long flags; - static struct dbgln prbuf[NDBGLNS]; - - spin_lock_irqsave(&dbgpr_lock, flags); - i = dbgbufs; - j = dbgbufe; - memcpy(prbuf, dbgbuf, sizeof(dbgbuf)); - dbgbufs = 0; - dbgbufe = 0; - spin_unlock_irqrestore(&dbgpr_lock, flags); - - while (i != j) - { - printk("%lu %d %lu %s", - prbuf[i].jiffy, prbuf[i].cpu, prbuf[i].run, - prbuf[i].buf); - if (++i == NDBGLNS) - i = 0; - } -} - -static int dbg_proc_read(char *buffer, char **start, off_t offset, - int count, int *peof, void *dat) -{ - printk("max up_task latency=%uus\n", up_max_latency); - dbgdump(); - *peof = 1; - return 0; -} - - -#else -#define dbgpr(...) do {} while (0) -#endif - -static int cpufreq_governor_interactive(struct cpufreq_policy *policy, - unsigned int event); - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -static -#endif -struct cpufreq_governor cpufreq_gov_interactive = { - .name = "interactive", - .governor = cpufreq_governor_interactive, - .max_transition_latency = 10000000, - .owner = THIS_MODULE, -}; - -static void cpufreq_interactive_timer(unsigned long data) -{ - unsigned int delta_idle; - unsigned int delta_time; - int cpu_load; - int load_since_change; - u64 time_in_idle; - u64 idle_exit_time; - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, data); - u64 now_idle; - unsigned int new_freq; - unsigned int index; - unsigned long flags; - - smp_rmb(); - - if (!pcpu->governor_enabled) - goto exit; - - /* - * Once pcpu->timer_run_time is updated to >= pcpu->idle_exit_time, - * this lets idle exit know the current idle time sample has - * been processed, and idle exit can generate a new sample and - * re-arm the timer. This prevents a concurrent idle - * exit on that CPU from writing a new set of info at the same time - * the timer function runs (the timer function can't use that info - * until more time passes). - */ - time_in_idle = pcpu->time_in_idle; - idle_exit_time = pcpu->idle_exit_time; - now_idle = get_cpu_idle_time_us(data, &pcpu->timer_run_time); - smp_wmb(); - - /* If we raced with cancelling a timer, skip. */ - if (!idle_exit_time) { - dbgpr("timer %d: no valid idle exit sample\n", (int) data); - goto exit; - } - -#if DEBUG - if ((int) jiffies - (int) pcpu->cpu_timer.expires >= 10) - dbgpr("timer %d: late by %d ticks\n", - (int) data, jiffies - pcpu->cpu_timer.expires); -#endif - - delta_idle = (unsigned int) cputime64_sub(now_idle, time_in_idle); - delta_time = (unsigned int) cputime64_sub(pcpu->timer_run_time, - idle_exit_time); - - /* - * If timer ran less than 1ms after short-term sample started, retry. - */ - if (delta_time < 1000) { - dbgpr("timer %d: time delta %u too short exit=%llu now=%llu\n", (int) data, - delta_time, idle_exit_time, pcpu->timer_run_time); - goto rearm; - } - - if (delta_idle > delta_time) - cpu_load = 0; - else - cpu_load = 100 * (delta_time - delta_idle) / delta_time; - - delta_idle = (unsigned int) cputime64_sub(now_idle, - pcpu->freq_change_time_in_idle); - delta_time = (unsigned int) cputime64_sub(pcpu->timer_run_time, - pcpu->freq_change_time); - - if (delta_idle > delta_time) - load_since_change = 0; - else - load_since_change = - 100 * (delta_time - delta_idle) / delta_time; - - /* - * Choose greater of short-term load (since last idle timer - * started or timer function re-armed itself) or long-term load - * (since last frequency change). - */ - if (load_since_change > cpu_load) - cpu_load = load_since_change; - - if (cpu_load >= go_maxspeed_load) - new_freq = pcpu->policy->max; - else - new_freq = pcpu->policy->max * cpu_load / 100; - - if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table, - new_freq, CPUFREQ_RELATION_H, - &index)) { - dbgpr("timer %d: cpufreq_frequency_table_target error\n", (int) data); - goto rearm; - } - - new_freq = pcpu->freq_table[index].frequency; - - if (pcpu->target_freq == new_freq) - { - dbgpr("timer %d: load=%d, already at %d\n", (int) data, cpu_load, new_freq); - goto rearm_if_notmax; - } - - /* - * Do not scale down unless we have been at this frequency for the - * minimum sample time. - */ - if (new_freq < pcpu->target_freq) { - if (cputime64_sub(pcpu->timer_run_time, pcpu->freq_change_time) < - min_sample_time) { - dbgpr("timer %d: load=%d cur=%d tgt=%d not yet\n", (int) data, cpu_load, pcpu->target_freq, new_freq); - goto rearm; - } - } - - dbgpr("timer %d: load=%d cur=%d tgt=%d queue\n", (int) data, cpu_load, pcpu->target_freq, new_freq); - - if (new_freq < pcpu->target_freq) { - pcpu->target_freq = new_freq; - spin_lock_irqsave(&down_cpumask_lock, flags); - cpumask_set_cpu(data, &down_cpumask); - spin_unlock_irqrestore(&down_cpumask_lock, flags); - queue_work(down_wq, &freq_scale_down_work); - } else { - pcpu->target_freq = new_freq; -#if DEBUG - up_request_time = ktime_to_us(ktime_get()); -#endif - spin_lock_irqsave(&up_cpumask_lock, flags); - cpumask_set_cpu(data, &up_cpumask); - spin_unlock_irqrestore(&up_cpumask_lock, flags); - wake_up_process(up_task); - } - -rearm_if_notmax: - /* - * Already set max speed and don't see a need to change that, - * wait until next idle to re-evaluate, don't need timer. - */ - if (pcpu->target_freq == pcpu->policy->max) - goto exit; - -rearm: - if (!timer_pending(&pcpu->cpu_timer)) { - /* - * If already at min: if that CPU is idle, don't set timer. - * Else cancel the timer if that CPU goes idle. We don't - * need to re-evaluate speed until the next idle exit. - */ - if (pcpu->target_freq == pcpu->policy->min) { - smp_rmb(); - - if (pcpu->idling) { - dbgpr("timer %d: cpu idle, don't re-arm\n", (int) data); - goto exit; - } - - pcpu->timer_idlecancel = 1; - } - - pcpu->time_in_idle = get_cpu_idle_time_us( - data, &pcpu->idle_exit_time); - mod_timer(&pcpu->cpu_timer, jiffies + 2); - dbgpr("timer %d: set timer for %lu exit=%llu\n", (int) data, pcpu->cpu_timer.expires, pcpu->idle_exit_time); - } - -exit: - return; -} - -static void cpufreq_interactive_idle(void) -{ - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, smp_processor_id()); - int pending; - - if (!pcpu->governor_enabled) { - pm_idle_old(); - return; - } - - pcpu->idling = 1; - smp_wmb(); - pending = timer_pending(&pcpu->cpu_timer); - - if (pcpu->target_freq != pcpu->policy->min) { -#ifdef CONFIG_SMP - /* - * Entering idle while not at lowest speed. On some - * platforms this can hold the other CPU(s) at that speed - * even though the CPU is idle. Set a timer to re-evaluate - * speed so this idle CPU doesn't hold the other CPUs above - * min indefinitely. This should probably be a quirk of - * the CPUFreq driver. - */ - if (!pending) { - pcpu->time_in_idle = get_cpu_idle_time_us( - smp_processor_id(), &pcpu->idle_exit_time); - pcpu->timer_idlecancel = 0; - mod_timer(&pcpu->cpu_timer, jiffies + 2); - dbgpr("idle: enter at %d, set timer for %lu exit=%llu\n", - pcpu->target_freq, pcpu->cpu_timer.expires, - pcpu->idle_exit_time); - } -#endif - } else { - /* - * If at min speed and entering idle after load has - * already been evaluated, and a timer has been set just in - * case the CPU suddenly goes busy, cancel that timer. The - * CPU didn't go busy; we'll recheck things upon idle exit. - */ - if (pending && pcpu->timer_idlecancel) { - dbgpr("idle: cancel timer for %lu\n", pcpu->cpu_timer.expires); - del_timer(&pcpu->cpu_timer); - /* - * Ensure last timer run time is after current idle - * sample start time, so next idle exit will always - * start a new idle sampling period. - */ - pcpu->idle_exit_time = 0; - pcpu->timer_idlecancel = 0; - } - } - - pm_idle_old(); - pcpu->idling = 0; - smp_wmb(); - - /* - * Arm the timer for 1-2 ticks later if not already, and if the timer - * function has already processed the previous load sampling - * interval. (If the timer is not pending but has not processed - * the previous interval, it is probably racing with us on another - * CPU. Let it compute load based on the previous sample and then - * re-arm the timer for another interval when it's done, rather - * than updating the interval start time to be "now", which doesn't - * give the timer function enough time to make a decision on this - * run.) - */ - if (timer_pending(&pcpu->cpu_timer) == 0 && - pcpu->timer_run_time >= pcpu->idle_exit_time && - pcpu->governor_enabled) { - pcpu->time_in_idle = - get_cpu_idle_time_us(smp_processor_id(), - &pcpu->idle_exit_time); - pcpu->timer_idlecancel = 0; - mod_timer(&pcpu->cpu_timer, jiffies + 2); - dbgpr("idle: exit, set timer for %lu exit=%llu\n", pcpu->cpu_timer.expires, pcpu->idle_exit_time); -#if DEBUG - } else if (timer_pending(&pcpu->cpu_timer) == 0 && - pcpu->timer_run_time < pcpu->idle_exit_time) { - dbgpr("idle: timer not run yet: exit=%llu tmrrun=%llu\n", - pcpu->idle_exit_time, pcpu->timer_run_time); -#endif - } - -} - -static int cpufreq_interactive_up_task(void *data) -{ - unsigned int cpu; - cpumask_t tmp_mask; - unsigned long flags; - struct cpufreq_interactive_cpuinfo *pcpu; - -#if DEBUG - u64 now; - u64 then; - unsigned int lat; -#endif - - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irqsave(&up_cpumask_lock, flags); - - if (cpumask_empty(&up_cpumask)) { - spin_unlock_irqrestore(&up_cpumask_lock, flags); - schedule(); - - if (kthread_should_stop()) - break; - - spin_lock_irqsave(&up_cpumask_lock, flags); - } - - set_current_state(TASK_RUNNING); - -#if DEBUG - then = up_request_time; - now = ktime_to_us(ktime_get()); - - if (now > then) { - lat = ktime_to_us(ktime_get()) - then; - - if (lat > up_max_latency) - up_max_latency = lat; - } -#endif - - tmp_mask = up_cpumask; - cpumask_clear(&up_cpumask); - spin_unlock_irqrestore(&up_cpumask_lock, flags); - - for_each_cpu(cpu, &tmp_mask) { - pcpu = &per_cpu(cpuinfo, cpu); - - if (nr_running() == 1) { - dbgpr("up %d: tgt=%d nothing else running\n", cpu, - pcpu->target_freq); - } - - smp_rmb(); - - if (!pcpu->governor_enabled) - continue; - - __cpufreq_driver_target(pcpu->policy, - pcpu->target_freq, - CPUFREQ_RELATION_H); - pcpu->freq_change_time_in_idle = - get_cpu_idle_time_us(cpu, - &pcpu->freq_change_time); - dbgpr("up %d: set tgt=%d (actual=%d)\n", cpu, pcpu->target_freq, pcpu->policy->cur); - } - } - - return 0; -} - -static void cpufreq_interactive_freq_down(struct work_struct *work) -{ - unsigned int cpu; - cpumask_t tmp_mask; - unsigned long flags; - struct cpufreq_interactive_cpuinfo *pcpu; - - spin_lock_irqsave(&down_cpumask_lock, flags); - tmp_mask = down_cpumask; - cpumask_clear(&down_cpumask); - spin_unlock_irqrestore(&down_cpumask_lock, flags); - - for_each_cpu(cpu, &tmp_mask) { - pcpu = &per_cpu(cpuinfo, cpu); - - smp_rmb(); - - if (!pcpu->governor_enabled) - continue; - - __cpufreq_driver_target(pcpu->policy, - pcpu->target_freq, - CPUFREQ_RELATION_H); - pcpu->freq_change_time_in_idle = - get_cpu_idle_time_us(cpu, - &pcpu->freq_change_time); - dbgpr("down %d: set tgt=%d (actual=%d)\n", cpu, pcpu->target_freq, pcpu->policy->cur); - } -} - -static ssize_t show_go_maxspeed_load(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", go_maxspeed_load); -} - -static ssize_t store_go_maxspeed_load(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - return strict_strtoul(buf, 0, &go_maxspeed_load); -} - -static struct global_attr go_maxspeed_load_attr = __ATTR(go_maxspeed_load, 0644, - show_go_maxspeed_load, store_go_maxspeed_load); - -static ssize_t show_min_sample_time(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - return sprintf(buf, "%lu\n", min_sample_time); -} - -static ssize_t store_min_sample_time(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t count) -{ - return strict_strtoul(buf, 0, &min_sample_time); -} - -static struct global_attr min_sample_time_attr = __ATTR(min_sample_time, 0644, - show_min_sample_time, store_min_sample_time); - -static struct attribute *interactive_attributes[] = { - &go_maxspeed_load_attr.attr, - &min_sample_time_attr.attr, - NULL, -}; - -static struct attribute_group interactive_attr_group = { - .attrs = interactive_attributes, - .name = "interactive", -}; - -static int cpufreq_governor_interactive(struct cpufreq_policy *new_policy, - unsigned int event) -{ - int rc; - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, new_policy->cpu); - - switch (event) { - case CPUFREQ_GOV_START: - if (!cpu_online(new_policy->cpu)) - return -EINVAL; - - pcpu->policy = new_policy; - pcpu->freq_table = cpufreq_frequency_get_table(new_policy->cpu); - pcpu->target_freq = new_policy->cur; - pcpu->freq_change_time_in_idle = - get_cpu_idle_time_us(new_policy->cpu, - &pcpu->freq_change_time); - pcpu->governor_enabled = 1; - smp_wmb(); - /* - * Do not register the idle hook and create sysfs - * entries if we have already done so. - */ - if (atomic_inc_return(&active_count) > 1) - return 0; - - rc = sysfs_create_group(cpufreq_global_kobject, - &interactive_attr_group); - if (rc) - return rc; - - pm_idle_old = pm_idle; - pm_idle = cpufreq_interactive_idle; - break; - - case CPUFREQ_GOV_STOP: - pcpu->governor_enabled = 0; - smp_wmb(); - del_timer_sync(&pcpu->cpu_timer); - flush_work(&freq_scale_down_work); - /* - * Reset idle exit time since we may cancel the timer - * before it can run after the last idle exit time, - * to avoid tripping the check in idle exit for a timer - * that is trying to run. - */ - pcpu->idle_exit_time = 0; - - if (atomic_dec_return(&active_count) > 0) - return 0; - - sysfs_remove_group(cpufreq_global_kobject, - &interactive_attr_group); - - pm_idle = pm_idle_old; - break; - - case CPUFREQ_GOV_LIMITS: - if (new_policy->max < new_policy->cur) - __cpufreq_driver_target(new_policy, - new_policy->max, CPUFREQ_RELATION_H); - else if (new_policy->min > new_policy->cur) - __cpufreq_driver_target(new_policy, - new_policy->min, CPUFREQ_RELATION_L); - break; - } - return 0; -} - -static int __init cpufreq_interactive_init(void) -{ - unsigned int i; - struct cpufreq_interactive_cpuinfo *pcpu; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - - go_maxspeed_load = DEFAULT_GO_MAXSPEED_LOAD; - min_sample_time = DEFAULT_MIN_SAMPLE_TIME; - - /* Initalize per-cpu timers */ - for_each_possible_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - init_timer(&pcpu->cpu_timer); - pcpu->cpu_timer.function = cpufreq_interactive_timer; - pcpu->cpu_timer.data = i; - } - - up_task = kthread_create(cpufreq_interactive_up_task, NULL, - "kinteractiveup"); - if (IS_ERR(up_task)) - return PTR_ERR(up_task); - - sched_setscheduler_nocheck(up_task, SCHED_FIFO, ¶m); - get_task_struct(up_task); - - /* No rescuer thread, bind to CPU queuing the work for possibly - warm cache (probably doesn't matter much). */ - down_wq = alloc_workqueue("knteractive_down", 0, 1); - - if (! down_wq) - goto err_freeuptask; - - INIT_WORK(&freq_scale_down_work, - cpufreq_interactive_freq_down); - - spin_lock_init(&up_cpumask_lock); - spin_lock_init(&down_cpumask_lock); - -#if DEBUG - spin_lock_init(&dbgpr_lock); - dbg_proc = create_proc_entry("igov", S_IWUSR | S_IRUGO, NULL); - dbg_proc->read_proc = dbg_proc_read; -#endif - - return cpufreq_register_governor(&cpufreq_gov_interactive); - -err_freeuptask: - put_task_struct(up_task); - return -ENOMEM; -} - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -fs_initcall(cpufreq_interactive_init); -#else -module_init(cpufreq_interactive_init); -#endif - -static void __exit cpufreq_interactive_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_interactive); - kthread_stop(up_task); - put_task_struct(up_task); - destroy_workqueue(down_wq); -} - -module_exit(cpufreq_interactive_exit); - -MODULE_AUTHOR("Mike Chan "); -MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for " - "Latency sensitive workloads"); -MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index ca3f24c296a0..00d73fc8e4e2 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -305,27 +305,6 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, return 0; } -static int cpufreq_stats_create_table_cpu(unsigned int cpu) -{ - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *table; - int ret = -ENODEV; - - policy = cpufreq_cpu_get(cpu); - if (!policy) - return -ENODEV; - - table = cpufreq_frequency_get_table(cpu); - if (!table) - goto out; - - ret = cpufreq_stats_create_table(policy, table); - -out: - cpufreq_cpu_put(policy); - return ret; -} - static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -337,14 +316,10 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, case CPU_ONLINE_FROZEN: cpufreq_update_policy(cpu); break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: + case CPU_DEAD: + case CPU_DEAD_FROZEN: cpufreq_stats_free_table(cpu); break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_stats_create_table_cpu(cpu); - break; } return NOTIFY_OK; } @@ -352,7 +327,6 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, static struct notifier_block cpufreq_stat_cpu_notifier __refdata = { .notifier_call = cpufreq_stat_cpu_callback, - .priority = 1, }; static struct notifier_block notifier_policy_block = { diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index f8ee741b16f0..ea0b3863ad0f 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -243,13 +243,4 @@ config CRYPTO_DEV_OMAP_SHAM OMAP processors have SHA1/MD5 hw accelerator. Select this if you want to use the OMAP module for SHA1/MD5 algorithms. -config CRYPTO_DEV_TEGRA_AES - tristate "Support for TEGRA AES hw engine" - depends on ARCH_TEGRA_2x_SOC - select CRYPTO_AES - select TEGRA_ARB_SEMAPHORE - help - TEGRA processors have AES module accelerator. Select this if you - want to use the TEGRA module for AES algorithms. - endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index b00ec7817532..6dbbe00c4524 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -9,5 +9,4 @@ obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o -obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 8a515baa38f7..2e992bc8015b 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -286,7 +286,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, if (initial) asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) - : "d" (control_word), "b" (key), "c" (initial)); + : "d" (control_word), "b" (key), "c" (count)); asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c deleted file mode 100644 index 125658712e8c..000000000000 --- a/drivers/crypto/tegra-aes.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* - * drivers/crypto/tegra-aes.c - * - * aes driver for NVIDIA tegra aes hardware - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "tegra-aes.h" - -#define FLAGS_MODE_MASK 0x000f -#define FLAGS_ENCRYPT BIT(0) -#define FLAGS_CBC BIT(1) -#define FLAGS_GIV BIT(2) -#define FLAGS_RNG BIT(3) -#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 - -/* - * Defines AES engine Max process bytes size in one go, which takes 1 msec. - * AES engine spends about 176 cycles/16-bytes or 11 cycles/byte - * The duration CPU can use the BSE to 1 msec, then the number of available - * cycles of AVP/BSE is 216K. In this duration, AES can process 216/11 ~= 19KB - * Based on this AES_HW_DMA_BUFFER_SIZE_BYTES is configured to 16KB. - */ -#define AES_HW_DMA_BUFFER_SIZE_BYTES 0x4000 - -/* - * The key table length is 64 bytes - * (This includes first upto 32 bytes key + 16 bytes original initial vector - * and 16 bytes updated initial vector) - */ -#define AES_HW_KEY_TABLE_LENGTH_BYTES 64 - -#define AES_HW_IV_SIZE 16 -#define AES_HW_KEYSCHEDULE_LEN 256 -#define ARB_SEMA_TIMEOUT 500 - -/* - * The memory being used is divides as follows: - * 1. Key - 32 bytes - * 2. Original IV - 16 bytes - * 3. Updated IV - 16 bytes - * 4. Key schedule - 256 bytes - * - * 1+2+3 constitute the hw key table. - */ -#define AES_IVKEY_SIZE (AES_HW_KEY_TABLE_LENGTH_BYTES + AES_HW_KEYSCHEDULE_LEN) - -#define DEFAULT_RNG_BLK_SZ 16 - -/* As of now only 5 commands are USED for AES encryption/Decryption */ -#define AES_HW_MAX_ICQ_LENGTH 5 - -#define ICQBITSHIFT_BLKCNT 0 - -/* memdma_vd command */ -#define MEMDMA_DIR_DTOVRAM 0 -#define MEMDMA_DIR_VTODRAM 1 -#define MEMDMABITSHIFT_DIR 25 -#define MEMDMABITSHIFT_NUM_WORDS 12 - -/* Define AES Interactive command Queue commands Bit positions */ -enum { - ICQBITSHIFT_KEYTABLEADDR = 0, - ICQBITSHIFT_KEYTABLEID = 17, - ICQBITSHIFT_VRAMSEL = 23, - ICQBITSHIFT_TABLESEL = 24, - ICQBITSHIFT_OPCODE = 26, -}; - -/* Define Ucq opcodes required for AES operation */ -enum { - UCQOPCODE_BLKSTARTENGINE = 0x0E, - UCQOPCODE_DMASETUP = 0x10, - UCQOPCODE_DMACOMPLETE = 0x11, - UCQOPCODE_SETTABLE = 0x15, - UCQOPCODE_MEMDMAVD = 0x22, -}; - -/* Define Aes command values */ -enum { - UCQCMD_VRAM_SEL = 0x1, - UCQCMD_CRYPTO_TABLESEL = 0x3, - UCQCMD_KEYSCHEDTABLESEL = 0x4, - UCQCMD_KEYTABLESEL = 0x8, -}; - -#define UCQCMD_KEYTABLEADDRMASK 0x1FFFF - -#define AES_NR_KEYSLOTS 8 -#define SSK_SLOT_NUM 4 - -struct tegra_aes_slot { - struct list_head node; - int slot_num; - bool available; -}; - -static struct tegra_aes_slot ssk = { - .slot_num = SSK_SLOT_NUM, - .available = true, -}; - -struct tegra_aes_reqctx { - unsigned long mode; -}; - -#define TEGRA_AES_QUEUE_LENGTH 50 - -struct tegra_aes_dev { - struct device *dev; - unsigned long phys_base; - void __iomem *io_base; - dma_addr_t ivkey_phys_base; - void __iomem *ivkey_base; - struct clk *iclk; - struct clk *pclk; - struct tegra_aes_ctx *ctx; - unsigned long flags; - struct completion op_complete; - u32 *buf_in; - dma_addr_t dma_buf_in; - u32 *buf_out; - dma_addr_t dma_buf_out; - u8 *iv; - u8 dt[DEFAULT_RNG_BLK_SZ]; - int ivlen; - u64 ctr; - int res_id; - spinlock_t lock; - struct crypto_queue queue; - struct tegra_aes_slot *slots; - struct ablkcipher_request *req; - size_t total; - struct scatterlist *in_sg; - size_t in_offset; - struct scatterlist *out_sg; - size_t out_offset; -}; - -static struct tegra_aes_dev *aes_dev; - -struct tegra_aes_ctx { - struct tegra_aes_dev *dd; - unsigned long flags; - struct tegra_aes_slot *slot; - int keylen; -}; - -static struct tegra_aes_ctx rng_ctx = { - .flags = FLAGS_NEW_KEY, - .keylen = AES_KEYSIZE_128, -}; - -/* keep registered devices data here */ -static LIST_HEAD(dev_list); -static DEFINE_SPINLOCK(list_lock); -static DEFINE_MUTEX(aes_lock); - -static void aes_workqueue_handler(struct work_struct *work); -static DECLARE_WORK(aes_work, aes_workqueue_handler); -static struct workqueue_struct *aes_wq; - -extern unsigned long long tegra_chip_uid(void); - -static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset) -{ - return readl(dd->io_base + offset); -} - -static inline void aes_writel(struct tegra_aes_dev *dd, u32 val, u32 offset) -{ - writel(val, dd->io_base + offset); -} - -static int aes_hw_init(struct tegra_aes_dev *dd) -{ - int ret = 0; - - ret = clk_enable(dd->pclk); - if (ret < 0) { - dev_err(dd->dev, "%s: pclock enable fail(%d)\n", __func__, ret); - return ret; - } - - ret = clk_enable(dd->iclk); - if (ret < 0) { - dev_err(dd->dev, "%s: iclock enable fail(%d)\n", __func__, ret); - clk_disable(dd->pclk); - return ret; - } - - ret = clk_set_rate(dd->iclk, 240000000); - if (ret) { - dev_err(dd->dev, "%s: iclk set_rate fail(%d)\n", __func__, ret); - clk_disable(dd->iclk); - clk_disable(dd->pclk); - return ret; - } - - aes_writel(dd, 0x33, INT_ENB); - return ret; -} - -static void aes_hw_deinit(struct tegra_aes_dev *dd) -{ - clk_disable(dd->iclk); - clk_disable(dd->pclk); -} - -static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr, - int nblocks, int mode, bool upd_iv) -{ - u32 cmdq[AES_HW_MAX_ICQ_LENGTH]; - int qlen = 0, i, eng_busy, icq_empty, dma_busy, ret = 0; - u32 value; - - cmdq[qlen++] = UCQOPCODE_DMASETUP << ICQBITSHIFT_OPCODE; - cmdq[qlen++] = in_addr; - cmdq[qlen++] = UCQOPCODE_BLKSTARTENGINE << ICQBITSHIFT_OPCODE | - (nblocks-1) << ICQBITSHIFT_BLKCNT; - cmdq[qlen++] = UCQOPCODE_DMACOMPLETE << ICQBITSHIFT_OPCODE; - - value = aes_readl(dd, CMDQUE_CONTROL); - /* access SDRAM through AHB */ - value &= ~CMDQ_CTRL_SRC_STM_SEL_FIELD; - value &= ~CMDQ_CTRL_DST_STM_SEL_FIELD; - value |= (CMDQ_CTRL_SRC_STM_SEL_FIELD | CMDQ_CTRL_DST_STM_SEL_FIELD | - CMDQ_CTRL_ICMDQEN_FIELD); - aes_writel(dd, value, CMDQUE_CONTROL); - dev_dbg(dd->dev, "cmd_q_ctrl=0x%x", value); - - value = 0; - value |= CONFIG_ENDIAN_ENB_FIELD; - aes_writel(dd, value, CONFIG); - dev_dbg(dd->dev, "config=0x%x", value); - - value = aes_readl(dd, SECURE_CONFIG_EXT); - value &= ~SECURE_OFFSET_CNT_FIELD; - aes_writel(dd, value, SECURE_CONFIG_EXT); - dev_dbg(dd->dev, "secure_cfg_xt=0x%x", value); - - if (mode & FLAGS_CBC) { - value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) | - ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) | - ((u32)upd_iv << SECURE_IV_SELECT_SHIFT) | - (((mode & FLAGS_ENCRYPT) ? 2 : 3) - << SECURE_XOR_POS_SHIFT) | - (0 << SECURE_INPUT_SEL_SHIFT) | - (((mode & FLAGS_ENCRYPT) ? 2 : 3) - << SECURE_VCTRAM_SEL_SHIFT) | - ((mode & FLAGS_ENCRYPT) ? 1 : 0) - << SECURE_CORE_SEL_SHIFT | - (0 << SECURE_RNG_ENB_SHIFT) | - (0 << SECURE_HASH_ENB_SHIFT)); - } else if (mode & FLAGS_RNG){ - value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) | - ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) | - ((u32)upd_iv << SECURE_IV_SELECT_SHIFT) | - (0 << SECURE_XOR_POS_SHIFT) | - (0 << SECURE_INPUT_SEL_SHIFT) | - ((mode & FLAGS_ENCRYPT) ? 1 : 0) - << SECURE_CORE_SEL_SHIFT | - (1 << SECURE_RNG_ENB_SHIFT) | - (0 << SECURE_HASH_ENB_SHIFT)); - } else { - value = ((0x1 << SECURE_INPUT_ALG_SEL_SHIFT) | - ((dd->ctx->keylen * 8) << SECURE_INPUT_KEY_LEN_SHIFT) | - ((u32)upd_iv << SECURE_IV_SELECT_SHIFT) | - (0 << SECURE_XOR_POS_SHIFT) | - (0 << SECURE_INPUT_SEL_SHIFT) | - (((mode & FLAGS_ENCRYPT) ? 1 : 0) - << SECURE_CORE_SEL_SHIFT) | - (0 << SECURE_RNG_ENB_SHIFT) | - (0 << SECURE_HASH_ENB_SHIFT)); - } - dev_dbg(dd->dev, "secure_in_sel=0x%x", value); - aes_writel(dd, value, SECURE_INPUT_SELECT); - - aes_writel(dd, out_addr, SECURE_DEST_ADDR); - INIT_COMPLETION(dd->op_complete); - - for (i = 0; i < qlen - 1; i++) { - do { - value = aes_readl(dd, INTR_STATUS); - eng_busy = value & (0x1); - icq_empty = value & (0x1<<3); - dma_busy = value & (0x1<<23); - } while (eng_busy & (!icq_empty) & dma_busy); - aes_writel(dd, cmdq[i], ICMDQUE_WR); - } - - ret = wait_for_completion_timeout(&dd->op_complete, msecs_to_jiffies(150)); - if (ret == 0) { - dev_err(dd->dev, "timed out (0x%x)\n", - aes_readl(dd, INTR_STATUS)); - return -ETIMEDOUT; - } - - aes_writel(dd, cmdq[qlen - 1], ICMDQUE_WR); - return 0; -} - -static void aes_release_key_slot(struct tegra_aes_dev *dd) -{ - spin_lock(&list_lock); - dd->ctx->slot->available = true; - dd->ctx->slot = NULL; - spin_unlock(&list_lock); -} - -static struct tegra_aes_slot *aes_find_key_slot(struct tegra_aes_dev *dd) -{ - struct tegra_aes_slot *slot = NULL; - bool found = false; - - spin_lock(&list_lock); - list_for_each_entry(slot, &dev_list, node) { - dev_dbg(dd->dev, "empty:%d, num:%d\n", slot->available, - slot->slot_num); - if (slot->available) { - slot->available = false; - found = true; - break; - } - } - spin_unlock(&list_lock); - return found ? slot : NULL; -} - -static int aes_set_key(struct tegra_aes_dev *dd) -{ - u32 value, cmdq[2]; - struct tegra_aes_ctx *ctx = dd->ctx; - int i, eng_busy, icq_empty, dma_busy; - bool use_ssk = false; - - if (!ctx) { - dev_err(dd->dev, "%s: context invalid\n", __func__); - return -EINVAL; - } - - /* use ssk? */ - if (!dd->ctx->slot) { - dev_dbg(dd->dev, "using ssk"); - dd->ctx->slot = &ssk; - use_ssk = true; - } - - /* disable key read from hw */ - value = aes_readl(dd, SECURE_SEC_SEL0+(ctx->slot->slot_num*4)); - value &= ~SECURE_SEL0_KEYREAD_ENB0_FIELD; - aes_writel(dd, value, SECURE_SEC_SEL0+(ctx->slot->slot_num*4)); - - /* enable key schedule generation in hardware */ - value = aes_readl(dd, SECURE_CONFIG_EXT); - value &= ~SECURE_KEY_SCH_DIS_FIELD; - aes_writel(dd, value, SECURE_CONFIG_EXT); - - /* select the key slot */ - value = aes_readl(dd, SECURE_CONFIG); - value &= ~SECURE_KEY_INDEX_FIELD; - value |= (ctx->slot->slot_num << SECURE_KEY_INDEX_SHIFT); - aes_writel(dd, value, SECURE_CONFIG); - - if (use_ssk) - goto out; - - /* copy the key table from sdram to vram */ - cmdq[0] = 0; - cmdq[0] = UCQOPCODE_MEMDMAVD << ICQBITSHIFT_OPCODE | - (MEMDMA_DIR_DTOVRAM << MEMDMABITSHIFT_DIR) | - (AES_HW_KEY_TABLE_LENGTH_BYTES/sizeof(u32)) - << MEMDMABITSHIFT_NUM_WORDS; - cmdq[1] = (u32)dd->ivkey_phys_base; - - for (i = 0; i < ARRAY_SIZE(cmdq); i++) - aes_writel(dd, cmdq[i], ICMDQUE_WR); - - do { - value = aes_readl(dd, INTR_STATUS); - eng_busy = value & (0x1); - icq_empty = value & (0x1<<3); - dma_busy = value & (0x1<<23); - } while (eng_busy & (!icq_empty) & dma_busy); - - /* settable command to get key into internal registers */ - value = 0; - value = UCQOPCODE_SETTABLE << ICQBITSHIFT_OPCODE | - UCQCMD_CRYPTO_TABLESEL << ICQBITSHIFT_TABLESEL | - UCQCMD_VRAM_SEL << ICQBITSHIFT_VRAMSEL | - (UCQCMD_KEYTABLESEL | ctx->slot->slot_num) - << ICQBITSHIFT_KEYTABLEID; - aes_writel(dd, value, ICMDQUE_WR); - do { - value = aes_readl(dd, INTR_STATUS); - eng_busy = value & (0x1); - icq_empty = value & (0x1<<3); - } while (eng_busy & (!icq_empty)); - -out: - return 0; -} - -static int tegra_aes_handle_req(struct tegra_aes_dev *dd) -{ - struct crypto_async_request *async_req, *backlog; - struct tegra_aes_ctx *ctx; - struct tegra_aes_reqctx *rctx; - struct ablkcipher_request *req; - unsigned long flags; - int dma_max = AES_HW_DMA_BUFFER_SIZE_BYTES; - int ret = 0, nblocks, total; - int count = 0; - dma_addr_t addr_in, addr_out; - struct scatterlist *in_sg, *out_sg; - - if (!dd) - return -EINVAL; - - spin_lock_irqsave(&dd->lock, flags); - backlog = crypto_get_backlog(&dd->queue); - async_req = crypto_dequeue_request(&dd->queue); - if (!async_req) - clear_bit(FLAGS_BUSY, &dd->flags); - spin_unlock_irqrestore(&dd->lock, flags); - - if (!async_req) - return -ENODATA; - - if (backlog) - backlog->complete(backlog, -EINPROGRESS); - - req = ablkcipher_request_cast(async_req); - - dev_dbg(dd->dev, "%s: get new req\n", __func__); - - /* take mutex to access the aes hw */ - mutex_lock(&aes_lock); - - /* assign new request to device */ - dd->req = req; - dd->total = req->nbytes; - dd->in_offset = 0; - dd->in_sg = req->src; - dd->out_offset = 0; - dd->out_sg = req->dst; - - in_sg = dd->in_sg; - out_sg = dd->out_sg; - - if (!in_sg || !out_sg) { - mutex_unlock(&aes_lock); - return -EINVAL; - } - - total = dd->total; - rctx = ablkcipher_request_ctx(req); - ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); - rctx->mode &= FLAGS_MODE_MASK; - dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; - - dd->iv = (u8 *)req->info; - dd->ivlen = AES_BLOCK_SIZE; - - if ((dd->flags & FLAGS_CBC) && dd->iv) - dd->flags |= FLAGS_NEW_IV; - else - dd->flags &= ~FLAGS_NEW_IV; - - ctx->dd = dd; - if (dd->ctx != ctx) { - /* assign new context to device */ - dd->ctx = ctx; - ctx->flags |= FLAGS_NEW_KEY; - } - - /* take the hardware semaphore */ - if (tegra_arb_mutex_lock_timeout(dd->res_id, ARB_SEMA_TIMEOUT) < 0) { - dev_err(dd->dev, "aes hardware not available\n"); - mutex_unlock(&aes_lock); - return -EBUSY; - } - - ret = aes_hw_init(dd); - if (ret < 0) { - dev_err(dd->dev, "%s: hw init fail(%d)\n", __func__, ret); - goto fail; - } - - aes_set_key(dd); - - /* set iv to the aes hw slot */ - memset(dd->buf_in, 0 , AES_BLOCK_SIZE); - memcpy(dd->buf_in, dd->iv, dd->ivlen); - - ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, - (u32)dd->dma_buf_out, 1, FLAGS_CBC, false); - if (ret < 0) { - dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); - goto out; - } - - while (total) { - dev_dbg(dd->dev, "remain: 0x%x\n", total); - - ret = dma_map_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); - if (!ret) { - dev_err(dd->dev, "dma_map_sg() error\n"); - goto out; - } - - ret = dma_map_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); - if (!ret) { - dev_err(dd->dev, "dma_map_sg() error\n"); - dma_unmap_sg(dd->dev, dd->in_sg, - 1, DMA_TO_DEVICE); - goto out; - } - - addr_in = sg_dma_address(in_sg); - addr_out = sg_dma_address(out_sg); - dd->flags |= FLAGS_FAST; - count = min((int)sg_dma_len(in_sg), (int)dma_max); - WARN_ON(sg_dma_len(in_sg) != sg_dma_len(out_sg)); - nblocks = DIV_ROUND_UP(count, AES_BLOCK_SIZE); - - ret = aes_start_crypt(dd, addr_in, addr_out, nblocks, - dd->flags, true); - - dma_unmap_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); - dma_unmap_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); - - if (ret < 0) { - dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); - goto out; - } - dd->flags &= ~FLAGS_FAST; - - dev_dbg(dd->dev, "out: copied 0x%x\n", count); - total -= count; - in_sg = sg_next(in_sg); - out_sg = sg_next(out_sg); - WARN_ON(((total != 0) && (!in_sg || !out_sg))); - } - -out: - aes_hw_deinit(dd); - -fail: - /* release the hardware semaphore */ - tegra_arb_mutex_unlock(dd->res_id); - - dd->total = total; - - /* release the mutex */ - mutex_unlock(&aes_lock); - - if (dd->req->base.complete) - dd->req->base.complete(&dd->req->base, ret); - - dev_dbg(dd->dev, "%s: exit\n", __func__); - return ret; -} - -static int tegra_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int keylen) -{ - struct tegra_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct tegra_aes_dev *dd = aes_dev; - struct tegra_aes_slot *key_slot; - - if (!ctx || !dd) { - dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n", - (unsigned int)ctx, (unsigned int)dd); - return -EINVAL; - } - - if ((keylen != AES_KEYSIZE_128) && (keylen != AES_KEYSIZE_192) && - (keylen != AES_KEYSIZE_256)) { - dev_err(dd->dev, "unsupported key size\n"); - return -EINVAL; - } - - dev_dbg(dd->dev, "keylen: %d\n", keylen); - - ctx->dd = dd; - dd->ctx = ctx; - - if (ctx->slot) - aes_release_key_slot(dd); - - key_slot = aes_find_key_slot(dd); - if (!key_slot) { - dev_err(dd->dev, "no empty slot\n"); - return -ENOMEM; - } - - ctx->slot = key_slot; - ctx->keylen = keylen; - ctx->flags |= FLAGS_NEW_KEY; - - /* copy the key */ - memset(dd->ivkey_base, 0, AES_HW_KEY_TABLE_LENGTH_BYTES); - memcpy(dd->ivkey_base, key, keylen); - - dev_dbg(dd->dev, "done\n"); - return 0; -} - -static void aes_workqueue_handler(struct work_struct *work) -{ - struct tegra_aes_dev *dd = aes_dev; - int ret; - - set_bit(FLAGS_BUSY, &dd->flags); - - do { - ret = tegra_aes_handle_req(dd); - } while (!ret); -} - -static irqreturn_t aes_irq(int irq, void *dev_id) -{ - struct tegra_aes_dev *dd = (struct tegra_aes_dev *)dev_id; - u32 value = aes_readl(dd, INTR_STATUS); - - dev_dbg(dd->dev, "irq_stat: 0x%x", value); - if (!((value & ENGINE_BUSY_FIELD) & !(value & ICQ_EMPTY_FIELD))) - complete(&dd->op_complete); - - return IRQ_HANDLED; -} - -static int tegra_aes_crypt(struct ablkcipher_request *req, unsigned long mode) -{ - struct tegra_aes_reqctx *rctx = ablkcipher_request_ctx(req); - struct tegra_aes_dev *dd = aes_dev; - unsigned long flags; - int err = 0; - int busy; - - dev_dbg(dd->dev, "nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, - !!(mode & FLAGS_ENCRYPT), - !!(mode & FLAGS_CBC)); - - rctx->mode = mode; - - spin_lock_irqsave(&dd->lock, flags); - err = ablkcipher_enqueue_request(&dd->queue, req); - busy = test_and_set_bit(FLAGS_BUSY, &dd->flags); - spin_unlock_irqrestore(&dd->lock, flags); - - if (!busy) - queue_work(aes_wq, &aes_work); - - return err; -} - -static int tegra_aes_ecb_encrypt(struct ablkcipher_request *req) -{ - return tegra_aes_crypt(req, FLAGS_ENCRYPT); -} - -static int tegra_aes_ecb_decrypt(struct ablkcipher_request *req) -{ - return tegra_aes_crypt(req, 0); -} - -static int tegra_aes_cbc_encrypt(struct ablkcipher_request *req) -{ - return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); -} - -static int tegra_aes_cbc_decrypt(struct ablkcipher_request *req) -{ - return tegra_aes_crypt(req, FLAGS_CBC); -} - -static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata, - unsigned int dlen) -{ - struct tegra_aes_dev *dd = aes_dev; - struct tegra_aes_ctx *ctx = &rng_ctx; - int ret, i; - u8 *dest = rdata, *dt = dd->dt; - - /* take mutex to access the aes hw */ - mutex_lock(&aes_lock); - - /* take the hardware semaphore */ - if (tegra_arb_mutex_lock_timeout(dd->res_id, ARB_SEMA_TIMEOUT) < 0) { - dev_err(dd->dev, "aes hardware not available\n"); - mutex_unlock(&aes_lock); - return -EBUSY; - } - - ret = aes_hw_init(dd); - if (ret < 0) { - dev_err(dd->dev, "%s: hw init fail(%d)\n", __func__, ret); - dlen = ret; - goto fail; - } - - ctx->dd = dd; - dd->ctx = ctx; - dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; - - memset(dd->buf_in, 0, AES_BLOCK_SIZE); - memcpy(dd->buf_in, dt, DEFAULT_RNG_BLK_SZ); - - ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, - (u32)dd->dma_buf_out, 1, dd->flags, true); - if (ret < 0) { - dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); - dlen = ret; - goto out; - } - memcpy(dest, dd->buf_out, dlen); - - /* update the DT */ - for (i = DEFAULT_RNG_BLK_SZ - 1; i >= 0; i--) { - dt[i] += 1; - if (dt[i] != 0) - break; - } - -out: - aes_hw_deinit(dd); - -fail: - /* release the hardware semaphore */ - tegra_arb_mutex_unlock(dd->res_id); - mutex_unlock(&aes_lock); - dev_dbg(dd->dev, "%s: done\n", __func__); - return dlen; -} - -static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed, - unsigned int slen) -{ - struct tegra_aes_dev *dd = aes_dev; - struct tegra_aes_ctx *ctx = &rng_ctx; - struct tegra_aes_slot *key_slot; - struct timespec ts; - int ret = 0; - u64 nsec, tmp[2]; - u8 *dt; - - if (!ctx || !dd) { - dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n", - (unsigned int)ctx, (unsigned int)dd); - return -EINVAL; - } - - if (slen < (DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { - dev_err(dd->dev, "seed size invalid"); - return -ENOMEM; - } - - /* take mutex to access the aes hw */ - mutex_lock(&aes_lock); - - if (!ctx->slot) { - key_slot = aes_find_key_slot(dd); - if (!key_slot) { - dev_err(dd->dev, "no empty slot\n"); - mutex_unlock(&aes_lock); - return -ENOMEM; - } - ctx->slot = key_slot; - } - - ctx->dd = dd; - dd->ctx = ctx; - dd->ctr = 0; - - ctx->keylen = AES_KEYSIZE_128; - ctx->flags |= FLAGS_NEW_KEY; - - /* copy the key to the key slot */ - memset(dd->ivkey_base, 0, AES_HW_KEY_TABLE_LENGTH_BYTES); - memcpy(dd->ivkey_base, seed + DEFAULT_RNG_BLK_SZ, AES_KEYSIZE_128); - - dd->iv = seed; - dd->ivlen = slen; - - dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; - - /* take the hardware semaphore */ - if (tegra_arb_mutex_lock_timeout(dd->res_id, ARB_SEMA_TIMEOUT) < 0) { - dev_err(dd->dev, "aes hardware not available\n"); - mutex_unlock(&aes_lock); - return -EBUSY; - } - - ret = aes_hw_init(dd); - if (ret < 0) { - dev_err(dd->dev, "%s: hw init fail(%d)\n", __func__, ret); - goto fail; - } - - aes_set_key(dd); - - /* set seed to the aes hw slot */ - memset(dd->buf_in, 0, AES_BLOCK_SIZE); - memcpy(dd->buf_in, dd->iv, DEFAULT_RNG_BLK_SZ); - ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, - (u32)dd->dma_buf_out, 1, FLAGS_CBC, false); - if (ret < 0) { - dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); - goto out; - } - - if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { - dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128; - } else { - getnstimeofday(&ts); - nsec = timespec_to_ns(&ts); - do_div(nsec, 1000); - nsec ^= dd->ctr << 56; - dd->ctr++; - tmp[0] = nsec; - tmp[1] = tegra_chip_uid(); - dt = (u8 *)tmp; - } - memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ); - -out: - aes_hw_deinit(dd); - -fail: - /* release the hardware semaphore */ - tegra_arb_mutex_unlock(dd->res_id); - mutex_unlock(&aes_lock); - - dev_dbg(dd->dev, "%s: done\n", __func__); - return ret; -} - -static int tegra_aes_cra_init(struct crypto_tfm *tfm) -{ - tfm->crt_ablkcipher.reqsize = sizeof(struct tegra_aes_reqctx); - - return 0; -} - -static struct crypto_alg algs[] = { - { - .cra_name = "disabled_ecb(aes)", - .cra_driver_name = "ecb-aes-tegra", - .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct tegra_aes_ctx), - .cra_alignmask = 3, - .cra_type = &crypto_ablkcipher_type, - .cra_module = THIS_MODULE, - .cra_init = tegra_aes_cra_init, - .cra_u.ablkcipher = { - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .setkey = tegra_aes_setkey, - .encrypt = tegra_aes_ecb_encrypt, - .decrypt = tegra_aes_ecb_decrypt, - }, - }, { - .cra_name = "disabled_cbc(aes)", - .cra_driver_name = "cbc-aes-tegra", - .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct tegra_aes_ctx), - .cra_alignmask = 3, - .cra_type = &crypto_ablkcipher_type, - .cra_module = THIS_MODULE, - .cra_init = tegra_aes_cra_init, - .cra_u.ablkcipher = { - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_MIN_KEY_SIZE, - .setkey = tegra_aes_setkey, - .encrypt = tegra_aes_cbc_encrypt, - .decrypt = tegra_aes_cbc_decrypt, - } - }, { - .cra_name = "disabled_ansi_cprng", - .cra_driver_name = "rng-aes-tegra", - .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_RNG, - .cra_ctxsize = sizeof(struct tegra_aes_ctx), - .cra_type = &crypto_rng_type, - .cra_module = THIS_MODULE, - .cra_init = tegra_aes_cra_init, - .cra_u.rng = { - .rng_make_random = tegra_aes_get_random, - .rng_reset = tegra_aes_rng_reset, - .seedsize = AES_KEYSIZE_128 + (2 * DEFAULT_RNG_BLK_SZ), - } - } -}; - -static int tegra_aes_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct tegra_aes_dev *dd; - struct resource *res; - int err = -ENOMEM, i = 0, j; - - if (aes_dev) - return -EEXIST; - - dd = kzalloc(sizeof(struct tegra_aes_dev), GFP_KERNEL); - if (dd == NULL) { - dev_err(dev, "unable to alloc data struct.\n"); - return -ENOMEM;; - } - dd->dev = dev; - platform_set_drvdata(pdev, dd); - - dd->slots = kzalloc(sizeof(struct tegra_aes_slot) * AES_NR_KEYSLOTS, - GFP_KERNEL); - if (dd->slots == NULL) { - dev_err(dev, "unable to alloc slot struct.\n"); - goto out; - } - - spin_lock_init(&dd->lock); - crypto_init_queue(&dd->queue, TEGRA_AES_QUEUE_LENGTH); - - /* Get the module base address */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "invalid resource type: base\n"); - err = -ENODEV; - goto out; - } - dd->phys_base = res->start; - - dd->io_base = ioremap(dd->phys_base, resource_size(res)); - if (!dd->io_base) { - dev_err(dev, "can't ioremap phys_base\n"); - err = -ENOMEM; - goto out; - } - - dd->res_id = TEGRA_ARB_AES; - - /* Initialise the master bsev clock */ - dd->pclk = clk_get(dev, "bsev"); - if (!dd->pclk) { - dev_err(dev, "pclock intialization failed.\n"); - err = -ENODEV; - goto out; - } - - /* Initialize the vde clock */ - dd->iclk = clk_get(dev, "vde"); - if (!dd->iclk) { - dev_err(dev, "iclock intialization failed.\n"); - err = -ENODEV; - goto out; - } - - /* - * the foll contiguous memory is allocated as follows - - * - hardware key table - * - key schedule - */ - dd->ivkey_base = dma_alloc_coherent(dev, SZ_512, &dd->ivkey_phys_base, - GFP_KERNEL); - if (!dd->ivkey_base) { - dev_err(dev, "can not allocate iv/key buffer\n"); - err = -ENOMEM; - goto out; - } - - dd->buf_in = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - &dd->dma_buf_in, GFP_KERNEL); - if (!dd->buf_in) { - dev_err(dev, "can not allocate dma-in buffer\n"); - err = -ENOMEM; - goto out; - } - - dd->buf_out = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - &dd->dma_buf_out, GFP_KERNEL); - if (!dd->buf_out) { - dev_err(dev, "can not allocate dma-out buffer\n"); - err = -ENOMEM; - goto out; - } - - init_completion(&dd->op_complete); - aes_wq = alloc_workqueue("aes_wq", WQ_HIGHPRI, 16); - if (!aes_wq) { - dev_err(dev, "alloc_workqueue failed\n"); - goto out; - } - - /* get the irq */ - err = request_irq(INT_VDE_BSE_V, aes_irq, IRQF_TRIGGER_HIGH, - "tegra-aes", dd); - if (err) { - dev_err(dev, "request_irq failed\n"); - goto out; - } - - spin_lock_init(&list_lock); - spin_lock(&list_lock); - for (i = 0; i < AES_NR_KEYSLOTS; i++) { - dd->slots[i].available = true; - dd->slots[i].slot_num = i; - INIT_LIST_HEAD(&dd->slots[i].node); - list_add_tail(&dd->slots[i].node, &dev_list); - } - spin_unlock(&list_lock); - - aes_dev = dd; - for (i = 0; i < ARRAY_SIZE(algs); i++) { - INIT_LIST_HEAD(&algs[i].cra_list); - err = crypto_register_alg(&algs[i]); - if (err) - goto out; - } - - dev_info(dev, "registered"); - return 0; - -out: - for (j = 0; j < i; j++) - crypto_unregister_alg(&algs[j]); - if (dd->ivkey_base) - dma_free_coherent(dev, SZ_512, dd->ivkey_base, - dd->ivkey_phys_base); - if (dd->buf_in) - dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - dd->buf_in, dd->dma_buf_in); - if (dd->buf_out) - dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - dd->buf_out, dd->dma_buf_out); - if (dd->io_base) - iounmap(dd->io_base); - if (dd->iclk) - clk_put(dd->iclk); - if (dd->pclk) - clk_put(dd->pclk); - if (aes_wq) - destroy_workqueue(aes_wq); - free_irq(INT_VDE_BSE_V, dd); - spin_lock(&list_lock); - list_del(&dev_list); - spin_unlock(&list_lock); - - kfree(dd->slots); - kfree(dd); - aes_dev = NULL; - dev_err(dev, "%s: initialization failed.\n", __func__); - return err; -} - -static int __devexit tegra_aes_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct tegra_aes_dev *dd = platform_get_drvdata(pdev); - int i; - - if (!dd) - return -ENODEV; - - cancel_work_sync(&aes_work); - destroy_workqueue(aes_wq); - free_irq(INT_VDE_BSE_V, dd); - spin_lock(&list_lock); - list_del(&dev_list); - spin_unlock(&list_lock); - - for (i = 0; i < ARRAY_SIZE(algs); i++) - crypto_unregister_alg(&algs[i]); - - dma_free_coherent(dev, SZ_512, dd->ivkey_base, - dd->ivkey_phys_base); - dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - dd->buf_in, dd->dma_buf_in); - dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, - dd->buf_out, dd->dma_buf_out); - iounmap(dd->io_base); - clk_put(dd->iclk); - clk_put(dd->pclk); - kfree(dd->slots); - kfree(dd); - aes_dev = NULL; - - return 0; -} - -static struct platform_driver tegra_aes_driver = { - .probe = tegra_aes_probe, - .remove = __devexit_p(tegra_aes_remove), - .driver = { - .name = "tegra-aes", - .owner = THIS_MODULE, - }, -}; - -static int __init tegra_aes_mod_init(void) -{ - mutex_init(&aes_lock); - INIT_LIST_HEAD(&dev_list); - return platform_driver_register(&tegra_aes_driver); -} - -static void __exit tegra_aes_mod_exit(void) -{ - platform_driver_unregister(&tegra_aes_driver); -} - -module_init(tegra_aes_mod_init); -module_exit(tegra_aes_mod_exit); - -MODULE_DESCRIPTION("Tegra AES hw acceleration support."); -MODULE_AUTHOR("NVIDIA Corporation"); -MODULE_LICENSE("GPLv2"); diff --git a/drivers/crypto/tegra-aes.h b/drivers/crypto/tegra-aes.h deleted file mode 100644 index 83dd6bbc90e0..000000000000 --- a/drivers/crypto/tegra-aes.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __CRYPTODEV_TEGRA_AES_H -#define __CRYPTODEV_TEGRA_AES_H - -#define ICMDQUE_WR 0x1000 -#define CMDQUE_CONTROL 0x1008 -#define INTR_STATUS 0x1018 -#define INT_ENB 0x1040 -#define CONFIG 0x1044 -#define IRAM_ACCESS_CFG 0x10A0 -#define SECURE_DEST_ADDR 0x1100 -#define SECURE_INPUT_SELECT 0x1104 -#define SECURE_CONFIG 0x1108 -#define SECURE_CONFIG_EXT 0x110C -#define SECURE_SECURITY 0x1110 -#define SECURE_HASH_RESULT0 0x1120 -#define SECURE_HASH_RESULT1 0x1124 -#define SECURE_HASH_RESULT2 0x1128 -#define SECURE_HASH_RESULT3 0x112C -#define SECURE_SEC_SEL0 0x1140 -#define SECURE_SEC_SEL1 0x1144 -#define SECURE_SEC_SEL2 0x1148 -#define SECURE_SEC_SEL3 0x114C -#define SECURE_SEC_SEL4 0x1150 -#define SECURE_SEC_SEL5 0x1154 -#define SECURE_SEC_SEL6 0x1158 -#define SECURE_SEC_SEL7 0x115C - -/* interrupt status reg masks and shifts */ -#define DMA_BUSY_SHIFT 9 -#define DMA_BUSY_FIELD (0x1 << DMA_BUSY_SHIFT) -#define ICQ_EMPTY_SHIFT 3 -#define ICQ_EMPTY_FIELD (0x1 << ICQ_EMPTY_SHIFT) -#define ENGINE_BUSY_SHIFT 0 -#define ENGINE_BUSY_FIELD (0x1 << ENGINE_BUSY_SHIFT) - -/* secure select reg masks and shifts */ -#define SECURE_SEL0_KEYREAD_ENB0_SHIFT 0 -#define SECURE_SEL0_KEYREAD_ENB0_FIELD (0x1 << SECURE_SEL0_KEYREAD_ENB0_SHIFT) - -/* secure config ext masks and shifts */ -#define SECURE_KEY_SCH_DIS_SHIFT 15 -#define SECURE_KEY_SCH_DIS_FIELD (0x1 << SECURE_KEY_SCH_DIS_SHIFT) - -/* secure config masks and shifts */ -#define SECURE_KEY_INDEX_SHIFT 20 -#define SECURE_KEY_INDEX_FIELD (0x1F << SECURE_KEY_INDEX_SHIFT) -#define SECURE_BLOCK_CNT_SHIFT 0 -#define SECURE_BLOCK_CNT_FIELD (0xFFFFF << SECURE_BLOCK_CNT_SHIFT) - -/* stream interface select masks and shifts */ -#define CMDQ_CTRL_SRC_STM_SEL_SHIFT 4 -#define CMDQ_CTRL_SRC_STM_SEL_FIELD (1 << CMDQ_CTRL_SRC_STM_SEL_SHIFT) -#define CMDQ_CTRL_DST_STM_SEL_SHIFT 5 -#define CMDQ_CTRL_DST_STM_SEL_FIELD (1 << CMDQ_CTRL_DST_STM_SEL_SHIFT) -#define CMDQ_CTRL_ICMDQEN_SHIFT 1 -#define CMDQ_CTRL_ICMDQEN_FIELD (1 << CMDQ_CTRL_SRC_STM_SEL_SHIFT) -#define CMDQ_CTRL_UCMDQEN_SHIFT 0 -#define CMDQ_CTRL_UCMDQEN_FIELD (1 << CMDQ_CTRL_DST_STM_SEL_SHIFT) - -/* config regsiter masks and shifts */ -#define CONFIG_ENDIAN_ENB_SHIFT 10 -#define CONFIG_ENDIAN_ENB_FIELD (0x1 << CONFIG_ENDIAN_ENB_SHIFT) -#define CONFIG_MODE_SEL_SHIFT 0 -#define CONFIG_MODE_SEL_FIELD (0x1F << CONFIG_MODE_SEL_SHIFT) - -/* extended config */ -#define SECURE_OFFSET_CNT_SHIFT 24 -#define SECURE_OFFSET_CNT_FIELD (0xFF << SECURE_OFFSET_CNT_SHIFT) -#define SECURE_KEYSCHED_GEN_SHIFT 15 -#define SECURE_KEYSCHED_GEN_FIELD (1 << SECURE_KEYSCHED_GEN_SHIFT) - -/* init vector select */ -#define SECURE_IV_SELECT_SHIFT 10 -#define SECURE_IV_SELECT_FIELD (1 << SECURE_IV_SELECT_SHIFT) - -/* secure engine input */ -#define SECURE_INPUT_ALG_SEL_SHIFT 28 -#define SECURE_INPUT_ALG_SEL_FIELD (0xF << SECURE_INPUT_ALG_SEL_SHIFT) -#define SECURE_INPUT_KEY_LEN_SHIFT 16 -#define SECURE_INPUT_KEY_LEN_FIELD (0xFFF << SECURE_INPUT_KEY_LEN_SHIFT) -#define SECURE_RNG_ENB_SHIFT 11 -#define SECURE_RNG_ENB_FIELD (0x1 << SECURE_RNG_ENB_SHIFT) -#define SECURE_CORE_SEL_SHIFT 9 -#define SECURE_CORE_SEL_FIELD (0x1 << SECURE_CORE_SEL_SHIFT) -#define SECURE_VCTRAM_SEL_SHIFT 7 -#define SECURE_VCTRAM_SEL_FIELD (0x3 << SECURE_VCTRAM_SEL_SHIFT) -#define SECURE_INPUT_SEL_SHIFT 5 -#define SECURE_INPUT_SEL_FIELD (0x3 << SECURE_INPUT_SEL_SHIFT) -#define SECURE_XOR_POS_SHIFT 3 -#define SECURE_XOR_POS_FIELD (0x3 << SECURE_XOR_POS_SHIFT) -#define SECURE_HASH_ENB_SHIFT 2 -#define SECURE_HASH_ENB_FIELD (0x1 << SECURE_HASH_ENB_SHIFT) -#define SECURE_ON_THE_FLY_SHIFT 0 -#define SECURE_ON_THE_FLY_FIELD (1 << SECURE_ON_THE_FLY_SHIFT) - -#endif diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a25f5f61e0e0..411d5bf50fc4 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/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 33780d856acb..e7d5d6b5dcf6 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_mc.c b/drivers/edac/edac_mc.c index 6d2e34d0f52a..6b21e25f7a84 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -578,16 +578,14 @@ 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 */ + /* flush workq processes and remove sysfs */ 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/ohci.c b/drivers/firewire/ohci.c index a03cb6acaeda..9dcb17d51aee 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -242,7 +242,6 @@ 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 @@ -254,34 +253,18 @@ 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, revision, flags; + unsigned short vendor, device, flags; } ohci_quirks[] = { - {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}, + {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}, }; /* This overrides anything that was found in ohci_quirks[]. */ @@ -756,7 +739,7 @@ static void ar_context_tasklet(unsigned long data) d = &ab->descriptor; if (d->res_count == 0) { - size_t size, size2, rest, pktsize, size3, offset; + size_t size, rest, offset; dma_addr_t start_bus; void *start; @@ -767,61 +750,25 @@ static void ar_context_tasklet(unsigned long data) */ offset = offsetof(struct ar_buffer, data); - start = ab; + start = buffer = 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 */ + size = buffer + PAGE_SIZE - ctx->pointer; 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; + memcpy(buffer + size, ab->data, rest); + ctx->current_buffer = ab; + ctx->pointer = (void *) ab->data + rest; + end = buffer + size + rest; - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); - - ctx->current_buffer = ab; - ctx->pointer = end; + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); - dma_free_coherent(ohci->card.device, PAGE_SIZE, - start, start_bus); - ar_context_add_page(ctx); - } else { - ctx->pointer = start + PAGE_SIZE; - } + dma_free_coherent(ohci->card.device, PAGE_SIZE, + start, start_bus); + ar_context_add_page(ctx); } else { buffer = ctx->pointer; ctx->pointer = end = @@ -2938,11 +2885,9 @@ 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 == (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)) { + if (ohci_quirks[i].vendor == dev->vendor && + (ohci_quirks[i].device == dev->device || + ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { ohci->quirks = ohci_quirks[i].flags; break; } diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index d3e55a0ae92b..e23c06893d19 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c @@ -56,29 +56,6 @@ 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) { @@ -87,7 +64,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset, outl(1 << offset, chip->base + reg); else /* high bank register */ - errata_outl(chip, 1 << (offset - 16), reg); + outl(1 << (offset - 16), chip->base + 0x80 + reg); } void cs5535_gpio_set(unsigned offset, unsigned int reg) @@ -109,7 +86,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset, outl(1 << (offset + 16), chip->base + reg); else /* high bank register */ - errata_outl(chip, 1 << offset, reg); + outl(1 << offset, chip->base + 0x80 + reg); } void cs5535_gpio_clear(unsigned offset, unsigned int reg) diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index 897e0577e65e..2762698e0204 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 = platform_get_drvdata(pdev); + pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); return -ENODEV; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index dfc635884619..37e0b4fa482a 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, "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_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_TV, "TV", 0 }, - { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, + { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, }; static struct drm_prop_enum_list drm_encoder_enum_list[] = diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c836b886b357..2dd2c93ebfa3 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -34,7 +34,6 @@ #include "i915_drm.h" #include "i915_drv.h" #include "i915_trace.h" -#include "../../../platform/x86/intel_ips.h" #include #include #include @@ -2047,26 +2046,6 @@ 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 @@ -2255,8 +2234,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* XXX Prevent module unload due to memory corruption bugs. */ __module_get(THIS_MODULE); - ips_ping_for_i915_load(); - return 0; out_workqueue_free: @@ -2329,9 +2306,6 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_lastclose(dev); intel_cleanup_overlay(dev); - - if (!I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); } intel_teardown_mchbar(dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 477e4ac66639..744225ebb4b2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -310,7 +310,6 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier, pch_iir; - u32 hotplug_mask; struct drm_i915_master_private *master_priv; struct intel_ring_buffer *render_ring = &dev_priv->render_ring; @@ -326,11 +325,6 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) goto done; - if (HAS_PCH_CPT(dev)) - hotplug_mask = SDE_HOTPLUG_MASK_CPT; - else - hotplug_mask = SDE_HOTPLUG_MASK; - ret = IRQ_HANDLED; if (dev->primary->master) { @@ -372,8 +366,10 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) drm_handle_vblank(dev, 1); /* check event from PCH */ - if ((de_iir & DE_PCH_EVENT) && (pch_iir & hotplug_mask)) + if ((de_iir & DE_PCH_EVENT) && + (pch_iir & SDE_HOTPLUG_MASK)) { queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } if (de_iir & DE_PCU_EVENT) { I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); @@ -1428,7 +1424,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; - u32 hotplug_mask; + u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | + SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; dev_priv->irq_mask_reg = ~display_mask; dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK; @@ -1453,14 +1450,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev) I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); (void) I915_READ(GTIER); - if (HAS_PCH_CPT(dev)) { - hotplug_mask = SDE_CRT_HOTPLUG_CPT | SDE_PORTB_HOTPLUG_CPT | - SDE_PORTC_HOTPLUG_CPT | SDE_PORTD_HOTPLUG_CPT ; - } else { - hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | - SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; - } - dev_priv->pch_irq_mask_reg = ~hotplug_mask; dev_priv->pch_irq_enable_reg = hotplug_mask; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cda89f49b5b2..4f5e15577e89 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2551,10 +2551,6 @@ #define SDE_PORTD_HOTPLUG_CPT (1 << 23) #define SDE_PORTC_HOTPLUG_CPT (1 << 22) #define SDE_PORTB_HOTPLUG_CPT (1 << 21) -#define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \ - SDE_PORTD_HOTPLUG_CPT | \ - SDE_PORTC_HOTPLUG_CPT | \ - SDE_PORTB_HOTPLUG_CPT) #define SDEISR 0xc4000 #define SDEIMR 0xc4004 @@ -2726,9 +2722,6 @@ #define FDI_RXB_CHICKEN 0xc2010 #define FDI_RX_PHASE_SYNC_POINTER_ENABLE (1) -#define SOUTH_DSPCLK_GATE_D 0xc2020 -#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29) - /* CPU: FDI_TX */ #define FDI_TXA_CTL 0x60100 #define FDI_TXB_CTL 0x61100 @@ -2953,7 +2946,6 @@ #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 2df5b9aadd5b..31f08581e93a 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -862,10 +862,8 @@ int i915_restore_state(struct drm_device *dev) /* Clock gating state */ intel_init_clock_gating(dev); - if (HAS_PCH_SPLIT(dev)) { + if (HAS_PCH_SPLIT(dev)) ironlake_enable_drps(dev); - intel_init_emon(dev); - } /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0f950e74db3c..197d4f32585a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -191,8 +191,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); if (turn_off_dac) { - /* Make sure hotplug is enabled */ - I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE); + I915_WRITE(PCH_ADPA, temp); (void)I915_READ(PCH_ADPA); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 932a061f28d0..979228594599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2044,11 +2044,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) reg = I915_READ(trans_dp_ctl); reg &= ~(TRANS_DP_PORT_SEL_MASK | - TRANS_DP_SYNC_MASK | - TRANS_DP_BPC_MASK); + TRANS_DP_SYNC_MASK); reg |= (TRANS_DP_OUTPUT_ENABLE | TRANS_DP_ENH_FRAMING); - reg |= TRANS_DP_8BPC; if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; @@ -5675,13 +5673,6 @@ void intel_init_clock_gating(struct drm_device *dev) I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); - /* * According to the spec the following bits should be set in * order to enable memory self-refresh diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f2bcfdf3ec1f..9ab8708ac6ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -425,7 +425,6 @@ 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; @@ -460,33 +459,14 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, break; } - for (retry = 0; retry < 5; retry++) { - ret = intel_dp_aux_ch(intel_dp, - msg, msg_bytes, - reply, reply_bytes); + for (;;) { + 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) { @@ -494,20 +474,17 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } return reply_bytes - 1; case AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_i2c nack\n"); + DRM_DEBUG_KMS("aux_ch nack\n"); return -EREMOTEIO; case AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_i2c defer\n"); + DRM_DEBUG_KMS("aux_ch defer\n"); udelay(100); break; default: - DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); + DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); return -EREMOTEIO; } } - - DRM_ERROR("too many retries, giving up\n"); - return -EREMOTEIO; } static int diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2b161375a38d..8828b3ac6414 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -250,7 +250,6 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, extern void intel_init_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); -extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 743664187fef..1d306a458be6 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1367,12 +1367,6 @@ void intel_setup_overlay(struct drm_device *dev) goto out_free_bo; } overlay->flip_addr = overlay->reg_bo->gtt_offset; - - ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); - if (ret) { - DRM_ERROR("failed to move overlay register bo into the GTT\n"); - goto out_unpin_bo; - } } else { ret = i915_gem_attach_phys_object(dev, reg_bo, I915_GEM_PHYS_OVERLAY_REGS, @@ -1405,8 +1399,6 @@ void intel_setup_overlay(struct drm_device *dev) DRM_INFO("initialized overlay support\n"); return; -out_unpin_bo: - i915_gem_object_unpin(reg_bo); out_free_bo: drm_gem_object_unreference(reg_bo); out_free: diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index b60652bfd1a3..ee73e428a84a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1498,12 +1498,10 @@ 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; - - /* add 30ms delay when the output type might be TV */ - if (intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) + if (intel_sdvo->is_tv) { + /* add 30ms delay when the output type is SDVO-TV */ mdelay(30); - + } if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) return connector_status_unknown; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c926d8891a46..b1be617373b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -531,12 +531,6 @@ struct drm_nouveau_private { struct work_struct irq_work; struct work_struct hpd_work; - struct { - spinlock_t lock; - uint32_t hpd0_bits; - uint32_t hpd1_bits; - } hpd_state; - struct list_head vbl_waiting; struct { diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index b62a601737a4..794b0ee30cf6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -52,7 +52,6 @@ nouveau_irq_preinstall(struct drm_device *dev) if (dev_priv->card_type >= NV_50) { INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); - spin_lock_init(&dev_priv->hpd_state.lock); INIT_LIST_HEAD(&dev_priv->vbl_waiting); } } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index d967cb65d641..612fa6d6a0cb 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1012,18 +1012,11 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) struct drm_connector *connector; const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; uint32_t unplug_mask, plug_mask, change_mask; - uint32_t hpd0, hpd1; + uint32_t hpd0, hpd1 = 0; - spin_lock_irq(&dev_priv->hpd_state.lock); - hpd0 = dev_priv->hpd_state.hpd0_bits; - dev_priv->hpd_state.hpd0_bits = 0; - hpd1 = dev_priv->hpd_state.hpd1_bits; - dev_priv->hpd_state.hpd1_bits = 0; - spin_unlock_irq(&dev_priv->hpd_state.lock); - - hpd0 &= nv_rd32(dev, 0xe050); + hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); if (dev_priv->chipset >= 0x90) - hpd1 &= nv_rd32(dev, 0xe070); + hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); @@ -1065,6 +1058,10 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); } + nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054)); + if (dev_priv->chipset >= 0x90) + nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074)); + drm_helper_hpd_irq_event(dev); } @@ -1075,22 +1072,8 @@ nv50_display_irq_handler(struct drm_device *dev) uint32_t delayed = 0; if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { - uint32_t hpd0_bits, hpd1_bits = 0; - - hpd0_bits = nv_rd32(dev, 0xe054); - nv_wr32(dev, 0xe054, hpd0_bits); - - if (dev_priv->chipset >= 0x90) { - hpd1_bits = nv_rd32(dev, 0xe074); - nv_wr32(dev, 0xe074, hpd1_bits); - } - - spin_lock(&dev_priv->hpd_state.lock); - dev_priv->hpd_state.hpd0_bits |= hpd0_bits; - dev_priv->hpd_state.hpd1_bits |= hpd1_bits; - spin_unlock(&dev_priv->hpd_state.lock); - - queue_work(dev_priv->wq, &dev_priv->hpd_work); + if (!work_pending(&dev_priv->hpd_work)) + queue_work(dev_priv->wq, &dev_priv->hpd_work); } while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 05efb5b9f13e..8e421f644a54 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -112,7 +112,6 @@ 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 e226f47b497c..cd0290f946cf 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -253,8 +253,7 @@ 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); - if (radeon_crtc->enabled) - atombios_blank_crtc(crtc, ATOM_ENABLE); + atombios_blank_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev)) atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); atombios_enable_crtc(crtc, ATOM_DISABLE); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 9e3dd2fd2766..2f93d46ae69a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1423,6 +1423,7 @@ 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"); @@ -1461,6 +1462,16 @@ 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", @@ -1471,6 +1482,10 @@ 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; } @@ -2082,11 +2097,6 @@ 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. @@ -2183,11 +2193,6 @@ 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/r100.c b/drivers/gpu/drm/radeon/r100.c index 0ba4163ee0a4..e59422320bb6 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2318,9 +2318,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev) /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - * Novell bug 204882 + along with lots of ubuntu ones */ - if (rdev->mc.aper_size > config_aper_size) - config_aper_size = rdev->mc.aper_size; - if (config_aper_size > rdev->mc.real_vram_size) rdev->mc.mc_vram_size = config_aper_size; else @@ -3228,8 +3225,6 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, for (u = 0; u < track->num_texture; u++) { if (!track->textures[u].enabled) continue; - if (track->textures[u].lookup_disable) - continue; robj = track->textures[u].robj; if (robj == NULL) { DRM_ERROR("No texture bound to unit %u\n", u); @@ -3464,7 +3459,6 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->textures[i].robj = NULL; /* CS IB emission code makes sure texture unit are disabled */ track->textures[i].enabled = false; - track->textures[i].lookup_disable = false; track->textures[i].roundup_w = true; track->textures[i].roundup_h = true; if (track->separate_cube) diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index af65600e6564..f47cdca1c004 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -46,7 +46,6 @@ struct r100_cs_track_texture { unsigned height_11; bool use_pitch; bool enabled; - bool lookup_disable; bool roundup_w; bool roundup_h; unsigned compress_format; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index d2408c395619..0266d72e0a4c 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -447,8 +447,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); } - if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) - track->textures[i].lookup_disable = true; switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { case R200_TXFORMAT_I8: case R200_TXFORMAT_RGB332: diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 74b9fb7a71df..7b65e4efe8af 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -97,8 +97,14 @@ u32 rv6xx_get_temp(struct radeon_device *rdev) { u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> ASIC_T_SHIFT; + u32 actual_temp = 0; - return temp * 1000; + if ((temp >> 7) & 1) + actual_temp = 0; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; } void r600_pm_get_dynpm_state(struct radeon_device *rdev) @@ -878,15 +884,12 @@ 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) && - !(rdev->flags & RADEON_IS_AGP)) { + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { 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); @@ -1198,10 +1201,8 @@ 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; - base <<= 24; - } + if (rdev->flags & RADEON_IS_IGP) + base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = 0; radeon_gtt_location(rdev, mc); @@ -1607,11 +1608,8 @@ void r600_gpu_init(struct radeon_device *rdev) rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); - tiling_config |= GROUP_SIZE((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.r600.tiling_group_size = 512; - else - rdev->config.r600.tiling_group_size = 256; + tiling_config |= GROUP_SIZE(0); + rdev->config.r600.tiling_group_size = 256; tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; if (tmp > 3) { tiling_config |= ROW_TILING(3); @@ -3530,12 +3528,10 @@ 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. - * This seems to cause problems on some AGP cards. Just use the old - * method for them. + * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL */ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && - rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { + rdev->vram_scratch.ptr) { void __iomem *ptr = (void *)rdev->vram_scratch.ptr; u32 tmp; diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index e5d4928fd2dc..3473c00781ff 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -650,8 +650,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev, int src_x = src_gpu_addr & 255; int dst_x = dst_gpu_addr & 255; int h = 1; - src_gpu_addr = src_gpu_addr & ~255ULL; - dst_gpu_addr = dst_gpu_addr & ~255ULL; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; if (!src_x && !dst_x) { h = (cur_size / max_bytes); @@ -744,8 +744,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev, int src_x = (src_gpu_addr & 255); int dst_x = (dst_gpu_addr & 255); int h = 1; - src_gpu_addr = src_gpu_addr & ~255ULL; - dst_gpu_addr = dst_gpu_addr & ~255ULL; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; if (!src_x && !dst_x) { h = (cur_size / max_bytes); diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 478fddf08f9a..250a3a918193 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -228,7 +228,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) __func__, __LINE__, pitch); return -EINVAL; } - if (!IS_ALIGNED((height / 8), track->npipes)) { + if (!IS_ALIGNED((height / 8), track->nbanks)) { dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", __func__, __LINE__, height); return -EINVAL; @@ -367,7 +367,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) __func__, __LINE__, pitch); return -EINVAL; } - if (!IS_ALIGNED((height / 8), track->npipes)) { + if ((height / 8) & (track->nbanks - 1)) { dev_warn(p->dev, "%s:%d db height (%d) invalid\n", __func__, __LINE__, height); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index 33cda016b083..d84612ae47e0 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h @@ -86,7 +86,6 @@ #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 3779265c3b95..8e43ddae70cc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -98,14 +98,6 @@ 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; @@ -182,14 +174,6 @@ 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 8f2c7b50dcf5..654787ec43f4 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -130,7 +130,6 @@ 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; @@ -144,7 +143,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev) bool r; viph_control = RREG32(RADEON_VIPH_CONTROL); - bus_cntl = RREG32(R600_BUS_CNTL); + bus_cntl = RREG32(RADEON_BUS_CNTL); d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); @@ -153,7 +152,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(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); + WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); /* Disable VGA mode */ WREG32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | @@ -192,7 +191,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(R600_BUS_CNTL, bus_cntl); + WREG32(RADEON_BUS_CNTL, bus_cntl); WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); @@ -217,7 +216,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev) bool r; viph_control = RREG32(RADEON_VIPH_CONTROL); - bus_cntl = RREG32(R600_BUS_CNTL); + bus_cntl = RREG32(RADEON_BUS_CNTL); d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); @@ -232,7 +231,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(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); + WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); /* Disable VGA mode */ WREG32(AVIVO_D1VGA_CONTROL, (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | @@ -263,7 +262,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev) /* restore regs */ WREG32(RADEON_VIPH_CONTROL, viph_control); - WREG32(R600_BUS_CNTL, bus_cntl); + WREG32(RADEON_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 137b8075f6e7..7b7ea269549c 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -571,7 +571,6 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde } if (clk_mask && data_mask) { - /* system specific masks */ i2c.mask_clk_mask = clk_mask; i2c.mask_data_mask = data_mask; i2c.a_clk_mask = clk_mask; @@ -580,19 +579,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde i2c.en_data_mask = data_mask; i2c.y_clk_mask = clk_mask; i2c.y_data_mask = data_mask; - } else if ((ddc_line == RADEON_GPIOPAD_MASK) || - (ddc_line == RADEON_MDGPIO_MASK)) { - /* default gpiopad masks */ - i2c.mask_clk_mask = (0x20 << 8); - i2c.mask_data_mask = 0x80; - i2c.a_clk_mask = (0x20 << 8); - i2c.a_data_mask = 0x80; - i2c.en_clk_mask = (0x20 << 8); - i2c.en_data_mask = 0x80; - i2c.y_clk_mask = (0x20 << 8); - i2c.y_data_mask = 0x80; } else { - /* default masks for ddc pads */ i2c.mask_clk_mask = RADEON_GPIO_EN_1; i2c.mask_data_mask = RADEON_GPIO_EN_0; i2c.a_clk_mask = RADEON_GPIO_A_1; @@ -729,7 +716,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, - (1 << clk), (1 << data)); + clk, 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 5e222c9739c7..ecc1a8fafbfd 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1119,8 +1119,6 @@ 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); @@ -1136,8 +1134,6 @@ 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: @@ -1167,11 +1163,6 @@ 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: @@ -1195,11 +1186,6 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.underscan_property, UNDERSCAN_AUTO); 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: @@ -1230,9 +1216,6 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.underscan_property, UNDERSCAN_AUTO); - 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: @@ -1248,8 +1231,6 @@ 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); @@ -1268,8 +1249,6 @@ 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; } @@ -1347,8 +1326,6 @@ 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); @@ -1364,8 +1341,6 @@ 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: @@ -1383,11 +1358,6 @@ 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: @@ -1410,8 +1380,6 @@ 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); @@ -1425,8 +1393,6 @@ 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 ed5e153384ac..256d204a6d24 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -829,6 +829,11 @@ 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(); @@ -836,10 +841,6 @@ 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_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index b82015e148e6..2c293e8304d6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -595,7 +595,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) int atombios_get_encoder_mode(struct drm_encoder *encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct drm_connector *connector; @@ -603,20 +602,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) struct radeon_connector_atom_dig *dig_connector; connector = radeon_get_connector_for_encoder(encoder); - if (!connector) { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - return ATOM_ENCODER_MODE_DVI; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - default: - return ATOM_ENCODER_MODE_CRT; - } - } + if (!connector) + return 0; + radeon_connector = to_radeon_connector(connector); switch (connector->connector_type) { @@ -1559,23 +1547,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig; - - /* check for pre-DCE3 cards with shared encoders; - * can't really use the links individually, so don't disable - * the encoder if it's in use by another connector - */ - if (!ASIC_IS_DCE3(rdev)) { - struct drm_encoder *other_encoder; - struct radeon_encoder *other_radeon_encoder; - - list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { - other_radeon_encoder = to_radeon_encoder(other_encoder); - if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && - drm_helper_encoder_in_use(other_encoder)) - goto disable_done; - } - } - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); switch (radeon_encoder->encoder_id) { @@ -1615,7 +1586,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) break; } -disable_done: if (radeon_encoder_is_digital(encoder)) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) r600_hdmi_disable(encoder); diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index acae80ee91a2..6a13ee38a5b9 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -946,7 +946,6 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->dev = dev; - sprintf(i2c->adapter.name, "Radeon aux bus %s", name); i2c_set_adapdata(&i2c->adapter, i2c); i2c->adapter.algo_data = &i2c->algo.dp; i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 25d345ecee8e..b3b5306bb578 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -102,8 +102,6 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, type = ttm_bo_type_device; } *bo_ptr = NULL; - -retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -111,6 +109,8 @@ retry: bo->gobj = gobj; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); + +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 64928814de53..c332f46340d5 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -2836,7 +2836,6 @@ # define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) # define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) # define R200_TXFORMAT_ST_ROUTE_SHIFT 24 -# define R200_TXFORMAT_LOOKUP_DISABLE (1 << 27) # define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) # define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) # define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b88353d6ed2e..9490da700749 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -643,11 +643,10 @@ static void rv770_gpu_init(struct radeon_device *rdev) else gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); - gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.rv770.tiling_group_size = 512; - else - rdev->config.rv770.tiling_group_size = 256; + + gb_tiling_config |= GROUP_SIZE(0); + rdev->config.rv770.tiling_group_size = 256; + if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { gb_tiling_config |= ROW_TILING(3); gb_tiling_config |= SAMPLE_SPLIT(3); diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 874851a2bcfd..6369ba7f96f8 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -264,13 +264,6 @@ config HID_MONTEREY ---help--- Support for Monterey Genius KB29E. -config HID_MOTOROLA - tristate "Motorola" if EMBEDDED - depends on USB_HID - default !EMBEDDED - ---help--- - Support for Motorola HID devices - config HID_NTRIG tristate "NTrig" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index cbd9b40dfd12..46f037f3df80 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o obj-$(CONFIG_HID_MOSART) += hid-mosart.o -obj-$(CONFIG_HID_MOTOROLA) += hid-motorola.o obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o obj-$(CONFIG_HID_ORTEK) += hid-ortek.o obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 45e9a295e02d..a0dea3d1296e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1248,7 +1248,6 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, @@ -1348,7 +1347,6 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOTOROLA, USB_DEVICE_ID_HD_DOCK) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index 54b017ad258d..8ca7f65cf2f8 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c @@ -31,7 +31,7 @@ struct egalax_data { 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 */ + __u16 lastx, lasty; /* latest valid (x, y) in the frame */ }; static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, @@ -79,10 +79,6 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_TIPPRESSURE: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_PRESSURE); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_PRESSURE, - field->logical_minimum, - field->logical_maximum, 0, 0); return 1; } return 0; @@ -113,8 +109,8 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) 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_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); @@ -125,7 +121,6 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) */ td->lastx = td->x; td->lasty = td->y; - td->lastz = td->z; } /* @@ -134,9 +129,8 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) * 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); + input_event(input, EV_ABS, ABS_X, td->lastx); + input_event(input, EV_ABS, ABS_Y, td->lasty); } if (!td->valid) { diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 2e23804b65d6..c5ae5f1545bd 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -63,7 +63,6 @@ #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d -#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 @@ -392,9 +391,6 @@ #define USB_VENDOR_ID_MONTEREY 0x0566 #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 -#define USB_VENDOR_ID_MOTOROLA 0x22b8 -#define USB_DEVICE_ID_HD_DOCK 0x0938 - #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 #define USB_DEVICE_ID_N_S_HARMONY 0xc359 diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 51f945a9e9e0..319b0e57ee41 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -2,7 +2,6 @@ * Apple "Magic" Wireless Mouse driver * * Copyright (c) 2010 Michael Poole - * Copyright (c) 2010 Chase Douglas */ /* @@ -54,9 +53,7 @@ static bool report_undeciphered; module_param(report_undeciphered, bool, 0644); MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); -#define TRACKPAD_REPORT_ID 0x28 -#define MOUSE_REPORT_ID 0x29 -#define DOUBLE_REPORT_ID 0xf7 +#define TOUCH_REPORT_ID 0x29 /* These definitions are not precise, but they're close enough. (Bits * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem * to be some kind of bit mask -- 0x20 may be a near-field reading, @@ -70,19 +67,15 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie #define SCROLL_ACCEL_DEFAULT 7 -/* Single touch emulation should only begin when no touches are currently down. - * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches - * are down and the touch providing for single touch emulation is lifted, - * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is - * occuring, single_touch_id corresponds with the tracking id of the touch used. - */ -#define NO_TOUCHES -1 -#define SINGLE_TOUCH_UP -2 - /** * struct magicmouse_sc - Tracks Magic Mouse-specific data. * @input: Input device through which we report events. * @quirks: Currently unused. + * @last_timestamp: Timestamp from most recent (18-bit) touch report + * (units of milliseconds over short windows, but seems to + * increase faster when there are no touches). + * @delta_time: 18-bit difference between the two most recent touch + * reports from the mouse. * @ntouches: Number of touches in most recent touch report. * @scroll_accel: Number of consecutive scroll motions. * @scroll_jiffies: Time of last scroll motion. @@ -93,6 +86,8 @@ struct magicmouse_sc { struct input_dev *input; unsigned long quirks; + int last_timestamp; + int delta_time; int ntouches; int scroll_accel; unsigned long scroll_jiffies; @@ -103,9 +98,9 @@ struct magicmouse_sc { short scroll_x; short scroll_y; u8 size; + u8 down; } touches[16]; int tracking_ids[16]; - int single_touch_id; }; static int magicmouse_firm_touch(struct magicmouse_sc *msc) @@ -171,35 +166,18 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) { struct input_dev *input = msc->input; - int id, x, y, size, orientation, touch_major, touch_minor, state, down; - - if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; - x = (tdata[1] << 28 | tdata[0] << 20) >> 20; - y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); - size = tdata[5] & 0x3f; - orientation = (tdata[6] >> 2) - 32; - touch_major = tdata[3]; - touch_minor = tdata[4]; - state = tdata[7] & TOUCH_STATE_MASK; - down = state != TOUCH_STATE_NONE; - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; - x = (tdata[1] << 27 | tdata[0] << 19) >> 19; - y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); - size = tdata[6] & 0x3f; - orientation = (tdata[7] >> 2) - 32; - touch_major = tdata[4]; - touch_minor = tdata[5]; - state = tdata[8] & TOUCH_STATE_MASK; - down = state != TOUCH_STATE_NONE; - } + __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; + int misc = tdata[5] | tdata[6] << 8; + int id = (misc >> 6) & 15; + int x = x_y << 12 >> 20; + int y = -(x_y >> 20); + int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; /* Store tracking ID and other fields. */ msc->tracking_ids[raw_id] = id; msc->touches[id].x = x; msc->touches[id].y = y; - msc->touches[id].size = size; + msc->touches[id].size = misc & 63; /* If requested, emulate a scroll wheel by detecting small * vertical touch motions. @@ -210,7 +188,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda int step_y = msc->touches[id].scroll_y - y; /* Calculate and apply the scroll motion. */ - switch (state) { + switch (tdata[7] & TOUCH_STATE_MASK) { case TOUCH_STATE_START: msc->touches[id].scroll_x = x; msc->touches[id].scroll_y = y; @@ -244,28 +222,21 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda } } - if (down) { - msc->ntouches++; - if (msc->single_touch_id == NO_TOUCHES) - msc->single_touch_id = id; - } else if (msc->single_touch_id == id) - msc->single_touch_id = SINGLE_TOUCH_UP; - /* Generate the input events for this touch. */ if (report_touches && down) { + int orientation = (misc >> 10) - 32; + + msc->touches[id].down = 1; + input_report_abs(input, ABS_MT_TRACKING_ID, id); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); - input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); + input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); input_report_abs(input, ABS_MT_ORIENTATION, orientation); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); - if (report_undeciphered) { - if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) - input_event(input, EV_MSC, MSC_RAW, tdata[7]); - else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - input_event(input, EV_MSC, MSC_RAW, tdata[8]); - } + if (report_undeciphered) + input_event(input, EV_MSC, MSC_RAW, tdata[7]); input_mt_sync(input); } @@ -276,43 +247,39 @@ static int magicmouse_raw_event(struct hid_device *hdev, { struct magicmouse_sc *msc = hid_get_drvdata(hdev); struct input_dev *input = msc->input; - int x = 0, y = 0, ii, clicks = 0, npoints; + int x, y, ts, ii, clicks, last_up; switch (data[0]) { - case TRACKPAD_REPORT_ID: - /* Expect four bytes of prefix, and N*9 bytes of touch data. */ - if (size < 4 || ((size - 4) % 9) != 0) + case 0x10: + if (size != 6) return 0; - npoints = (size - 4) / 9; - msc->ntouches = 0; - for (ii = 0; ii < npoints; ii++) - magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); - - /* We don't need an MT sync here because trackpad emits a - * BTN_TOUCH event in a new frame when all touches are released. - */ - if (msc->ntouches == 0) - msc->single_touch_id = NO_TOUCHES; - + x = (__s16)(data[2] | data[3] << 8); + y = (__s16)(data[4] | data[5] << 8); clicks = data[1]; - - /* The following bits provide a device specific timestamp. They - * are unused here. - * - * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; - */ break; - case MOUSE_REPORT_ID: + case TOUCH_REPORT_ID: /* Expect six bytes of prefix, and N*8 bytes of touch data. */ if (size < 6 || ((size - 6) % 8) != 0) return 0; - npoints = (size - 6) / 8; - msc->ntouches = 0; - for (ii = 0; ii < npoints; ii++) + ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; + msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; + msc->last_timestamp = ts; + msc->ntouches = (size - 6) / 8; + for (ii = 0; ii < msc->ntouches; ii++) magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); - if (report_touches && msc->ntouches == 0) - input_mt_sync(input); + if (report_touches) { + last_up = 1; + for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { + if (msc->touches[ii].down) { + last_up = 0; + msc->touches[ii].down = 0; + } + } + if (last_up) { + input_mt_sync(input); + } + } /* When emulating three-button mode, it is important * to have the current touch information before @@ -321,72 +288,68 @@ static int magicmouse_raw_event(struct hid_device *hdev, x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; clicks = data[3]; - - /* The following bits provide a device specific timestamp. They - * are unused here. - * - * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; - */ - break; - case DOUBLE_REPORT_ID: - /* Sometimes the trackpad sends two touch reports in one - * packet. - */ - magicmouse_raw_event(hdev, report, data + 2, data[1]); - magicmouse_raw_event(hdev, report, data + 2 + data[1], - size - 2 - data[1]); break; + case 0x20: /* Theoretically battery status (0-100), but I have + * never seen it -- maybe it is only upon request. + */ + case 0x60: /* Unknown, maybe laser on/off. */ + case 0x61: /* Laser reflection status change. + * data[1]: 0 = spotted, 1 = lost + */ default: return 0; } - if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - magicmouse_emit_buttons(msc, clicks & 3); - input_report_rel(input, REL_X, x); - input_report_rel(input, REL_Y, y); - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - input_report_key(input, BTN_MOUSE, clicks & 1); - input_report_key(input, BTN_TOUCH, msc->ntouches > 0); - input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); - input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); - input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); - input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); - if (msc->single_touch_id >= 0) { - input_report_abs(input, ABS_X, - msc->touches[msc->single_touch_id].x); - input_report_abs(input, ABS_Y, - msc->touches[msc->single_touch_id].y); - } - } - + magicmouse_emit_buttons(msc, clicks & 3); + input_report_rel(input, REL_X, x); + input_report_rel(input, REL_Y, y); input_sync(input); return 1; } +static int magicmouse_input_open(struct input_dev *dev) +{ + struct hid_device *hid = input_get_drvdata(dev); + + return hid->ll_driver->open(hid); +} + +static void magicmouse_input_close(struct input_dev *dev) +{ + struct hid_device *hid = input_get_drvdata(dev); + + hid->ll_driver->close(hid); +} + static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) { - __set_bit(EV_KEY, input->evbit); + input_set_drvdata(input, hdev); + input->event = hdev->ll_driver->hidinput_input_event; + input->open = magicmouse_input_open; + input->close = magicmouse_input_close; + + input->name = hdev->name; + input->phys = hdev->phys; + input->uniq = hdev->uniq; + input->id.bustype = hdev->bus; + input->id.vendor = hdev->vendor; + input->id.product = hdev->product; + input->id.version = hdev->version; + input->dev.parent = hdev->dev.parent; - if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - __set_bit(BTN_LEFT, input->keybit); - __set_bit(BTN_RIGHT, input->keybit); - if (emulate_3button) - __set_bit(BTN_MIDDLE, input->keybit); - - __set_bit(EV_REL, input->evbit); - __set_bit(REL_X, input->relbit); - __set_bit(REL_Y, input->relbit); - if (emulate_scroll_wheel) { - __set_bit(REL_WHEEL, input->relbit); - __set_bit(REL_HWHEEL, input->relbit); - } - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - __set_bit(BTN_MOUSE, input->keybit); - __set_bit(BTN_TOOL_FINGER, input->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); - __set_bit(BTN_TOOL_QUADTAP, input->keybit); - __set_bit(BTN_TOUCH, input->keybit); + __set_bit(EV_KEY, input->evbit); + __set_bit(BTN_LEFT, input->keybit); + __set_bit(BTN_RIGHT, input->keybit); + if (emulate_3button) + __set_bit(BTN_MIDDLE, input->keybit); + __set_bit(BTN_TOOL_FINGER, input->keybit); + + __set_bit(EV_REL, input->evbit); + __set_bit(REL_X, input->relbit); + __set_bit(REL_Y, input->relbit); + if (emulate_scroll_wheel) { + __set_bit(REL_WHEEL, input->relbit); + __set_bit(REL_HWHEEL, input->relbit); } if (report_touches) { @@ -396,26 +359,16 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); - + input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, + 4, 0); /* Note: Touch Y position from the device is inverted relative * to how pointer motion is reported (and relative to how USB * HID recommends the coordinates work). This driver keeps * the origin at the same position, and just uses the additive * inverse of the reported Y. */ - if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, - 1358, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, - 2047, 4, 0); - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); - input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_X, -2909, - 3167, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, - 2565, 4, 0); - } + input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, + 4, 0); } if (report_undeciphered) { @@ -424,27 +377,12 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h } } -static int magicmouse_input_mapping(struct hid_device *hdev, - struct hid_input *hi, struct hid_field *field, - struct hid_usage *usage, unsigned long **bit, int *max) -{ - struct magicmouse_sc *msc = hid_get_drvdata(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; -} - static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { - __u8 feature[] = { 0xd7, 0x01 }; + __u8 feature_1[] = { 0xd7, 0x01 }; + __u8 feature_2[] = { 0xf8, 0x01, 0x32 }; + struct input_dev *input; struct magicmouse_sc *msc; struct hid_report *report; int ret; @@ -460,8 +398,6 @@ static int magicmouse_probe(struct hid_device *hdev, msc->quirks = id->driver_data; hid_set_drvdata(hdev, msc); - msc->single_touch_id = NO_TOUCHES; - ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "magicmouse hid parse failed\n"); @@ -474,22 +410,10 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - /* We do this after hid-input is done parsing reports so that - * hid-input uses the most natural button and axis IDs. - */ - if (msc->input) - magicmouse_setup_input(msc->input, hdev); - - if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) - report = hid_register_report(hdev, HID_INPUT_REPORT, - MOUSE_REPORT_ID); - else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - report = hid_register_report(hdev, HID_INPUT_REPORT, - TRACKPAD_REPORT_ID); - report = hid_register_report(hdev, HID_INPUT_REPORT, - DOUBLE_REPORT_ID); - } + /* we are handling the input ourselves */ + hidinput_disconnect(hdev); + report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); if (!report) { dev_err(&hdev->dev, "unable to register touch report\n"); ret = -ENOMEM; @@ -497,15 +421,39 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; - ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), + ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1), HID_FEATURE_REPORT); - if (ret != sizeof(feature)) { - dev_err(&hdev->dev, "unable to request touch data (%d)\n", + if (ret != sizeof(feature_1)) { + dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", + ret); + goto err_stop_hw; + } + ret = hdev->hid_output_raw_report(hdev, feature_2, + sizeof(feature_2), HID_FEATURE_REPORT); + if (ret != sizeof(feature_2)) { + dev_err(&hdev->dev, "unable to request touch data (2:%d)\n", ret); goto err_stop_hw; } + input = input_allocate_device(); + if (!input) { + dev_err(&hdev->dev, "can't alloc input device\n"); + ret = -ENOMEM; + goto err_stop_hw; + } + magicmouse_setup_input(input, hdev); + + ret = input_register_device(input); + if (ret) { + dev_err(&hdev->dev, "input device registration failed\n"); + goto err_input; + } + msc->input = input; + return 0; +err_input: + input_free_device(input); err_stop_hw: hid_hw_stop(hdev); err_free: @@ -518,14 +466,13 @@ static void magicmouse_remove(struct hid_device *hdev) struct magicmouse_sc *msc = hid_get_drvdata(hdev); hid_hw_stop(hdev); + input_unregister_device(msc->input); kfree(msc); } static const struct hid_device_id magic_mice[] = { - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, - USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, - USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), + .driver_data = 0 }, { } }; MODULE_DEVICE_TABLE(hid, magic_mice); @@ -536,7 +483,6 @@ static struct hid_driver magicmouse_driver = { .probe = magicmouse_probe, .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, - .input_mapping = magicmouse_input_mapping, }; static int __init magicmouse_init(void) diff --git a/drivers/hid/hid-motorola.c b/drivers/hid/hid-motorola.c deleted file mode 100644 index de9ef05119fb..000000000000 --- a/drivers/hid/hid-motorola.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include "hid-ids.h" - -#define MOT_SEMU 0x0001 -#define MOT_IR_REMOTE 0x0002 -#define MOT_AUDIO_JACK 0x0004 - -#define AUDIO_JACK_STATUS_REPORT 0x3E - -static struct switch_dev sdev; - -struct motorola_sc { - unsigned long quirks; - unsigned long audio_cable_inserted; - struct work_struct work; -}; - -static void audio_jack_status_work(struct work_struct *work) -{ - struct motorola_sc *sc = container_of(work, struct motorola_sc, work); - - cpcap_accy_whisper_spdif_set_state(sc->audio_cable_inserted); -} - -static int mot_rawevent(struct hid_device *hdev, struct hid_report *report, - u8 *data, int size) -{ - struct motorola_sc *sc = hid_get_drvdata(hdev); - - dbg_hid("%s\n", __func__); - - if (sc->quirks & MOT_AUDIO_JACK) { - if (data[0] == AUDIO_JACK_STATUS_REPORT) { - sc->audio_cable_inserted = data[1]; - schedule_work(&sc->work); - return 1; - } - } - - return 0; -} - -static int mot_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - unsigned long quirks = id->driver_data; - struct motorola_sc *sc; - unsigned int connect_mask = 0; - - dbg_hid("%s %d\n", __func__, __LINE__); - - sc = kzalloc(sizeof(*sc), GFP_KERNEL); - if (sc == NULL) { - dev_err(&hdev->dev, "can't alloc motorola descriptor\n"); - return -ENOMEM; - } - - sc->quirks = quirks; - hid_set_drvdata(hdev, sc); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - if (quirks & MOT_SEMU) - connect_mask |= HID_CONNECT_HIDRAW; - if (quirks & MOT_IR_REMOTE) - connect_mask |= (HID_CONNECT_HIDINPUT | - HID_CONNECT_HIDINPUT_FORCE); - if (quirks & MOT_AUDIO_JACK) - INIT_WORK(&sc->work, audio_jack_status_work); - - ret = hid_hw_start(hdev, connect_mask); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free_cancel; - } - - switch_set_state(&sdev, 1); - - dbg_hid("%s %d\n", __func__, __LINE__); - return 0; - -err_free_cancel: - cancel_work_sync(&sc->work); -err_free: - kfree(sc); - return ret; -} - -static void mot_remove(struct hid_device *hdev) -{ - struct motorola_sc *sc = hid_get_drvdata(hdev); - - dbg_hid("%s\n", __func__); - - cancel_work_sync(&sc->work); - - switch_set_state(&sdev, 0); - - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); -} - -static const struct hid_device_id mot_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_MOTOROLA, USB_DEVICE_ID_HD_DOCK), - .driver_data = MOT_SEMU | MOT_IR_REMOTE | MOT_AUDIO_JACK }, - {} -}; -MODULE_DEVICE_TABLE(hid, mot_devices); - -static const struct hid_report_id mot_reports[] = { - { HID_INPUT_REPORT }, - { HID_TERMINATOR } -}; - -static struct hid_driver motorola_driver = { - .name = "motorola", - .id_table = mot_devices, - .probe = mot_probe, - .remove = mot_remove, - .raw_event = mot_rawevent, - .report_table = mot_reports, -}; - -static int motorola_init(void) -{ - int ret; - - dbg_hid("Registering MOT HID driver\n"); - - ret = hid_register_driver(&motorola_driver); - if (ret) - printk(KERN_ERR "Can't register Motorola driver\n"); - - sdev.name = "whisper_hid"; - switch_dev_register(&sdev); - - return ret; -} - -static void motorola_exit(void) -{ - switch_dev_unregister(&sdev); - hid_unregister_driver(&motorola_driver); -} - -module_init(motorola_init); -module_exit(motorola_exit); -MODULE_LICENSE("GPL"); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 859ee7e39f5b..f0260c699adb 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -34,6 +34,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 9975bbfb1b31..65335b268fa9 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; + int val, orig_div, new_div, shift; 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(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)); + ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | + (new_div << shift))); } else { /* 3 < nr < 8 */ + shift = 2 * (nr - 4); adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, - (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)); + ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | + (new_div << shift))); } if (data->fan_div[nr] != orig_div) { diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 2e8f0c9458d4..b3841a615595 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1259,7 +1259,6 @@ static int lm85_probe(struct i2c_client *client, switch (data->type) { case adm1027: case adt7463: - case adt7468: case emc6d100: case emc6d102: data->freq_map = adm1027_freq_map; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 612c2088327b..ebfc1b818608 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -596,13 +596,6 @@ config I2C_STU300 This driver can also be built as a module. If so, the module will be called i2c-stu300. -config I2C_TEGRA - tristate "NVIDIA Tegra internal I2C controller" - depends on ARCH_TEGRA - help - If you say yes to this option, support will be included for the - I2C controller embedded in NVIDIA Tegra SOCs - config I2C_VERSATILE tristate "ARM Versatile/Realview I2C bus support" depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 53db8e58aaa6..a5ab954b890f 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_STU300) += i2c-stu300.o -obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index ace67995d7de..5f6d7f89e225 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -224,7 +224,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) if (irq) { ret = request_irq(irq, i2c_pca_pf_handler, - IRQF_TRIGGER_FALLING, pdev->name, i2c); + IRQF_TRIGGER_FALLING, i2c->adap.name, i2c); if (ret) goto e_reqirq; } diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c deleted file mode 100755 index e85fd847fb5a..000000000000 --- a/drivers/i2c/busses/i2c-tegra.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * drivers/i2c/busses/i2c-tegra.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) -#define BYTES_PER_FIFO_WORD 4 - -#define I2C_CNFG 0x000 -#define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12 -#define I2C_CNFG_PACKET_MODE_EN (1<<10) -#define I2C_CNFG_NEW_MASTER_FSM (1<<11) -#define I2C_STATUS 0x01C -#define I2C_SL_CNFG 0x020 -#define I2C_SL_CNFG_NEWSL (1<<2) -#define I2C_SL_ADDR1 0x02c -#define I2C_TX_FIFO 0x050 -#define I2C_RX_FIFO 0x054 -#define I2C_PACKET_TRANSFER_STATUS 0x058 -#define I2C_FIFO_CONTROL 0x05c -#define I2C_FIFO_CONTROL_TX_FLUSH (1<<1) -#define I2C_FIFO_CONTROL_RX_FLUSH (1<<0) -#define I2C_FIFO_CONTROL_TX_TRIG_SHIFT 5 -#define I2C_FIFO_CONTROL_RX_TRIG_SHIFT 2 -#define I2C_FIFO_STATUS 0x060 -#define I2C_FIFO_STATUS_TX_MASK 0xF0 -#define I2C_FIFO_STATUS_TX_SHIFT 4 -#define I2C_FIFO_STATUS_RX_MASK 0x0F -#define I2C_FIFO_STATUS_RX_SHIFT 0 -#define I2C_INT_MASK 0x064 -#define I2C_INT_STATUS 0x068 -#define I2C_INT_PACKET_XFER_COMPLETE (1<<7) -#define I2C_INT_ALL_PACKETS_XFER_COMPLETE (1<<6) -#define I2C_INT_TX_FIFO_OVERFLOW (1<<5) -#define I2C_INT_RX_FIFO_UNDERFLOW (1<<4) -#define I2C_INT_NO_ACK (1<<3) -#define I2C_INT_ARBITRATION_LOST (1<<2) -#define I2C_INT_TX_FIFO_DATA_REQ (1<<1) -#define I2C_INT_RX_FIFO_DATA_REQ (1<<0) -#define I2C_CLK_DIVISOR 0x06c - -#define DVC_CTRL_REG1 0x000 -#define DVC_CTRL_REG1_INTR_EN (1<<10) -#define DVC_CTRL_REG2 0x004 -#define DVC_CTRL_REG3 0x008 -#define DVC_CTRL_REG3_SW_PROG (1<<26) -#define DVC_CTRL_REG3_I2C_DONE_INTR_EN (1<<30) -#define DVC_STATUS 0x00c -#define DVC_STATUS_I2C_DONE_INTR (1<<30) - -#define I2C_ERR_NONE 0x00 -#define I2C_ERR_NO_ACK 0x01 -#define I2C_ERR_ARBITRATION_LOST 0x02 -#define I2C_ERR_UNKNOWN_INTERRUPT 0x04 - -#define PACKET_HEADER0_HEADER_SIZE_SHIFT 28 -#define PACKET_HEADER0_PACKET_ID_SHIFT 16 -#define PACKET_HEADER0_CONT_ID_SHIFT 12 -#define PACKET_HEADER0_PROTOCOL_I2C (1<<4) - -#define I2C_HEADER_HIGHSPEED_MODE (1<<22) -#define I2C_HEADER_CONT_ON_NAK (1<<21) -#define I2C_HEADER_SEND_START_BYTE (1<<20) -#define I2C_HEADER_READ (1<<19) -#define I2C_HEADER_10BIT_ADDR (1<<18) -#define I2C_HEADER_IE_ENABLE (1<<17) -#define I2C_HEADER_REPEAT_START (1<<16) -#define I2C_HEADER_MASTER_ADDR_SHIFT 12 -#define I2C_HEADER_SLAVE_ADDR_SHIFT 1 - -#define DEBUG_TEGRA_I2C_TEMP - -struct tegra_i2c_dev; - -struct tegra_i2c_bus { - struct tegra_i2c_dev *dev; - const struct tegra_pingroup_config *mux; - int mux_len; - unsigned long bus_clk_rate; - struct i2c_adapter adapter; -}; - -struct tegra_i2c_dev { - struct device *dev; - struct clk *clk; - struct clk *i2c_clk; - struct resource *iomem; - struct rt_mutex dev_lock; - void __iomem *base; - int cont_id; - int irq; - bool irq_disabled; - int is_dvc; - struct completion msg_complete; - int msg_err; - u8 *msg_buf; - size_t msg_buf_remaining; - int msg_read; - int msg_transfer_complete; - bool is_suspended; - int bus_count; - const struct tegra_pingroup_config *last_mux; - int last_mux_len; - unsigned long last_bus_clk; - struct tegra_i2c_bus busses[1]; -#ifdef DEBUG_TEGRA_I2C_TEMP - atomic_t incmplt_irq_count; -#endif -}; - -static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg) -{ - writel(val, i2c_dev->base + reg); -} - -static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg) -{ - return readl(i2c_dev->base + reg); -} - -/* i2c_writel and i2c_readl will offset the register if necessary to talk - * to the I2C block inside the DVC block - */ -static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg) -{ - if (i2c_dev->is_dvc) - reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40; - writel(val, i2c_dev->base + reg); -} - -static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg) -{ - if (i2c_dev->is_dvc) - reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40; - return readl(i2c_dev->base + reg); -} - -static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask) -{ - u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK); - int_mask &= ~mask; - i2c_writel(i2c_dev, int_mask, I2C_INT_MASK); -} - -static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask) -{ - u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK); - int_mask |= mask; - i2c_writel(i2c_dev, int_mask, I2C_INT_MASK); -} - -static void tegra_i2c_set_clk(struct tegra_i2c_dev *i2c_dev, unsigned int freq) -{ - clk_set_rate(i2c_dev->clk, freq * 8); -} - -static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev) -{ - unsigned long timeout = jiffies + HZ; - u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL); - val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH; - i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL); - - while (i2c_readl(i2c_dev, I2C_FIFO_CONTROL) & - (I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH)) { - if (time_after(jiffies, timeout)) { - dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n"); - return -ETIMEDOUT; - } - msleep(1); - } - return 0; -} - -static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev) -{ - u32 val; - int rx_fifo_avail; - int word; - u8 *buf = i2c_dev->msg_buf; - size_t buf_remaining = i2c_dev->msg_buf_remaining; - int words_to_transfer; - - val = i2c_readl(i2c_dev, I2C_FIFO_STATUS); - rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >> - I2C_FIFO_STATUS_RX_SHIFT; - - words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD; - if (words_to_transfer > rx_fifo_avail) - words_to_transfer = rx_fifo_avail; - - for (word = 0; word < words_to_transfer; word++) { - val = i2c_readl(i2c_dev, I2C_RX_FIFO); - put_unaligned_le32(val, buf); - buf += BYTES_PER_FIFO_WORD; - buf_remaining -= BYTES_PER_FIFO_WORD; - rx_fifo_avail--; - } - - if (rx_fifo_avail > 0 && buf_remaining > 0) { - int bytes_to_transfer = buf_remaining; - int byte; - BUG_ON(bytes_to_transfer > 3); - val = i2c_readl(i2c_dev, I2C_RX_FIFO); - for (byte = 0; byte < bytes_to_transfer; byte++) { - *buf++ = val & 0xFF; - val >>= 8; - } - buf_remaining -= bytes_to_transfer; - rx_fifo_avail--; - } - BUG_ON(rx_fifo_avail > 0 && buf_remaining > 0); - i2c_dev->msg_buf_remaining = buf_remaining; - i2c_dev->msg_buf = buf; - return 0; -} - -static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) -{ - u32 val; - int tx_fifo_avail; - int word; - u8 *buf = i2c_dev->msg_buf; - size_t buf_remaining = i2c_dev->msg_buf_remaining; - int words_to_transfer; - - val = i2c_readl(i2c_dev, I2C_FIFO_STATUS); - tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >> - I2C_FIFO_STATUS_TX_SHIFT; - - words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD; - if (words_to_transfer > tx_fifo_avail) - words_to_transfer = tx_fifo_avail; - - for (word = 0; word < words_to_transfer; word++) { - val = get_unaligned_le32(buf); - i2c_writel(i2c_dev, val, I2C_TX_FIFO); - buf += BYTES_PER_FIFO_WORD; - buf_remaining -= BYTES_PER_FIFO_WORD; - tx_fifo_avail--; - } - - if (tx_fifo_avail > 0 && buf_remaining > 0) { - int bytes_to_transfer = buf_remaining; - int byte; - BUG_ON(bytes_to_transfer > 3); - val = 0; - for (byte = 0; byte < bytes_to_transfer; byte++) - val |= (*buf++) << (byte * 8); - i2c_writel(i2c_dev, val, I2C_TX_FIFO); - buf_remaining -= bytes_to_transfer; - tx_fifo_avail--; - } - BUG_ON(tx_fifo_avail > 0 && buf_remaining > 0); - i2c_dev->msg_buf_remaining = buf_remaining; - i2c_dev->msg_buf = buf; - return 0; -} - -/* One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller) - * block. This block is identical to the rest of the I2C blocks, except that - * it only supports master mode, it has registers moved around, and it needs - * some extra init to get it into I2C mode. The register moves are handled - * by i2c_readl and i2c_writel - */ -static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev) -{ - u32 val = 0; - val = dvc_readl(i2c_dev, DVC_CTRL_REG3); - val |= DVC_CTRL_REG3_SW_PROG; - val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN; - dvc_writel(i2c_dev, val, DVC_CTRL_REG3); - - val = dvc_readl(i2c_dev, DVC_CTRL_REG1); - val |= DVC_CTRL_REG1_INTR_EN; - dvc_writel(i2c_dev, val, DVC_CTRL_REG1); -} - -static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) -{ - u32 val; - int err = 0; - - clk_enable(i2c_dev->clk); - - tegra_periph_reset_assert(i2c_dev->clk); - udelay(2); - tegra_periph_reset_deassert(i2c_dev->clk); - - if (i2c_dev->is_dvc) - tegra_dvc_init(i2c_dev); - - val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); - i2c_writel(i2c_dev, val, I2C_CNFG); - i2c_writel(i2c_dev, 0, I2C_INT_MASK); - tegra_i2c_set_clk(i2c_dev, i2c_dev->last_bus_clk); - - val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT | - 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT; - i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL); - - if (tegra_i2c_flush_fifos(i2c_dev)) - err = -ETIMEDOUT; - - clk_disable(i2c_dev->clk); - -#ifdef DEBUG_TEGRA_I2C_TEMP - atomic_set(&i2c_dev->incmplt_irq_count, 0); -#endif - - if (i2c_dev->irq_disabled) { - i2c_dev->irq_disabled = 0; - enable_irq(i2c_dev->irq); - } - - return 0; -} - -static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) -{ - u32 status; - const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; - struct tegra_i2c_dev *i2c_dev = dev_id; - - status = i2c_readl(i2c_dev, I2C_INT_STATUS); - -#ifdef DEBUG_TEGRA_I2C_TEMP - if (atomic_inc_return(&i2c_dev->incmplt_irq_count) == 1000) { - dev_err(i2c_dev->dev, "suspected irq storm\n"); - pr_err("ist=%x im=%x pxst=%x st=%x cfg=%x fst=%x fc=%x\n", - i2c_readl(i2c_dev, I2C_INT_STATUS), - i2c_readl(i2c_dev, I2C_INT_MASK), - i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), - i2c_readl(i2c_dev, I2C_STATUS), - i2c_readl(i2c_dev, I2C_CNFG), - i2c_readl(i2c_dev, I2C_FIFO_STATUS), - i2c_readl(i2c_dev, I2C_FIFO_CONTROL)); - pr_err("mbrm=%d mcmp=%d merr=%d\n", - i2c_dev->msg_buf_remaining, - i2c_dev->msg_transfer_complete, - i2c_dev->msg_err); - - i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT << 1; - - if (! i2c_dev->irq_disabled) { - disable_irq_nosync(i2c_dev->irq); - i2c_dev->irq_disabled = 1; - } - - complete(&i2c_dev->msg_complete); - goto err; - } -#endif - - if (status == 0) { - dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n", - i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), - i2c_readl(i2c_dev, I2C_STATUS), - i2c_readl(i2c_dev, I2C_CNFG)); - i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT; - - if (! i2c_dev->irq_disabled) { - disable_irq_nosync(i2c_dev->irq); - i2c_dev->irq_disabled = 1; - } - - complete(&i2c_dev->msg_complete); - goto err; - } - - if (unlikely(status & status_err)) { - if (status & I2C_INT_NO_ACK) - i2c_dev->msg_err |= I2C_ERR_NO_ACK; - if (status & I2C_INT_ARBITRATION_LOST) - i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST; - complete(&i2c_dev->msg_complete); - goto err; - } - - if (i2c_dev->msg_read && (status & I2C_INT_RX_FIFO_DATA_REQ)) { - if (i2c_dev->msg_buf_remaining) - tegra_i2c_empty_rx_fifo(i2c_dev); - else - BUG(); - } - - if (!i2c_dev->msg_read && (status & I2C_INT_TX_FIFO_DATA_REQ)) { - if (i2c_dev->msg_buf_remaining) - tegra_i2c_fill_tx_fifo(i2c_dev); - else - tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ); - } - - if (status & I2C_INT_PACKET_XFER_COMPLETE) - i2c_dev->msg_transfer_complete = 1; - - if (i2c_dev->msg_transfer_complete && !i2c_dev->msg_buf_remaining) - complete(&i2c_dev->msg_complete); - i2c_writel(i2c_dev, status, I2C_INT_STATUS); - if (i2c_dev->is_dvc) - dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); - return IRQ_HANDLED; -err: - /* An error occured, mask all interrupts */ - tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST | - I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ | - I2C_INT_RX_FIFO_DATA_REQ); - i2c_writel(i2c_dev, status, I2C_INT_STATUS); - if (i2c_dev->is_dvc) - dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); - return IRQ_NONE; -} - -static int tegra_i2c_xfer_msg(struct tegra_i2c_bus *i2c_bus, - struct i2c_msg *msg, int stop) -{ - struct tegra_i2c_dev *i2c_dev = i2c_bus->dev; - u32 packet_header; - u32 int_mask; - int ret; - - tegra_i2c_flush_fifos(i2c_dev); - i2c_writel(i2c_dev, 0xFF, I2C_INT_STATUS); - - if (msg->len == 0) - return -EINVAL; - - i2c_dev->msg_buf = msg->buf; - i2c_dev->msg_buf_remaining = msg->len; - i2c_dev->msg_err = I2C_ERR_NONE; - i2c_dev->msg_transfer_complete = 0; - i2c_dev->msg_read = (msg->flags & I2C_M_RD); - INIT_COMPLETION(i2c_dev->msg_complete); - - packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) | - PACKET_HEADER0_PROTOCOL_I2C | - (i2c_dev->cont_id << PACKET_HEADER0_CONT_ID_SHIFT) | - (1 << PACKET_HEADER0_PACKET_ID_SHIFT); - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); - - packet_header = msg->len - 1; - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); - - packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT; - packet_header |= I2C_HEADER_IE_ENABLE; - if (!stop) - packet_header |= I2C_HEADER_REPEAT_START; - if (msg->flags & I2C_M_TEN) - packet_header |= I2C_HEADER_10BIT_ADDR; - if (msg->flags & I2C_M_IGNORE_NAK) - packet_header |= I2C_HEADER_CONT_ON_NAK; - if (msg->flags & I2C_M_RD) - packet_header |= I2C_HEADER_READ; - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); - - if (!(msg->flags & I2C_M_RD)) - tegra_i2c_fill_tx_fifo(i2c_dev); - - int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; - if (msg->flags & I2C_M_RD) - int_mask |= I2C_INT_RX_FIFO_DATA_REQ; - else if (i2c_dev->msg_buf_remaining) - int_mask |= I2C_INT_TX_FIFO_DATA_REQ; - tegra_i2c_unmask_irq(i2c_dev, int_mask); - pr_debug("unmasked irq: %02x\n", i2c_readl(i2c_dev, I2C_INT_MASK)); - - ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT); - tegra_i2c_mask_irq(i2c_dev, int_mask); - -#ifdef DEBUG_TEGRA_I2C_TEMP - atomic_set(&i2c_dev->incmplt_irq_count, 0); -#endif - - if (WARN_ON(ret == 0)) { - dev_err(i2c_dev->dev, "i2c transfer timed out\n"); -#ifdef DEBUG_TEGRA_I2C_TEMP - pr_err("ist=%x im=%x pxst=%x st=%x cfg=%x fst=%x fc=%x\n", - i2c_readl(i2c_dev, I2C_INT_STATUS), - i2c_readl(i2c_dev, I2C_INT_MASK), - i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), - i2c_readl(i2c_dev, I2C_STATUS), - i2c_readl(i2c_dev, I2C_CNFG), - i2c_readl(i2c_dev, I2C_FIFO_STATUS), - i2c_readl(i2c_dev, I2C_FIFO_CONTROL)); - pr_err("mbrm=%d mcmp=%d merr=%d\n", - i2c_dev->msg_buf_remaining, - i2c_dev->msg_transfer_complete, - i2c_dev->msg_err); - pr_err("madr=%x mlen=%d mfl=%x stop=%d\n", msg->addr, msg->len, - msg->flags, stop); -#endif - tegra_i2c_init(i2c_dev); - return -ETIMEDOUT; - } - - pr_debug("transfer complete: %d %d %d\n", ret, completion_done(&i2c_dev->msg_complete), i2c_dev->msg_err); - - if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) - return 0; - - tegra_i2c_init(i2c_dev); - if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { - if (msg->flags & I2C_M_IGNORE_NAK) - return 0; - return -EREMOTEIO; - } - - return -EIO; -} - -static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], - int num) -{ - struct tegra_i2c_bus *i2c_bus = i2c_get_adapdata(adap); - struct tegra_i2c_dev *i2c_dev = i2c_bus->dev; - int i; - int ret = 0; - - if (i2c_dev->is_suspended) - return -EBUSY; - - rt_mutex_lock(&i2c_dev->dev_lock); - - if (i2c_dev->last_mux != i2c_bus->mux) { - tegra_pinmux_set_safe_pinmux_table(i2c_dev->last_mux, - i2c_dev->last_mux_len); - tegra_pinmux_config_pinmux_table(i2c_bus->mux, - i2c_bus->mux_len); - i2c_dev->last_mux = i2c_bus->mux; - i2c_dev->last_mux_len = i2c_bus->mux_len; - } - - if (i2c_dev->last_bus_clk != i2c_bus->bus_clk_rate) { - tegra_i2c_set_clk(i2c_dev, i2c_bus->bus_clk_rate); - i2c_dev->last_bus_clk = i2c_bus->bus_clk_rate; - } - - clk_enable(i2c_dev->clk); - for (i = 0; i < num; i++) { - int stop = (i == (num - 1)) ? 1 : 0; - ret = tegra_i2c_xfer_msg(i2c_bus, &msgs[i], stop); - if (ret) - goto out; - } - ret = i; - -out: - clk_disable(i2c_dev->clk); - - rt_mutex_unlock(&i2c_dev->dev_lock); - - return ret; -} - -static u32 tegra_i2c_func(struct i2c_adapter *adap) -{ - /* FIXME: For now keep it simple and don't support protocol mangling - features */ - return I2C_FUNC_I2C; -} - -static const struct i2c_algorithm tegra_i2c_algo = { - .master_xfer = tegra_i2c_xfer, - .functionality = tegra_i2c_func, -}; - -static int tegra_i2c_probe(struct platform_device *pdev) -{ - struct tegra_i2c_dev *i2c_dev; - struct tegra_i2c_platform_data *plat = pdev->dev.platform_data; - struct resource *res; - struct resource *iomem; - struct clk *clk; - struct clk *i2c_clk; - void *base; - int irq; - int nbus; - int i = 0; - int ret = 0; - - if (!plat) { - dev_err(&pdev->dev, "no platform data?\n"); - return -ENODEV; - } - - if (plat->bus_count <= 0 || plat->adapter_nr < 0) { - dev_err(&pdev->dev, "invalid platform data?\n"); - return -ENODEV; - } - - WARN_ON(plat->bus_count > TEGRA_I2C_MAX_BUS); - nbus = min(TEGRA_I2C_MAX_BUS, plat->bus_count); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mem resource?\n"); - return -ENODEV; - } - iomem = request_mem_region(res->start, resource_size(res), pdev->name); - if (!iomem) { - dev_err(&pdev->dev, "I2C region already claimed\n"); - return -EBUSY; - } - - base = ioremap(iomem->start, resource_size(iomem)); - if (!base) { - dev_err(&pdev->dev, "Can't ioremap I2C region\n"); - return -ENOMEM; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, "no irq resource?\n"); - ret = -ENODEV; - goto err_iounmap; - } - irq = res->start; - - clk = clk_get(&pdev->dev, NULL); - if (!clk) { - ret = -ENOMEM; - goto err_release_region; - } - - i2c_clk = clk_get(&pdev->dev, "i2c"); - if (!i2c_clk) { - ret = -ENOMEM; - goto err_clk_put; - } - - i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev) + - (nbus-1) * sizeof(struct tegra_i2c_bus), GFP_KERNEL); - if (!i2c_dev) { - ret = -ENOMEM; - goto err_i2c_clk_put; - } - - i2c_dev->base = base; - i2c_dev->clk = clk; - i2c_dev->i2c_clk = i2c_clk; - i2c_dev->iomem = iomem; - i2c_dev->irq = irq; - i2c_dev->cont_id = pdev->id; - i2c_dev->dev = &pdev->dev; - i2c_dev->last_bus_clk = plat->bus_clk_rate[0] ?: 100000; - rt_mutex_init(&i2c_dev->dev_lock); - - i2c_dev->is_dvc = plat->is_dvc; - init_completion(&i2c_dev->msg_complete); - - platform_set_drvdata(pdev, i2c_dev); - - ret = tegra_i2c_init(i2c_dev); - if (ret) - goto err_free; - - ret = request_irq(i2c_dev->irq, tegra_i2c_isr, IRQF_DISABLED, - pdev->name, i2c_dev); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); - goto err_free; - } - - clk_enable(i2c_dev->i2c_clk); - - for (i = 0; i < nbus; i++) { - struct tegra_i2c_bus *i2c_bus = &i2c_dev->busses[i]; - - i2c_bus->dev = i2c_dev; - i2c_bus->mux = plat->bus_mux[i]; - i2c_bus->mux_len = plat->bus_mux_len[i]; - i2c_bus->bus_clk_rate = plat->bus_clk_rate[i] ?: 100000; - - i2c_bus->adapter.algo = &tegra_i2c_algo; - i2c_set_adapdata(&i2c_bus->adapter, i2c_bus); - i2c_bus->adapter.owner = THIS_MODULE; - i2c_bus->adapter.class = I2C_CLASS_HWMON; - strlcpy(i2c_bus->adapter.name, "Tegra I2C adapter", - sizeof(i2c_bus->adapter.name)); - i2c_bus->adapter.dev.parent = &pdev->dev; - i2c_bus->adapter.nr = plat->adapter_nr + i; - ret = i2c_add_numbered_adapter(&i2c_bus->adapter); - if (ret) { - dev_err(&pdev->dev, "Failed to add I2C adapter\n"); - goto err_del_bus; - } - i2c_dev->bus_count++; - } - - return 0; - -err_del_bus: - while (i2c_dev->bus_count--) - i2c_del_adapter(&i2c_dev->busses[i2c_dev->bus_count].adapter); - free_irq(i2c_dev->irq, i2c_dev); -err_free: - kfree(i2c_dev); -err_i2c_clk_put: - clk_put(i2c_clk); -err_clk_put: - clk_put(clk); -err_release_region: - release_mem_region(iomem->start, resource_size(iomem)); -err_iounmap: - iounmap(base); - return ret; -} - -static int tegra_i2c_remove(struct platform_device *pdev) -{ - struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - while (i2c_dev->bus_count--) - i2c_del_adapter(&i2c_dev->busses[i2c_dev->bus_count].adapter); - - free_irq(i2c_dev->irq, i2c_dev); - clk_put(i2c_dev->i2c_clk); - clk_put(i2c_dev->clk); - release_mem_region(i2c_dev->iomem->start, - resource_size(i2c_dev->iomem)); - iounmap(i2c_dev->base); - kfree(i2c_dev); - return 0; -} - -#ifdef CONFIG_PM -static int tegra_i2c_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - - rt_mutex_lock(&i2c_dev->dev_lock); - i2c_dev->is_suspended = true; - rt_mutex_unlock(&i2c_dev->dev_lock); - - return 0; -} - -static int tegra_i2c_resume(struct platform_device *pdev) -{ - struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - int ret; - - rt_mutex_lock(&i2c_dev->dev_lock); - - ret = tegra_i2c_init(i2c_dev); - - if (ret) { - rt_mutex_unlock(&i2c_dev->dev_lock); - return ret; - } - - i2c_dev->is_suspended = false; - - rt_mutex_unlock(&i2c_dev->dev_lock); - - return 0; -} -#endif - -static struct platform_driver tegra_i2c_driver = { - .probe = tegra_i2c_probe, - .remove = tegra_i2c_remove, -#ifdef CONFIG_PM - .suspend = tegra_i2c_suspend, - .resume = tegra_i2c_resume, -#endif - .driver = { - .name = "tegra-i2c", - .owner = THIS_MODULE, - }, -}; - -static int __init tegra_i2c_init_driver(void) -{ - return platform_driver_register(&tegra_i2c_driver); -} -/* - * Some drivers (hdmi) depend on i2c busses already being present, - * so init at subsys time. - */ -subsys_initcall(tegra_i2c_init_driver); - -static void __exit tegra_i2c_exit_driver(void) -{ - platform_driver_unregister(&tegra_i2c_driver); -} -module_exit(tegra_i2c_exit_driver); diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index cf88588a8e80..c37ef64d1465 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -276,7 +276,7 @@ static int intel_idle_probe(void) case 0x1C: /* 28 - Atom Processor */ case 0x26: /* 38 - Lincroft Atom Processor */ - lapic_timer_reliable_states = (1 << 1); /* C1 */ + lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ cpuidle_state_table = atom_cstates; break; #ifdef FUTURE_USE diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index abb87140f29f..6fcfbeb24a23 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -891,81 +891,68 @@ 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; - u8 __user *header_ptr; - u8 __user *data_ptr; + struct ib_uverbs_poll_cq_resp *resp; struct ib_cq *cq; - struct ib_wc wc; - int ret; + struct ib_wc *wc; + int ret = 0; + int i; + int rsize; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); - if (!cq) - return -EINVAL; + wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); + if (!wc) + return -ENOMEM; - /* 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; + rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); + resp = kmalloc(rsize, GFP_KERNEL); + if (!resp) { + ret = -ENOMEM; + goto out_wc; + } - 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; + cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); + if (!cq) { + ret = -EINVAL; + goto out; + } - ret = copy_wc_to_user(data_ptr, &wc); - if (ret) - goto out_put; + resp->count = ib_poll_cq(cq, cmd.ne, wc); + + put_cq_read(cq); - data_ptr += sizeof(struct ib_uverbs_wc); - ++resp.count; + 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; } - if (copy_to_user(header_ptr, &resp, sizeof resp)) { + if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) ret = -EFAULT; - goto out_put; - } - ret = in_len; +out: + kfree(resp); -out_put: - put_cq_read(cq); - return ret; +out_wc: + kfree(wc); + return ret ? ret : in_len; } ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index ba3c4ddc35b4..1c7495c0786d 100755 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -161,15 +161,6 @@ config INPUT_APMPOWER To compile this driver as a module, choose M here: the module will be called apm-power. -config INPUT_KEYRESET - tristate "Reset key" - depends on INPUT - ---help--- - Say Y here if you want to reboot when some keys are pressed; - - To compile this driver as a module, choose M here: the - module will be called keyreset. - config XEN_KBDDEV_FRONTEND tristate "Xen virtual keyboard and mouse support" depends on XEN_FBDEV_FRONTEND diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 3c7125758b7f..7ad212d31f99 100755 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -24,6 +24,5 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o -obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o obj-$(CONFIG_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 43e94e5188dd..9ddafc30f432 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "input-compat.h" struct evdev { @@ -41,8 +40,6 @@ struct evdev_client { int head; int tail; spinlock_t buffer_lock; /* protects access to buffer, head and tail */ - struct wake_lock wake_lock; - char name[28]; struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; @@ -62,7 +59,6 @@ static void evdev_pass_event(struct evdev_client *client, * "empty" by having client->head == client->tail. */ spin_lock(&client->buffer_lock); - wake_lock_timeout(&client->wake_lock, 5 * HZ); do { client->buffer[client->head++] = *event; client->head &= client->bufsize - 1; @@ -82,11 +78,8 @@ static void evdev_event(struct input_handle *handle, struct evdev *evdev = handle->private; struct evdev_client *client; struct input_event event; - struct timespec ts; - ktime_get_ts(&ts); - event.time.tv_sec = ts.tv_sec; - event.time.tv_usec = ts.tv_nsec / NSEC_PER_USEC; + do_gettimeofday(&event.time); event.type = type; event.code = code; event.value = value; @@ -247,7 +240,6 @@ static int evdev_release(struct inode *inode, struct file *file) mutex_unlock(&evdev->mutex); evdev_detach_client(evdev, client); - wake_lock_destroy(&client->wake_lock); kfree(client); evdev_close_device(evdev); @@ -299,9 +291,6 @@ static int evdev_open(struct inode *inode, struct file *file) client->bufsize = bufsize; spin_lock_init(&client->buffer_lock); - snprintf(client->name, sizeof(client->name), "%s-%d", - dev_name(&evdev->dev), task_tgid_vnr(current)); - wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name); client->evdev = evdev; evdev_attach_client(evdev, client); @@ -316,7 +305,6 @@ static int evdev_open(struct inode *inode, struct file *file) err_free_client: evdev_detach_client(evdev, client); - wake_lock_destroy(&client->wake_lock); kfree(client); err_put_evdev: put_device(&evdev->dev); @@ -368,8 +356,6 @@ static int evdev_fetch_next_event(struct evdev_client *client, if (have_event) { *event = client->buffer[client->tail++]; client->tail &= client->bufsize - 1; - if (client->head == client->tail) - wake_unlock(&client->wake_lock); } spin_unlock_irq(&client->buffer_lock); diff --git a/drivers/input/input.c b/drivers/input/input.c index 5dc12e173ad3..ab6982056518 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1700,27 +1700,6 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int } EXPORT_SYMBOL(input_set_capability); -static void input_set_default_events_per_packet(struct input_dev *dev) -{ - int slots; - - if (dev->hint_events_per_packet) - return; - - if (dev->mtsize) - slots = dev->mtsize; - else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) - slots = min(20, dev->absinfo[ABS_MT_TRACKING_ID].maximum - - dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1); - else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) - slots = 2; - else - slots = 0; - - if (slots) - input_set_events_per_packet(dev, slots * 10); -} - #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ do { \ if (!test_bit(EV_##type, dev->evbit)) \ @@ -1759,9 +1738,6 @@ int input_register_device(struct input_dev *dev) const char *path; int error; - /* Use a larger default input buffer for MT devices */ - input_set_default_events_per_packet(dev); - /* Every input device generates EV_SYN/SYN_REPORT events. */ __set_bit(EV_SYN, dev->evbit); diff --git a/drivers/input/keyreset.c b/drivers/input/keyreset.c deleted file mode 100644 index 36208fe0baae..000000000000 --- a/drivers/input/keyreset.c +++ /dev/null @@ -1,239 +0,0 @@ -/* drivers/input/keyreset.c - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -struct keyreset_state { - struct input_handler input_handler; - unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; - unsigned long upbit[BITS_TO_LONGS(KEY_CNT)]; - unsigned long key[BITS_TO_LONGS(KEY_CNT)]; - spinlock_t lock; - int key_down_target; - int key_down; - int key_up; - int restart_disabled; - int (*reset_fn)(void); -}; - -int restart_requested; -static void deferred_restart(struct work_struct *dummy) -{ - restart_requested = 2; - sys_sync(); - restart_requested = 3; - kernel_restart(NULL); -} -static DECLARE_WORK(restart_work, deferred_restart); - -static void keyreset_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - unsigned long flags; - struct keyreset_state *state = handle->private; - - if (type != EV_KEY) - return; - - if (code >= KEY_MAX) - return; - - if (!test_bit(code, state->keybit)) - return; - - spin_lock_irqsave(&state->lock, flags); - if (!test_bit(code, state->key) == !value) - goto done; - __change_bit(code, state->key); - if (test_bit(code, state->upbit)) { - if (value) { - state->restart_disabled = 1; - state->key_up++; - } else - state->key_up--; - } else { - if (value) - state->key_down++; - else - state->key_down--; - } - if (state->key_down == 0 && state->key_up == 0) - state->restart_disabled = 0; - - pr_debug("reset key changed %d %d new state %d-%d-%d\n", code, value, - state->key_down, state->key_up, state->restart_disabled); - - if (value && !state->restart_disabled && - state->key_down == state->key_down_target) { - state->restart_disabled = 1; - if (restart_requested) - panic("keyboard reset failed, %d", restart_requested); - if (state->reset_fn) { - restart_requested = state->reset_fn(); - } else { - pr_info("keyboard reset\n"); - schedule_work(&restart_work); - restart_requested = 1; - } - } -done: - spin_unlock_irqrestore(&state->lock, flags); -} - -static int keyreset_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - int i; - int ret; - struct input_handle *handle; - struct keyreset_state *state = - container_of(handler, struct keyreset_state, input_handler); - - for (i = 0; i < KEY_MAX; i++) { - if (test_bit(i, state->keybit) && test_bit(i, dev->keybit)) - break; - } - if (i == KEY_MAX) - return -ENODEV; - - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "keyreset"; - handle->private = state; - - ret = input_register_handle(handle); - if (ret) - goto err_input_register_handle; - - ret = input_open_device(handle); - if (ret) - goto err_input_open_device; - - pr_info("using input dev %s for key reset\n", dev->name); - - return 0; - -err_input_open_device: - input_unregister_handle(handle); -err_input_register_handle: - kfree(handle); - return ret; -} - -static void keyreset_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id keyreset_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) }, - }, - { }, -}; -MODULE_DEVICE_TABLE(input, keyreset_ids); - -static int keyreset_probe(struct platform_device *pdev) -{ - int ret; - int key, *keyp; - struct keyreset_state *state; - struct keyreset_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) - return -EINVAL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - spin_lock_init(&state->lock); - keyp = pdata->keys_down; - while ((key = *keyp++)) { - if (key >= KEY_MAX) - continue; - state->key_down_target++; - __set_bit(key, state->keybit); - } - if (pdata->keys_up) { - keyp = pdata->keys_up; - while ((key = *keyp++)) { - if (key >= KEY_MAX) - continue; - __set_bit(key, state->keybit); - __set_bit(key, state->upbit); - } - } - - if (pdata->reset_fn) - state->reset_fn = pdata->reset_fn; - - state->input_handler.event = keyreset_event; - state->input_handler.connect = keyreset_connect; - state->input_handler.disconnect = keyreset_disconnect; - state->input_handler.name = KEYRESET_NAME; - state->input_handler.id_table = keyreset_ids; - ret = input_register_handler(&state->input_handler); - if (ret) { - kfree(state); - return ret; - } - platform_set_drvdata(pdev, state); - return 0; -} - -int keyreset_remove(struct platform_device *pdev) -{ - struct keyreset_state *state = platform_get_drvdata(pdev); - input_unregister_handler(&state->input_handler); - kfree(state); - return 0; -} - - -struct platform_driver keyreset_driver = { - .driver.name = KEYRESET_NAME, - .probe = keyreset_probe, - .remove = keyreset_remove, -}; - -static int __init keyreset_init(void) -{ - return platform_driver_register(&keyreset_driver); -} - -static void __exit keyreset_exit(void) -{ - return platform_driver_unregister(&keyreset_driver); -} - -module_init(keyreset_init); -module_exit(keyreset_exit); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 478be5fc7f67..9ab32b891205 100755 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -189,17 +189,6 @@ config INPUT_ATI_REMOTE2 To compile this driver as a module, choose M here: the module will be called ati_remote2. -config INPUT_KEYCHORD - tristate "Key chord input driver support" - help - Say Y here if you want to enable the key chord driver - accessible at /dev/keychord. This driver can be used - for receiving notifications when client specified key - combinations are pressed. - - To compile this driver as a module, choose M here: the - module will be called keychord. - config INPUT_KEYSPAN_REMOTE tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -329,11 +318,6 @@ config INPUT_WINBOND_CIR To compile this driver as a module, choose M here: the module will be called winbond_cir. -config INPUT_GPIO - tristate "GPIO driver support" - help - Say Y here if you want to support gpio based keys, wheels etc... - config HP_SDC_RTC tristate "HP SDC Real Time Clock" depends on (GSC || HP300) && SERIO diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index c3d85920d310..a60f517d2e08 100755 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -21,10 +21,8 @@ obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o obj-$(CONFIG_INPUT_CM109) += cm109.o obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o -obj-$(CONFIG_INPUT_GPIO) += gpio_event.o gpio_matrix.o gpio_input.o gpio_output.o gpio_axis.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o -obj-$(CONFIG_INPUT_KEYCHORD) += keychord.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o diff --git a/drivers/input/misc/gpio_axis.c b/drivers/input/misc/gpio_axis.c deleted file mode 100644 index 0acf4a576f53..000000000000 --- a/drivers/input/misc/gpio_axis.c +++ /dev/null @@ -1,192 +0,0 @@ -/* drivers/input/misc/gpio_axis.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 -#include -#include -#include -#include - -struct gpio_axis_state { - struct gpio_event_input_devs *input_devs; - struct gpio_event_axis_info *info; - uint32_t pos; -}; - -uint16_t gpio_axis_4bit_gray_map_table[] = { - [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */ - [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */ - [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */ - [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */ - [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */ - [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */ - [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */ - [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */ -}; -uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in) -{ - return gpio_axis_4bit_gray_map_table[in]; -} - -uint16_t gpio_axis_5bit_singletrack_map_table[] = { - [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */ - [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */ - [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */ - [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */ - [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */ - [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */ - [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */ - [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */ - [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */ - [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */ -}; -uint16_t gpio_axis_5bit_singletrack_map( - struct gpio_event_axis_info *info, uint16_t in) -{ - return gpio_axis_5bit_singletrack_map_table[in]; -} - -static void gpio_event_update_axis(struct gpio_axis_state *as, int report) -{ - struct gpio_event_axis_info *ai = as->info; - int i; - int change; - uint16_t state = 0; - uint16_t pos; - uint16_t old_pos = as->pos; - for (i = ai->count - 1; i >= 0; i--) - state = (state << 1) | gpio_get_value(ai->gpio[i]); - pos = ai->map(ai, state); - if (ai->flags & GPIOEAF_PRINT_RAW) - pr_info("axis %d-%d raw %x, pos %d -> %d\n", - ai->type, ai->code, state, old_pos, pos); - if (report && pos != old_pos) { - if (ai->type == EV_REL) { - change = (ai->decoded_size + pos - old_pos) % - ai->decoded_size; - if (change > ai->decoded_size / 2) - change -= ai->decoded_size; - if (change == ai->decoded_size / 2) { - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d unknown direction, " - "pos %d -> %d\n", ai->type, - ai->code, old_pos, pos); - change = 0; /* no closest direction */ - } - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d change %d\n", - ai->type, ai->code, change); - input_report_rel(as->input_devs->dev[ai->dev], - ai->code, change); - } else { - if (ai->flags & GPIOEAF_PRINT_EVENT) - pr_info("axis %d-%d now %d\n", - ai->type, ai->code, pos); - input_event(as->input_devs->dev[ai->dev], - ai->type, ai->code, pos); - } - input_sync(as->input_devs->dev[ai->dev]); - } - as->pos = pos; -} - -static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id) -{ - struct gpio_axis_state *as = dev_id; - gpio_event_update_axis(as, 1); - return IRQ_HANDLED; -} - -int gpio_event_axis_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int ret; - int i; - int irq; - struct gpio_event_axis_info *ai; - struct gpio_axis_state *as; - - ai = container_of(info, struct gpio_event_axis_info, info); - if (func == GPIO_EVENT_FUNC_SUSPEND) { - for (i = 0; i < ai->count; i++) - disable_irq(gpio_to_irq(ai->gpio[i])); - return 0; - } - if (func == GPIO_EVENT_FUNC_RESUME) { - for (i = 0; i < ai->count; i++) - enable_irq(gpio_to_irq(ai->gpio[i])); - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - *data = as = kmalloc(sizeof(*as), GFP_KERNEL); - if (as == NULL) { - ret = -ENOMEM; - goto err_alloc_axis_state_failed; - } - as->input_devs = input_devs; - as->info = ai; - if (ai->dev >= input_devs->count) { - pr_err("gpio_event_axis: bad device index %d >= %d " - "for %d:%d\n", ai->dev, input_devs->count, - ai->type, ai->code); - ret = -EINVAL; - goto err_bad_device_index; - } - - input_set_capability(input_devs->dev[ai->dev], - ai->type, ai->code); - if (ai->type == EV_ABS) { - input_set_abs_params(input_devs->dev[ai->dev], ai->code, - 0, ai->decoded_size - 1, 0, 0); - } - for (i = 0; i < ai->count; i++) { - ret = gpio_request(ai->gpio[i], "gpio_event_axis"); - if (ret < 0) - goto err_request_gpio_failed; - ret = gpio_direction_input(ai->gpio[i]); - if (ret < 0) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(ai->gpio[i]); - if (ret < 0) - goto err_get_irq_num_failed; - ret = request_irq(irq, gpio_axis_irq_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, - "gpio_event_axis", as); - if (ret < 0) - goto err_request_irq_failed; - } - gpio_event_update_axis(as, 0); - return 0; - } - - ret = 0; - as = *data; - for (i = ai->count - 1; i >= 0; i--) { - free_irq(gpio_to_irq(ai->gpio[i]), as); -err_request_irq_failed: -err_get_irq_num_failed: -err_gpio_direction_input_failed: - gpio_free(ai->gpio[i]); -err_request_gpio_failed: - ; - } -err_bad_device_index: - kfree(as); - *data = NULL; -err_alloc_axis_state_failed: - return ret; -} diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c deleted file mode 100644 index a98be67d1ab0..000000000000 --- a/drivers/input/misc/gpio_event.c +++ /dev/null @@ -1,260 +0,0 @@ -/* drivers/input/misc/gpio_event.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 -#include -#include -#include -#include -#include -#include - -struct gpio_event { - struct gpio_event_input_devs *input_devs; - const struct gpio_event_platform_data *info; - struct early_suspend early_suspend; - void *state[0]; -}; - -static int gpio_input_event( - struct input_dev *dev, unsigned int type, unsigned int code, int value) -{ - int i; - int devnr; - int ret = 0; - int tmp_ret; - struct gpio_event_info **ii; - struct gpio_event *ip = input_get_drvdata(dev); - - for (devnr = 0; devnr < ip->input_devs->count; devnr++) - if (ip->input_devs->dev[devnr] == dev) - break; - if (devnr == ip->input_devs->count) { - pr_err("gpio_input_event: unknown device %p\n", dev); - return -EIO; - } - - for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) { - if ((*ii)->event) { - tmp_ret = (*ii)->event(ip->input_devs, *ii, - &ip->state[i], - devnr, type, code, value); - if (tmp_ret) - ret = tmp_ret; - } - } - return ret; -} - -static int gpio_event_call_all_func(struct gpio_event *ip, int func) -{ - int i; - int ret; - struct gpio_event_info **ii; - - if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) { - ii = ip->info->info; - for (i = 0; i < ip->info->info_count; i++, ii++) { - if ((*ii)->func == NULL) { - ret = -ENODEV; - pr_err("gpio_event_probe: Incomplete pdata, " - "no function\n"); - goto err_no_func; - } - if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend) - continue; - ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i], - func); - if (ret) { - pr_err("gpio_event_probe: function failed\n"); - goto err_func_failed; - } - } - return 0; - } - - ret = 0; - i = ip->info->info_count; - ii = ip->info->info + i; - while (i > 0) { - i--; - ii--; - if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend) - continue; - (*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1); -err_func_failed: -err_no_func: - ; - } - return ret; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -void gpio_event_suspend(struct early_suspend *h) -{ - struct gpio_event *ip; - ip = container_of(h, struct gpio_event, early_suspend); - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND); - ip->info->power(ip->info, 0); -} - -void gpio_event_resume(struct early_suspend *h) -{ - struct gpio_event *ip; - ip = container_of(h, struct gpio_event, early_suspend); - ip->info->power(ip->info, 1); - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME); -} -#endif - -static int gpio_event_probe(struct platform_device *pdev) -{ - int err; - struct gpio_event *ip; - struct gpio_event_platform_data *event_info; - int dev_count = 1; - int i; - int registered = 0; - - event_info = pdev->dev.platform_data; - if (event_info == NULL) { - pr_err("gpio_event_probe: No pdata\n"); - return -ENODEV; - } - if ((!event_info->name && !event_info->names[0]) || - !event_info->info || !event_info->info_count) { - pr_err("gpio_event_probe: Incomplete pdata\n"); - return -ENODEV; - } - if (!event_info->name) - while (event_info->names[dev_count]) - dev_count++; - ip = kzalloc(sizeof(*ip) + - sizeof(ip->state[0]) * event_info->info_count + - sizeof(*ip->input_devs) + - sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL); - if (ip == NULL) { - err = -ENOMEM; - pr_err("gpio_event_probe: Failed to allocate private data\n"); - goto err_kp_alloc_failed; - } - ip->input_devs = (void*)&ip->state[event_info->info_count]; - platform_set_drvdata(pdev, ip); - - for (i = 0; i < dev_count; i++) { - struct input_dev *input_dev = input_allocate_device(); - if (input_dev == NULL) { - err = -ENOMEM; - pr_err("gpio_event_probe: " - "Failed to allocate input device\n"); - goto err_input_dev_alloc_failed; - } - input_set_drvdata(input_dev, ip); - input_dev->name = event_info->name ? - event_info->name : event_info->names[i]; - input_dev->event = gpio_input_event; - ip->input_devs->dev[i] = input_dev; - } - ip->input_devs->count = dev_count; - ip->info = event_info; - if (event_info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ip->early_suspend.suspend = gpio_event_suspend; - ip->early_suspend.resume = gpio_event_resume; - register_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 1); - } - - err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT); - if (err) - goto err_call_all_func_failed; - - for (i = 0; i < dev_count; i++) { - err = input_register_device(ip->input_devs->dev[i]); - if (err) { - pr_err("gpio_event_probe: Unable to register %s " - "input device\n", ip->input_devs->dev[i]->name); - goto err_input_register_device_failed; - } - registered++; - } - - return 0; - -err_input_register_device_failed: - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); -err_call_all_func_failed: - if (event_info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 0); - } - for (i = 0; i < registered; i++) - input_unregister_device(ip->input_devs->dev[i]); - for (i = dev_count - 1; i >= registered; i--) { - input_free_device(ip->input_devs->dev[i]); -err_input_dev_alloc_failed: - ; - } - kfree(ip); -err_kp_alloc_failed: - return err; -} - -static int gpio_event_remove(struct platform_device *pdev) -{ - struct gpio_event *ip = platform_get_drvdata(pdev); - int i; - - gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); - if (ip->info->power) { -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ip->early_suspend); -#endif - ip->info->power(ip->info, 0); - } - for (i = 0; i < ip->input_devs->count; i++) - input_unregister_device(ip->input_devs->dev[i]); - kfree(ip); - return 0; -} - -static struct platform_driver gpio_event_driver = { - .probe = gpio_event_probe, - .remove = gpio_event_remove, - .driver = { - .name = GPIO_EVENT_DEV_NAME, - }, -}; - -static int __devinit gpio_event_init(void) -{ - return platform_driver_register(&gpio_event_driver); -} - -static void __exit gpio_event_exit(void) -{ - platform_driver_unregister(&gpio_event_driver); -} - -module_init(gpio_event_init); -module_exit(gpio_event_exit); - -MODULE_DESCRIPTION("GPIO Event Driver"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c deleted file mode 100644 index 758df480600b..000000000000 --- a/drivers/input/misc/gpio_input.c +++ /dev/null @@ -1,353 +0,0 @@ -/* drivers/input/misc/gpio_input.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 -#include -#include -#include -#include -#include -#include -#include - -enum { - DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */ - DEBOUNCE_PRESSED = BIT(1), - DEBOUNCE_NOTPRESSED = BIT(2), - DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */ - DEBOUNCE_POLL = BIT(4), /* Stable polling state */ - - DEBOUNCE_UNKNOWN = - DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED, -}; - -struct gpio_key_state { - struct gpio_input_state *ds; - uint8_t debounce; -}; - -struct gpio_input_state { - struct gpio_event_input_devs *input_devs; - const struct gpio_event_input_info *info; - struct hrtimer timer; - int use_irq; - int debounce_count; - spinlock_t irq_lock; - struct wake_lock wake_lock; - struct gpio_key_state key_state[0]; -}; - -static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer) -{ - int i; - int pressed; - struct gpio_input_state *ds = - container_of(timer, struct gpio_input_state, timer); - unsigned gpio_flags = ds->info->flags; - unsigned npolarity; - int nkeys = ds->info->keymap_size; - const struct gpio_event_direct_entry *key_entry; - struct gpio_key_state *key_state; - unsigned long irqflags; - uint8_t debounce; - -#if 0 - key_entry = kp->keys_info->keymap; - key_state = kp->key_state; - for (i = 0; i < nkeys; i++, key_entry++, key_state++) - pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, - gpio_read_detect_status(key_entry->gpio)); -#endif - key_entry = ds->info->keymap; - key_state = ds->key_state; - spin_lock_irqsave(&ds->irq_lock, irqflags); - for (i = 0; i < nkeys; i++, key_entry++, key_state++) { - debounce = key_state->debounce; - if (debounce & DEBOUNCE_WAIT_IRQ) - continue; - if (key_state->debounce & DEBOUNCE_UNSTABLE) { - debounce = key_state->debounce = DEBOUNCE_UNKNOWN; - enable_irq(gpio_to_irq(key_entry->gpio)); - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) continue debounce\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - } - npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); - pressed = gpio_get_value(key_entry->gpio) ^ npolarity; - if (debounce & DEBOUNCE_POLL) { - if (pressed == !(debounce & DEBOUNCE_PRESSED)) { - ds->debounce_count++; - key_state->debounce = DEBOUNCE_UNKNOWN; - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-" - "%x, %d (%d) start debounce\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - } - continue; - } - if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) debounce pressed 1\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - key_state->debounce = DEBOUNCE_PRESSED; - continue; - } - if (!pressed && (debounce & DEBOUNCE_PRESSED)) { - if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_keys_scan_keys: key %x-%x, %d " - "(%d) debounce pressed 0\n", - ds->info->type, key_entry->code, - i, key_entry->gpio); - key_state->debounce = DEBOUNCE_NOTPRESSED; - continue; - } - /* key is stable */ - ds->debounce_count--; - if (ds->use_irq) - key_state->debounce |= DEBOUNCE_WAIT_IRQ; - else - key_state->debounce |= DEBOUNCE_POLL; - if (gpio_flags & GPIOEDF_PRINT_KEYS) - pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) " - "changed to %d\n", ds->info->type, - key_entry->code, i, key_entry->gpio, pressed); - input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, - key_entry->code, pressed); - } - -#if 0 - key_entry = kp->keys_info->keymap; - key_state = kp->key_state; - for (i = 0; i < nkeys; i++, key_entry++, key_state++) { - pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, - gpio_read_detect_status(key_entry->gpio)); - } -#endif - - if (ds->debounce_count) - hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL); - else if (!ds->use_irq) - hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL); - else - wake_unlock(&ds->wake_lock); - - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - - return HRTIMER_NORESTART; -} - -static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id) -{ - struct gpio_key_state *ks = dev_id; - struct gpio_input_state *ds = ks->ds; - int keymap_index = ks - ds->key_state; - const struct gpio_event_direct_entry *key_entry; - unsigned long irqflags; - int pressed; - - if (!ds->use_irq) - return IRQ_HANDLED; - - key_entry = &ds->info->keymap[keymap_index]; - - if (ds->info->debounce_time.tv64) { - spin_lock_irqsave(&ds->irq_lock, irqflags); - if (ks->debounce & DEBOUNCE_WAIT_IRQ) { - ks->debounce = DEBOUNCE_UNKNOWN; - if (ds->debounce_count++ == 0) { - wake_lock(&ds->wake_lock); - hrtimer_start( - &ds->timer, ds->info->debounce_time, - HRTIMER_MODE_REL); - } - if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE) - pr_info("gpio_event_input_irq_handler: " - "key %x-%x, %d (%d) start debounce\n", - ds->info->type, key_entry->code, - keymap_index, key_entry->gpio); - } else { - disable_irq_nosync(irq); - ks->debounce = DEBOUNCE_UNSTABLE; - } - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - } else { - pressed = gpio_get_value(key_entry->gpio) ^ - !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); - if (ds->info->flags & GPIOEDF_PRINT_KEYS) - pr_info("gpio_event_input_irq_handler: key %x-%x, %d " - "(%d) changed to %d\n", - ds->info->type, key_entry->code, keymap_index, - key_entry->gpio, pressed); - input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, - key_entry->code, pressed); - } - return IRQ_HANDLED; -} - -static int gpio_event_input_request_irqs(struct gpio_input_state *ds) -{ - int i; - int err; - unsigned int irq; - unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; - - for (i = 0; i < ds->info->keymap_size; i++) { - err = irq = gpio_to_irq(ds->info->keymap[i].gpio); - if (err < 0) - goto err_gpio_get_irq_num_failed; - err = request_irq(irq, gpio_event_input_irq_handler, - req_flags, "gpio_keys", &ds->key_state[i]); - if (err) { - pr_err("gpio_event_input_request_irqs: request_irq " - "failed for input %d, irq %d\n", - ds->info->keymap[i].gpio, irq); - goto err_request_irq_failed; - } - enable_irq_wake(irq); - } - return 0; - - for (i = ds->info->keymap_size - 1; i >= 0; i--) { - free_irq(gpio_to_irq(ds->info->keymap[i].gpio), - &ds->key_state[i]); -err_request_irq_failed: -err_gpio_get_irq_num_failed: - ; - } - return err; -} - -int gpio_event_input_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int ret; - int i; - unsigned long irqflags; - struct gpio_event_input_info *di; - struct gpio_input_state *ds = *data; - - di = container_of(info, struct gpio_event_input_info, info); - - if (func == GPIO_EVENT_FUNC_SUSPEND) { - if (ds->use_irq) - for (i = 0; i < di->keymap_size; i++) - disable_irq(gpio_to_irq(di->keymap[i].gpio)); - hrtimer_cancel(&ds->timer); - return 0; - } - if (func == GPIO_EVENT_FUNC_RESUME) { - spin_lock_irqsave(&ds->irq_lock, irqflags); - if (ds->use_irq) - for (i = 0; i < di->keymap_size; i++) - enable_irq(gpio_to_irq(di->keymap[i].gpio)); - hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - if (ktime_to_ns(di->poll_time) <= 0) - di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC); - - *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) * - di->keymap_size, GFP_KERNEL); - if (ds == NULL) { - ret = -ENOMEM; - pr_err("gpio_event_input_func: " - "Failed to allocate private data\n"); - goto err_ds_alloc_failed; - } - ds->debounce_count = di->keymap_size; - ds->input_devs = input_devs; - ds->info = di; - wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input"); - spin_lock_init(&ds->irq_lock); - - for (i = 0; i < di->keymap_size; i++) { - int dev = di->keymap[i].dev; - if (dev >= input_devs->count) { - pr_err("gpio_event_input_func: bad device " - "index %d >= %d for key code %d\n", - dev, input_devs->count, - di->keymap[i].code); - ret = -EINVAL; - goto err_bad_keymap; - } - input_set_capability(input_devs->dev[dev], di->type, - di->keymap[i].code); - ds->key_state[i].ds = ds; - ds->key_state[i].debounce = DEBOUNCE_UNKNOWN; - } - - for (i = 0; i < di->keymap_size; i++) { - ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in"); - if (ret) { - pr_err("gpio_event_input_func: gpio_request " - "failed for %d\n", di->keymap[i].gpio); - goto err_gpio_request_failed; - } - ret = gpio_direction_input(di->keymap[i].gpio); - if (ret) { - pr_err("gpio_event_input_func: " - "gpio_direction_input failed for %d\n", - di->keymap[i].gpio); - goto err_gpio_configure_failed; - } - } - - ret = gpio_event_input_request_irqs(ds); - - spin_lock_irqsave(&ds->irq_lock, irqflags); - ds->use_irq = ret == 0; - - pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s " - "mode\n", input_devs->dev[0]->name, - (input_devs->count > 1) ? "..." : "", - ret == 0 ? "interrupt" : "polling"); - - hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ds->timer.function = gpio_event_input_timer_func; - hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - return 0; - } - - ret = 0; - spin_lock_irqsave(&ds->irq_lock, irqflags); - hrtimer_cancel(&ds->timer); - if (ds->use_irq) { - for (i = di->keymap_size - 1; i >= 0; i--) { - free_irq(gpio_to_irq(di->keymap[i].gpio), - &ds->key_state[i]); - } - } - spin_unlock_irqrestore(&ds->irq_lock, irqflags); - - for (i = di->keymap_size - 1; i >= 0; i--) { -err_gpio_configure_failed: - gpio_free(di->keymap[i].gpio); -err_gpio_request_failed: - ; - } -err_bad_keymap: - wake_lock_destroy(&ds->wake_lock); - kfree(ds); -err_ds_alloc_failed: - return ret; -} diff --git a/drivers/input/misc/gpio_matrix.c b/drivers/input/misc/gpio_matrix.c deleted file mode 100644 index 227eb8fe3c09..000000000000 --- a/drivers/input/misc/gpio_matrix.c +++ /dev/null @@ -1,432 +0,0 @@ -/* drivers/input/misc/gpio_matrix.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 -#include -#include -#include -#include -#include -#include - -struct gpio_kp { - struct gpio_event_input_devs *input_devs; - struct gpio_event_matrix_info *keypad_info; - struct hrtimer timer; - struct wake_lock wake_lock; - int current_output; - unsigned int use_irq:1; - unsigned int key_state_changed:1; - unsigned int last_key_state_changed:1; - unsigned int some_keys_pressed:2; - unsigned int disabled_irq:1; - unsigned long keys_pressed[0]; -}; - -static void clear_phantom_key(struct gpio_kp *kp, int out, int in) -{ - struct gpio_event_matrix_info *mi = kp->keypad_info; - int key_index = out * mi->ninputs + in; - unsigned short keyentry = mi->keymap[key_index]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - - if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) { - if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) - pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " - "cleared\n", keycode, out, in, - mi->output_gpios[out], mi->input_gpios[in]); - __clear_bit(key_index, kp->keys_pressed); - } else { - if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) - pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " - "not cleared\n", keycode, out, in, - mi->output_gpios[out], mi->input_gpios[in]); - } -} - -static int restore_keys_for_input(struct gpio_kp *kp, int out, int in) -{ - int rv = 0; - int key_index; - - key_index = out * kp->keypad_info->ninputs + in; - while (out < kp->keypad_info->noutputs) { - if (test_bit(key_index, kp->keys_pressed)) { - rv = 1; - clear_phantom_key(kp, out, in); - } - key_index += kp->keypad_info->ninputs; - out++; - } - return rv; -} - -static void remove_phantom_keys(struct gpio_kp *kp) -{ - int out, in, inp; - int key_index; - - if (kp->some_keys_pressed < 3) - return; - - for (out = 0; out < kp->keypad_info->noutputs; out++) { - inp = -1; - key_index = out * kp->keypad_info->ninputs; - for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) { - if (test_bit(key_index, kp->keys_pressed)) { - if (inp == -1) { - inp = in; - continue; - } - if (inp >= 0) { - if (!restore_keys_for_input(kp, out + 1, - inp)) - break; - clear_phantom_key(kp, out, inp); - inp = -2; - } - restore_keys_for_input(kp, out, in); - } - } - } -} - -static void report_key(struct gpio_kp *kp, int key_index, int out, int in) -{ - struct gpio_event_matrix_info *mi = kp->keypad_info; - int pressed = test_bit(key_index, kp->keys_pressed); - unsigned short keyentry = mi->keymap[key_index]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - - if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) { - if (keycode == KEY_RESERVED) { - if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) - pr_info("gpiomatrix: unmapped key, %d-%d " - "(%d-%d) changed to %d\n", - out, in, mi->output_gpios[out], - mi->input_gpios[in], pressed); - } else { - if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS) - pr_info("gpiomatrix: key %x, %d-%d (%d-%d) " - "changed to %d\n", keycode, - out, in, mi->output_gpios[out], - mi->input_gpios[in], pressed); - input_report_key(kp->input_devs->dev[dev], keycode, pressed); - } - } -} - -static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer) -{ - int out, in; - int key_index; - int gpio; - struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer); - struct gpio_event_matrix_info *mi = kp->keypad_info; - unsigned gpio_keypad_flags = mi->flags; - unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH); - - out = kp->current_output; - if (out == mi->noutputs) { - out = 0; - kp->last_key_state_changed = kp->key_state_changed; - kp->key_state_changed = 0; - kp->some_keys_pressed = 0; - } else { - key_index = out * mi->ninputs; - for (in = 0; in < mi->ninputs; in++, key_index++) { - gpio = mi->input_gpios[in]; - if (gpio_get_value(gpio) ^ !polarity) { - if (kp->some_keys_pressed < 3) - kp->some_keys_pressed++; - kp->key_state_changed |= !__test_and_set_bit( - key_index, kp->keys_pressed); - } else - kp->key_state_changed |= __test_and_clear_bit( - key_index, kp->keys_pressed); - } - gpio = mi->output_gpios[out]; - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(gpio, !polarity); - else - gpio_direction_input(gpio); - out++; - } - kp->current_output = out; - if (out < mi->noutputs) { - gpio = mi->output_gpios[out]; - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(gpio, polarity); - else - gpio_direction_output(gpio, polarity); - hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) { - if (kp->key_state_changed) { - hrtimer_start(&kp->timer, mi->debounce_delay, - HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - kp->key_state_changed = kp->last_key_state_changed; - } - if (kp->key_state_changed) { - if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) - remove_phantom_keys(kp); - key_index = 0; - for (out = 0; out < mi->noutputs; out++) - for (in = 0; in < mi->ninputs; in++, key_index++) - report_key(kp, key_index, out, in); - } - if (!kp->use_irq || kp->some_keys_pressed) { - hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL); - return HRTIMER_NORESTART; - } - - /* No keys are pressed, reenable interrupt */ - for (out = 0; out < mi->noutputs; out++) { - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(mi->output_gpios[out], polarity); - else - gpio_direction_output(mi->output_gpios[out], polarity); - } - for (in = 0; in < mi->ninputs; in++) - enable_irq(gpio_to_irq(mi->input_gpios[in])); - wake_unlock(&kp->wake_lock); - return HRTIMER_NORESTART; -} - -static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id) -{ - int i; - struct gpio_kp *kp = dev_id; - struct gpio_event_matrix_info *mi = kp->keypad_info; - unsigned gpio_keypad_flags = mi->flags; - - if (!kp->use_irq) { - /* ignore interrupt while registering the handler */ - kp->disabled_irq = 1; - disable_irq_nosync(irq_in); - return IRQ_HANDLED; - } - - for (i = 0; i < mi->ninputs; i++) - disable_irq_nosync(gpio_to_irq(mi->input_gpios[i])); - for (i = 0; i < mi->noutputs; i++) { - if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) - gpio_set_value(mi->output_gpios[i], - !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH)); - else - gpio_direction_input(mi->output_gpios[i]); - } - wake_lock(&kp->wake_lock); - hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - return IRQ_HANDLED; -} - -static int gpio_keypad_request_irqs(struct gpio_kp *kp) -{ - int i; - int err; - unsigned int irq; - unsigned long request_flags; - struct gpio_event_matrix_info *mi = kp->keypad_info; - - switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) { - default: - request_flags = IRQF_TRIGGER_FALLING; - break; - case GPIOKPF_ACTIVE_HIGH: - request_flags = IRQF_TRIGGER_RISING; - break; - case GPIOKPF_LEVEL_TRIGGERED_IRQ: - request_flags = IRQF_TRIGGER_LOW; - break; - case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH: - request_flags = IRQF_TRIGGER_HIGH; - break; - } - - for (i = 0; i < mi->ninputs; i++) { - err = irq = gpio_to_irq(mi->input_gpios[i]); - if (err < 0) - goto err_gpio_get_irq_num_failed; - err = request_irq(irq, gpio_keypad_irq_handler, request_flags, - "gpio_kp", kp); - if (err) { - pr_err("gpiomatrix: request_irq failed for input %d, " - "irq %d\n", mi->input_gpios[i], irq); - goto err_request_irq_failed; - } - err = set_irq_wake(irq, 1); - if (err) { - pr_err("gpiomatrix: set_irq_wake failed for input %d, " - "irq %d\n", mi->input_gpios[i], irq); - } - disable_irq(irq); - if (kp->disabled_irq) { - kp->disabled_irq = 0; - enable_irq(irq); - } - } - return 0; - - for (i = mi->noutputs - 1; i >= 0; i--) { - free_irq(gpio_to_irq(mi->input_gpios[i]), kp); -err_request_irq_failed: -err_gpio_get_irq_num_failed: - ; - } - return err; -} - -int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, - struct gpio_event_info *info, void **data, int func) -{ - int i; - int err; - int key_count; - struct gpio_kp *kp; - struct gpio_event_matrix_info *mi; - - mi = container_of(info, struct gpio_event_matrix_info, info); - if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { - /* TODO: disable scanning */ - return 0; - } - - if (func == GPIO_EVENT_FUNC_INIT) { - if (mi->keymap == NULL || - mi->input_gpios == NULL || - mi->output_gpios == NULL) { - err = -ENODEV; - pr_err("gpiomatrix: Incomplete pdata\n"); - goto err_invalid_platform_data; - } - key_count = mi->ninputs * mi->noutputs; - - *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * - BITS_TO_LONGS(key_count), GFP_KERNEL); - if (kp == NULL) { - err = -ENOMEM; - pr_err("gpiomatrix: Failed to allocate private data\n"); - goto err_kp_alloc_failed; - } - kp->input_devs = input_devs; - kp->keypad_info = mi; - for (i = 0; i < key_count; i++) { - unsigned short keyentry = mi->keymap[i]; - unsigned short keycode = keyentry & MATRIX_KEY_MASK; - unsigned short dev = keyentry >> MATRIX_CODE_BITS; - if (dev >= input_devs->count) { - pr_err("gpiomatrix: bad device index %d >= " - "%d for key code %d\n", - dev, input_devs->count, keycode); - err = -EINVAL; - goto err_bad_keymap; - } - if (keycode && keycode <= KEY_MAX) - input_set_capability(input_devs->dev[dev], - EV_KEY, keycode); - } - - for (i = 0; i < mi->noutputs; i++) { - err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); - if (err) { - pr_err("gpiomatrix: gpio_request failed for " - "output %d\n", mi->output_gpios[i]); - goto err_request_output_gpio_failed; - } - if (gpio_cansleep(mi->output_gpios[i])) { - pr_err("gpiomatrix: unsupported output gpio %d," - " can sleep\n", mi->output_gpios[i]); - err = -EINVAL; - goto err_output_gpio_configure_failed; - } - if (mi->flags & GPIOKPF_DRIVE_INACTIVE) - err = gpio_direction_output(mi->output_gpios[i], - !(mi->flags & GPIOKPF_ACTIVE_HIGH)); - else - err = gpio_direction_input(mi->output_gpios[i]); - if (err) { - pr_err("gpiomatrix: gpio_configure failed for " - "output %d\n", mi->output_gpios[i]); - goto err_output_gpio_configure_failed; - } - } - for (i = 0; i < mi->ninputs; i++) { - err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); - if (err) { - pr_err("gpiomatrix: gpio_request failed for " - "input %d\n", mi->input_gpios[i]); - goto err_request_input_gpio_failed; - } - err = gpio_direction_input(mi->input_gpios[i]); - if (err) { - pr_err("gpiomatrix: gpio_direction_input failed" - " for input %d\n", mi->input_gpios[i]); - goto err_gpio_direction_input_failed; - } - } - kp->current_output = mi->noutputs; - kp->key_state_changed = 1; - - hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - kp->timer.function = gpio_keypad_timer_func; - wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); - err = gpio_keypad_request_irqs(kp); - kp->use_irq = err == 0; - - pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " - "%s%s in %s mode\n", input_devs->dev[0]->name, - (input_devs->count > 1) ? "..." : "", - kp->use_irq ? "interrupt" : "polling"); - - if (kp->use_irq) - wake_lock(&kp->wake_lock); - hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); - - return 0; - } - - err = 0; - kp = *data; - - if (kp->use_irq) - for (i = mi->noutputs - 1; i >= 0; i--) - free_irq(gpio_to_irq(mi->input_gpios[i]), kp); - - hrtimer_cancel(&kp->timer); - wake_lock_destroy(&kp->wake_lock); - for (i = mi->noutputs - 1; i >= 0; i--) { -err_gpio_direction_input_failed: - gpio_free(mi->input_gpios[i]); -err_request_input_gpio_failed: - ; - } - for (i = mi->noutputs - 1; i >= 0; i--) { -err_output_gpio_configure_failed: - gpio_free(mi->output_gpios[i]); -err_request_output_gpio_failed: - ; - } -err_bad_keymap: - kfree(kp); -err_kp_alloc_failed: -err_invalid_platform_data: - return err; -} diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c deleted file mode 100644 index 2aac2fad0a17..000000000000 --- a/drivers/input/misc/gpio_output.c +++ /dev/null @@ -1,97 +0,0 @@ -/* drivers/input/misc/gpio_output.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 -#include -#include - -int gpio_event_output_event( - struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, - void **data, unsigned int dev, unsigned int type, - unsigned int code, int value) -{ - int i; - struct gpio_event_output_info *oi; - oi = container_of(info, struct gpio_event_output_info, info); - if (type != oi->type) - return 0; - if (!(oi->flags & GPIOEDF_ACTIVE_HIGH)) - value = !value; - for (i = 0; i < oi->keymap_size; i++) - if (dev == oi->keymap[i].dev && code == oi->keymap[i].code) - gpio_set_value(oi->keymap[i].gpio, value); - return 0; -} - -int gpio_event_output_func( - struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, - void **data, int func) -{ - int ret; - int i; - struct gpio_event_output_info *oi; - oi = container_of(info, struct gpio_event_output_info, info); - - if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) - return 0; - - if (func == GPIO_EVENT_FUNC_INIT) { - int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH); - - for (i = 0; i < oi->keymap_size; i++) { - int dev = oi->keymap[i].dev; - if (dev >= input_devs->count) { - pr_err("gpio_event_output_func: bad device " - "index %d >= %d for key code %d\n", - dev, input_devs->count, - oi->keymap[i].code); - ret = -EINVAL; - goto err_bad_keymap; - } - input_set_capability(input_devs->dev[dev], oi->type, - oi->keymap[i].code); - } - - for (i = 0; i < oi->keymap_size; i++) { - ret = gpio_request(oi->keymap[i].gpio, - "gpio_event_output"); - if (ret) { - pr_err("gpio_event_output_func: gpio_request " - "failed for %d\n", oi->keymap[i].gpio); - goto err_gpio_request_failed; - } - ret = gpio_direction_output(oi->keymap[i].gpio, - output_level); - if (ret) { - pr_err("gpio_event_output_func: " - "gpio_direction_output failed for %d\n", - oi->keymap[i].gpio); - goto err_gpio_direction_output_failed; - } - } - return 0; - } - - ret = 0; - for (i = oi->keymap_size - 1; i >= 0; i--) { -err_gpio_direction_output_failed: - gpio_free(oi->keymap[i].gpio); -err_gpio_request_failed: - ; - } -err_bad_keymap: - return ret; -} - diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c deleted file mode 100644 index ca23905f3046..000000000000 --- a/drivers/input/misc/keychord.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * drivers/input/misc/keychord.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#define KEYCHORD_NAME "keychord" -#define BUFFER_SIZE 16 - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("Key chord input driver"); -MODULE_SUPPORTED_DEVICE("keychord"); -MODULE_LICENSE("GPL"); - -#define NEXT_KEYCHORD(kc) ((struct input_keychord *) \ - ((char *)kc + sizeof(struct input_keychord) + \ - kc->count * sizeof(kc->keycodes[0]))) - -struct keychord_device { - struct input_handler input_handler; - int registered; - - /* list of keychords to monitor */ - struct input_keychord *keychords; - int keychord_count; - - /* bitmask of keys contained in our keychords */ - unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; - /* current state of the keys */ - unsigned long keystate[BITS_TO_LONGS(KEY_CNT)]; - /* number of keys that are currently pressed */ - int key_down; - - /* second input_device_id is needed for null termination */ - struct input_device_id device_ids[2]; - - spinlock_t lock; - wait_queue_head_t waitq; - unsigned char head; - unsigned char tail; - __u16 buff[BUFFER_SIZE]; -}; - -static int check_keychord(struct keychord_device *kdev, - struct input_keychord *keychord) -{ - int i; - - if (keychord->count != kdev->key_down) - return 0; - - for (i = 0; i < keychord->count; i++) { - if (!test_bit(keychord->keycodes[i], kdev->keystate)) - return 0; - } - - /* we have a match */ - return 1; -} - -static void keychord_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - struct keychord_device *kdev = handle->private; - struct input_keychord *keychord; - unsigned long flags; - int i, got_chord = 0; - - if (type != EV_KEY || code >= KEY_MAX) - return; - - spin_lock_irqsave(&kdev->lock, flags); - /* do nothing if key state did not change */ - if (!test_bit(code, kdev->keystate) == !value) - goto done; - __change_bit(code, kdev->keystate); - if (value) - kdev->key_down++; - else - kdev->key_down--; - - /* don't notify on key up */ - if (!value) - goto done; - /* ignore this event if it is not one of the keys we are monitoring */ - if (!test_bit(code, kdev->keybit)) - goto done; - - keychord = kdev->keychords; - if (!keychord) - goto done; - - /* check to see if the keyboard state matches any keychords */ - for (i = 0; i < kdev->keychord_count; i++) { - if (check_keychord(kdev, keychord)) { - kdev->buff[kdev->head] = keychord->id; - kdev->head = (kdev->head + 1) % BUFFER_SIZE; - got_chord = 1; - break; - } - /* skip to next keychord */ - keychord = NEXT_KEYCHORD(keychord); - } - -done: - spin_unlock_irqrestore(&kdev->lock, flags); - - if (got_chord) - wake_up_interruptible(&kdev->waitq); -} - -static int keychord_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - int i, ret; - struct input_handle *handle; - struct keychord_device *kdev = - container_of(handler, struct keychord_device, input_handler); - - /* - * ignore this input device if it does not contain any keycodes - * that we are monitoring - */ - for (i = 0; i < KEY_MAX; i++) { - if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit)) - break; - } - if (i == KEY_MAX) - return -ENODEV; - - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = KEYCHORD_NAME; - handle->private = kdev; - - ret = input_register_handle(handle); - if (ret) - goto err_input_register_handle; - - ret = input_open_device(handle); - if (ret) - goto err_input_open_device; - - pr_info("keychord: using input dev %s for fevent\n", dev->name); - - return 0; - -err_input_open_device: - input_unregister_handle(handle); -err_input_register_handle: - kfree(handle); - return ret; -} - -static void keychord_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -/* - * keychord_read is used to read keychord events from the driver - */ -static ssize_t keychord_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct keychord_device *kdev = file->private_data; - __u16 id; - int retval; - unsigned long flags; - - if (count < sizeof(id)) - return -EINVAL; - count = sizeof(id); - - if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK)) - return -EAGAIN; - - retval = wait_event_interruptible(kdev->waitq, - kdev->head != kdev->tail); - if (retval) - return retval; - - spin_lock_irqsave(&kdev->lock, flags); - /* pop a keychord ID off the queue */ - id = kdev->buff[kdev->tail]; - kdev->tail = (kdev->tail + 1) % BUFFER_SIZE; - spin_unlock_irqrestore(&kdev->lock, flags); - - if (copy_to_user(buffer, &id, count)) - return -EFAULT; - - return count; -} - -/* - * keychord_write is used to configure the driver - */ -static ssize_t keychord_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct keychord_device *kdev = file->private_data; - struct input_keychord *keychords = 0; - struct input_keychord *keychord, *next, *end; - int ret, i, key; - unsigned long flags; - - if (count < sizeof(struct input_keychord)) - return -EINVAL; - keychords = kzalloc(count, GFP_KERNEL); - if (!keychords) - return -ENOMEM; - - /* read list of keychords from userspace */ - if (copy_from_user(keychords, buffer, count)) { - kfree(keychords); - return -EFAULT; - } - - /* unregister handler before changing configuration */ - if (kdev->registered) { - input_unregister_handler(&kdev->input_handler); - kdev->registered = 0; - } - - spin_lock_irqsave(&kdev->lock, flags); - /* clear any existing configuration */ - kfree(kdev->keychords); - kdev->keychords = 0; - kdev->keychord_count = 0; - kdev->key_down = 0; - memset(kdev->keybit, 0, sizeof(kdev->keybit)); - memset(kdev->keystate, 0, sizeof(kdev->keystate)); - kdev->head = kdev->tail = 0; - - keychord = keychords; - end = (struct input_keychord *)((char *)keychord + count); - - while (keychord < end) { - next = NEXT_KEYCHORD(keychord); - if (keychord->count <= 0 || next > end) { - pr_err("keychord: invalid keycode count %d\n", - keychord->count); - goto err_unlock_return; - } - if (keychord->version != KEYCHORD_VERSION) { - pr_err("keychord: unsupported version %d\n", - keychord->version); - goto err_unlock_return; - } - - /* keep track of the keys we are monitoring in keybit */ - for (i = 0; i < keychord->count; i++) { - key = keychord->keycodes[i]; - if (key < 0 || key >= KEY_CNT) { - pr_err("keychord: keycode %d out of range\n", - key); - goto err_unlock_return; - } - __set_bit(key, kdev->keybit); - } - - kdev->keychord_count++; - keychord = next; - } - - kdev->keychords = keychords; - spin_unlock_irqrestore(&kdev->lock, flags); - - ret = input_register_handler(&kdev->input_handler); - if (ret) { - kfree(keychords); - kdev->keychords = 0; - return ret; - } - kdev->registered = 1; - - return count; - -err_unlock_return: - spin_unlock_irqrestore(&kdev->lock, flags); - kfree(keychords); - return -EINVAL; -} - -static unsigned int keychord_poll(struct file *file, poll_table *wait) -{ - struct keychord_device *kdev = file->private_data; - - poll_wait(file, &kdev->waitq, wait); - - if (kdev->head != kdev->tail) - return POLLIN | POLLRDNORM; - - return 0; -} - -static int keychord_open(struct inode *inode, struct file *file) -{ - struct keychord_device *kdev; - - kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL); - if (!kdev) - return -ENOMEM; - - spin_lock_init(&kdev->lock); - init_waitqueue_head(&kdev->waitq); - - kdev->input_handler.event = keychord_event; - kdev->input_handler.connect = keychord_connect; - kdev->input_handler.disconnect = keychord_disconnect; - kdev->input_handler.name = KEYCHORD_NAME; - kdev->input_handler.id_table = kdev->device_ids; - - kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT; - __set_bit(EV_KEY, kdev->device_ids[0].evbit); - - file->private_data = kdev; - - return 0; -} - -static int keychord_release(struct inode *inode, struct file *file) -{ - struct keychord_device *kdev = file->private_data; - - if (kdev->registered) - input_unregister_handler(&kdev->input_handler); - kfree(kdev); - - return 0; -} - -static const struct file_operations keychord_fops = { - .owner = THIS_MODULE, - .open = keychord_open, - .release = keychord_release, - .read = keychord_read, - .write = keychord_write, - .poll = keychord_poll, -}; - -static struct miscdevice keychord_misc = { - .fops = &keychord_fops, - .name = KEYCHORD_NAME, - .minor = MISC_DYNAMIC_MINOR, -}; - -static int __init keychord_init(void) -{ - return misc_register(&keychord_misc); -} - -static void __exit keychord_exit(void) -{ - misc_deregister(&keychord_misc); -} - -module_init(keychord_init); -module_exit(keychord_exit); diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 298c8e505cc2..b6aa7d20d8a3 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -51,8 +51,7 @@ #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) & 0x100000) /* 1-button ClickPad */ -#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ +#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) /* synaptics modes query bits */ diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 8c53926eb20b..ed7ad7416b24 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -332,13 +332,6 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), }, }, - { - /* Sony Vaio VPCZ122GX */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VPCZ122GX"), - }, - }, { /* Sony Vaio FS-115b */ .matches = { diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index a390cbad3049..0069d9703fda 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -328,25 +328,6 @@ config TOUCHSCREEN_MIGOR To compile this driver as a module, choose M here: the module will be called migor_ts. -config TOUCHSCREEN_PANJIT_I2C - tristate "PANJIT I2C touchscreen driver" - depends on I2C - default n - help - Say Y here to enable PANJIT I2C capacitive touchscreen support, - covering devices such as the MGG1010AI06 and EGG1010AI06 - - If unsure, say N - - To compile this driver as a module, choose M here: the module will - be called panjit_i2c. - -config TOUCHSCREEN_SYNAPTICS_I2C_RMI - tristate "Synaptics i2c touchscreen" - depends on I2C - help - This enables support for Synaptics RMI over I2C based touchscreens. - config TOUCHSCREEN_TOUCHRIGHT tristate "Touchright serial touchscreen" select SERIO @@ -657,13 +638,4 @@ config TOUCHSCREEN_STMPE To compile this driver as a module, choose M here: the module will be called stmpe-ts. -config TOUCHSCREEN_QUANTUM_OBP - tristate "Quantum OBP based touchscreens" - depends on I2C - help - Say Y here if you have a Quantum touchscreen that uses - the Object Based Protocol based firmware. - - If unsure, say N. - endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index f62f2325af50..c4928eebba7b 100755 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -32,14 +32,11 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o -obj-$(CONFIG_TOUCHSCREEN_PANJIT_I2C) += panjit_i2c.o obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o -obj-$(CONFIG_TOUCHSCREEN_QUANTUM_OBP) += qtouch_obp_ts.o obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI) += synaptics_i2c_rmi.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff --git a/drivers/input/touchscreen/panjit_i2c.c b/drivers/input/touchscreen/panjit_i2c.c deleted file mode 100644 index 4fccebc52ea8..000000000000 --- a/drivers/input/touchscreen/panjit_i2c.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * drivers/input/touchscreen/panjit_i2c.c - * - * Touchscreen class input driver for Panjit touch panel using I2C bus - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CSR 0x00 - #define CSR_SCAN_EN (1 << 3) - #define CSR_SLEEP_EN (1 << 7) -#define C_FLAG 0x01 -#define X1_H 0x03 - -#define DRIVER_NAME "panjit_touch" - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void pj_early_suspend(struct early_suspend *h); -static void pj_late_resume(struct early_suspend *h); -#endif - -struct pj_data { - struct input_dev *input_dev; - struct i2c_client *client; - int gpio_reset; - struct early_suspend early_suspend; -}; - -struct pj_event { - __be16 coord[2][2]; - __u8 fingers; - __u8 gesture; -}; - -union pj_buff { - struct pj_event data; - unsigned char buff[sizeof(struct pj_data)]; -}; - -static void pj_reset(struct pj_data *touch) -{ - if (touch->gpio_reset < 0) - return; - - gpio_set_value(touch->gpio_reset, 1); - msleep(50); - gpio_set_value(touch->gpio_reset, 0); - msleep(50); -} - -static irqreturn_t pj_irq(int irq, void *dev_id) -{ - struct pj_data *touch = dev_id; - struct i2c_client *client = touch->client; - union pj_buff event; - int ret, i; - - ret = i2c_smbus_read_i2c_block_data(client, X1_H, - sizeof(event.buff), event.buff); - if (WARN_ON(ret < 0)) { - dev_err(&client->dev, "error %d reading event data\n", ret); - return IRQ_NONE; - } - ret = i2c_smbus_write_byte_data(client, C_FLAG, 0); - if (WARN_ON(ret < 0)) { - dev_err(&client->dev, "error %d clearing interrupt\n", ret); - return IRQ_NONE; - } - - input_report_key(touch->input_dev, BTN_TOUCH, - (event.data.fingers == 1 || event.data.fingers == 2)); - input_report_key(touch->input_dev, BTN_2, (event.data.fingers == 2)); - - if (!event.data.fingers || (event.data.fingers > 2)) - goto out; - - for (i = 0; i < event.data.fingers; i++) { - input_report_abs(touch->input_dev, ABS_MT_POSITION_X, - __be16_to_cpu(event.data.coord[i][0])); - input_report_abs(touch->input_dev, ABS_MT_POSITION_Y, - __be16_to_cpu(event.data.coord[i][1])); - input_report_abs(touch->input_dev, ABS_MT_TRACKING_ID, i + 1); - input_mt_sync(touch->input_dev); - } - -out: - input_sync(touch->input_dev); - return IRQ_HANDLED; -} - -static int pj_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct panjit_i2c_ts_platform_data *pdata = client->dev.platform_data; - struct pj_data *touch = NULL; - struct input_dev *input_dev = NULL; - int ret = 0; - - touch = kzalloc(sizeof(struct pj_data), GFP_KERNEL); - if (!touch) { - dev_err(&client->dev, "%s: no memory\n", __func__); - return -ENOMEM; - } - - touch->gpio_reset = -EINVAL; - - if (pdata) { - ret = gpio_request(pdata->gpio_reset, "panjit_reset"); - if (!ret) { - ret = gpio_direction_output(pdata->gpio_reset, 1); - if (ret < 0) - gpio_free(pdata->gpio_reset); - } - - if (!ret) - touch->gpio_reset = pdata->gpio_reset; - else - dev_warn(&client->dev, "unable to configure GPIO\n"); - } - - input_dev = input_allocate_device(); - if (!input_dev) { - dev_err(&client->dev, "%s: no memory\n", __func__); - kfree(touch); - return -ENOMEM; - } - - touch->client = client; - i2c_set_clientdata(client, touch); - - pj_reset(touch); - - /* clear interrupt */ - ret = i2c_smbus_write_byte_data(touch->client, C_FLAG, 0); - if (ret < 0) { - dev_err(&client->dev, "%s: clear interrupt failed\n", - __func__); - goto fail_i2c_or_register; - } - - /* enable scanning */ - ret = i2c_smbus_write_byte_data(touch->client, CSR, CSR_SCAN_EN); - if (ret < 0) { - dev_err(&client->dev, "%s: enable interrupt failed\n", - __func__); - goto fail_i2c_or_register; - } - - touch->input_dev = input_dev; - touch->input_dev->name = DRIVER_NAME; - - set_bit(EV_SYN, touch->input_dev->evbit); - set_bit(EV_KEY, touch->input_dev->evbit); - set_bit(EV_ABS, touch->input_dev->evbit); - set_bit(BTN_TOUCH, touch->input_dev->keybit); - set_bit(BTN_2, touch->input_dev->keybit); - - /* expose multi-touch capabilities */ - set_bit(ABS_MT_POSITION_X, touch->input_dev->keybit); - set_bit(ABS_MT_POSITION_Y, touch->input_dev->keybit); - set_bit(ABS_X, touch->input_dev->keybit); - set_bit(ABS_Y, touch->input_dev->keybit); - - /* all coordinates are reported in 0..4095 */ - input_set_abs_params(touch->input_dev, ABS_X, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_Y, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_HAT0X, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_HAT0Y, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_HAT1X, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_HAT1Y, 0, 4095, 0, 0); - - input_set_abs_params(touch->input_dev, ABS_MT_POSITION_X, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_MT_POSITION_Y, 0, 4095, 0, 0); - input_set_abs_params(touch->input_dev, ABS_MT_TRACKING_ID, 0, 2, 1, 0); - - ret = input_register_device(touch->input_dev); - if (ret) { - dev_err(&client->dev, "%s: input_register_device failed\n", - __func__); - goto fail_i2c_or_register; - } - - /* get the irq */ - ret = request_threaded_irq(touch->client->irq, NULL, pj_irq, - IRQF_ONESHOT | IRQF_TRIGGER_LOW, - DRIVER_NAME, touch); - if (ret) { - dev_err(&client->dev, "%s: request_irq(%d) failed\n", - __func__, touch->client->irq); - goto fail_irq; - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - touch->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - touch->early_suspend.suspend = pj_early_suspend; - touch->early_suspend.resume = pj_late_resume; - register_early_suspend(&touch->early_suspend); -#endif - dev_info(&client->dev, "%s: initialized\n", __func__); - return 0; - -fail_irq: - input_unregister_device(touch->input_dev); - -fail_i2c_or_register: - if (touch->gpio_reset >= 0) - gpio_free(touch->gpio_reset); - - input_free_device(input_dev); - kfree(touch); - return ret; -} - -static int pj_suspend(struct i2c_client *client, pm_message_t state) -{ - struct pj_data *touch = i2c_get_clientdata(client); - int ret; - - if (WARN_ON(!touch)) - return -EINVAL; - - disable_irq(client->irq); - - /* disable scanning and enable deep sleep */ - ret = i2c_smbus_write_byte_data(client, CSR, CSR_SLEEP_EN); - if (ret < 0) { - dev_err(&client->dev, "%s: sleep enable fail\n", __func__); - return ret; - } - - return 0; -} - -static int pj_resume(struct i2c_client *client) -{ - struct pj_data *touch = i2c_get_clientdata(client); - int ret = 0; - - if (WARN_ON(!touch)) - return -EINVAL; - - pj_reset(touch); - - /* enable scanning and disable deep sleep */ - ret = i2c_smbus_write_byte_data(client, C_FLAG, 0); - if (ret >= 0) - ret = i2c_smbus_write_byte_data(client, CSR, CSR_SCAN_EN); - if (ret < 0) { - dev_err(&client->dev, "%s: scan enable fail\n", __func__); - return ret; - } - - enable_irq(client->irq); - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void pj_early_suspend(struct early_suspend *es) -{ - struct pj_data *touch; - touch = container_of(es, struct pj_data, early_suspend); - - if (pj_suspend(touch->client, PMSG_SUSPEND) != 0) - dev_err(&touch->client->dev, "%s: failed\n", __func__); -} - -static void pj_late_resume(struct early_suspend *es) -{ - struct pj_data *touch; - touch = container_of(es, struct pj_data, early_suspend); - - if (pj_resume(touch->client) != 0) - dev_err(&touch->client->dev, "%s: failed\n", __func__); -} -#endif - -static int pj_remove(struct i2c_client *client) -{ - struct pj_data *touch = i2c_get_clientdata(client); - - if (!touch) - return -EINVAL; - -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&touch->early_suspend); -#endif - free_irq(touch->client->irq, touch); - if (touch->gpio_reset >= 0) - gpio_free(touch->gpio_reset); - input_unregister_device(touch->input_dev); - input_free_device(touch->input_dev); - kfree(touch); - return 0; -} - -static const struct i2c_device_id panjit_ts_id[] = { - { DRIVER_NAME, 0 }, - { } -}; - -static struct i2c_driver panjit_driver = { - .probe = pj_probe, - .remove = pj_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = pj_suspend, - .resume = pj_resume, -#endif - .id_table = panjit_ts_id, - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __devinit panjit_init(void) -{ - int e; - - e = i2c_add_driver(&panjit_driver); - if (e != 0) { - pr_err("%s: failed to register with I2C bus with " - "error: 0x%x\n", __func__, e); - } - return e; -} - -static void __exit panjit_exit(void) -{ - i2c_del_driver(&panjit_driver); -} - -module_init(panjit_init); -module_exit(panjit_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Panjit I2C touch driver"); diff --git a/drivers/input/touchscreen/qtouch_obp_ts.c b/drivers/input/touchscreen/qtouch_obp_ts.c deleted file mode 100644 index b4a35fc1830c..000000000000 --- a/drivers/input/touchscreen/qtouch_obp_ts.c +++ /dev/null @@ -1,2042 +0,0 @@ -/* - * drivers/input/touchscreen/qtouch_obp_ts.c - driver for Quantum touch IC - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009-2010 Motorola, 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. - * - * Derived from the Motorola OBP touch driver. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IGNORE_CHECKSUM_MISMATCH - -struct qtm_object { - struct qtm_obj_entry entry; - uint8_t report_id_min; - uint8_t report_id_max; -}; - -struct axis_map { - int key; - int x; - int y; -}; - -struct coordinate_map { - int x_data; - int y_data; - int z_data; - int w_data; - int vector; - int down; -}; - -#define _BITMAP_LEN BITS_TO_LONGS(QTM_OBP_MAX_OBJECT_NUM) -#define _NUM_FINGERS 10 -struct qtouch_ts_data { - struct i2c_client *client; - struct input_dev *input_dev; - struct work_struct init_work; - struct work_struct work; - struct work_struct boot_work; - struct qtouch_ts_platform_data *pdata; - struct coordinate_map finger_data[_NUM_FINGERS]; - struct early_suspend early_suspend; - - struct qtm_object obj_tbl[QTM_OBP_MAX_OBJECT_NUM]; - unsigned long obj_map[_BITMAP_LEN]; - - uint32_t last_keystate; - uint32_t eeprom_checksum; - uint8_t checksum_cnt; - int x_delta; - int y_delta; - uint8_t family_id; - uint8_t variant_id; - uint8_t fw_version; - uint8_t build_version; - uint8_t fw_error_count; - uint32_t touch_fw_size; - uint8_t *touch_fw_image; - uint8_t base_fw_version; - uint8_t *touch_fw; - - uint8_t xpos_rshift_lsb; - uint8_t ypos_rshift_lsb; - uint8_t xpos_lshift_msb; - uint8_t ypos_lshift_msb; - - atomic_t irq_enabled; - atomic_t process_open; - int enable_irq_flag; - int status; - - uint8_t mode; - int boot_pkt_size; - int current_pkt_sz; - uint8_t org_i2c_addr; - - /* Note: The message buffer is reused for reading different messages. - * MUST enforce that there is no concurrent access to msg_buf. */ - uint8_t *msg_buf; - int msg_size; - - struct regulator *regulator; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void qtouch_ts_early_suspend(struct early_suspend *handler); -static void qtouch_ts_late_resume(struct early_suspend *handler); -#endif - -static struct workqueue_struct *qtouch_ts_wq; -const struct firmware *fw_entry; - -static uint32_t qtouch_tsdebug; -module_param_named(tsdebug, qtouch_tsdebug, uint, 0664); - -static uint32_t qtouch_disable_touch; -module_param_named(disable_touch, qtouch_disable_touch, uint, 0644); - -static irqreturn_t qtouch_ts_irq_handler(int irq, void *dev_id) -{ - struct qtouch_ts_data *ts = dev_id; - - disable_irq_nosync(ts->client->irq); - if (ts->mode == 1) - queue_work(qtouch_ts_wq, &ts->boot_work); - else - queue_work(qtouch_ts_wq, &ts->work); - - return IRQ_HANDLED; -} - -static int qtouch_write(struct qtouch_ts_data *ts, void *buf, int buf_sz) -{ - int retries = 10; - int ret; - - do { - ret = i2c_master_send(ts->client, (char *)buf, buf_sz); - } while ((ret < buf_sz) && (--retries > 0)); - - if (ret < 0) - pr_info("%s: Error while trying to write %d bytes\n", __func__, - buf_sz); - else if (ret != buf_sz) { - pr_info("%s: Write %d bytes, expected %d\n", __func__, - ret, buf_sz); - ret = -EIO; - } - return ret; -} - -static int qtouch_set_addr(struct qtouch_ts_data *ts, uint16_t addr) -{ - int ret; - - /* Note: addr on the wire is LSB first */ - ret = qtouch_write(ts, (char *)&addr, sizeof(uint16_t)); - if (ret < 0) - pr_info("%s: Can't send obp addr 0x%4x\n", __func__, addr); - - return ret >= 0 ? 0 : ret; -} - -static int qtouch_read(struct qtouch_ts_data *ts, void *buf, int buf_sz) -{ - int retries = 10; - int ret; - - do { - memset(buf, 0, buf_sz); - ret = i2c_master_recv(ts->client, (char *)buf, buf_sz); - } while ((ret < 0) && (--retries > 0)); - - if (ret < 0) - pr_info("%s: Error while trying to read %d bytes\n", __func__, - buf_sz); - else if (ret != buf_sz) { - pr_info("%s: Read %d bytes, expected %d\n", __func__, - ret, buf_sz); - ret = -EIO; - } - - return ret >= 0 ? 0 : ret; -} - -static int qtouch_read_addr(struct qtouch_ts_data *ts, uint16_t addr, - void *buf, int buf_sz) -{ - int ret; - - ret = qtouch_set_addr(ts, addr); - if (ret != 0) - return ret; - - return qtouch_read(ts, buf, buf_sz); -} - -static struct qtm_obj_message *qtouch_read_msg(struct qtouch_ts_data *ts) -{ - int ret; - - ret = qtouch_read(ts, ts->msg_buf, ts->msg_size); - if (!ret) - return (struct qtm_obj_message *)ts->msg_buf; - return NULL; -} - -static int qtouch_write_addr(struct qtouch_ts_data *ts, uint16_t addr, - void *buf, int buf_sz) -{ - int ret; - uint8_t *write_buf; - - write_buf = kzalloc((buf_sz + sizeof(uint16_t)), GFP_KERNEL); - if (write_buf == NULL) { - pr_err("%s: Can't allocate write buffer (%d)\n", - __func__, buf_sz); - return -ENOMEM; - } - - memcpy(write_buf, (void *)&addr, sizeof(addr)); - memcpy((void *)write_buf + sizeof(addr), buf, buf_sz); - - ret = qtouch_write(ts, write_buf, buf_sz + sizeof(addr)); - - kfree(write_buf); - - if (ret < 0) { - pr_err("%s: Could not write %d bytes.\n", __func__, buf_sz); - return ret; - } - - return 0; -} -static uint32_t crc24(uint32_t crc, uint8_t first_byte, uint8_t sec_byte) -{ - static const uint32_t crcpoly = 0x80001b; - uint32_t result = 0; - uint16_t data_word = 0; - - data_word = (uint16_t)((uint16_t)(sec_byte << 8u) | first_byte); - result = ((crc<<1u) ^ (uint32_t)data_word); - /* If bit 25 is set, XOR result with crcpoly */ - if (result & 0x1000000) - result ^= crcpoly; - - return result; -} - -static uint32_t calc_csum(uint32_t curr_sum, void *_buf, int buf_sz) -{ - uint8_t *buf = _buf; - int i = 0; - int odd = 0; - - if (buf_sz % 2) { - buf_sz -= 1; - odd = 1; - } - while (i < buf_sz) { - curr_sum = crc24(curr_sum, *(buf + i), *(buf + i + 1)); - i += 2; - } - if (odd) - curr_sum = crc24(curr_sum, *(buf + i), 0); - /* Final Result */ - curr_sum = (curr_sum & 0x00FFFFFF); - - return curr_sum; -} - -static inline struct qtm_object *find_obj(struct qtouch_ts_data *ts, int id) -{ - return &ts->obj_tbl[id]; -} - -static struct qtm_object *create_obj(struct qtouch_ts_data *ts, - struct qtm_obj_entry *entry) -{ - struct qtm_object *obj; - - obj = &ts->obj_tbl[entry->type]; - memcpy(&obj->entry, entry, sizeof(*entry)); - set_bit(entry->type, ts->obj_map); - - return obj; -} - -static struct qtm_object *find_object_rid(struct qtouch_ts_data *ts, int rid) -{ - int i; - - for_each_set_bit(i, ts->obj_map, QTM_OBP_MAX_OBJECT_NUM) { - struct qtm_object *obj = &ts->obj_tbl[i]; - - if ((rid >= obj->report_id_min) && (rid <= obj->report_id_max)) - return obj; - } - - return NULL; -} - -static void qtouch_force_reset(struct qtouch_ts_data *ts, uint8_t sw_reset) -{ - struct qtm_object *obj; - uint16_t addr; - uint8_t val = 1; - int ret; - - if (ts->pdata->hw_reset && !sw_reset) { - pr_info("%s: Forcing HW reset\n", __func__); - ts->pdata->hw_reset(); - } else if (sw_reset) { - pr_info("%s: Forcing SW reset\n", __func__); - obj = find_obj(ts, QTM_OBJ_GEN_CMD_PROC); - addr = - obj->entry.addr + offsetof(struct qtm_gen_cmd_proc, reset); - /* Check to see if to reset into boot mode */ - if (sw_reset == 2) - val = 0xa5; - ret = qtouch_write_addr(ts, addr, &val, 1); - if (ret) - pr_err("%s: Unable to send the reset msg\n", __func__); - } -} - -static int qtouch_force_calibration(struct qtouch_ts_data *ts) -{ - struct qtm_object *obj; - uint16_t addr; - uint8_t val; - int ret; - - pr_info("%s: Forcing calibration\n", __func__); - - obj = find_obj(ts, QTM_OBJ_GEN_CMD_PROC); - - addr = obj->entry.addr + offsetof(struct qtm_gen_cmd_proc, calibrate); - val = 1; - ret = qtouch_write_addr(ts, addr, &val, 1); - if (ret) - pr_err("%s: Unable to send the calibrate message\n", __func__); - return ret; -} - -#undef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) -static int qtouch_power_config(struct qtouch_ts_data *ts, int on) -{ - struct qtm_gen_power_cfg pwr_cfg; - struct qtm_object *obj; - - if (!on) { - /* go to standby mode */ - pwr_cfg.idle_acq_int = 0; - pwr_cfg.active_acq_int = 0; - } else { - pwr_cfg.idle_acq_int = ts->pdata->power_cfg.idle_acq_int; - pwr_cfg.active_acq_int = ts->pdata->power_cfg.active_acq_int; - } - - pwr_cfg.active_idle_to = ts->pdata->power_cfg.active_idle_to; - - obj = find_obj(ts, QTM_OBJ_GEN_PWR_CONF); - return qtouch_write_addr(ts, obj->entry.addr, &pwr_cfg, - min(sizeof(pwr_cfg), obj->entry.size)); -} - -/* Apply the configuration provided in the platform_data to the hardware */ -static int qtouch_hw_init(struct qtouch_ts_data *ts) -{ - struct qtm_object *obj; - int i; - int ret; - uint16_t adj_addr; - - pr_info("%s: Doing hw init\n", __func__); - - /* take the IC out of suspend */ - qtouch_power_config(ts, 1); - - /* configure the acquisition object. */ - obj = find_obj(ts, QTM_OBJ_GEN_ACQUIRE_CONF); - ret = qtouch_write_addr(ts, obj->entry.addr, &ts->pdata->acquire_cfg, - min(sizeof(ts->pdata->acquire_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write acquisition config\n", __func__); - return ret; - } - - /* The multitouch and keyarray objects have very similar memory - * layout, but are just different enough where we basically have to - * repeat the same code */ - - /* configure the multi-touch object. */ - obj = find_obj(ts, QTM_OBJ_TOUCH_MULTI); - if (obj && obj->entry.num_inst > 0) { - struct qtm_touch_multi_cfg cfg; - memcpy(&cfg, &ts->pdata->multi_touch_cfg, sizeof(cfg)); - if (ts->pdata->flags & QTOUCH_USE_MULTITOUCH) - cfg.ctrl |= (1 << 1) | (1 << 0); /* reporten | enable */ - else - cfg.ctrl = 0; - ret = qtouch_write_addr(ts, obj->entry.addr, &cfg, - min(sizeof(cfg), obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write multi-touch config\n", - __func__); - return ret; - } - } - - /* configure the key-array object. */ - obj = find_obj(ts, QTM_OBJ_TOUCH_KEYARRAY); - if (obj && obj->entry.num_inst > 0) { - struct qtm_touch_keyarray_cfg cfg; - for (i = 0; i < obj->entry.num_inst; i++) { - if (ts->pdata->flags & QTOUCH_USE_KEYARRAY) { - memcpy(&cfg, &ts->pdata->key_array.cfg[i], - sizeof(cfg)); - } else - memset(&cfg, 0, sizeof(cfg)); - - adj_addr = obj->entry.addr + - ((obj->entry.size + 1) * i); - ret = qtouch_write_addr(ts, adj_addr, &cfg, - min(sizeof(cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write keyarray config\n", - __func__); - return ret; - } - } - } - - /* configure the signal filter */ - obj = find_obj(ts, QTM_OBJ_PROCG_SIG_FILTER); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->sig_filter_cfg, - min(sizeof(ts->pdata->sig_filter_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write signal filter config\n", - __func__); - return ret; - } - } - - /* configure the linearization table */ - obj = find_obj(ts, QTM_OBJ_PROCI_LINEAR_TBL); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->linear_tbl_cfg, - min(sizeof(ts->pdata->linear_tbl_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write linear table config\n", - __func__); - return ret; - } - } - - /* configure the comms configuration */ - obj = find_obj(ts, QTM_OBJ_SPT_COM_CONFIG); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->comms_config_cfg, - min(sizeof(ts->pdata->comms_config_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the comms configuration config\n", - __func__); - return ret; - } - } - - /* configure the GPIO PWM support */ - obj = find_obj(ts, QTM_OBJ_SPT_GPIO_PWM); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->gpio_pwm_cfg, - min(sizeof(ts->pdata->gpio_pwm_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the GPIO PWM config\n", - __func__); - return ret; - } - } - - /* configure the grip face suppression table */ - obj = find_obj(ts, QTM_OBJ_PROCI_GRIPFACESUPPRESSION); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->grip_face_suppression_cfg, - min(sizeof - (ts->pdata->grip_face_suppression_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the grip face suppression config\n", - __func__); - return ret; - } - } - - /* configure noise suppression */ - obj = find_obj(ts, QTM_OBJ_PROCG_NOISE_SUPPRESSION); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->noise_suppression_cfg, - min(sizeof(ts->pdata->noise_suppression_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the noise suppression config\n", - __func__); - return ret; - } - } - - /* configure the touch proximity sensor */ - obj = find_obj(ts, QTM_OBJ_TOUCH_PROXIMITY); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->touch_proximity_cfg, - min(sizeof(ts->pdata->touch_proximity_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the touch proximity config\n", - __func__); - return ret; - } - } - - /* configure the one touch gesture processor */ - obj = find_obj(ts, QTM_OBJ_PROCI_ONE_TOUCH_GESTURE_PROC); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->one_touch_gesture_proc_cfg, - min(sizeof(ts->pdata->one_touch_gesture_proc_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the one touch gesture processor config\n", - __func__); - return ret; - } - } - - /* configure self test */ - obj = find_obj(ts, QTM_OBJ_SPT_SELF_TEST); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->self_test_cfg, - min(sizeof(ts->pdata->self_test_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the self test config\n", - __func__); - return ret; - } - } - - /* configure the two touch gesture processor */ - obj = find_obj(ts, QTM_OBJ_PROCI_TWO_TOUCH_GESTURE_PROC); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->two_touch_gesture_proc_cfg, - min(sizeof(ts->pdata->two_touch_gesture_proc_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the two touch gesture processor config\n", - __func__); - return ret; - } - } - - /* configure the capacitive touch engine */ - obj = find_obj(ts, QTM_OBJ_SPT_CTE_CONFIG); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->cte_config_cfg, - min(sizeof(ts->pdata->cte_config_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the capacitive touch engine config\n", - __func__); - return ret; - } - } - - /* configure the noise suppression table */ - obj = find_obj(ts, QTM_OBJ_NOISESUPPRESSION_1); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->noise1_suppression_cfg, - min(sizeof - (ts->pdata->noise1_suppression_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the noise suppression config\n", - __func__); - return ret; - } - } - - /* configure the grip suppression table */ - obj = find_obj(ts, QTM_OBJ_PROCI_GRIPSUPPRESSION); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->gripsuppression_t40_cfg, - min(sizeof(ts->pdata->gripsuppression_t40_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the grip suppression config\n", - __func__); - return ret; - } - } - - /* configure the palm suppression table */ - obj = find_obj(ts, QTM_OBJ_PROCI_PALMSUPPRESSION); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->palm_suppression_cfg, - min(sizeof(ts->pdata->palm_suppression_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the palm suppression config\n", - __func__); - return ret; - } - } - - /* configure the Digitizer HID config */ - obj = find_obj(ts, QTM_OBJ_SPT_DIGITIZER); - if (obj && obj->entry.num_inst > 0) { - ret = qtouch_write_addr(ts, obj->entry.addr, - &ts->pdata->spt_digitizer_cfg, - min(sizeof(ts->pdata->spt_digitizer_cfg), - obj->entry.size)); - if (ret != 0) { - pr_err("%s: Can't write the Digitizer HID config\n", - __func__); - return ret; - } - } - - ret = qtouch_force_calibration(ts); - if (ret != 0) { - pr_err("%s: Unable to recalibrate after reset\n", __func__); - return ret; - } - - /* Write the settings into nvram, if needed */ - if (ts->pdata->flags & QTOUCH_CFG_BACKUPNV) { - uint8_t val; - uint16_t addr; - - obj = find_obj(ts, QTM_OBJ_GEN_CMD_PROC); - addr = obj->entry.addr + offsetof(struct qtm_gen_cmd_proc, - backupnv); - val = 0x55; - ret = qtouch_write_addr(ts, addr, &val, 1); - if (ret != 0) { - pr_err("%s: Can't backup nvram settings\n", __func__); - return ret; - } - /* Since the IC does not indicate that has completed the - backup place a hard wait here. If we communicate with the - IC during backup the EEPROM may be corrupted */ - - msleep(QTM_OBP_SLEEP_WAIT_FOR_BACKUP); - } - - /* If debugging, read back and print all settings */ - if (qtouch_tsdebug) { - int object; - int size; - uint8_t *data_buff; - int byte; - int msg_bytes; - int msg_location; - char *msg; - - msg = kmalloc(1024, GFP_KERNEL); - if (msg != NULL) { - for (object = 7; object < QTM_OBP_MAX_OBJECT_NUM; object++) { - - size = ts->obj_tbl[object].entry.size - * ts->obj_tbl[object].entry.num_inst; - if (size != 0) { - data_buff = kmalloc(size, GFP_KERNEL); - if (data_buff == NULL) { - pr_err("%s: Object %d: Malloc failed\n", - __func__, object); - continue; - } - - qtouch_read_addr(ts, - ts->obj_tbl[object].entry.addr, - (void *)data_buff, size); - - msg_location = sprintf(msg, "%s: Object %d:", - __func__, object); - for (byte = 0; byte < size; byte++) { - msg_bytes = snprintf((msg + msg_location), - (1024 - msg_location), - " 0x%02x", - *(data_buff + byte)); - msg_location += msg_bytes; - if (msg_location >= 1024) - break; - } - if (msg_location < 1024) { - pr_info("%s\n", msg); - } else { - pr_info("%s: Object %d: String overflow\n", - __func__, object); - } - - kfree(data_buff); - } - } - - kfree(msg); - } - } - - /* reset the address pointer */ - ret = qtouch_set_addr(ts, ts->obj_tbl[QTM_OBJ_GEN_MSG_PROC].entry.addr); - if (ret != 0) { - pr_err("%s: Unable to reset address pointer after reset\n", - __func__); - return ret; - } - - return 0; -} - -/* Handles a message from the command processor object. */ -static int do_cmd_proc_msg(struct qtouch_ts_data *ts, struct qtm_object *obj, - void *_msg) -{ - struct qtm_cmd_proc_msg *msg = _msg; - int ret = 0; - int hw_reset = 0; - uint32_t checksum = (msg->checksum[2] << 16) - | (msg->checksum[1] << 8) | msg->checksum[0]; - - if (msg->status & QTM_CMD_PROC_STATUS_RESET) { - if (qtouch_tsdebug) - pr_info("%s:EEPROM checksum is 0x%X cnt %i\n", - __func__, checksum, ts->checksum_cnt); - if (checksum != ts->eeprom_checksum) { - if (ts->checksum_cnt > 2) { - /* Assume the checksum is what it is, cannot - disable the touch screen so set the checksum*/ - ts->eeprom_checksum = checksum; - ts->checksum_cnt = 0; - } else { - pr_info("%s:EEPROM checksum doesn't match 0x%x\n", - __func__, checksum); - ret = qtouch_hw_init(ts); - if (ret != 0) - pr_err("%s:Cannot init the touch IC\n", - __func__); - hw_reset = 1; - ts->checksum_cnt++; - } - } else { - pr_info("%s:EEPROM checksum matches\n", __func__); - } - pr_info("%s: Reset done.\n", __func__); - } - - if (msg->status & QTM_CMD_PROC_STATUS_CAL) - pr_info("%s: Self-calibration started.\n", __func__); - - if (msg->status & QTM_CMD_PROC_STATUS_OFL) - pr_err("%s: Acquisition cycle length overflow\n", __func__); - - if (msg->status & QTM_CMD_PROC_STATUS_SIGERR) - pr_err("%s: Acquisition error\n", __func__); - - if (msg->status & QTM_CMD_PROC_STATUS_CFGERR) { - pr_err("%s: Configuration error\n", __func__); - ret = qtouch_hw_init(ts); - if (ret != 0) - pr_err("%s:Cannot init the touch IC\n", __func__); - } - /* Check the EEPROM checksum. An ESD event may cause - the checksum to change during operation so we need to - reprogram the EEPROM and reset the IC */ - if (ts->pdata->flags & QTOUCH_EEPROM_CHECKSUM) { - if (checksum != ts->eeprom_checksum) { - if (qtouch_tsdebug) - pr_info("%s:EEPROM checksum is 0x%X cnt %i\n", - __func__, checksum, - ts->checksum_cnt); - if (ts->checksum_cnt > 2) { - /* Assume the checksum is what it is, cannot - disable the touch screen so set the checksum*/ - ts->eeprom_checksum = checksum; - ts->checksum_cnt = 0; - } else { - if (!hw_reset) { - ret = qtouch_hw_init(ts); - if (ret != 0) - pr_err("%s:Cannot init the touch IC\n", - __func__); - qtouch_force_reset(ts, 0); - ts->checksum_cnt++; - } - } - } - } - return ret; -} - -/* Handles a message from a multi-touch object. */ -static int do_touch_multi_msg(struct qtouch_ts_data *ts, struct qtm_object *obj, - void *_msg) -{ - struct qtm_touch_multi_msg *msg = _msg; - int i; - int x; - int y; - int pressure; - int width; - uint32_t finger; - int down; - - finger = msg->report_id - obj->report_id_min; - if (finger >= ts->pdata->multi_touch_cfg.num_touch) - return 0; - - if (qtouch_tsdebug & 0x10) - pr_info("%s: msgxpos_msb 0x%X msgypos_msb 0x%X msgxypos 0x%X \n", - __func__, msg->xpos_msb, msg->ypos_msb, msg->xypos_lsb); - - /* x/y are 10bit values(<1024), with bottom 2 bits inside the xypos_lsb */ - /* x/y are 12bit values(>1023), with bottom 4 bits inside the xypos_lsb */ - x = (msg->xpos_msb << ts->xpos_lshift_msb) | - ((msg->xypos_lsb >> ts->xpos_rshift_lsb) & 0xf); - y = (msg->ypos_msb << ts->ypos_lshift_msb) | - ((msg->xypos_lsb >> ts->ypos_rshift_lsb) & 0xf); - - width = msg->touch_area; - pressure = msg->touch_amp; - - if (qtouch_tsdebug & 2) - pr_info("%s: stat=%02x, f=%d x=%d y=%d p=%d w=%d\n", __func__, - msg->status, finger, x, y, pressure, width); - - if (finger >= _NUM_FINGERS) { - pr_err("%s: Invalid finger number %dd\n", __func__, finger); - return 1; - } - - down = !(msg->status & (QTM_TOUCH_MULTI_STATUS_RELEASE | - QTM_TOUCH_MULTI_STATUS_SUPPRESS)); - - ts->finger_data[finger].x_data = x; - ts->finger_data[finger].y_data = y; - ts->finger_data[finger].w_data = width; - ts->finger_data[finger].vector = msg->touch_vect; - - /* The touch IC will not give back a pressure of zero - so send a 0 when a liftoff is produced */ - if (!down) { - ts->finger_data[finger].z_data = 0; - } else { - ts->finger_data[finger].z_data = pressure; - ts->finger_data[finger].down = down; - } - - for (i = 0; i < ts->pdata->multi_touch_cfg.num_touch; i++) { - if (ts->finger_data[i].down == 0) - continue; - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - ts->finger_data[i].z_data); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - ts->finger_data[i].w_data); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - ts->finger_data[i].x_data); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - ts->finger_data[i].y_data); - input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, - ts->finger_data[i].vector); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, - i); - input_mt_sync(ts->input_dev); - } - input_sync(ts->input_dev); - - if (!down) { - memset(&ts->finger_data[finger], 0, - sizeof(struct coordinate_map)); - } - - return 0; -} - -/* Handles a message from a keyarray object. */ -static int do_touch_keyarray_msg(struct qtouch_ts_data *ts, - struct qtm_object *obj, void *_msg) -{ - struct qtm_touch_keyarray_msg *msg = _msg; - int i; - - /* nothing changed.. odd. */ - if (ts->last_keystate == msg->keystate) - return 0; - - for (i = 0; i < ts->pdata->key_array.num_keys; ++i) { - struct qtouch_key *key = &ts->pdata->key_array.keys[i]; - uint32_t bit = 1 << (key->channel & 0x1f); - if ((msg->keystate & bit) != (ts->last_keystate & bit)) - input_report_key(ts->input_dev, key->code, - msg->keystate & bit); - } - input_sync(ts->input_dev); - - if (qtouch_tsdebug & 2) - pr_info("%s: key state changed 0x%08x -> 0x%08x\n", __func__, - ts->last_keystate, msg->keystate); - - /* update our internal state */ - ts->last_keystate = msg->keystate; - - return 0; -} - -static int qtouch_handle_msg(struct qtouch_ts_data *ts, struct qtm_object *obj, - struct qtm_obj_message *msg) -{ - int ret = 0; - - /* These are all the known objects that we know how to handle. */ - switch (obj->entry.type) { - case QTM_OBJ_GEN_CMD_PROC: - ret = do_cmd_proc_msg(ts, obj, msg); - break; - - case QTM_OBJ_TOUCH_MULTI: - ret = do_touch_multi_msg(ts, obj, msg); - break; - - case QTM_OBJ_TOUCH_KEYARRAY: - ret = do_touch_keyarray_msg(ts, obj, msg); - break; - - default: - /* probably not fatal? */ - ret = 0; - pr_info("%s: No handler defined for message from object " - "type %d, report_id %d\n", __func__, obj->entry.type, - msg->report_id); - } - - return ret; -} - -static int qtouch_ts_prep_msg_proc(struct qtouch_ts_data *ts) -{ - struct qtm_object *obj; - int err; - - ts->msg_buf = kmalloc(ts->msg_size, GFP_KERNEL); - if (ts->msg_buf == NULL) { - pr_err("%s: Cannot allocate msg_buf\n", __func__); - err = -ENOMEM; - goto err_alloc_msg_buf; - } - - /* Point the address pointer to the message processor. - * Must do this before enabling interrupts */ - obj = find_obj(ts, QTM_OBJ_GEN_MSG_PROC); - err = qtouch_set_addr(ts, obj->entry.addr); - if (err != 0) { - pr_err("%s: Can't to set addr to msg processor\n", __func__); - goto err_rst_addr_msg_proc; - } - - return 0; - -err_rst_addr_msg_proc: - if (ts->msg_buf) - kfree(ts->msg_buf); -err_alloc_msg_buf: - - return err; -} - -int qtouch_input_open(struct input_dev *input) -{ - int err; - struct qtouch_ts_data *ts = input_get_drvdata(input); - - if (!atomic_xchg(&ts->process_open, 0)) - return 0; - - if (ts->touch_fw_image == NULL) - goto finish_touch_upgrade; - - err = request_firmware(&fw_entry, ts->pdata->touch_fw_cfg.fw_name, - &ts->client->dev); - - if (err == 0) { - ts->touch_fw = (uint8_t *)fw_entry->data; - ts->touch_fw_size = fw_entry->size; - pr_info("firmware name: %s size: %d\n", ts->touch_fw_image, - ts->touch_fw_size); - - if ((ts->touch_fw_size != 0) && (ts->touch_fw != NULL)) { - /* Add 2 because the firmware packet size bytes - are not taken into account for the total size */ - ts->boot_pkt_size = ((ts->touch_fw[0] << 8) | - ts->touch_fw[1]) + 2; - - pr_info("%s: write first packet \n", __func__); - err = qtouch_write(ts, &ts->touch_fw[0], ts->boot_pkt_size); - if (err != ts->boot_pkt_size) { - pr_err("%s: Could not write the first packet %i\n", __func__, err); - goto reset_to_normal; - } - goto finish_touch_upgrade; - } - goto reset_to_cleanup; - } else { - pr_err("%s: Firmware %s not available : %d\n", - __func__, ts->pdata->touch_fw_cfg.fw_name, err); - ts->touch_fw = NULL; - goto reset_to_normal; - } - -reset_to_cleanup: - release_firmware(fw_entry); -reset_to_normal: - ts->status = 0xff; - qtouch_force_reset(ts, 0); -finish_touch_upgrade: - - return 0; -} - -static int qtouch_ts_register_input(struct qtouch_ts_data *ts) -{ - int err; - int i; - - if (ts->input_dev == NULL) { - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) { - pr_err("%s: failed to alloc input device\n", __func__); - err = -ENOMEM; - return err; - } - } - - ts->input_dev->name = "qtouch-touchscreen"; - input_set_drvdata(ts->input_dev, ts); - - set_bit(EV_SYN, ts->input_dev->evbit); - - /* register the harwdare assisted virtual keys, if any */ - if (ts->pdata->flags & QTOUCH_USE_KEYARRAY) { - for (i = 0; i < ts->pdata->key_array.num_keys; ++i) - input_set_capability(ts->input_dev, EV_KEY, - ts->pdata->key_array.keys[i].code); - } - - /* register the software virtual keys, if any are provided */ - for (i = 0; i < ts->pdata->vkeys.count; ++i) - input_set_capability(ts->input_dev, EV_KEY, - ts->pdata->vkeys.keys[i].code); - - if (ts->pdata->flags & QTOUCH_USE_MULTITOUCH) { - set_bit(EV_ABS, ts->input_dev->evbit); - /* Legacy support for testing only */ - input_set_capability(ts->input_dev, EV_KEY, BTN_TOUCH); - input_set_capability(ts->input_dev, EV_KEY, BTN_2); - input_set_abs_params(ts->input_dev, ABS_X, - ts->pdata->abs_min_x, ts->pdata->abs_max_x, - ts->pdata->fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0X, - ts->pdata->abs_min_x, ts->pdata->abs_max_x, - ts->pdata->fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_Y, - ts->pdata->abs_min_y, ts->pdata->abs_max_y, - ts->pdata->fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0Y, - ts->pdata->abs_min_x, ts->pdata->abs_max_x, - ts->pdata->fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_PRESSURE, - ts->pdata->abs_min_p, ts->pdata->abs_max_p, - ts->pdata->fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, - ts->pdata->abs_min_w, ts->pdata->abs_max_w, - ts->pdata->fuzz_w, 0); - - /* multi touch */ - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, - ts->pdata->abs_min_x, ts->pdata->abs_max_x, - ts->pdata->fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, - ts->pdata->abs_min_y, ts->pdata->abs_max_y, - ts->pdata->fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, - ts->pdata->abs_min_p, ts->pdata->abs_max_p, - ts->pdata->fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, - ts->pdata->abs_min_w, ts->pdata->abs_max_w, - ts->pdata->fuzz_w, 0); - input_set_abs_params(ts->input_dev, ABS_MT_ORIENTATION, - 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, - 0, ts->pdata->multi_touch_cfg.num_touch, 1, 0); - } - - memset(&ts->finger_data[0], 0, - (sizeof(struct coordinate_map) * - _NUM_FINGERS)); - - ts->input_dev->open = qtouch_input_open; - - err = input_register_device(ts->input_dev); - if (err != 0) { - pr_err("%s: Cannot register input device \"%s\"\n", __func__, - ts->input_dev->name); - goto err_input_register_dev; - } - return 0; - -err_input_register_dev: - input_free_device(ts->input_dev); - ts->input_dev = NULL; - - return err; -} - -static int qtouch_process_info_block(struct qtouch_ts_data *ts) -{ - struct qtm_id_info qtm_info; - uint32_t our_csum = 0x0; - uint32_t their_csum; - uint8_t report_id; - uint16_t addr; - int err; - int i; - uint8_t *info_blk_buf, *info_blk_start; - uint16_t info_blk_size; - struct qtm_obj_entry entry; - - /* query the device and get the info block. */ - err = qtouch_read_addr(ts, QTM_OBP_ID_INFO_ADDR, &qtm_info, - sizeof(qtm_info)); - if (err != 0) { - pr_err("%s: Cannot read info object block\n", __func__); - goto err_read_info_block; - } - - pr_info("%s: Build version is 0x%x\n", __func__, qtm_info.version); - - if (qtm_info.num_objs == 0) { - pr_err("%s: Device (0x%x/0x%x/0x%x/0x%x) does not export any " - "objects.\n", __func__, qtm_info.family_id, - qtm_info.variant_id, qtm_info.version, qtm_info.build); - err = -ENODEV; - goto err_no_objects; - } - - info_blk_size = sizeof(qtm_info) + qtm_info.num_objs * sizeof(entry); - info_blk_buf = kzalloc(info_blk_size, GFP_KERNEL); - if (info_blk_buf == NULL) { - pr_err("%s: Can't allocate write buffer (%d)\n", - __func__, info_blk_size); - err = -ENOMEM; - goto err_no_objects; - } - info_blk_start = info_blk_buf; - memcpy(info_blk_buf, (void *)&qtm_info, sizeof(qtm_info)); - info_blk_buf += sizeof(qtm_info); - addr = QTM_OBP_ID_INFO_ADDR + sizeof(qtm_info); - report_id = 1; - - /* Clear the object table */ - for (i = 0; i < QTM_OBP_MAX_OBJECT_NUM; ++i) { - ts->obj_tbl[i].entry.type = 0; - ts->obj_tbl[i].entry.addr = 0; - ts->obj_tbl[i].entry.size = 0; - ts->obj_tbl[i].entry.num_inst = 0; - ts->obj_tbl[i].entry.num_rids = 0; - ts->obj_tbl[i].report_id_min = 0; - ts->obj_tbl[i].report_id_max = 0; - } - - pr_info("%s: Num obj: %i addr: %i\n", __func__, qtm_info.num_objs, addr); - /* read out the object entries table */ - for (i = 0; i < qtm_info.num_objs; ++i) { - struct qtm_object *obj; - - pr_info("%s: Reading addr: %i\n", __func__, addr); - err = qtouch_read_addr(ts, addr, &entry, sizeof(entry)); - if (err != 0) { - pr_err("%s: Can't read object (%d) entry.\n", - __func__, i); - err = -EIO; - goto err_read_entry; - } - - memcpy(info_blk_buf, (void *)&entry, sizeof(entry)); - info_blk_buf += sizeof(entry); - addr += sizeof(entry); - - entry.size++; - entry.num_inst++; - - pr_info("%s: Object %d @ 0x%04x (%d) insts %d rep_ids %d\n", - __func__, entry.type, entry.addr, entry.size, - entry.num_inst, entry.num_rids); - - if (entry.type >= QTM_OBP_MAX_OBJECT_NUM) { - pr_warning("%s: Unknown object type (%d) encountered\n", - __func__, entry.type); - /* Not fatal */ - continue; - } - - /* save the message_procesor msg_size for easy reference. */ - if (entry.type == QTM_OBJ_GEN_MSG_PROC) { - if (ts->pdata->flags & QTOUCH_USE_MSG_CRC) { - ts->msg_size = entry.size; - entry.addr |= QTOUCH_USE_MSG_CRC_MASK; - } else { - ts->msg_size = entry.size - 1; - } - } - - obj = create_obj(ts, &entry); - /* set the report_id range that the object is responsible for */ - if ((obj->entry.num_rids * obj->entry.num_inst) != 0) { - obj->report_id_min = report_id; - report_id += obj->entry.num_rids * obj->entry.num_inst; - obj->report_id_max = report_id - 1; - } - } - - if (!ts->msg_size) { - pr_err("%s: Message processing object not found. Bailing.\n", - __func__); - err = -ENODEV; - goto err_no_msg_proc; - } - - /* verify that some basic objects are present. These objects are - * assumed to be present by the rest of the driver, so fail out now - * if the firmware is busted. */ - if (!find_obj(ts, QTM_OBJ_GEN_PWR_CONF) || - !find_obj(ts, QTM_OBJ_GEN_ACQUIRE_CONF) || - !find_obj(ts, QTM_OBJ_GEN_MSG_PROC) || - !find_obj(ts, QTM_OBJ_GEN_CMD_PROC)) { - pr_err("%s: Required objects are missing\n", __func__); - err = -ENOENT; - goto err_missing_objs; - } - - err = qtouch_read_addr(ts, addr, &their_csum, sizeof(their_csum)); - if (err != 0) { - pr_err("%s: Unable to read remote checksum\n", __func__); - err = -ENODEV; - goto err_no_checksum; - } - - our_csum = calc_csum(our_csum, info_blk_start, info_blk_size); - - if (our_csum != their_csum) { - pr_warning("%s: Checksum mismatch (0x%08x != 0x%08x)\n", - __func__, our_csum, their_csum); -#ifndef IGNORE_CHECKSUM_MISMATCH - err = -ENODEV; - goto err_bad_checksum; -#endif - } - - pr_info("%s: %s found.\n" - " family 0x%x, variant 0x%x, ver 0x%x, build 0x%x\n" - " matrix %dx%d, %d objects, info blk chksum 0x%x\n", __func__, - QTOUCH_TS_NAME, qtm_info.family_id, qtm_info.variant_id, - qtm_info.version, qtm_info.build, qtm_info.matrix_x_size, - qtm_info.matrix_y_size, qtm_info.num_objs, our_csum); - - ts->eeprom_checksum = ts->pdata->nv_checksum; - ts->family_id = qtm_info.family_id; - ts->variant_id = qtm_info.variant_id; - ts->fw_version = qtm_info.version; - ts->build_version = qtm_info.build; - kfree(info_blk_start); - - return 0; - -#ifndef IGNORE_CHECKSUM_MISMATCH -err_bad_checksum: -#endif -err_no_checksum: -err_missing_objs: -err_no_msg_proc: -err_read_entry: - kfree(info_blk_start); -err_no_objects: -err_read_info_block: - return err; -} - -static int qtouch_ts_unregister_input(struct qtouch_ts_data *ts) -{ - input_unregister_device(ts->input_dev); - ts->input_dev = NULL; - return 0; -} - -static void qtouch_ts_boot_work_func(struct work_struct *work) -{ - int err = 0; - struct qtouch_ts_data *ts = container_of(work, - struct qtouch_ts_data, - boot_work); - unsigned char boot_msg[3]; - - if (ts->status == 0xff) { - pr_err("%s: Entered in Wrong Mode\n", __func__); - goto touch_to_normal_mode; - } - - err = qtouch_read(ts, &boot_msg, sizeof(boot_msg)); - if (err) { - pr_err("%s: Cannot read message\n", __func__); - goto done; - } - if (qtouch_tsdebug & 8) - pr_err("%s: Message is 0x%X err is %i\n", - __func__, boot_msg[0], err); - - if (boot_msg[0] == QTM_OBP_BOOT_CRC_CHECK) { - if (qtouch_tsdebug & 8) - pr_err("%s: CRC Check\n", __func__); - goto done; - } else if (boot_msg[0] == QTM_OBP_BOOT_CRC_FAIL) { - if (qtouch_tsdebug & 8) - pr_err("%s: Boot size %i current pkt size %i\n", - __func__, ts->boot_pkt_size, ts->current_pkt_sz); - - if (ts->fw_error_count > 3) { - pr_err("%s: Resetting the IC fw upgrade failed\n", - __func__); - goto reset_touch_ic; - } else { - /* If this is a failure on the first packet then - reset the boot packet size to 0 */ - if (!ts->fw_error_count) { - if (ts->current_pkt_sz == 0) { - ts->current_pkt_sz = ts->boot_pkt_size; - ts->boot_pkt_size -= ts->boot_pkt_size; - } - } - ts->fw_error_count++; - pr_err("%s: Frame CRC check failed %i times\n", - __func__, ts->fw_error_count); - } - goto done; - } else if (boot_msg[0] == QTM_OBP_BOOT_CRC_PASSED) { - if (qtouch_tsdebug & 8) - pr_err("%s: Frame CRC check passed\n", __func__); - - ts->status = - (ts->boot_pkt_size * 100) / ts->touch_fw_size; - - ts->boot_pkt_size += ts->current_pkt_sz; - ts->fw_error_count = 0; - - /* Check to see if the update is done if it is - then register the touch with the system */ - if (ts->boot_pkt_size == ts->touch_fw_size) { - pr_info("%s: Touch FW update done\n", __func__); - ts->status = 100; - goto touch_to_normal_mode; - } - goto done; - } else if (boot_msg[0] & QTM_OBP_BOOT_WAIT_FOR_DATA) { - if (qtouch_tsdebug & 8) - pr_err("%s: Data sent so far %i\n", - __func__, ts->boot_pkt_size); - - /* Don't change the packet size if there was a failure */ - if (!ts->fw_error_count) { - ts->current_pkt_sz = - ((ts->touch_fw[ts->boot_pkt_size] << 8) | - ts->touch_fw[ts->boot_pkt_size + 1]) + 2; - } - if (qtouch_tsdebug & 8) - pr_err("%s: Size of the next packet is %i\n", - __func__, ts->current_pkt_sz); - - err = qtouch_write(ts, &ts->touch_fw[ts->boot_pkt_size], - ts->current_pkt_sz); - if (err != ts->current_pkt_sz) { - pr_err("%s: Could not write the packet %i\n", - __func__, err); - ts->status = 0xff; - goto reset_touch_ic; - } - } else { - pr_err("%s: Message is 0x%X is not handled\n", - __func__, boot_msg[0]); - } - -done: - enable_irq(ts->client->irq); - return; - -reset_touch_ic: - qtouch_force_reset(ts, 0); -touch_to_normal_mode: - if (ts->touch_fw) - release_firmware(fw_entry); - ts->client->addr = ts->org_i2c_addr; - ts->mode = 0; - /* Wait for the IC to recover */ - msleep(QTM_OBP_SLEEP_WAIT_FOR_RESET); - err = qtouch_process_info_block(ts); - if (err != 0) { - pr_err("%s:Cannot read info block %i\n", __func__, err); - goto err_return; - } - err = qtouch_ts_prep_msg_proc(ts); - if (err != 0) { - pr_err("%s: setting message proc failed %i\n", __func__, err); - goto err_return; - } - - enable_irq(ts->client->irq); -err_return: - return; -} - -static void qtouch_ts_work_func(struct work_struct *work) -{ - struct qtouch_ts_data *ts = - container_of(work, struct qtouch_ts_data, work); - struct qtm_obj_message *msg; - struct qtm_object *obj; - int ret; - - msg = qtouch_read_msg(ts); - if (msg == NULL) { - pr_err("%s: Cannot read message\n", __func__); - goto done; - } - - obj = find_object_rid(ts, msg->report_id); - if (!obj) { - pr_err("%s: Unknown object for report_id %d\n", __func__, - msg->report_id); - goto done; - } - - ret = qtouch_handle_msg(ts, obj, msg); - if (ret != 0) { - pr_err("%s: Unable to process message for obj %d, " - "report_id %d\n", __func__, obj->entry.type, - msg->report_id); - goto done; - } - -done: - if (qtouch_disable_touch) - pr_err("%s: Not enabling touch\n", __func__); - else - enable_irq(ts->client->irq); -} - -static int qtouch_set_boot_mode(struct qtouch_ts_data *ts) -{ - unsigned char FWupdateInfo[3]; - int err; - int try_again = 0; - - err = qtouch_read(ts, FWupdateInfo, 3); - if (err) - pr_err("%s: Could not read back data\n", __func__); - - while ((FWupdateInfo[0] & QTM_OBP_BOOT_CMD_MASK) != QTM_OBP_BOOT_WAIT_FOR_DATA) { - err = qtouch_read(ts, FWupdateInfo, 3); - if (err) - pr_err("%s: Could not read back data\n", __func__); - - if ((FWupdateInfo[0] & QTM_OBP_BOOT_CMD_MASK) == QTM_OBP_BOOT_WAIT_ON_BOOT_CMD) { - FWupdateInfo[0] = 0xDC; - FWupdateInfo[1] = 0xAA; - err = qtouch_write(ts, FWupdateInfo, 2); - if (err != 2) { - pr_err("%s: Could not write to BL %i\n", - __func__, err); - return -EIO; - } - } else if (try_again > 10) { - pr_err("%s: Cannot get into bootloader mode\n", - __func__); - return -ENODEV; - } else { - try_again++; - msleep(QTM_OBP_SLEEP_WAIT_FOR_BOOT); - } - } - - return err; -} - -static ssize_t qtouch_irq_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev, - struct i2c_client, dev); - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - return sprintf(buf, "%u\n", atomic_read(&ts->irq_enabled)); -} - -static ssize_t qtouch_irq_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - struct i2c_client *client = container_of(dev, - struct i2c_client, dev); - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - int err = 0; - unsigned long value; - struct qtm_obj_message *msg; - - if (size > 2) - return -EINVAL; - - err = strict_strtoul(buf, 10, &value); - if (err != 0) - return err; - - switch (value) { - case 0: - if (atomic_cmpxchg(&ts->irq_enabled, 1, 0)) { - pr_info("touch irq disabled!\n"); - disable_irq_nosync(ts->client->irq); - } - err = size; - break; - case 1: - if (!atomic_cmpxchg(&ts->irq_enabled, 0, 1)) { - pr_info("touch irq enabled!\n"); - msg = qtouch_read_msg(ts); - if (msg == NULL) - pr_err("%s: Cannot read message\n", __func__); - enable_irq(ts->client->irq); - } - err = size; - break; - default: - pr_info("qtouch_irq_enable failed -> irq_enabled = %d\n", - atomic_read(&ts->irq_enabled)); - err = -EINVAL; - break; - } - - return err; -} - -static DEVICE_ATTR(irq_enable, 0644, qtouch_irq_status, qtouch_irq_enable); - -static ssize_t qtouch_update_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev, - struct i2c_client, dev); - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - - return sprintf(buf, "%u\n", ts->status); -} - -static DEVICE_ATTR(update_status, 0644, qtouch_update_status, NULL); - -static ssize_t qtouch_fw_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev, - struct i2c_client, dev); - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - - return sprintf(buf, "0x%X%X\n", ts->fw_version, ts->build_version); -} - -static DEVICE_ATTR(fw_version, 0644, qtouch_fw_version, NULL); - -static int qtouch_ts_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct qtouch_ts_platform_data *pdata = client->dev.platform_data; - struct qtouch_ts_data *ts; - int err; - unsigned char boot_info; - int loop_count; - - if (pdata == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - } else if (!client->irq) { - pr_err("%s: polling mode currently not supported\n", __func__); - return -ENODEV; - } else if (!pdata->hw_reset) { - pr_err("%s: Must supply a hw reset function\n", __func__); - return -ENODEV; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s: need I2C_FUNC_I2C\n", __func__); - return -ENODEV; - } - - ts = kzalloc(sizeof(struct qtouch_ts_data), GFP_KERNEL); - if (ts == NULL) { - err = -ENOMEM; - goto err_alloc_data_failed; - } - ts->pdata = pdata; - ts->client = client; - i2c_set_clientdata(client, ts); - ts->checksum_cnt = 0; - ts->fw_version = 0; - ts->build_version = 0; - ts->fw_error_count = 0; - ts->current_pkt_sz = 0; - ts->x_delta = ts->pdata->x_delta; - ts->y_delta = ts->pdata->y_delta; - atomic_set(&ts->irq_enabled, 1); - atomic_set(&ts->process_open, 1); - ts->enable_irq_flag = 1; - ts->status = 0xfe; - ts->touch_fw_size = 0; - ts->touch_fw_image = NULL; - ts->touch_fw = NULL; - ts->base_fw_version = 0; - - ts->xpos_rshift_lsb = 6; - ts->xpos_lshift_msb = 2; - ts->ypos_rshift_lsb = 2; - ts->ypos_lshift_msb = 2; - - if (ts->pdata->multi_touch_cfg.x_res > 1023) { - ts->xpos_rshift_lsb = 4; - ts->xpos_lshift_msb = 4; - } - if (ts->pdata->multi_touch_cfg.y_res > 1023) { - ts->ypos_rshift_lsb = 0; - ts->ypos_lshift_msb = 4; - } - - pr_info("%s: xpos_msb %d xpos_lsb %d ypos_msb %d ypos_lsb %d\n", __func__, - ts->xpos_lshift_msb, ts->xpos_rshift_lsb, - ts->ypos_lshift_msb, ts->ypos_rshift_lsb); - - qtouch_force_reset(ts, 0); - msleep(QTM_OBP_SLEEP_WAIT_FOR_HW_RESET); - err = qtouch_process_info_block(ts); - - if (err == 0) { - pr_info("%s: FW version is 0x%X Build 0x%X\n", __func__, - ts->fw_version, ts->build_version); - - if ((ts->family_id == ts->pdata->touch_fw_cfg.family_id) - && (ts->variant_id == ts->pdata->touch_fw_cfg.variant_id)) { - pr_info("%s: Chip type matched\n", __func__); - - if ((ts->fw_version != ts->pdata->touch_fw_cfg.fw_version) - || (ts->build_version != ts->pdata->touch_fw_cfg.fw_build)) { - pr_info("%s: Reflash needed\n", __func__); - ts->touch_fw_image = ts->pdata->touch_fw_cfg.fw_name; - ts->base_fw_version = ts->pdata->touch_fw_cfg.base_fw_version; - } else { - pr_info("%s: Reflash not needed\n", __func__); - } - } - - if (ts->touch_fw_image != NULL) { - /* Reset the chip into bootloader mode */ - if (ts->fw_version >= ts->base_fw_version) { - qtouch_force_reset(ts, 2); - msleep(QTM_OBP_SLEEP_WAIT_FOR_HW_RESET); - - ts->org_i2c_addr = ts->client->addr; - ts->client->addr = ts->pdata->boot_i2c_addr; - } else { - pr_err("%s:FW 0x%X does not support boot mode\n", - __func__, ts->fw_version); - ts->touch_fw_image = NULL; - } - } - } else { - pr_info("%s:Cannot read info block %i, checking for bootloader mode.\n", __func__, err); - - qtouch_force_reset(ts, 0); - msleep(QTM_OBP_SLEEP_WAIT_FOR_HW_RESET); - - ts->org_i2c_addr = ts->client->addr; - ts->client->addr = ts->pdata->boot_i2c_addr; - - err = qtouch_read(ts, &boot_info, 1); - if (err) { - pr_err("%s:Read failed %d\n", __func__, err); - } else { - pr_info("%s:Data read 0x%x\n", __func__, boot_info); - loop_count = 0; - while ((boot_info & QTM_OBP_BOOT_CMD_MASK) != QTM_OBP_BOOT_WAIT_ON_BOOT_CMD) { - err = qtouch_read(ts, &boot_info, 1); - if (err) { - pr_err("%s:Read failed %d\n", __func__, err); - break; - } - pr_info("%s:Data read 0x%x\n", __func__, boot_info); - loop_count++; - if (loop_count == 10) { - err = 1; - break; - } - } - } - if (!err) { - boot_info &= QTM_OBP_BOOT_VERSION_MASK; - pr_info("%s:Bootloader version %d\n", __func__, boot_info); - - if (boot_info == ts->pdata->touch_fw_cfg.boot_version) { - pr_info("%s: Chip type matched\n", __func__); - ts->touch_fw_image = ts->pdata->touch_fw_cfg.fw_name; - ts->base_fw_version = ts->pdata->touch_fw_cfg.base_fw_version; - } - } - } - - INIT_WORK(&ts->work, qtouch_ts_work_func); - INIT_WORK(&ts->boot_work, qtouch_ts_boot_work_func); - - if (ts->touch_fw_image != NULL) { - err = qtouch_set_boot_mode(ts); - if (err < 0) { - pr_err("%s: Failed setting IC in boot mode %i\n", - __func__, err); - /* We must have been in boot mode to begin with - or the IC is not present so just exit out of probe */ - if (ts->fw_version == 0) { - ts->status = 0xfd; - return err; - } - - ts->client->addr = ts->org_i2c_addr; - qtouch_force_reset(ts, 0); - msleep(QTM_OBP_SLEEP_WAIT_FOR_HW_RESET); - pr_err("%s: I2C address is 0x%X\n", - __func__, ts->client->addr); - err = qtouch_process_info_block(ts); - if (err) { - pr_err("%s: Failed reading info block %i\n", - __func__, err); - goto err_reading_info_block; - } - goto err_boot_mode_failure; - } - - ts->mode = 1; - goto finish_touch_setup; - - } - -/* If the update should fail the touch should still work */ -err_boot_mode_failure: - ts->mode = 0; - err = qtouch_ts_prep_msg_proc(ts); - if (err != 0) { - pr_err("%s: setting message proc failed %i\n", __func__, err); - goto err_set_msg_proc; - } - -finish_touch_setup: - err = qtouch_ts_register_input(ts); - if (err != 0) { - pr_err("%s: Registering input failed %i\n", __func__, err); - goto err_input_register_dev; - } - - err = request_irq(ts->client->irq, qtouch_ts_irq_handler, - IRQ_DISABLED | pdata->irqflags, "qtouch_ts_int", ts); - if (err != 0) { - pr_err("%s: request_irq (%d) failed\n", __func__, - ts->client->irq); - goto err_request_irq; - } - pr_info("%s: request_irq [%d] success.\n", __func__, - ts->client->irq); - - err = device_create_file(&ts->client->dev, &dev_attr_irq_enable); - if (err != 0) { - pr_err("%s:File device creation failed: %d\n", __func__, err); - err = -ENODEV; - goto err_create_file_failed; - } - - err = device_create_file(&ts->client->dev, &dev_attr_update_status); - if (err != 0) { - pr_err("%s:File device creation failed: %d\n", __func__, err); - err = -ENODEV; - goto err_create_update_status_failed; - } - - err = device_create_file(&ts->client->dev, &dev_attr_fw_version); - if (err != 0) { - pr_err("%s:File device creation failed: %d\n", __func__, err); - err = -ENODEV; - goto err_create_fw_version_file_failed; - } - - ts->regulator = regulator_get(&ts->client->dev, "vio"); - if (!IS_ERR_OR_NULL(ts->regulator)) - regulator_enable(ts->regulator); - -#ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - ts->early_suspend.suspend = qtouch_ts_early_suspend; - ts->early_suspend.resume = qtouch_ts_late_resume; - register_early_suspend(&ts->early_suspend); -#endif - - return 0; - -err_create_fw_version_file_failed: - device_remove_file(&ts->client->dev, &dev_attr_update_status); -err_create_update_status_failed: - device_remove_file(&ts->client->dev, &dev_attr_irq_enable); -err_create_file_failed: - free_irq(ts->client->irq, ts); -err_request_irq: - qtouch_ts_unregister_input(ts); - -err_set_msg_proc: -err_input_register_dev: -err_reading_info_block: - i2c_set_clientdata(client, NULL); - kfree(ts); - -err_alloc_data_failed: - return err; -} - -static int qtouch_ts_remove(struct i2c_client *client) -{ - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - - if (!IS_ERR_OR_NULL(ts->regulator)) - regulator_put(ts->regulator); - - device_remove_file(&ts->client->dev, &dev_attr_irq_enable); - device_remove_file(&ts->client->dev, &dev_attr_update_status); - device_remove_file(&ts->client->dev, &dev_attr_fw_version); - - unregister_early_suspend(&ts->early_suspend); - free_irq(ts->client->irq, ts); - qtouch_ts_unregister_input(ts); - i2c_set_clientdata(client, NULL); - kfree(ts); - return 0; -} - -static int qtouch_ts_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - int ret; - if (qtouch_tsdebug & 4) - pr_info("%s: Suspending\n", __func__); - - if (!atomic_read(&ts->irq_enabled)) - return 0; - - if (ts->mode == 1) - return -EBUSY; - - if (ts->enable_irq_flag) - disable_irq_nosync(ts->client->irq); - ret = cancel_work_sync(&ts->work); - if (ret) { /* if work was pending disable-count is now 2 */ - pr_info("%s: Pending work item\n", __func__); - enable_irq(ts->client->irq); - } - - ret = qtouch_power_config(ts, 0); - if (ret < 0) - pr_err("%s: Cannot write power config\n", __func__); - - if (ts->pdata->hw_suspend) - ts->pdata->hw_suspend(1); - - if (!IS_ERR_OR_NULL(ts->regulator)) - regulator_disable(ts->regulator); - - return 0; -} - -static int qtouch_ts_resume(struct i2c_client *client) -{ - struct qtouch_ts_data *ts = i2c_get_clientdata(client); - int ret; - int i; - struct qtm_object *obj; - - if (qtouch_tsdebug & 4) - pr_info("%s: Resuming\n", __func__); - - if (!atomic_read(&ts->irq_enabled)) - return 0; - - if (ts->mode == 1) - return -EBUSY; - - if (!IS_ERR_OR_NULL(ts->regulator)) - regulator_enable(ts->regulator); - - if (ts->pdata->hw_suspend) - ts->pdata->hw_suspend(0); - - /* If we were suspended while a touch was happening - we need to tell the upper layers so they do not hang - waiting on the liftoff that will not come. */ - for (i = 0; i < ts->pdata->multi_touch_cfg.num_touch; i++) { - if (qtouch_tsdebug & 4) - pr_info("%s: Finger %i down state %i\n", - __func__, i, ts->finger_data[i].down); - if (ts->finger_data[i].down == 0) - continue; - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i); - input_mt_sync(ts->input_dev); - memset(&ts->finger_data[i], 0, sizeof(struct coordinate_map)); - } - input_sync(ts->input_dev); - - ret = qtouch_power_config(ts, 1); - if (ret < 0) { - pr_err("%s: Cannot write power config\n", __func__); - ts->enable_irq_flag = 0; - return -EIO; - } - ret = qtouch_force_calibration(ts); - if (ret != 0) { - pr_err("%s: Unable to recalibrate after power config\n", __func__); - return ret; - } - - /* Point the address pointer to the message processor. - * Must do this before enabling interrupts */ - obj = find_obj(ts, QTM_OBJ_GEN_MSG_PROC); - ret = qtouch_set_addr(ts, obj->entry.addr); - if (ret != 0) { - pr_err("%s: Can't to set addr to msg processor\n", __func__); - ts->enable_irq_flag = 0; - return -EIO; - } - - enable_irq(ts->client->irq); - ts->enable_irq_flag = 1; - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void qtouch_ts_early_suspend(struct early_suspend *handler) -{ - struct qtouch_ts_data *ts; - - ts = container_of(handler, struct qtouch_ts_data, early_suspend); - qtouch_ts_suspend(ts->client, PMSG_SUSPEND); -} - -static void qtouch_ts_late_resume(struct early_suspend *handler) -{ - struct qtouch_ts_data *ts; - - ts = container_of(handler, struct qtouch_ts_data, early_suspend); - qtouch_ts_resume(ts->client); -} -#endif - -/******** init ********/ -static const struct i2c_device_id qtouch_ts_id[] = { - { QTOUCH_TS_NAME, 0 }, - { } -}; - -static struct i2c_driver qtouch_ts_driver = { - .probe = qtouch_ts_probe, - .remove = qtouch_ts_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = qtouch_ts_suspend, - .resume = qtouch_ts_resume, -#endif - .id_table = qtouch_ts_id, - .driver = { - .name = QTOUCH_TS_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __devinit qtouch_ts_init(void) -{ - qtouch_ts_wq = create_singlethread_workqueue("qtouch_obp_ts_wq"); - if (qtouch_ts_wq == NULL) { - pr_err("%s: No memory for qtouch_ts_wq\n", __func__); - return -ENOMEM; - } - return i2c_add_driver(&qtouch_ts_driver); -} - -static void __exit qtouch_ts_exit(void) -{ - i2c_del_driver(&qtouch_ts_driver); - if (qtouch_ts_wq) - destroy_workqueue(qtouch_ts_wq); -} - -module_init(qtouch_ts_init); -module_exit(qtouch_ts_exit); - -MODULE_AUTHOR("Dima Zavin "); -MODULE_DESCRIPTION("Quantum OBP Touchscreen Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c deleted file mode 100644 index 5729602cbb63..000000000000 --- a/drivers/input/touchscreen/synaptics_i2c_rmi.c +++ /dev/null @@ -1,675 +0,0 @@ -/* drivers/input/keyboard/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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct workqueue_struct *synaptics_wq; - -struct synaptics_ts_data { - uint16_t addr; - struct i2c_client *client; - struct input_dev *input_dev; - int use_irq; - bool has_relative_report; - struct hrtimer timer; - struct work_struct work; - uint16_t max[2]; - int snap_state[2][2]; - int snap_down_on[2]; - int snap_down_off[2]; - int snap_up_on[2]; - int snap_up_off[2]; - int snap_down[2]; - int snap_up[2]; - uint32_t flags; - int reported_finger_count; - int8_t sensitivity_adjust; - int (*power)(int on); - struct early_suspend early_suspend; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void synaptics_ts_early_suspend(struct early_suspend *h); -static void synaptics_ts_late_resume(struct early_suspend *h); -#endif - -static int synaptics_init_panel(struct synaptics_ts_data *ts) -{ - int ret; - - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - goto err_page_select_failed; - } - ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */ - if (ret < 0) - printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n"); - - ret = i2c_smbus_write_byte_data(ts->client, 0x44, - ts->sensitivity_adjust); - if (ret < 0) - pr_err("synaptics_ts: failed to set Sensitivity Adjust\n"); - -err_page_select_failed: - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */ - if (ret < 0) - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n"); - return ret; -} - -static void synaptics_ts_work_func(struct work_struct *work) -{ - int i; - int ret; - int bad_data = 0; - struct i2c_msg msg[2]; - uint8_t start_reg; - uint8_t buf[15]; - struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); - int buf_len = ts->has_relative_report ? 15 : 13; - - msg[0].addr = ts->client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &start_reg; - start_reg = 0x00; - msg[1].addr = ts->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = buf_len; - msg[1].buf = buf; - - /* printk("synaptics_ts_work_func\n"); */ - for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) { - ret = i2c_transfer(ts->client->adapter, msg, 2); - if (ret < 0) { - printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n"); - bad_data = 1; - } else { - /* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */ - /* " %x %x %x %x %x %x %x %x %x, ret %d\n", */ - /* buf[0], buf[1], buf[2], buf[3], */ - /* buf[4], buf[5], buf[6], buf[7], */ - /* buf[8], buf[9], buf[10], buf[11], */ - /* buf[12], buf[13], buf[14], ret); */ - if ((buf[buf_len - 1] & 0xc0) != 0x40) { - printk(KERN_WARNING "synaptics_ts_work_func:" - " bad read %x %x %x %x %x %x %x %x %x" - " %x %x %x %x %x %x, ret %d\n", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7], - buf[8], buf[9], buf[10], buf[11], - buf[12], buf[13], buf[14], ret); - if (bad_data) - synaptics_init_panel(ts); - bad_data = 1; - continue; - } - bad_data = 0; - if ((buf[buf_len - 1] & 1) == 0) { - /* printk("read %d coordinates\n", i); */ - break; - } else { - int pos[2][2]; - int f, a; - int base; - /* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */ - /* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */ - int z = buf[1]; - int w = buf[0] >> 4; - int finger = buf[0] & 7; - - /* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */ - /* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */ - /* int z2 = buf[1+6]; */ - /* int w2 = buf[0+6] >> 4; */ - /* int finger2 = buf[0+6] & 7; */ - - /* int dx = (int8_t)buf[12]; */ - /* int dy = (int8_t)buf[13]; */ - int finger2_pressed; - - /* printk("x %4d, y %4d, z %3d, w %2d, F %d, 2nd: x %4d, y %4d, z %3d, w %2d, F %d, dx %4d, dy %4d\n", */ - /* x, y, z, w, finger, */ - /* x2, y2, z2, w2, finger2, */ - /* dx, dy); */ - - base = 2; - for (f = 0; f < 2; f++) { - uint32_t flip_flag = SYNAPTICS_FLIP_X; - for (a = 0; a < 2; a++) { - int p = buf[base + 1]; - p |= (uint16_t)(buf[base] & 0x1f) << 8; - if (ts->flags & flip_flag) - p = ts->max[a] - p; - if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) { - if (ts->snap_state[f][a]) { - if (p <= ts->snap_down_off[a]) - p = ts->snap_down[a]; - else if (p >= ts->snap_up_off[a]) - p = ts->snap_up[a]; - else - ts->snap_state[f][a] = 0; - } else { - if (p <= ts->snap_down_on[a]) { - p = ts->snap_down[a]; - ts->snap_state[f][a] = 1; - } else if (p >= ts->snap_up_on[a]) { - p = ts->snap_up[a]; - ts->snap_state[f][a] = 1; - } - } - } - pos[f][a] = p; - base += 2; - flip_flag <<= 1; - } - base += 2; - if (ts->flags & SYNAPTICS_SWAP_XY) - swap(pos[f][0], pos[f][1]); - } - if (z) { - input_report_abs(ts->input_dev, ABS_X, pos[0][0]); - input_report_abs(ts->input_dev, ABS_Y, pos[0][1]); - } - input_report_abs(ts->input_dev, ABS_PRESSURE, z); - input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w); - input_report_key(ts->input_dev, BTN_TOUCH, finger); - finger2_pressed = finger > 1 && finger != 7; - input_report_key(ts->input_dev, BTN_2, finger2_pressed); - if (finger2_pressed) { - input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]); - input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]); - } - - if (!finger) - z = 0; - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]); - input_mt_sync(ts->input_dev); - if (finger2_pressed) { - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]); - input_mt_sync(ts->input_dev); - } else if (ts->reported_finger_count > 1) { - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); - input_mt_sync(ts->input_dev); - } - ts->reported_finger_count = finger; - input_sync(ts->input_dev); - } - } - } - if (ts->use_irq) - enable_irq(ts->client->irq); -} - -static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) -{ - struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer); - /* printk("synaptics_ts_timer_func\n"); */ - - queue_work(synaptics_wq, &ts->work); - - hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); - return HRTIMER_NORESTART; -} - -static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id) -{ - struct synaptics_ts_data *ts = dev_id; - - /* printk("synaptics_ts_irq_handler\n"); */ - disable_irq_nosync(ts->client->irq); - queue_work(synaptics_wq, &ts->work); - return IRQ_HANDLED; -} - -static int synaptics_ts_probe( - struct i2c_client *client, const struct i2c_device_id *id) -{ - struct synaptics_ts_data *ts; - uint8_t buf0[4]; - uint8_t buf1[8]; - struct i2c_msg msg[2]; - int ret = 0; - uint16_t max_x, max_y; - int fuzz_x, fuzz_y, fuzz_p, fuzz_w; - struct synaptics_i2c_rmi_platform_data *pdata; - unsigned long irqflags; - int inactive_area_left; - int inactive_area_right; - int inactive_area_top; - int inactive_area_bottom; - int snap_left_on; - int snap_left_off; - int snap_right_on; - int snap_right_off; - int snap_top_on; - int snap_top_off; - int snap_bottom_on; - int snap_bottom_off; - uint32_t panel_version; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n"); - ret = -ENODEV; - goto err_check_functionality_failed; - } - - ts = kzalloc(sizeof(*ts), GFP_KERNEL); - if (ts == NULL) { - ret = -ENOMEM; - goto err_alloc_data_failed; - } - INIT_WORK(&ts->work, synaptics_ts_work_func); - ts->client = client; - i2c_set_clientdata(client, ts); - pdata = client->dev.platform_data; - if (pdata) - ts->power = pdata->power; - if (ts->power) { - ret = ts->power(1); - if (ret < 0) { - printk(KERN_ERR "synaptics_ts_probe power on failed\n"); - goto err_power_failed; - } - } - - ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); - /* fail? */ - } - { - int retry = 10; - while (retry-- > 0) { - ret = i2c_smbus_read_byte_data(ts->client, 0xe4); - if (ret >= 0) - break; - msleep(100); - } - } - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret); - panel_version = ret << 8; - ret = i2c_smbus_read_byte_data(ts->client, 0xe5); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret); - panel_version |= ret; - - ret = i2c_smbus_read_byte_data(ts->client, 0xe3); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret); - - if (pdata) { - while (pdata->version > panel_version) - pdata++; - ts->flags = pdata->flags; - ts->sensitivity_adjust = pdata->sensitivity_adjust; - irqflags = pdata->irqflags; - inactive_area_left = pdata->inactive_left; - inactive_area_right = pdata->inactive_right; - inactive_area_top = pdata->inactive_top; - inactive_area_bottom = pdata->inactive_bottom; - snap_left_on = pdata->snap_left_on; - snap_left_off = pdata->snap_left_off; - snap_right_on = pdata->snap_right_on; - snap_right_off = pdata->snap_right_off; - snap_top_on = pdata->snap_top_on; - snap_top_off = pdata->snap_top_off; - snap_bottom_on = pdata->snap_bottom_on; - snap_bottom_off = pdata->snap_bottom_off; - fuzz_x = pdata->fuzz_x; - fuzz_y = pdata->fuzz_y; - fuzz_p = pdata->fuzz_p; - fuzz_w = pdata->fuzz_w; - } else { - irqflags = 0; - inactive_area_left = 0; - inactive_area_right = 0; - inactive_area_top = 0; - inactive_area_bottom = 0; - snap_left_on = 0; - snap_left_off = 0; - snap_right_on = 0; - snap_right_off = 0; - snap_top_on = 0; - snap_top_off = 0; - snap_bottom_on = 0; - snap_bottom_off = 0; - fuzz_x = 0; - fuzz_y = 0; - fuzz_p = 0; - fuzz_w = 0; - } - - ret = i2c_smbus_read_byte_data(ts->client, 0xf0); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret); - - ret = i2c_smbus_read_byte_data(ts->client, 0xf1); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret); - - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); - goto err_detect_failed; - } - - msg[0].addr = ts->client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf0; - buf0[0] = 0xe0; - msg[1].addr = ts->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 8; - msg[1].buf = buf1; - ret = i2c_transfer(ts->client->adapter, msg, 2); - if (ret < 0) { - printk(KERN_ERR "i2c_transfer failed\n"); - goto err_detect_failed; - } - printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n", - buf1[0], buf1[1], buf1[2], buf1[3], - buf1[4], buf1[5], buf1[6], buf1[7]); - - ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); - goto err_detect_failed; - } - ret = i2c_smbus_read_word_data(ts->client, 0x02); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->has_relative_report = !(ret & 0x100); - printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret); - ret = i2c_smbus_read_word_data(ts->client, 0x04); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); - ret = i2c_smbus_read_word_data(ts->client, 0x06); - if (ret < 0) { - printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); - goto err_detect_failed; - } - ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); - if (ts->flags & SYNAPTICS_SWAP_XY) - swap(max_x, max_y); - - ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */ - if (ret < 0) { - printk(KERN_ERR "synaptics_init_panel failed\n"); - goto err_detect_failed; - } - - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) { - ret = -ENOMEM; - printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); - goto err_input_dev_alloc_failed; - } - ts->input_dev->name = "synaptics-rmi-touchscreen"; - set_bit(EV_SYN, ts->input_dev->evbit); - set_bit(EV_KEY, ts->input_dev->evbit); - set_bit(BTN_TOUCH, ts->input_dev->keybit); - set_bit(BTN_2, ts->input_dev->keybit); - set_bit(EV_ABS, ts->input_dev->evbit); - inactive_area_left = inactive_area_left * max_x / 0x10000; - inactive_area_right = inactive_area_right * max_x / 0x10000; - inactive_area_top = inactive_area_top * max_y / 0x10000; - inactive_area_bottom = inactive_area_bottom * max_y / 0x10000; - snap_left_on = snap_left_on * max_x / 0x10000; - snap_left_off = snap_left_off * max_x / 0x10000; - snap_right_on = snap_right_on * max_x / 0x10000; - snap_right_off = snap_right_off * max_x / 0x10000; - snap_top_on = snap_top_on * max_y / 0x10000; - snap_top_off = snap_top_off * max_y / 0x10000; - snap_bottom_on = snap_bottom_on * max_y / 0x10000; - snap_bottom_off = snap_bottom_off * max_y / 0x10000; - fuzz_x = fuzz_x * max_x / 0x10000; - fuzz_y = fuzz_y * max_y / 0x10000; - ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left; - ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right; - ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top; - ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom; - ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on; - ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off; - ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on; - ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off; - ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on; - ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off; - ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on; - ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off; - printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y); - printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n", - inactive_area_left, inactive_area_right, - inactive_area_top, inactive_area_bottom); - printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n", - snap_left_on, snap_left_off, snap_right_on, snap_right_off, - snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off); - input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0); - /* ts->input_dev->name = ts->keypad_info->name; */ - ret = input_register_device(ts->input_dev); - if (ret) { - printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); - goto err_input_register_device_failed; - } - if (client->irq) { - ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts); - if (ret == 0) { - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ - if (ret) - free_irq(client->irq, ts); - } - if (ret == 0) - ts->use_irq = 1; - else - dev_err(&client->dev, "request_irq failed\n"); - } - if (!ts->use_irq) { - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ts->timer.function = synaptics_ts_timer_func; - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } -#ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = synaptics_ts_early_suspend; - ts->early_suspend.resume = synaptics_ts_late_resume; - register_early_suspend(&ts->early_suspend); -#endif - - printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); - - return 0; - -err_input_register_device_failed: - input_free_device(ts->input_dev); - -err_input_dev_alloc_failed: -err_detect_failed: -err_power_failed: - kfree(ts); -err_alloc_data_failed: -err_check_functionality_failed: - return ret; -} - -static int synaptics_ts_remove(struct i2c_client *client) -{ - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - unregister_early_suspend(&ts->early_suspend); - if (ts->use_irq) - free_irq(client->irq, ts); - else - hrtimer_cancel(&ts->timer); - input_unregister_device(ts->input_dev); - kfree(ts); - return 0; -} - -static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) -{ - int ret; - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - - if (ts->use_irq) - disable_irq(client->irq); - else - hrtimer_cancel(&ts->timer); - ret = cancel_work_sync(&ts->work); - if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ - enable_irq(client->irq); - ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); - - ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */ - if (ret < 0) - printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); - if (ts->power) { - ret = ts->power(0); - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume power off failed\n"); - } - return 0; -} - -static int synaptics_ts_resume(struct i2c_client *client) -{ - int ret; - struct synaptics_ts_data *ts = i2c_get_clientdata(client); - - if (ts->power) { - ret = ts->power(1); - if (ret < 0) - printk(KERN_ERR "synaptics_ts_resume power on failed\n"); - } - - synaptics_init_panel(ts); - - if (ts->use_irq) - enable_irq(client->irq); - - if (!ts->use_irq) - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - else - i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void synaptics_ts_early_suspend(struct early_suspend *h) -{ - struct synaptics_ts_data *ts; - ts = container_of(h, struct synaptics_ts_data, early_suspend); - synaptics_ts_suspend(ts->client, PMSG_SUSPEND); -} - -static void synaptics_ts_late_resume(struct early_suspend *h) -{ - struct synaptics_ts_data *ts; - ts = container_of(h, struct synaptics_ts_data, early_suspend); - synaptics_ts_resume(ts->client); -} -#endif - -static const struct i2c_device_id synaptics_ts_id[] = { - { SYNAPTICS_I2C_RMI_NAME, 0 }, - { } -}; - -static struct i2c_driver synaptics_ts_driver = { - .probe = synaptics_ts_probe, - .remove = synaptics_ts_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = synaptics_ts_suspend, - .resume = synaptics_ts_resume, -#endif - .id_table = synaptics_ts_id, - .driver = { - .name = SYNAPTICS_I2C_RMI_NAME, - }, -}; - -static int __devinit synaptics_ts_init(void) -{ - synaptics_wq = create_singlethread_workqueue("synaptics_wq"); - if (!synaptics_wq) - return -ENOMEM; - return i2c_add_driver(&synaptics_ts_driver); -} - -static void __exit synaptics_ts_exit(void) -{ - i2c_del_driver(&synaptics_ts_driver); - if (synaptics_wq) - destroy_workqueue(synaptics_wq); -} - -module_init(synaptics_ts_init); -module_exit(synaptics_ts_exit); - -MODULE_DESCRIPTION("Synaptics Touchscreen Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 131976d880d0..707d9c94cf9e 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -438,27 +438,23 @@ static void cmd_in_timeout(unsigned long data) return; } - if (ucs->retry_cmd_in++ >= BAS_RETRY) { + if (ucs->retry_cmd_in++ < BAS_RETRY) { + dev_notice(cs->dev, "control read: timeout, retry %d\n", + ucs->retry_cmd_in); + rc = atread_submit(cs, BAS_TIMEOUT); + if (rc >= 0 || rc == -ENODEV) + /* resubmitted or disconnected */ + /* - bypass regular exit block */ + return; + } else { dev_err(cs->dev, "control read: timeout, giving up after %d tries\n", ucs->retry_cmd_in); - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - error_reset(cs); - return; - } - - gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d", - __func__, ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc < 0) { - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - if (rc != -ENODEV) - error_reset(cs); } + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + error_reset(cs); } /* read_ctrl_callback @@ -474,11 +470,18 @@ static void read_ctrl_callback(struct urb *urb) struct cardstate *cs = inbuf->cs; struct bas_cardstate *ucs = cs->hw.bas; int status = urb->status; + int have_data = 0; unsigned numbytes; int rc; update_basstate(ucs, 0, BS_ATRDPEND); wake_up(&ucs->waitqueue); + + if (!ucs->rcvbuf_size) { + dev_warn(cs->dev, "%s: no receive in progress\n", __func__); + return; + } + del_timer(&ucs->timer_cmd_in); switch (status) { @@ -492,10 +495,19 @@ static void read_ctrl_callback(struct urb *urb) numbytes = ucs->rcvbuf_size; } - /* copy received bytes to inbuf, notify event layer */ - if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(cs); + /* copy received bytes to inbuf */ + have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); + + if (unlikely(numbytes < ucs->rcvbuf_size)) { + /* incomplete - resubmit for remaining bytes */ + ucs->rcvbuf_size -= numbytes; + ucs->retry_cmd_in = 0; + rc = atread_submit(cs, BAS_TIMEOUT); + if (rc >= 0 || rc == -ENODEV) + /* resubmitted or disconnected */ + /* - bypass regular exit block */ + return; + error_reset(cs); } break; @@ -504,32 +516,37 @@ static void read_ctrl_callback(struct urb *urb) case -EINPROGRESS: /* pending */ case -ENODEV: /* device removed */ case -ESHUTDOWN: /* device shut down */ - /* no further action necessary */ + /* no action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(status)); break; - default: /* other errors: retry */ + default: /* severe trouble */ + dev_warn(cs->dev, "control read: %s\n", + get_usb_statmsg(status)); if (ucs->retry_cmd_in++ < BAS_RETRY) { - gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__, - get_usb_statmsg(status), ucs->retry_cmd_in); + dev_notice(cs->dev, "control read: retry %d\n", + ucs->retry_cmd_in); rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0) - /* successfully resubmitted, skip freeing */ + if (rc >= 0 || rc == -ENODEV) + /* resubmitted or disconnected */ + /* - bypass regular exit block */ return; - if (rc == -ENODEV) - /* disconnect, no further action necessary */ - break; + } else { + dev_err(cs->dev, + "control read: giving up after %d tries\n", + ucs->retry_cmd_in); } - dev_err(cs->dev, "control read: %s, giving up after %d tries\n", - get_usb_statmsg(status), ucs->retry_cmd_in); error_reset(cs); } - /* read finished, free buffer */ kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; + if (have_data) { + gig_dbg(DEBUG_INTR, "%s-->BH", __func__); + gigaset_schedule_event(cs); + } } /* atread_submit @@ -1581,13 +1598,13 @@ static int gigaset_init_bchannel(struct bc_state *bcs) ret = starturbs(bcs); if (ret < 0) { - spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "could not start isochronous I/O for channel B%d: %s\n", bcs->channel + 1, ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); if (ret != -ENODEV) error_hangup(bcs); + spin_unlock_irqrestore(&cs->lock, flags); return ret; } @@ -1597,11 +1614,11 @@ static int gigaset_init_bchannel(struct bc_state *bcs) dev_err(cs->dev, "could not open channel B%d\n", bcs->channel + 1); stopurbs(bcs->hw.bas); + if (ret != -ENODEV) + error_hangup(bcs); } spin_unlock_irqrestore(&cs->lock, flags); - if (ret < 0 && ret != -ENODEV) - error_hangup(bcs); return ret; } diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index f39ccdf87a17..2dfd346fc889 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c @@ -842,14 +842,13 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (unlikely(bcs->ignore)) { bcs->ignore--; + hdlc_flush(bcs); return; } skb = bcs->rx_skb; - if (skb == NULL) { + if (skb == NULL) skb = gigaset_new_rx_skb(bcs); - if (skb == NULL) - return; - } + bcs->hw.bas->goodbytes += skb->len; dobytes = bcs->rx_bufsize - skb->len; while (count > 0) { dst = skb_put(skb, count < dobytes ? count : dobytes); @@ -861,7 +860,6 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (dobytes == 0) { dump_bytes(DEBUG_STREAM_DUMP, "rcv data", skb->data, skb->len); - bcs->hw.bas->goodbytes += skb->len; gigaset_skb_rcvd(bcs, skb); skb = gigaset_new_rx_skb(bcs); if (skb == NULL) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 36877b7c8633..01052c2f8060 100755 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -138,30 +138,6 @@ config LEDS_PCA9532 LED controller. It is generally only useful as a platform driver -config LEDS_AUO_PANEL - tristate "Support for AUO display backlight driver" - depends on LEDS_CLASS - help - This option enables support for AUO display backlight driver - -config LEDS_CPCAP - tristate "LED Support for Display LEDS connected to CPCAP" - depends on LEDS_CLASS && MFD_CPCAP - help - This option enables support for display LEDs connected to CPCAP - -config LEDS_LP8550 - tristate "LED support for the LP8550" - depends on LEDS_CLASS && I2C - help - This option enables support for the LP8550 LED driver - -config LEDS_LM3559 - tristate "LED support for the LM3559" - depends on LEDS_CLASS && I2C - help - This option enables support for the LM3559 LED driver - config LEDS_GPIO tristate "LED Support for GPIO connected LEDs" depends on GENERIC_GPIO @@ -412,12 +388,6 @@ config LEDS_TRIGGER_DEFAULT_ON This allows LEDs to be initialised in the ON state. If unsure, say Y. -config LEDS_TRIGGER_SLEEP - tristate "LED Sleep Mode Trigger" - depends on LEDS_TRIGGERS && HAS_EARLYSUSPEND - help - This turns LEDs on when the screen is off but the cpu still running. - comment "iptables trigger is under Netfilter config (LED target)" depends on LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index f630b9151af1..5ba3fb7a402d 100755 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -40,10 +40,6 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o obj-$(CONFIG_LEDS_NS2) += leds-ns2.o -obj-$(CONFIG_LEDS_AUO_PANEL) += leds-auo-panel-backlight.o -obj-$(CONFIG_LEDS_CPCAP) += leds-ld-cpcap.o -obj-$(CONFIG_LEDS_LP8550) += leds-lp8550.o -obj-$(CONFIG_LEDS_LM3559) += led-lm3559.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o @@ -55,4 +51,3 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o -obj-$(CONFIG_LEDS_TRIGGER_SLEEP) += ledtrig-sleep.o diff --git a/drivers/leds/led-lm3559.c b/drivers/leds/led-lm3559.c deleted file mode 100644 index ffff728f030f..000000000000 --- a/drivers/leds/led-lm3559.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include - -/* #define DEBUG */ - -#define LM3559_ALLOWED_R_BYTES 1 -#define LM3559_ALLOWED_W_BYTES 2 -#define LM3559_MAX_RW_RETRIES 5 -#define LM3559_I2C_RETRY_DELAY 10 -#define LM3559_TORCH_STEP 64 -#define LM3559_STROBE_STEP 16 -#define LM3559_PRIVACY_STEP 32 -#define LM3559_RGB_STEP 32 - -#define LM3559_ENABLE_REG 0x10 -#define LM3559_PRIVACY_REG 0x11 -#define LM3559_MSG_IND_REG 0x12 -#define LM3559_MSG_BLINK_REG 0x13 -#define LM3559_PWM_REG 0x14 -#define LM3559_GPIO_REG 0x20 -#define LM3559_VLED_MON_REG 0x30 -#define LM3559_ADC_DELAY_REG 0x31 -#define LM3559_VIN_MONITOR 0x80 -#define LM3559_LAST_FLASH 0x81 -#define LM3559_TORCH_BRIGHTNESS 0xA0 -#define LM3559_FLASH_BRIGHTNESS 0xB0 -#define LM3559_FLASH_DURATION 0xC0 -#define LM3559_FLAG_REG 0xD0 -#define LM3559_CONFIG_REG_1 0xE0 -#define LM3559_CONFIG_REG_2 0xF0 - - -#define LED_FAULT 0x04 -#define THERMAL_SHUTDOWN 0x02 -#define TX1_INTERRUPT_FAULT 0x08 -#define THERMAL_MONITOR_FAULT 0x20 -#define VOLTAGE_MONITOR_FAULT 0x80 - -struct lm3559_data { - struct i2c_client *client; - struct lm3559_platform_data *pdata; - struct led_classdev flash_dev; - struct led_classdev torch_dev; -}; - -#ifdef DEBUG -struct lm3559_reg { - const char *name; - uint8_t reg; -} lm3559_regs[] = { - { "ENABLE", LM3559_ENABLE_REG}, - { "PRIVACY", LM3559_PRIVACY_REG}, - { "MSG_IND", LM3559_MSG_IND_REG}, - { "MSG_BLINK", LM3559_MSG_BLINK_REG}, - { "PRIVACY_PWM", LM3559_PWM_REG}, - { "GPIO", LM3559_GPIO_REG}, - { "VLED_MON", LM3559_VLED_MON_REG}, - { "ADC_DELAY", LM3559_ADC_DELAY_REG}, - { "VIN_MONITOR", LM3559_VIN_MONITOR}, - { "LAST_FLASH", LM3559_LAST_FLASH}, - { "TORCH_BRIGHTNESS", LM3559_TORCH_BRIGHTNESS}, - { "FLASH_BRIGHTNESS", LM3559_FLASH_BRIGHTNESS}, - { "FLASH_DURATION", LM3559_FLASH_DURATION}, - { "FLAG", LM3559_FLAG_REG}, - { "CONFIG_REG_1", LM3559_CONFIG_REG_1}, - { "CONFIG_REG_2", LM3559_CONFIG_REG_2}, -}; -#endif - -static uint32_t lm3559_debug; -module_param_named(flash_debug, lm3559_debug, uint, 0664); - -static int lm3559_read_reg(struct lm3559_data *torch_data, - uint8_t reg, uint8_t* val) -{ - int err = -1; - int i = 0; - uint8_t dest_buffer; - - if (!val) { - pr_err("%s: invalid value pointer\n", __func__); - return -EINVAL; - } - /* If I2C client doesn't exist */ - if (torch_data->client == NULL) { - pr_err("%s: null i2c client\n", __func__); - return -EUNATCH; - } - - do { - dest_buffer = reg; - err = i2c_master_send(torch_data->client, &dest_buffer, - LM3559_ALLOWED_R_BYTES); - if (err == LM3559_ALLOWED_R_BYTES) - err = i2c_master_recv(torch_data->client, val, - LM3559_ALLOWED_R_BYTES); - if (err != LM3559_ALLOWED_R_BYTES) - msleep_interruptible(LM3559_I2C_RETRY_DELAY); - } while ((err != LM3559_ALLOWED_R_BYTES) && - ((++i) < LM3559_MAX_RW_RETRIES)); - - if (err != LM3559_ALLOWED_R_BYTES) - return -EINVAL; - - return 0; -} - -static int lm3559_write_reg(struct lm3559_data *torch_data, - uint8_t reg, uint8_t val) -{ - int bytes; - int i = 0; - uint8_t buf[LM3559_ALLOWED_W_BYTES] = { reg, val }; - - /* If I2C client doesn't exist */ - if (torch_data->client == NULL) { - pr_err("%s: null i2c client\n", __func__); - return -EUNATCH; - } - - do { - bytes = i2c_master_send(torch_data->client, buf, - LM3559_ALLOWED_W_BYTES); - - if (bytes != LM3559_ALLOWED_W_BYTES) - msleep_interruptible(LM3559_I2C_RETRY_DELAY); - } while ((bytes != LM3559_ALLOWED_W_BYTES) && - ((++i) < LM3559_MAX_RW_RETRIES)); - - if (bytes != LM3559_ALLOWED_W_BYTES) { - pr_err("%s: i2c_master_send error\n", __func__); - return -EINVAL; - } - - return 0; -} - -#ifdef DEBUG -static ssize_t ld_lm3559_registers_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev->parent, struct i2c_client, - dev); - struct lm3559_data *flash_data = i2c_get_clientdata(client); - unsigned i, n, reg_count; - uint8_t value = 0; - - reg_count = sizeof(lm3559_regs) / sizeof(lm3559_regs[0]); - for (i = 0, n = 0; i < reg_count; i++) { - lm3559_read_reg(flash_data, lm3559_regs[i].reg, &value); - n += scnprintf(buf + n, PAGE_SIZE - n, - "%-20s = 0x%02X\n", - lm3559_regs[i].name, - value); - } - - return n; -} - -static ssize_t ld_lm3559_registers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = container_of(dev->parent, - struct i2c_client, dev); - struct lm3559_data *flash_data = i2c_get_clientdata(client); - unsigned i, reg_count, value; - int error; - char name[30]; - - if (count >= 30) { - pr_err("%s:input too long\n", __func__); - return -1; - } - - if (sscanf(buf, "%s %x", name, &value) != 2) { - pr_err("%s:unable to parse input\n", __func__); - return -1; - } - - reg_count = sizeof(lm3559_regs) / sizeof(lm3559_regs[0]); - for (i = 0; i < reg_count; i++) { - if (!strcmp(name, lm3559_regs[i].name)) { - error = lm3559_write_reg(flash_data, - lm3559_regs[i].reg, - value); - if (error) { - pr_err("%s:Failed to write register %s\n", - __func__, name); - return -1; - } - return count; - } - } - - pr_err("%s:no such register %s\n", __func__, name); - return -1; -} -static DEVICE_ATTR(registers, 0644, ld_lm3559_registers_show, - ld_lm3559_registers_store); -#endif - -int lm3559_init_registers(struct lm3559_data *torch_data) -{ - if (lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS, 0) || - lm3559_write_reg(torch_data, LM3559_ADC_DELAY_REG, 0) || - lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS, 0) || - lm3559_write_reg(torch_data, LM3559_FLASH_DURATION, - torch_data->pdata->flash_duration_def) || - lm3559_write_reg(torch_data, LM3559_CONFIG_REG_1, 0x6C) || - lm3559_write_reg(torch_data, LM3559_CONFIG_REG_2, 0) || - lm3559_write_reg(torch_data, LM3559_VIN_MONITOR, - torch_data->pdata->vin_monitor_def) || - lm3559_write_reg(torch_data, LM3559_GPIO_REG, 0) || - lm3559_write_reg(torch_data, LM3559_FLAG_REG, 0) || - lm3559_write_reg(torch_data, LM3559_PRIVACY_REG, 0x10) || - lm3559_write_reg(torch_data, LM3559_MSG_IND_REG, 0) || - lm3559_write_reg(torch_data, LM3559_MSG_BLINK_REG, 0) || - lm3559_write_reg(torch_data, LM3559_PWM_REG, 0) || - lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0)) { - pr_err("%s:Register initialization failed\n", __func__); - return -EIO; - } - return 0; -} - -static int lm3559_check_led_error(struct lm3559_data *torch_data) { - int err = 0; - - if (torch_data->pdata->flags & LM3559_FLAG_ERROR_CHECK) { - - uint8_t err_flags; - err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags); - if (err) { - pr_err("%s: Reading the status failed for %i\n", - __func__, err); - return -EIO; - } - - if (err_flags & (VOLTAGE_MONITOR_FAULT | - THERMAL_MONITOR_FAULT | - LED_FAULT | - THERMAL_SHUTDOWN)) { - pr_err("%s: Error indicated by the chip 0x%X\n", - __func__, err_flags); - err = -EIO; - } - } - - return err; -} - -static int lm3559_flash_prepare(struct lm3559_data *torch_data) -{ - int err = lm3559_check_led_error(torch_data); - if (err) - return err; - - if (torch_data->flash_dev.brightness) { - uint8_t strobe_brightness; - uint val = torch_data->flash_dev.brightness - 1; - strobe_brightness = val | (val << 4); - - err = lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS, - strobe_brightness); - if (err) { - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_FLASH_BRIGHTNESS, err); - return -EIO; - } - - err = lm3559_write_reg(torch_data, LM3559_FLASH_DURATION, - torch_data->pdata->flash_duration_def); - if (err) { - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_FLASH_DURATION, err); - return -EIO; - } - - err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR, - torch_data->pdata->vin_monitor_def); - if (err) { - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_VIN_MONITOR, err); - return -EIO; - } - - /* setup flash for trigger by strobe pin: - enable LED1 and LED2, but do not enable current */ - err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0x18); - - } else { - /* disable LED1 and LED2 and current */ - err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0); - } - - if (err) - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_ENABLE_REG, err); - - return err; -} - -static int lm3559_torch_enable(struct lm3559_data *torch_data) -{ - int err = lm3559_check_led_error(torch_data); - if (err) - return err; - - if (torch_data->torch_dev.brightness) { - uint8_t torch_brightness; - uint val = (torch_data->torch_dev.brightness - 1) & 0x3F; - torch_brightness = val | (val << 3); - - err = lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS, - torch_brightness); - if (err) { - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_TORCH_BRIGHTNESS, err); - return -EIO; - } - - err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR, - torch_data->pdata->vin_monitor_def); - if (err) { - pr_err("%s: Writing to 0x%X failed %i\n", - __func__, LM3559_VIN_MONITOR, err); - return -EIO; - } - - /* enable LED1 and LED2, enable current */ - err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0x1A); - - } else { - /* disable LED1 and LED2 and current */ - err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0); - } - - return err; -} - -static void lm3559_flash_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct lm3559_data *torch_data = - container_of(led_cdev, struct lm3559_data, flash_dev); - lm3559_flash_prepare(torch_data); -} - -static void lm3559_torch_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct lm3559_data *torch_data = - container_of(led_cdev, struct lm3559_data, torch_dev); - lm3559_torch_enable(torch_data); -} - -static int lm3559_remove(struct i2c_client *client) -{ - struct lm3559_data *torch_data = i2c_get_clientdata(client); - - if (torch_data) { - - if (!IS_ERR_OR_NULL(torch_data->torch_dev.dev)) { -#ifdef DEBUG - device_remove_file(torch_data->torch_dev.dev, - &dev_attr_registers); -#endif - led_classdev_unregister(&torch_data->torch_dev); - } - - if (!IS_ERR_OR_NULL(torch_data->flash_dev.dev)) { -#ifdef DEBUG - device_remove_file(torch_data->flash_dev.dev, - &dev_attr_registers); -#endif - led_classdev_unregister(&torch_data->flash_dev); - } - - kfree(torch_data); - } - return 0; -} - -static int lm3559_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lm3559_platform_data *pdata = client->dev.platform_data; - struct lm3559_data *torch_data; - int err = -1; - - if (pdata == NULL) { - dev_err(&client->dev, "platform data is NULL. exiting.\n"); - return -ENODEV; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "client not i2c capable\n"); - return -ENODEV; - } - - torch_data = kzalloc(sizeof(struct lm3559_data), GFP_KERNEL); - if (torch_data == NULL) { - dev_err(&client->dev, "kzalloc failed\n"); - return -ENOMEM; - } - - torch_data->client = client; - torch_data->pdata = pdata; - - i2c_set_clientdata(client, torch_data); - - err = lm3559_init_registers(torch_data); - if (err < 0) - goto error; - - torch_data->flash_dev.name = "flash"; - torch_data->flash_dev.brightness_set = lm3559_flash_brightness_set; - torch_data->flash_dev.brightness = LED_OFF; - torch_data->flash_dev.max_brightness = LED_FULL; - err = led_classdev_register((struct device *) - &client->dev, &torch_data->flash_dev); - if (err < 0) { - pr_err("%s: Register flash led class failed: %d\n", - __func__, err); - goto error; - } - -#ifdef DEBUG - err = device_create_file(torch_data->flash_dev.dev, - &dev_attr_registers); - if (err < 0) - pr_err("%s:File device creation failed: %d\n", __func__, err); -#endif - - torch_data->torch_dev.name = "torch"; - torch_data->torch_dev.brightness_set = lm3559_torch_brightness_set; - torch_data->torch_dev.brightness = LED_OFF; - torch_data->torch_dev.max_brightness = LED_FULL; - err = led_classdev_register((struct device *) - &client->dev, &torch_data->torch_dev); - if (err < 0) { - pr_err("%s: Register torch led class failed: %d\n", - __func__, err); - goto error; - } - -#ifdef DEBUG - err = device_create_file(torch_data->torch_dev.dev, - &dev_attr_registers); - if (err < 0) - pr_err("%s:File device creation failed: %d\n", __func__, err); -#endif - - return 0; -error: - lm3559_remove(client); - return err; -} - -static const struct i2c_device_id lm3559_id[] = { - {LM3559_NAME, 0}, - {} -}; - -static struct i2c_driver lm3559_i2c_driver = { - .probe = lm3559_probe, - .remove = lm3559_remove, - .id_table = lm3559_id, - .driver = { - .name = LM3559_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init lm3559_init(void) -{ - return i2c_add_driver(&lm3559_i2c_driver); -} - -static void lm3559_exit(void) -{ - i2c_del_driver(&lm3559_i2c_driver); -} - -module_init(lm3559_init); -module_exit(lm3559_exit); - -/****************************************************************************/ - -MODULE_DESCRIPTION("Lighting driver for LM3559"); -MODULE_AUTHOR("MOTOROLA"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-auo-panel-backlight.c b/drivers/leds/leds-auo-panel-backlight.c deleted file mode 100755 index e95131a7c71a..000000000000 --- a/drivers/leds/leds-auo-panel-backlight.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include - -struct auo_panel_data { - struct led_classdev led_dev; - struct auo_panel_bl_platform_data *auo_pdata; - struct mutex lock; - int led_on; -}; - -static uint32_t auo_panel_debug; -module_param_named(auo_bl_debug, auo_panel_debug, uint, 0664); - -static void ld_auo_panel_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct auo_panel_data *auo_data = - container_of(led_cdev, struct auo_panel_data, led_dev); - - mutex_lock(&auo_data->lock); - if (value == LED_OFF) { - if (auo_data->led_on == 1) { - if (auo_data->auo_pdata->bl_disable) { - auo_data->auo_pdata->bl_disable(); - auo_data->led_on = 0; - } - } - } else { - if (auo_data->led_on == 0) { - if (auo_data->auo_pdata->bl_enable) { - auo_data->auo_pdata->bl_enable(); - auo_data->led_on = 1; - } - } - } - mutex_unlock(&auo_data->lock); -} - -static int __devinit ld_auo_panel_bl_probe(struct platform_device *pdev) -{ - struct auo_panel_data *auo_data; - int error = 0; - - if (pdev->dev.platform_data == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - } - auo_data = kzalloc(sizeof(struct auo_panel_data), GFP_KERNEL); - if (auo_data == NULL) - return -ENOMEM; - - auo_data->led_dev.name = LD_AUO_PANEL_BL_LED_DEV; - auo_data->led_dev.brightness_set = ld_auo_panel_brightness_set; - - auo_data->auo_pdata = pdev->dev.platform_data; - - error = led_classdev_register(&pdev->dev, &auo_data->led_dev); - if (error < 0) { - pr_err("%s: Register led class failed: %d\n", __func__, error); - error = -ENODEV; - kfree(auo_data); - return error; - } - mutex_init(&auo_data->lock); - - mutex_lock(&auo_data->lock); - auo_data->led_on = 1; - mutex_unlock(&auo_data->lock); - - platform_set_drvdata(pdev, auo_data); - - return 0; -} - -static int __devexit ld_auo_panel_remove(struct platform_device *pdev) -{ - struct auo_panel_data *auo_data = pdev->dev.platform_data; - led_classdev_unregister(&auo_data->led_dev); - kfree(auo_data); - return 0; -} - -static struct platform_driver auo_led_driver = { - .probe = ld_auo_panel_bl_probe, - .remove = __devexit_p(ld_auo_panel_remove), - .driver = { - .name = LD_AUO_PANEL_BL_NAME, - .owner = THIS_MODULE, - }, -}; -static int __init ld_auo_panel_init(void) -{ - return platform_driver_register(&auo_led_driver); -} - -static void __exit ld_auo_panel_exit(void) -{ - platform_driver_unregister(&auo_led_driver); - -} - -module_init(ld_auo_panel_init); -module_exit(ld_auo_panel_exit); - -MODULE_DESCRIPTION("Lighting driver for the AUO display panel"); -MODULE_AUTHOR("Dan Murphy "); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-ld-cpcap.c b/drivers/leds/leds-ld-cpcap.c deleted file mode 100755 index 1bcdf7faad5f..000000000000 --- a/drivers/leds/leds-ld-cpcap.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, Inc. - * - * This program is free dispware; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free dispware 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 dispware - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct cpcap_led_data { - struct led_classdev cpcap_class_dev; - struct cpcap_device *cpcap; - struct cpcap_led *pdata; - struct regulator *regulator; - struct work_struct brightness_work; - enum led_brightness brightness; - int regulator_state; - short blink_val; -}; - -static void cpcap_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct cpcap_led_data *cpcap_led_data = - container_of(led_cdev, struct cpcap_led_data, - cpcap_class_dev); - - if (brightness > 255) - brightness = 255; - - cpcap_led_data->brightness = brightness; - queue_work(system_nrt_wq, &cpcap_led_data->brightness_work); -} -EXPORT_SYMBOL(cpcap_set); - -static void -cpcap_led_set_blink(struct cpcap_led_data *info, unsigned long blink) -{ - info->blink_val = blink; - - if (info->pdata->blink_able) { - if(info->blink_val) { - cpcap_uc_start(info->cpcap, CPCAP_MACRO_6); - } else { - cpcap_uc_stop(info->cpcap, CPCAP_MACRO_6); - queue_work(system_nrt_wq, &info->brightness_work); - } - } -} - -static int cpcap_led_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - struct cpcap_led_data *info = - container_of(led_cdev, struct cpcap_led_data, - cpcap_class_dev); - - cpcap_led_set_blink(info, *delay_on); - return 0; -} - -static void cpcap_brightness_work(struct work_struct *work) -{ - int cpcap_status = 0; - unsigned short brightness = 0; - - struct cpcap_led_data *cpcap_led_data = - container_of(work, struct cpcap_led_data, brightness_work); - - brightness = cpcap_led_data->brightness; - - if (brightness > 0) { - brightness = (cpcap_led_data->pdata->cpcap_reg_period | - cpcap_led_data->pdata->cpcap_reg_duty_cycle | - cpcap_led_data->pdata->cpcap_reg_current | - 0x01); - - if ((cpcap_led_data->regulator) && - (cpcap_led_data->regulator_state == 0)) { - regulator_enable(cpcap_led_data->regulator); - cpcap_led_data->regulator_state = 1; - } - - cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap, - cpcap_led_data->pdata->cpcap_register, - brightness, - cpcap_led_data->pdata->cpcap_reg_mask); - - if (cpcap_status < 0) - pr_err("%s: Writing to the register failed for %i\n", - __func__, cpcap_status); - - } else { - if ((cpcap_led_data->regulator) && - (cpcap_led_data->regulator_state == 1)) { - regulator_disable(cpcap_led_data->regulator); - cpcap_led_data->regulator_state = 0; - } - /* Due to a HW issue turn off the current then - turn off the duty cycle */ - brightness = 0x01; - cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap, - cpcap_led_data->pdata->cpcap_register, - brightness, - cpcap_led_data->pdata->cpcap_reg_mask); - - - brightness = 0x00; - cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap, - cpcap_led_data->pdata->cpcap_register, - brightness, - cpcap_led_data->pdata->cpcap_reg_mask); - - - if (cpcap_status < 0) - pr_err("%s: Writing to the register failed for %i\n", - __func__, cpcap_status); - - } -} - -static ssize_t blink_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct cpcap_led_data *info = - container_of(led_cdev, struct cpcap_led_data, cpcap_class_dev); - - return sprintf(buf, "%u\n", info->blink_val); -} - -static ssize_t blink_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct cpcap_led_data *info = - container_of(led_cdev, struct cpcap_led_data, cpcap_class_dev); - unsigned long blink = simple_strtoul(buf, NULL, 10); - cpcap_led_set_blink(info, blink); - return size; -} - -static DEVICE_ATTR(blink, 0644, blink_show, blink_store); - -static int cpcap_probe(struct platform_device *pdev) -{ - int ret = 0; - struct cpcap_led_data *info; - - if (pdev == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - - } - info = kzalloc(sizeof(struct cpcap_led_data), GFP_KERNEL); - if (info == NULL) { - ret = -ENOMEM; - return ret; - } - - info->pdata = pdev->dev.platform_data; - info->cpcap = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, info); - - if (info->pdata->led_regulator != NULL) { - info->regulator = regulator_get(&pdev->dev, - info->pdata->led_regulator); - if (IS_ERR(info->regulator)) { - pr_err("%s: Cannot get %s regulator\n", - __func__, info->pdata->led_regulator); - ret = PTR_ERR(info->regulator); - goto exit_request_reg_failed; - - } - } - info->regulator_state = 0; - - info->cpcap_class_dev.name = info->pdata->class_name; - info->cpcap_class_dev.brightness_set = cpcap_set; - info->cpcap_class_dev.blink_set = cpcap_led_blink; - info->cpcap_class_dev.brightness = LED_OFF; - info->cpcap_class_dev.max_brightness = 255; - if (info->pdata->blink_able) - info->cpcap_class_dev.default_trigger = "timer"; - - ret = led_classdev_register(&pdev->dev, &info->cpcap_class_dev); - if (ret < 0) { - pr_err("%s:Register %s class failed\n", - __func__, info->cpcap_class_dev.name); - goto err_reg_button_class_failed; - } - - /* Create a device file to control blinking. - * We do this to avoid problems setting permissions on the - * timer trigger delay_on and delay_off files. - */ - ret = device_create_file(info->cpcap_class_dev.dev, &dev_attr_blink); - if (ret < 0) { - pr_err("%s:device_create_file failed for blink\n", __func__); - goto err_device_create_file_failed; - } - - INIT_WORK(&info->brightness_work, cpcap_brightness_work); - - return ret; - -err_device_create_file_failed: - led_classdev_unregister(&info->cpcap_class_dev); -err_reg_button_class_failed: - if (info->regulator) - regulator_put(info->regulator); -exit_request_reg_failed: - kfree(info); - return ret; -} - -static int cpcap_remove(struct platform_device *pdev) -{ - struct cpcap_led_data *info = platform_get_drvdata(pdev); - - device_remove_file(info->cpcap_class_dev.dev, &dev_attr_blink); - if (info->regulator) - regulator_put(info->regulator); - led_classdev_unregister(&info->cpcap_class_dev); - return 0; -} - -static struct platform_driver ld_cpcap_driver = { - .probe = cpcap_probe, - .remove = cpcap_remove, - .driver = { - .name = LD_CPCAP_LED_DRV, - }, -}; - -static int __init led_cpcap_init(void) -{ - return platform_driver_register(&ld_cpcap_driver); -} - -static void __exit led_cpcap_exit(void) -{ - platform_driver_unregister(&ld_cpcap_driver); -} - -module_init(led_cpcap_init); -module_exit(led_cpcap_exit); - -MODULE_DESCRIPTION("CPCAP Lighting driver"); -MODULE_AUTHOR("Dan Murphy "); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-lp8550.c b/drivers/leds/leds-lp8550.c deleted file mode 100755 index aa7f1a4c6981..000000000000 --- a/drivers/leds/leds-lp8550.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG - -#define LD_LP8550_ON_OFF_MASK 0xFE - -#define LD_LP8550_ALLOWED_R_BYTES 1 -#define LD_LP8550_ALLOWED_W_BYTES 2 -#define LD_LP8550_MAX_RW_RETRIES 5 -#define LD_LP8550_I2C_RETRY_DELAY 10 - -#define LP8550_BRIGHTNESS_CTRL 0x00 -#define LP8550_DEVICE_CTRL 0x01 -#define LP8550_FAULT 0x02 -#define LP8550_CHIP_ID 0x03 -#define LP8550_DIRECT_CTRL 0x04 -#define LP8550_TEMP_MSB 0x05 -#define LP8550_TEMP_LSB 0x06 - -#define LP8550_BRT_MODE_PWM 0x02 -#define LP8550_BRT_MODE_BRIGHT 0x04 - -/* EEPROM Register address */ -#define LP8550_EEPROM_CTRL 0x72 -#define LP8550_EEPROM_A0 0xa0 -#define LP8550_EEPROM_A1 0xa1 -#define LP8550_EEPROM_A2 0xa2 -#define LP8550_EEPROM_A3 0xa3 -#define LP8550_EEPROM_A4 0xa4 -#define LP8550_EEPROM_A5 0xa5 -#define LP8550_EEPROM_A6 0xa6 -#define LP8550_EEPROM_A7 0xa7 - - -struct lp8550_data { - struct led_classdev led_dev; - struct i2c_client *client; - struct work_struct wq; - struct lp8550_platform_data *led_pdata; - uint8_t last_requested_brightness; - int brightness; - atomic_t enabled; - bool suspended; - struct regulator *regulator; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspender; -#endif -}; - -#ifdef DEBUG -struct lp8550_reg { - const char *name; - uint8_t reg; -} lp8550_regs[] = { - { "BRIGHTNESS_CTRL", LP8550_BRIGHTNESS_CTRL }, - { "DEV_CTRL", LP8550_DEVICE_CTRL }, - { "FAULT", LP8550_FAULT }, - { "CHIP_ID", LP8550_CHIP_ID }, - { "DIRECT_CTRL", LP8550_DIRECT_CTRL }, - { "EEPROM_CTRL", LP8550_EEPROM_CTRL }, - { "EEPROM_A0", LP8550_EEPROM_A0 }, - { "EEPROM_A1", LP8550_EEPROM_A1 }, - { "EEPROM_A2", LP8550_EEPROM_A2 }, - { "EEPROM_A3", LP8550_EEPROM_A3 }, - { "EEPROM_A4", LP8550_EEPROM_A4 }, - { "EEPROM_A5", LP8550_EEPROM_A5 }, - { "EEPROM_A6", LP8550_EEPROM_A6 }, - { "EEPROM_A7", LP8550_EEPROM_A7 }, -}; -#endif - -static uint32_t lp8550_debug; -module_param_named(als_debug, lp8550_debug, uint, 0664); -static void lp8550_brightness_write(struct lp8550_data *led_data); - -static int lp8550_read_reg(struct lp8550_data *led_data, uint8_t reg, - uint8_t *value) -{ - int error = 0; - int i = 0; - uint8_t dest_buffer; - - if (!value) { - pr_err("%s: invalid value pointer\n", __func__); - return -EINVAL; - } - do { - dest_buffer = reg; - error = i2c_master_send(led_data->client, &dest_buffer, 1); - if (error == 1) { - error = i2c_master_recv(led_data->client, - &dest_buffer, LD_LP8550_ALLOWED_R_BYTES); - } - if (error != LD_LP8550_ALLOWED_R_BYTES) { - pr_err("%s: read[%i] failed: %d\n", __func__, i, error); - msleep(LD_LP8550_I2C_RETRY_DELAY); - } - } while ((error != LD_LP8550_ALLOWED_R_BYTES) && - ((++i) < LD_LP8550_MAX_RW_RETRIES)); - - if (error == LD_LP8550_ALLOWED_R_BYTES) { - error = 0; - *value = dest_buffer; - } - - return error; -} - -static int lp8550_write_reg(struct lp8550_data *led_data, uint8_t reg, - uint8_t value) -{ - uint8_t buf[LD_LP8550_ALLOWED_W_BYTES] = { reg, value }; - int bytes; - int i = 0; - - do { - bytes = i2c_master_send(led_data->client, buf, - LD_LP8550_ALLOWED_W_BYTES); - - if (bytes != LD_LP8550_ALLOWED_W_BYTES) { - pr_err("%s: write %d failed: %d\n", __func__, i, bytes); - msleep(LD_LP8550_I2C_RETRY_DELAY); - } - } while ((bytes != (LD_LP8550_ALLOWED_W_BYTES)) - && ((++i) < LD_LP8550_MAX_RW_RETRIES)); - - if (bytes != LD_LP8550_ALLOWED_W_BYTES) { - pr_err("%s: i2c_master_send error\n", __func__); - return -EINVAL; - } - return 0; -} - -static int ld_lp8550_init_registers(struct lp8550_data *led_data) -{ - unsigned i, reg_addr; - uint8_t value = 0; - - if (lp8550_write_reg(led_data, LP8550_DEVICE_CTRL, 0x05)) - pr_err("%s:Register initialization failed\n", - __func__); - - for (i = 0; i < led_data->led_pdata->eeprom_tbl_sz; i++) { - reg_addr = LP8550_EEPROM_A0 + i; - value = led_data->led_pdata->eeprom_table[i].eeprom_data; - if (lp8550_write_reg(led_data, reg_addr, value)) - pr_err("%s:Register initialization failed\n", __func__); - } - - if (lp8550_write_reg(led_data, LP8550_DEVICE_CTRL, - (led_data->led_pdata->dev_ctrl_config | 0x01))) { - pr_err("%s:Register initialization failed\n", __func__); - return -EINVAL; - } - return 0; -} - -static void ld_lp8550_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct lp8550_data *led_data = - container_of(led_cdev, struct lp8550_data, led_dev); - - if (brightness > 255) - brightness = 255; - - led_data->brightness = brightness; - if (!led_data->suspended) - queue_work(system_nrt_wq, &led_data->wq); -} -EXPORT_SYMBOL(ld_lp8550_brightness_set); - -static void lp8550_brightness_work(struct work_struct *work) -{ - struct lp8550_data *led_data = - container_of(work, struct lp8550_data, wq); - - lp8550_brightness_write(led_data); -} - -static void lp8550_brightness_write(struct lp8550_data *led_data) -{ - int error = 0; - int brightness = led_data->brightness; - unsigned i, reg_addr; - uint8_t value = 0; - - if (lp8550_debug) - pr_info("%s: setting brightness to %i\n", - __func__, brightness); - - if (brightness == LED_OFF) { - if (lp8550_write_reg(led_data, LP8550_DEVICE_CTRL, - LP8550_BRT_MODE_BRIGHT)) { - pr_err("%s:writing failed while setting brightness:%d\n", - __func__, error); - } - if (atomic_cmpxchg(&led_data->enabled, 1, 0)) - if (!IS_ERR_OR_NULL(led_data->regulator)) - regulator_disable(led_data->regulator); - } else { - if (!atomic_cmpxchg(&led_data->enabled, 0, 1)) { - if (!IS_ERR_OR_NULL(led_data->regulator)) - regulator_enable(led_data->regulator); - if (lp8550_write_reg(led_data, LP8550_DEVICE_CTRL, - led_data->led_pdata->dev_ctrl_config | 0x01)) { - pr_err("%s:writing failed while setting brightness:%d\n", - __func__, error); - atomic_set(&led_data->enabled, 0); - } - - /* restore values a1 to a8 in case they have been reset */ - /* a0 will be set below with the brightness */ - for (i = 1; i < led_data->led_pdata->eeprom_tbl_sz; i++) { - reg_addr = LP8550_EEPROM_A0 + i; - value = led_data->led_pdata->eeprom_table[i].eeprom_data; - if (lp8550_write_reg(led_data, reg_addr, value)) - pr_err("%s: Register initialization failed\n", - __func__); - } - } - - if (led_data->led_pdata->dev_ctrl_config == - LP8550_BRT_MODE_BRIGHT) { - if (lp8550_write_reg(led_data, LP8550_BRIGHTNESS_CTRL, - brightness)) - pr_err("%s:Failed to set brightness:%d\n", - __func__, error); - } - - if (led_data->led_pdata->dev_ctrl_config == - LP8550_BRT_MODE_PWM) { - /* scale the brightness to prevent more than 19mA per LED */ - if (lp8550_write_reg(led_data, LP8550_EEPROM_A0, - (brightness * led_data->led_pdata->scaling_factor) / 1000)) - pr_err("%s:Failed to set brightness:%d\n", - __func__, error); - } - led_data->last_requested_brightness = brightness; - } -} - -#ifdef DEBUG -static ssize_t ld_lp8550_registers_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev->parent, struct i2c_client, - dev); - struct lp8550_data *led_data = i2c_get_clientdata(client); - unsigned i, n, reg_count; - uint8_t value = 0; - - reg_count = sizeof(lp8550_regs) / sizeof(lp8550_regs[0]); - for (i = 0, n = 0; i < reg_count; i++) { - lp8550_read_reg(led_data, lp8550_regs[i].reg, &value); - n += scnprintf(buf + n, PAGE_SIZE - n, - "%-20s = 0x%02X\n", - lp8550_regs[i].name, - value); - } - - return n; -} - -static ssize_t ld_lp8550_registers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = container_of(dev->parent, struct i2c_client, - dev); - struct lp8550_data *led_data = i2c_get_clientdata(client); - unsigned i, reg_count, value; - int error; - char name[30]; - - if (count >= 30) { - pr_err("%s:input too long\n", __func__); - return -1; - } - - if (sscanf(buf, "%s %x", name, &value) != 2) { - pr_err("%s:unable to parse input\n", __func__); - return -1; - } - - reg_count = sizeof(lp8550_regs) / sizeof(lp8550_regs[0]); - for (i = 0; i < reg_count; i++) { - if (!strcmp(name, lp8550_regs[i].name)) { - error = lp8550_write_reg(led_data, - lp8550_regs[i].reg, - value); - if (error) { - pr_err("%s:Failed to write register %s\n", - __func__, name); - return -1; - } - return count; - } - } - - pr_err("%s:no such register %s\n", __func__, name); - return -1; -} -static DEVICE_ATTR(registers, 0644, ld_lp8550_registers_show, - ld_lp8550_registers_store); -#endif - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void lp8550_early_suspend(struct early_suspend *h) -{ - struct lp8550_data *led_data = - container_of(h, struct lp8550_data, early_suspender); - enum led_brightness cur_brightness = led_data->brightness; - - led_data->suspended = true; - - cancel_work_sync(&led_data->wq); - led_data->brightness = LED_OFF; - lp8550_brightness_write(led_data); - led_data->brightness = cur_brightness; -} - -static void lp8550_late_resume(struct early_suspend *h) -{ - struct lp8550_data *led_data = - container_of(h, struct lp8550_data, early_suspender); - led_data->suspended = false; - queue_work(system_nrt_wq, &led_data->wq); -} -#endif - - -static int ld_lp8550_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp8550_platform_data *pdata = client->dev.platform_data; - struct lp8550_data *led_data; - int error = 0; - - if (pdata == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - } else if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s:I2C_FUNC_I2C not supported\n", __func__); - return -ENODEV; - } - - led_data = kzalloc(sizeof(struct lp8550_data), GFP_KERNEL); - if (led_data == NULL) { - error = -ENOMEM; - goto err_alloc_data_failed; - } - - led_data->client = client; - - led_data->led_dev.name = LD_LP8550_LED_DEV; - led_data->led_dev.brightness_set = ld_lp8550_brightness_set; - led_data->led_pdata = client->dev.platform_data; - - i2c_set_clientdata(client, led_data); - - error = ld_lp8550_init_registers(led_data); - if (error < 0) { - pr_err("%s: Register Initialization failed: %d\n", - __func__, error); - error = -ENODEV; - goto err_reg_init_failed; - } - - if (led_data->led_pdata->dev_ctrl_config == LP8550_BRT_MODE_BRIGHT) { - error = lp8550_write_reg(led_data, LP8550_BRIGHTNESS_CTRL, - pdata->power_up_brightness); - } else if (led_data->led_pdata->dev_ctrl_config == LP8550_BRT_MODE_PWM) { - error = lp8550_write_reg(led_data, LP8550_EEPROM_A0, - pdata->power_up_brightness); - } - - if (error) { - pr_err("%s:Setting power up brightness failed %d\n", - __func__, error); - error = -ENODEV; - goto err_reg_init_failed; - } - - atomic_set(&led_data->enabled, 0); - - INIT_WORK(&led_data->wq, lp8550_brightness_work); - -#ifdef CONFIG_HAS_EARLYSUSPEND - led_data->early_suspender.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; - led_data->early_suspender.suspend = lp8550_early_suspend; - led_data->early_suspender.resume = lp8550_late_resume, - register_early_suspend(&led_data->early_suspender); -#endif - - error = led_classdev_register((struct device *) &client->dev, - &led_data->led_dev); - if (error < 0) { - pr_err("%s: Register led class failed: %d\n", __func__, error); - error = -ENODEV; - goto err_class_reg_failed; - } - -#ifdef DEBUG - error = device_create_file(led_data->led_dev.dev, &dev_attr_registers); - if (error < 0) { - pr_err("%s:File device creation failed: %d\n", __func__, error); - } -#endif - - led_data->regulator = regulator_get(&client->dev, "vio"); - - return 0; - -err_class_reg_failed: -err_reg_init_failed: - kfree(led_data); -err_alloc_data_failed: - return error; -} - -static int ld_lp8550_remove(struct i2c_client *client) -{ - struct lp8550_data *led_data = i2c_get_clientdata(client); - -#ifdef DEBUG - device_remove_file(led_data->led_dev.dev, &dev_attr_registers); -#endif - if (!IS_ERR_OR_NULL(led_data->regulator)) - regulator_put(led_data->regulator); - led_classdev_unregister(&led_data->led_dev); - kfree(led_data); - return 0; -} - -static const struct i2c_device_id lp8550_id[] = { - {LD_LP8550_NAME, 0}, - {} -}; - -static struct i2c_driver ld_lp8550_i2c_driver = { - .probe = ld_lp8550_probe, - .remove = ld_lp8550_remove, - .id_table = lp8550_id, - .driver = { - .name = LD_LP8550_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init ld_lp8550_init(void) -{ - return i2c_add_driver(&ld_lp8550_i2c_driver); -} - -static void __exit ld_lp8550_exit(void) -{ - i2c_del_driver(&ld_lp8550_i2c_driver); - -} - -module_init(ld_lp8550_init); -module_exit(ld_lp8550_exit); - -MODULE_DESCRIPTION("Lighting driver for LP8550"); -MODULE_AUTHOR("Dan Murphy D.Murphy@Motorola.com"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 614ebebaaa28..a688293abd0b 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -102,7 +102,6 @@ static struct dmi_system_id __initdata nas_led_whitelist[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") } }, - {} }; /* diff --git a/drivers/leds/ledtrig-sleep.c b/drivers/leds/ledtrig-sleep.c deleted file mode 100644 index f16404212152..000000000000 --- a/drivers/leds/ledtrig-sleep.c +++ /dev/null @@ -1,80 +0,0 @@ -/* drivers/leds/ledtrig-sleep.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 -#include -#include - -static int ledtrig_sleep_pm_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored); - -DEFINE_LED_TRIGGER(ledtrig_sleep) -static struct notifier_block ledtrig_sleep_pm_notifier = { - .notifier_call = ledtrig_sleep_pm_callback, - .priority = 0, -}; - -static void ledtrig_sleep_early_suspend(struct early_suspend *h) -{ - led_trigger_event(ledtrig_sleep, LED_FULL); -} - -static void ledtrig_sleep_early_resume(struct early_suspend *h) -{ - led_trigger_event(ledtrig_sleep, LED_OFF); -} - -static struct early_suspend ledtrig_sleep_early_suspend_handler = { - .suspend = ledtrig_sleep_early_suspend, - .resume = ledtrig_sleep_early_resume, -}; - -static int ledtrig_sleep_pm_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored) -{ - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - led_trigger_event(ledtrig_sleep, LED_OFF); - return NOTIFY_OK; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - led_trigger_event(ledtrig_sleep, LED_FULL); - return NOTIFY_OK; - } - - return NOTIFY_DONE; -} - -static int __init ledtrig_sleep_init(void) -{ - led_trigger_register_simple("sleep", &ledtrig_sleep); - register_pm_notifier(&ledtrig_sleep_pm_notifier); - register_early_suspend(&ledtrig_sleep_early_suspend_handler); - return 0; -} - -static void __exit ledtrig_sleep_exit(void) -{ - unregister_early_suspend(&ledtrig_sleep_early_suspend_handler); - unregister_pm_notifier(&ledtrig_sleep_pm_notifier); - led_trigger_unregister_simple(ledtrig_sleep); -} - -module_init(ledtrig_sleep_init); -module_exit(ledtrig_sleep_exit); - diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 87e4e78790c0..f9fc07d7a4b9 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1136,6 +1136,11 @@ 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/md.c b/drivers/md/md.c index 4d45012f77b3..f20d13e717d5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1329,7 +1329,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors; + return num_sectors / 2; /* kB for sysfs */ } @@ -1697,7 +1697,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors; + return num_sectors / 2; /* kB for sysfs */ } static struct super_type super_types[] = { @@ -2172,8 +2172,6 @@ repeat: if (!mddev->persistent) { clear_bit(MD_CHANGE_CLEAN, &mddev->flags); clear_bit(MD_CHANGE_DEVS, &mddev->flags); - if (!mddev->external) - clear_bit(MD_CHANGE_PENDING, &mddev->flags); wake_up(&mddev->sb_wait); return; } @@ -4289,6 +4287,9 @@ 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); @@ -5147,7 +5148,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) PTR_ERR(rdev)); return PTR_ERR(rdev); } - /* set saved_raid_disk if appropriate */ + /* set save_raid_disk if appropriate */ if (!mddev->persistent) { if (info->state & (1<raid_disk < mddev->raid_disks) @@ -5157,10 +5158,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) } else super_types[mddev->major_version]. validate_super(mddev, rdev); - if (test_bit(In_sync, &rdev->flags)) - rdev->saved_raid_disk = rdev->raid_disk; - else - rdev->saved_raid_disk = -1; + rdev->saved_raid_disk = rdev->raid_disk; clear_bit(In_sync, &rdev->flags); /* just to be sure */ if (info->state & (1<timeout); - if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) - thread->run(thread->mddev); + clear_bit(THREAD_WAKEUP, &thread->flags); + + thread->run(thread->mddev); } return 0; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d8b2d7b0c3be..0b830bbe1d8b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1210,7 +1210,6 @@ static int raid1_remove_disk(mddev_t *mddev, int number) * is not possible. */ if (!test_bit(Faulty, &rdev->flags) && - !mddev->recovery_disabled && mddev->degraded < conf->raid_disks) { err = -EBUSY; goto abort; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 838c275fd3c8..84718383124d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2396,13 +2396,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/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index 1d1d8d200755..05bde9ccb770 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 = saa7146_format_by_fourcc(dev, pixelformat); + struct saa7146_format *sfmt = 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 = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); + struct saa7146_format *sfmt = 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 = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); + struct saa7146_format *sfmt = 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 = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); + struct saa7146_format *sfmt = 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 5f01da182aff..a212a91a30f0 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* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) +struct saa7146_format* 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 = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); + struct saa7146_format *sfmt = 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 = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); + fmt = 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 = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); + fmt = 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 = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat); + fmt = 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 = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); + fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); if (NULL == fmt) return -EINVAL; @@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q, buf->fmt = &fh->video_fmt; buf->vb.field = fh->video_fmt.field; - sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); + sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); release_all_pagetables(dev, buf); if( 0 != IS_PLANAR(sfmt->trans)) { @@ -1378,7 +1378,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 = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); + sfmt = 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/video/Kconfig b/drivers/media/video/Kconfig index eb5a53dc52c7..31f658eecb46 100755 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -554,7 +554,6 @@ config VIDEO_VIVI source "drivers/media/video/davinci/Kconfig" source "drivers/media/video/omap/Kconfig" -source "drivers/media/video/tegra/Kconfig" source "drivers/media/video/bt8xx/Kconfig" diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 399ff510d79c..40f98fba5f88 100755 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -179,7 +179,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-y += davinci/ obj-$(CONFIG_ARCH_OMAP) += omap/ -obj-$(CONFIG_ARCH_TEGRA) += tegra/ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 11c987eb6df9..f6b62e7398af 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -815,7 +815,6 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) case 0x0e: /* CX23887-15Z */ dev->hwrevision = 0xc0; - break; case 0x0f: /* CX23887-14Z */ dev->hwrevision = 0xb1; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index a50bf65de06e..78abc1c1f9d5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -652,7 +652,7 @@ 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) + if (gspca_dev->audio) i++; while (++i < gspca_dev->nbalt) { ep = alt_xfer(&intf->altsetting[i], xfer); @@ -660,7 +660,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) break; } } else { - if (gspca_dev->audio && i > 1) + if (gspca_dev->audio) i--; while (--i >= 0) { ep = alt_xfer(&intf->altsetting[i], xfer); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 248c2e62b278..370544361be2 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -56,7 +56,6 @@ struct sd { u8 jpegqual; /* webcam quality */ u8 reg18; - u8 flags; s8 ag_cnt; #define AG_CNT_START 13 @@ -88,9 +87,6 @@ enum sensors { SENSOR_SP80708, }; -/* device flags */ -#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */ - /* 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); @@ -1781,8 +1777,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; sd->bridge = id->driver_info >> 16; - sd->sensor = id->driver_info >> 8; - sd->flags = id->driver_info; + sd->sensor = id->driver_info; cam = &gspca_dev->cam; if (sd->sensor == SENSOR_ADCM1700) { @@ -2479,7 +2474,8 @@ static int sd_start(struct gspca_dev *gspca_dev) reg1 = 0x44; reg17 = 0xa2; break; - case SENSOR_SP80708: + default: +/* case SENSOR_SP80708: */ init = sp80708_sensor_param1; if (mode) { /*?? reg1 = 0x04; * 320 clk 48Mhz */ @@ -2989,18 +2985,14 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ #define BS(bridge, sensor) \ .driver_info = (BRIDGE_ ## bridge << 16) \ - | (SENSOR_ ## sensor << 8) -#define BSF(bridge, sensor, flags) \ - .driver_info = (BRIDGE_ ## bridge << 16) \ - | (SENSOR_ ## sensor << 8) \ - | (flags) + | SENSOR_ ## sensor 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), BSF(SN9C105, OV7660, PDN_INV)}, - {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)}, + {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)}, + {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)}, {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/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index 93f795960a94..4863a21b1f24 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -157,7 +157,6 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) mem, dev->bulk_in_size, hdpvr_read_bulk_callback, buf); - buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; buf->status = BUFSTAT_AVAILABLE; list_add_tail(&buf->buff_list, &dev->free_buff_list); } diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 4897d90f6a25..0e412131da7c 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -382,12 +382,7 @@ static int msp_s_ctrl(struct v4l2_ctrl *ctrl) void msp_update_volume(struct msp_state *state) { - /* Force an update of the volume/mute cluster */ - v4l2_ctrl_lock(state->volume); - state->volume->val = state->volume->cur.val; - state->muted->val = state->muted->cur.val; - msp_s_ctrl(state->volume); - v4l2_ctrl_unlock(state->volume); + v4l2_ctrl_s_ctrl(state->volume, v4l2_ctrl_g_ctrl(state->volume)); } /* --- v4l2 ioctls --- */ diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 15cb5b3f8ac2..b6ea67221d1d 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -791,6 +791,8 @@ 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/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 7c74751d299e..bb8d83d8ddaf 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -6660,18 +6660,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x13c2, .subdevice = 0x2804, .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000, - }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ - .subdevice = 0x7190, - .driver_data = SAA7134_BOARD_BEHOLD_H7, - }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ - .subdevice = 0x7090, - .driver_data = SAA7134_BOARD_BEHOLD_A7, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -6710,6 +6698,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = SAA7134_BOARD_UNKNOWN, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ + .subdevice = 0x7190, + .driver_data = SAA7134_BOARD_BEHOLD_H7, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ + .subdevice = 0x7090, + .driver_data = SAA7134_BOARD_BEHOLD_A7, },{ /* --- end of list --- */ } diff --git a/drivers/media/video/tegra/Kconfig b/drivers/media/video/tegra/Kconfig deleted file mode 100644 index 701453635b21..000000000000 --- a/drivers/media/video/tegra/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -source "drivers/media/video/tegra/avp/Kconfig" - -config TEGRA_CAMERA - bool "Enable support for tegra camera/isp hardware" - depends on ARCH_TEGRA - default y - help - Enables support for the Tegra camera interface - - If unsure, say Y - -config VIDEO_OV5650 - tristate "OV5650 camera sensor support" - depends on I2C && ARCH_TEGRA - ---help--- - This is a driver for the Omnivision OV5650 5MP camera sensor - for use with the tegra isp. - -config VIDEO_SOC2030 - tristate "SOC2030 camera sensor support" - depends on I2C && ARCH_TEGRA - ---help--- - This is a driver for the SOC2030 2MP camera sensor - for use with the tegra isp. - -config VIDEO_DW9714L - tristate "DW9714L focuser support" - depends on I2C && ARCH_TEGRA - ---help--- - This is a driver for the the dw9714l focuser. diff --git a/drivers/media/video/tegra/Makefile b/drivers/media/video/tegra/Makefile deleted file mode 100644 index 1a70f4bc7d4b..000000000000 --- a/drivers/media/video/tegra/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-y += avp/ -obj-$(CONFIG_TEGRA_CAMERA) += tegra_camera.o -obj-$(CONFIG_VIDEO_OV5650) += ov5650.o -obj-$(CONFIG_VIDEO_SOC2030) += soc2030.o -obj-$(CONFIG_VIDEO_DW9714L) += dw9714l.o diff --git a/drivers/media/video/tegra/avp/Kconfig b/drivers/media/video/tegra/avp/Kconfig deleted file mode 100644 index fdd208510fcb..000000000000 --- a/drivers/media/video/tegra/avp/Kconfig +++ /dev/null @@ -1,25 +0,0 @@ -config TEGRA_RPC - bool "Enable support for Tegra RPC" - depends on ARCH_TEGRA - default y - help - Enables support for the RPC mechanism necessary for the Tegra - multimedia framework. It is both used to communicate locally on the - CPU between multiple multimedia components as well as to communicate - with the AVP for offloading media decode. - - Exports the local tegra RPC interface on device node - /dev/tegra_rpc. Also provides tegra fd based semaphores needed by - the tegra multimedia framework. - - If unsure, say Y - -config TEGRA_AVP - bool "Enable support for the AVP multimedia offload engine" - depends on ARCH_TEGRA && TEGRA_RPC - default y - help - Enables support for the multimedia offload engine used by Tegra - multimedia framework. - - If unsure, say Y diff --git a/drivers/media/video/tegra/avp/Makefile b/drivers/media/video/tegra/avp/Makefile deleted file mode 100644 index 6d8be11c3f81..000000000000 --- a/drivers/media/video/tegra/avp/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_TEGRA_RPC) += tegra_rpc.o -obj-$(CONFIG_TEGRA_RPC) += trpc_local.o -obj-$(CONFIG_TEGRA_RPC) += trpc_sema.o -obj-$(CONFIG_TEGRA_AVP) += avp.o -obj-$(CONFIG_TEGRA_AVP) += avp_svc.o -obj-$(CONFIG_TEGRA_AVP) += headavp.o diff --git a/drivers/media/video/tegra/avp/avp.c b/drivers/media/video/tegra/avp/avp.c deleted file mode 100644 index ced838ac6e2b..000000000000 --- a/drivers/media/video/tegra/avp/avp.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "../../../../video/tegra/nvmap/nvmap.h" - -#include "headavp.h" -#include "avp_msg.h" -#include "trpc.h" -#include "avp.h" - -enum { - AVP_DBG_TRACE_XPC = 1U << 0, - AVP_DBG_TRACE_XPC_IRQ = 1U << 1, - AVP_DBG_TRACE_XPC_MSG = 1U << 2, - AVP_DBG_TRACE_XPC_CONN = 1U << 3, - AVP_DBG_TRACE_TRPC_MSG = 1U << 4, - AVP_DBG_TRACE_TRPC_CONN = 1U << 5, - AVP_DBG_TRACE_LIB = 1U << 6, -}; - -static u32 avp_debug_mask = 0; -module_param_named(debug_mask, avp_debug_mask, uint, S_IWUSR | S_IRUGO); - -#define DBG(flag, args...) \ - do { if (unlikely(avp_debug_mask & (flag))) pr_info(args); } while (0) - -#define TEGRA_AVP_NAME "tegra-avp" - -#define TEGRA_AVP_KERNEL_FW "nvrm_avp.bin" - -#define TEGRA_AVP_RESET_VECTOR_ADDR \ - (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x200) - -#define TEGRA_AVP_RESUME_ADDR IO_ADDRESS(TEGRA_IRAM_BASE) - -#define FLOW_CTRL_HALT_COP_EVENTS IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + 0x4) -#define FLOW_MODE_STOP (0x2 << 29) -#define FLOW_MODE_NONE 0x0 - -#define MBOX_FROM_AVP IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x10) -#define MBOX_TO_AVP IO_ADDRESS(TEGRA_RES_SEMA_BASE + 0x20) - -/* Layout of the mailbox registers: - * bit 31 - pending message interrupt enable (mailbox full, i.e. valid=1) - * bit 30 - message cleared interrupt enable (mailbox empty, i.e. valid=0) - * bit 29 - message valid. peer clears this bit after reading msg - * bits 27:0 - message data - */ -#define MBOX_MSG_PENDING_INT_EN (1 << 31) -#define MBOX_MSG_READ_INT_EN (1 << 30) -#define MBOX_MSG_VALID (1 << 29) - -#define AVP_MSG_MAX_CMD_LEN 16 -#define AVP_MSG_AREA_SIZE (AVP_MSG_MAX_CMD_LEN + TEGRA_RPC_MAX_MSG_LEN) - -struct avp_info { - struct clk *cop_clk; - - int mbox_from_avp_pend_irq; - - dma_addr_t msg_area_addr; - u32 msg; - void *msg_to_avp; - void *msg_from_avp; - struct mutex to_avp_lock; - struct mutex from_avp_lock; - - struct work_struct recv_work; - struct workqueue_struct *recv_wq; - - struct trpc_node *rpc_node; - struct miscdevice misc_dev; - bool opened; - struct mutex open_lock; - - spinlock_t state_lock; - bool initialized; - bool shutdown; - bool suspending; - bool defer_remote; - - struct mutex libs_lock; - struct list_head libs; - struct nvmap_client *nvmap_libs; - - /* client for driver allocations, persistent */ - struct nvmap_client *nvmap_drv; - struct nvmap_handle_ref *kernel_handle; - void *kernel_data; - unsigned long kernel_phys; - - struct nvmap_handle_ref *iram_backup_handle; - void *iram_backup_data; - unsigned long iram_backup_phys; - unsigned long resume_addr; - - struct trpc_endpoint *avp_ep; - struct rb_root endpoints; - - struct avp_svc_info *avp_svc; -}; - -struct remote_info { - u32 loc_id; - u32 rem_id; - struct kref ref; - - struct trpc_endpoint *trpc_ep; - struct rb_node rb_node; -}; - -struct lib_item { - struct list_head list; - u32 handle; - char name[TEGRA_AVP_LIB_MAX_NAME]; -}; - -static struct avp_info *tegra_avp; - -static int avp_trpc_send(struct trpc_endpoint *ep, void *buf, size_t len); -static void avp_trpc_close(struct trpc_endpoint *ep); -static void avp_trpc_show(struct seq_file *s, struct trpc_endpoint *ep); -static void libs_cleanup(struct avp_info *avp); - -static struct trpc_ep_ops remote_ep_ops = { - .send = avp_trpc_send, - .close = avp_trpc_close, - .show = avp_trpc_show, -}; - -static struct remote_info *rinfo_alloc(struct avp_info *avp) -{ - struct remote_info *rinfo; - - rinfo = kzalloc(sizeof(struct remote_info), GFP_KERNEL); - if (!rinfo) - return NULL; - kref_init(&rinfo->ref); - return rinfo; -} - -static void _rinfo_release(struct kref *ref) -{ - struct remote_info *rinfo = container_of(ref, struct remote_info, ref); - kfree(rinfo); -} - -static inline void rinfo_get(struct remote_info *rinfo) -{ - kref_get(&rinfo->ref); -} - -static inline void rinfo_put(struct remote_info *rinfo) -{ - kref_put(&rinfo->ref, _rinfo_release); -} - -static int remote_insert(struct avp_info *avp, struct remote_info *rinfo) -{ - struct rb_node **p; - struct rb_node *parent; - struct remote_info *tmp; - - p = &avp->endpoints.rb_node; - parent = NULL; - while (*p) { - parent = *p; - tmp = rb_entry(parent, struct remote_info, rb_node); - - if (rinfo->loc_id < tmp->loc_id) - p = &(*p)->rb_left; - else if (rinfo->loc_id > tmp->loc_id) - p = &(*p)->rb_right; - else { - pr_info("%s: avp endpoint id=%x (%s) already exists\n", - __func__, rinfo->loc_id, - trpc_name(rinfo->trpc_ep)); - return -EEXIST; - } - } - rb_link_node(&rinfo->rb_node, parent, p); - rb_insert_color(&rinfo->rb_node, &avp->endpoints); - rinfo_get(rinfo); - return 0; -} - -static struct remote_info *remote_find(struct avp_info *avp, u32 local_id) -{ - struct rb_node *n = avp->endpoints.rb_node; - struct remote_info *rinfo; - - while (n) { - rinfo = rb_entry(n, struct remote_info, rb_node); - - if (local_id < rinfo->loc_id) - n = n->rb_left; - else if (local_id > rinfo->loc_id) - n = n->rb_right; - else - return rinfo; - } - return NULL; -} - -static void remote_remove(struct avp_info *avp, struct remote_info *rinfo) -{ - rb_erase(&rinfo->rb_node, &avp->endpoints); - rinfo_put(rinfo); -} - -/* test whether or not the trpc endpoint provided is a valid AVP node - * endpoint */ -static struct remote_info *validate_trpc_ep(struct avp_info *avp, - struct trpc_endpoint *ep) -{ - struct remote_info *tmp = trpc_priv(ep); - struct remote_info *rinfo; - - if (!tmp) - return NULL; - rinfo = remote_find(avp, tmp->loc_id); - if (rinfo && rinfo == tmp && rinfo->trpc_ep == ep) - return rinfo; - return NULL; -} - -static void avp_trpc_show(struct seq_file *s, struct trpc_endpoint *ep) -{ - struct avp_info *avp = tegra_avp; - struct remote_info *rinfo; - unsigned long flags; - - spin_lock_irqsave(&avp->state_lock, flags); - rinfo = validate_trpc_ep(avp, ep); - if (!rinfo) { - seq_printf(s, " \n"); - goto out; - } - seq_printf(s, " loc_id:0x%x\n rem_id:0x%x\n", - rinfo->loc_id, rinfo->rem_id); -out: - spin_unlock_irqrestore(&avp->state_lock, flags); -} - -static inline void mbox_writel(u32 val, void __iomem *mbox) -{ - writel(val, mbox); -} - -static inline u32 mbox_readl(void __iomem *mbox) -{ - return readl(mbox); -} - -static inline void msg_ack_remote(struct avp_info *avp, u32 cmd, u32 arg) -{ - struct msg_ack *ack = avp->msg_from_avp; - - /* must make sure the arg is there first */ - ack->arg = arg; - wmb(); - ack->cmd = cmd; - wmb(); -} - -static inline u32 msg_recv_get_cmd(struct avp_info *avp) -{ - volatile u32 *cmd = avp->msg_from_avp; - rmb(); - return *cmd; -} - -static inline int __msg_write(struct avp_info *avp, void *hdr, size_t hdr_len, - void *buf, size_t len) -{ - memcpy(avp->msg_to_avp, hdr, hdr_len); - if (buf && len) - memcpy(avp->msg_to_avp + hdr_len, buf, len); - mbox_writel(avp->msg, MBOX_TO_AVP); - return 0; -} - -static inline int msg_write(struct avp_info *avp, void *hdr, size_t hdr_len, - void *buf, size_t len) -{ - /* rem_ack is a pointer into shared memory that the AVP modifies */ - volatile u32 *rem_ack = avp->msg_to_avp; - unsigned long endtime = jiffies + HZ; - - /* the other side ack's the message by clearing the first word, - * wait for it to do so */ - rmb(); - while (*rem_ack != 0 && time_before(jiffies, endtime)) { - usleep_range(100, 2000); - rmb(); - } - if (*rem_ack != 0) - return -ETIMEDOUT; - __msg_write(avp, hdr, hdr_len, buf, len); - return 0; -} - -static inline int msg_check_ack(struct avp_info *avp, u32 cmd, u32 *arg) -{ - struct msg_ack ack; - - rmb(); - memcpy(&ack, avp->msg_to_avp, sizeof(ack)); - if (ack.cmd != cmd) - return -ENOENT; - if (arg) - *arg = ack.arg; - return 0; -} - -/* XXX: add timeout */ -static int msg_wait_ack_locked(struct avp_info *avp, u32 cmd, u32 *arg) -{ - /* rem_ack is a pointer into shared memory that the AVP modifies */ - volatile u32 *rem_ack = avp->msg_to_avp; - unsigned long endtime = jiffies + HZ / 5; - int ret; - - do { - ret = msg_check_ack(avp, cmd, arg); - usleep_range(1000, 5000); - } while (ret && time_before(jiffies, endtime)); - - /* if we timed out, try one more time */ - if (ret) - ret = msg_check_ack(avp, cmd, arg); - - /* clear out the ack */ - *rem_ack = 0; - wmb(); - return ret; -} - -static int avp_trpc_send(struct trpc_endpoint *ep, void *buf, size_t len) -{ - struct avp_info *avp = tegra_avp; - struct remote_info *rinfo; - struct msg_port_data msg; - int ret; - unsigned long flags; - - DBG(AVP_DBG_TRACE_TRPC_MSG, "%s: ep=%p priv=%p buf=%p len=%d\n", - __func__, ep, trpc_priv(ep), buf, len); - - spin_lock_irqsave(&avp->state_lock, flags); - if (unlikely(avp->suspending && trpc_peer(ep) != avp->avp_ep)) { - ret = -EBUSY; - goto err_state_locked; - } else if (avp->shutdown) { - ret = -ENODEV; - goto err_state_locked; - } - rinfo = validate_trpc_ep(avp, ep); - if (!rinfo) { - ret = -ENOTTY; - goto err_state_locked; - } - rinfo_get(rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - - msg.cmd = CMD_MESSAGE; - msg.port_id = rinfo->rem_id; - msg.msg_len = len; - - mutex_lock(&avp->to_avp_lock); - ret = msg_write(avp, &msg, sizeof(msg), buf, len); - mutex_unlock(&avp->to_avp_lock); - - DBG(AVP_DBG_TRACE_TRPC_MSG, "%s: msg sent for %s (%x->%x) (%d)\n", - __func__, trpc_name(ep), rinfo->loc_id, rinfo->rem_id, ret); - rinfo_put(rinfo); - return ret; - -err_state_locked: - spin_unlock_irqrestore(&avp->state_lock, flags); - return ret; -} - -static int _send_disconnect(struct avp_info *avp, u32 port_id) -{ - struct msg_disconnect msg; - int ret; - - msg.cmd = CMD_DISCONNECT; - msg.port_id = port_id; - - mutex_lock(&avp->to_avp_lock); - ret = msg_write(avp, &msg, sizeof(msg), NULL, 0); - if (ret) { - pr_err("%s: remote has not acked last message (%x)\n", __func__, - port_id); - goto err_msg_write; - } - - ret = msg_wait_ack_locked(avp, CMD_ACK, NULL); - if (ret) { - pr_err("%s: remote end won't respond for %x\n", __func__, - port_id); - goto err_wait_ack; - } - - DBG(AVP_DBG_TRACE_XPC_CONN, "%s: sent disconnect msg for %x\n", - __func__, port_id); - -err_wait_ack: -err_msg_write: - mutex_unlock(&avp->to_avp_lock); - return ret; -} - -/* Note: Assumes that the rinfo was previously successfully added to the - * endpoints rb_tree. The initial refcnt of 1 is inherited by the port when the - * trpc endpoint is created with thi trpc_xxx functions. Thus, on close, - * we must drop that reference here. - * The avp->endpoints rb_tree keeps its own reference on rinfo objects. - * - * The try_connect function does not use this on error because it needs to - * split the close of trpc_ep port and the put. - */ -static inline void remote_close(struct remote_info *rinfo) -{ - trpc_close(rinfo->trpc_ep); - rinfo_put(rinfo); -} - -static void avp_trpc_close(struct trpc_endpoint *ep) -{ - struct avp_info *avp = tegra_avp; - struct remote_info *rinfo; - unsigned long flags; - int ret; - - spin_lock_irqsave(&avp->state_lock, flags); - if (avp->shutdown) { - spin_unlock_irqrestore(&avp->state_lock, flags); - return; - } - - rinfo = validate_trpc_ep(avp, ep); - if (!rinfo) { - pr_err("%s: tried to close invalid port '%s' endpoint (%p)\n", - __func__, trpc_name(ep), ep); - spin_unlock_irqrestore(&avp->state_lock, flags); - return; - } - rinfo_get(rinfo); - remote_remove(avp, rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - - DBG(AVP_DBG_TRACE_TRPC_CONN, "%s: closing '%s' (%x)\n", __func__, - trpc_name(ep), rinfo->rem_id); - - ret = _send_disconnect(avp, rinfo->rem_id); - if (ret) - pr_err("%s: error while closing remote port '%s' (%x)\n", - __func__, trpc_name(ep), rinfo->rem_id); - remote_close(rinfo); - rinfo_put(rinfo); -} - -/* takes and holds avp->from_avp_lock */ -static void recv_msg_lock(struct avp_info *avp) -{ - unsigned long flags; - - mutex_lock(&avp->from_avp_lock); - spin_lock_irqsave(&avp->state_lock, flags); - avp->defer_remote = true; - spin_unlock_irqrestore(&avp->state_lock, flags); -} - -/* MUST be called with avp->from_avp_lock held */ -static void recv_msg_unlock(struct avp_info *avp) -{ - unsigned long flags; - - spin_lock_irqsave(&avp->state_lock, flags); - avp->defer_remote = false; - spin_unlock_irqrestore(&avp->state_lock, flags); - mutex_unlock(&avp->from_avp_lock); -} - -static int avp_node_try_connect(struct trpc_node *node, - struct trpc_node *src_node, - struct trpc_endpoint *from) -{ - struct avp_info *avp = tegra_avp; - const char *port_name = trpc_name(from); - struct remote_info *rinfo; - struct msg_connect msg; - int ret; - unsigned long flags; - int len; - - DBG(AVP_DBG_TRACE_TRPC_CONN, "%s: trying connect from %s\n", __func__, - port_name); - - if (node != avp->rpc_node || node->priv != avp) - return -ENODEV; - - len = strlen(port_name); - if (len > XPC_PORT_NAME_LEN) { - pr_err("%s: port name (%s) to long\n", __func__, port_name); - return -EINVAL; - } - - ret = 0; - spin_lock_irqsave(&avp->state_lock, flags); - if (avp->suspending) { - ret = -EBUSY; - } else if (likely(src_node != avp->rpc_node)) { - /* only check for initialized when the source is not ourselves - * since we'll end up calling into here during initialization */ - if (!avp->initialized) - ret = -ENODEV; - } else if (strncmp(port_name, "RPC_AVP_PORT", XPC_PORT_NAME_LEN)) { - /* we only allow connections to ourselves for the cpu-to-avp - port */ - ret = -EINVAL; - } - spin_unlock_irqrestore(&avp->state_lock, flags); - if (ret) - return ret; - - rinfo = rinfo_alloc(avp); - if (!rinfo) { - pr_err("%s: cannot alloc mem for rinfo\n", __func__); - ret = -ENOMEM; - goto err_alloc_rinfo; - } - rinfo->loc_id = (u32)rinfo; - - msg.cmd = CMD_CONNECT; - msg.port_id = rinfo->loc_id; - memcpy(msg.name, port_name, len); - memset(msg.name + len, 0, XPC_PORT_NAME_LEN - len); - - /* when trying to connect to remote, we need to block remote - * messages until we get our ack and can insert it into our lists. - * Otherwise, we can get a message from the other side for a port - * that we haven't finished setting up. - * - * 'defer_remote' will force the irq handler to not process messages - * at irq context but to schedule work to do so. The work function will - * take the from_avp_lock and everything should stay consistent. - */ - recv_msg_lock(avp); - mutex_lock(&avp->to_avp_lock); - ret = msg_write(avp, &msg, sizeof(msg), NULL, 0); - if (ret) { - pr_err("%s: remote has not acked last message (%s)\n", __func__, - port_name); - mutex_unlock(&avp->to_avp_lock); - goto err_msg_write; - } - ret = msg_wait_ack_locked(avp, CMD_RESPONSE, &rinfo->rem_id); - mutex_unlock(&avp->to_avp_lock); - - if (ret) { - pr_err("%s: remote end won't respond for '%s'\n", __func__, - port_name); - goto err_wait_ack; - } - if (!rinfo->rem_id) { - pr_err("%s: can't connect to '%s'\n", __func__, port_name); - ret = -ECONNREFUSED; - goto err_nack; - } - - DBG(AVP_DBG_TRACE_TRPC_CONN, "%s: got conn ack '%s' (%x <-> %x)\n", - __func__, port_name, rinfo->loc_id, rinfo->rem_id); - - rinfo->trpc_ep = trpc_create_peer(node, from, &remote_ep_ops, - rinfo); - if (!rinfo->trpc_ep) { - pr_err("%s: cannot create peer for %s\n", __func__, port_name); - ret = -EINVAL; - goto err_create_peer; - } - - spin_lock_irqsave(&avp->state_lock, flags); - ret = remote_insert(avp, rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - if (ret) - goto err_ep_insert; - - recv_msg_unlock(avp); - return 0; - -err_ep_insert: - trpc_close(rinfo->trpc_ep); -err_create_peer: - _send_disconnect(avp, rinfo->rem_id); -err_nack: -err_wait_ack: -err_msg_write: - recv_msg_unlock(avp); - rinfo_put(rinfo); -err_alloc_rinfo: - return ret; -} - -static void process_disconnect_locked(struct avp_info *avp, - struct msg_data *raw_msg) -{ - struct msg_disconnect *disconn_msg = (struct msg_disconnect *)raw_msg; - unsigned long flags; - struct remote_info *rinfo; - - DBG(AVP_DBG_TRACE_XPC_CONN, "%s: got disconnect (%x)\n", __func__, - disconn_msg->port_id); - - if (avp_debug_mask & AVP_DBG_TRACE_XPC_MSG) - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, disconn_msg, - sizeof(struct msg_disconnect)); - - spin_lock_irqsave(&avp->state_lock, flags); - rinfo = remote_find(avp, disconn_msg->port_id); - if (!rinfo) { - spin_unlock_irqrestore(&avp->state_lock, flags); - pr_warning("%s: got disconnect for unknown port %x\n", - __func__, disconn_msg->port_id); - goto ack; - } - rinfo_get(rinfo); - remote_remove(avp, rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - - remote_close(rinfo); - rinfo_put(rinfo); -ack: - msg_ack_remote(avp, CMD_ACK, 0); -} - -static void process_connect_locked(struct avp_info *avp, - struct msg_data *raw_msg) -{ - struct msg_connect *conn_msg = (struct msg_connect *)raw_msg; - struct trpc_endpoint *trpc_ep; - struct remote_info *rinfo; - char name[XPC_PORT_NAME_LEN + 1]; - int ret; - u32 local_port_id = 0; - unsigned long flags; - - DBG(AVP_DBG_TRACE_XPC_CONN, "%s: got connect (%x)\n", __func__, - conn_msg->port_id); - if (avp_debug_mask & AVP_DBG_TRACE_XPC_MSG) - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - conn_msg, sizeof(struct msg_connect)); - - rinfo = rinfo_alloc(avp); - if (!rinfo) { - pr_err("%s: cannot alloc mem for rinfo\n", __func__); - ret = -ENOMEM; - goto ack; - } - rinfo->loc_id = (u32)rinfo; - rinfo->rem_id = conn_msg->port_id; - - memcpy(name, conn_msg->name, XPC_PORT_NAME_LEN); - name[XPC_PORT_NAME_LEN] = '\0'; - trpc_ep = trpc_create_connect(avp->rpc_node, name, &remote_ep_ops, - rinfo, 0); - if (IS_ERR(trpc_ep)) { - pr_err("%s: remote requested unknown port '%s' (%d)\n", - __func__, name, (int)PTR_ERR(trpc_ep)); - goto nack; - } - rinfo->trpc_ep = trpc_ep; - - spin_lock_irqsave(&avp->state_lock, flags); - ret = remote_insert(avp, rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - if (ret) - goto err_ep_insert; - - local_port_id = rinfo->loc_id; - goto ack; - -err_ep_insert: - trpc_close(trpc_ep); -nack: - rinfo_put(rinfo); - local_port_id = 0; -ack: - msg_ack_remote(avp, CMD_RESPONSE, local_port_id); -} - -static int process_message(struct avp_info *avp, struct msg_data *raw_msg, - gfp_t gfp_flags) -{ - struct msg_port_data *port_msg = (struct msg_port_data *)raw_msg; - struct remote_info *rinfo; - unsigned long flags; - int len; - int ret; - - len = min(port_msg->msg_len, (u32)TEGRA_RPC_MAX_MSG_LEN); - - if (avp_debug_mask & AVP_DBG_TRACE_XPC_MSG) { - pr_info("%s: got message cmd=%x port=%x len=%d\n", __func__, - port_msg->cmd, port_msg->port_id, port_msg->msg_len); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, port_msg, - sizeof(struct msg_port_data) + len); - } - - if (len != port_msg->msg_len) - pr_err("%s: message sent is too long (%d bytes)\n", __func__, - port_msg->msg_len); - - spin_lock_irqsave(&avp->state_lock, flags); - rinfo = remote_find(avp, port_msg->port_id); - if (rinfo) { - rinfo_get(rinfo); - trpc_get(rinfo->trpc_ep); - } else { - pr_err("%s: port %x not found\n", __func__, port_msg->port_id); - spin_unlock_irqrestore(&avp->state_lock, flags); - ret = -ENOENT; - goto ack; - } - spin_unlock_irqrestore(&avp->state_lock, flags); - - ret = trpc_send_msg(avp->rpc_node, rinfo->trpc_ep, port_msg->data, - len, gfp_flags); - if (ret == -ENOMEM) { - trpc_put(rinfo->trpc_ep); - rinfo_put(rinfo); - goto no_ack; - } else if (ret) { - pr_err("%s: cannot queue message for port %s/%x (%d)\n", - __func__, trpc_name(rinfo->trpc_ep), rinfo->loc_id, - ret); - } else { - DBG(AVP_DBG_TRACE_XPC_MSG, "%s: msg queued\n", __func__); - } - - trpc_put(rinfo->trpc_ep); - rinfo_put(rinfo); -ack: - msg_ack_remote(avp, CMD_ACK, 0); -no_ack: - return ret; -} - -static void process_avp_message(struct work_struct *work) -{ - struct avp_info *avp = container_of(work, struct avp_info, recv_work); - struct msg_data *msg = avp->msg_from_avp; - - mutex_lock(&avp->from_avp_lock); - rmb(); - switch (msg->cmd) { - case CMD_CONNECT: - process_connect_locked(avp, msg); - break; - case CMD_DISCONNECT: - process_disconnect_locked(avp, msg); - break; - case CMD_MESSAGE: - process_message(avp, msg, GFP_KERNEL); - break; - default: - pr_err("%s: unknown cmd (%x) received\n", __func__, msg->cmd); - break; - } - mutex_unlock(&avp->from_avp_lock); -} - -static irqreturn_t avp_mbox_pending_isr(int irq, void *data) -{ - struct avp_info *avp = data; - struct msg_data *msg = avp->msg_from_avp; - u32 mbox_msg; - unsigned long flags; - int ret; - - mbox_msg = mbox_readl(MBOX_FROM_AVP); - mbox_writel(0, MBOX_FROM_AVP); - - DBG(AVP_DBG_TRACE_XPC_IRQ, "%s: got msg %x\n", __func__, mbox_msg); - - /* XXX: re-use previous message? */ - if (!(mbox_msg & MBOX_MSG_VALID)) { - WARN_ON(1); - goto done; - } - - mbox_msg <<= 4; - if (mbox_msg == 0x2f00bad0UL) { - pr_info("%s: petting watchdog\n", __func__); - goto done; - } - - spin_lock_irqsave(&avp->state_lock, flags); - if (avp->shutdown) { - spin_unlock_irqrestore(&avp->state_lock, flags); - goto done; - } else if (avp->defer_remote) { - spin_unlock_irqrestore(&avp->state_lock, flags); - goto defer; - } - spin_unlock_irqrestore(&avp->state_lock, flags); - - rmb(); - if (msg->cmd == CMD_MESSAGE) { - ret = process_message(avp, msg, GFP_ATOMIC); - if (ret != -ENOMEM) - goto done; - pr_info("%s: deferring message (%d)\n", __func__, ret); - } -defer: - queue_work(avp->recv_wq, &avp->recv_work); -done: - return IRQ_HANDLED; -} - -static int avp_reset(struct avp_info *avp, unsigned long reset_addr) -{ - unsigned long stub_code_phys = virt_to_phys(_tegra_avp_boot_stub); - dma_addr_t stub_data_phys; - unsigned long timeout; - int ret = 0; - - writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS); - - _tegra_avp_boot_stub_data.map_phys_addr = avp->kernel_phys; - _tegra_avp_boot_stub_data.jump_addr = reset_addr; - wmb(); - stub_data_phys = dma_map_single(NULL, &_tegra_avp_boot_stub_data, - sizeof(_tegra_avp_boot_stub_data), - DMA_TO_DEVICE); - - writel(stub_code_phys, TEGRA_AVP_RESET_VECTOR_ADDR); - - tegra_periph_reset_assert(avp->cop_clk); - udelay(10); - tegra_periph_reset_deassert(avp->cop_clk); - - writel(FLOW_MODE_NONE, FLOW_CTRL_HALT_COP_EVENTS); - - /* the AVP firmware will reprogram its reset vector as the kernel - * starts, so a dead kernel can be detected by polling this value */ - timeout = jiffies + msecs_to_jiffies(2000); - while (time_before(jiffies, timeout)) { - if (readl(TEGRA_AVP_RESET_VECTOR_ADDR) != stub_code_phys) - break; - cpu_relax(); - } - if (readl(TEGRA_AVP_RESET_VECTOR_ADDR) == stub_code_phys) - ret = -EINVAL; - WARN_ON(ret); - dma_unmap_single(NULL, stub_data_phys, - sizeof(_tegra_avp_boot_stub_data), - DMA_TO_DEVICE); - return ret; -} - -static void avp_halt(struct avp_info *avp) -{ - /* ensure the AVP is halted */ - writel(FLOW_MODE_STOP, FLOW_CTRL_HALT_COP_EVENTS); - tegra_periph_reset_assert(avp->cop_clk); - - /* set up the initial memory areas and mailbox contents */ - *((u32 *)avp->msg_from_avp) = 0; - *((u32 *)avp->msg_to_avp) = 0xfeedf00d; - mbox_writel(0, MBOX_FROM_AVP); - mbox_writel(0, MBOX_TO_AVP); -} - -/* Note: CPU_PORT server and AVP_PORT client are registered with the avp - * node, but are actually meant to be processed on our side (either - * by the svc thread for processing remote calls or by the client - * of the char dev for receiving replies for managing remote - * libraries/modules. */ - -static int avp_init(struct avp_info *avp, const char *fw_file) -{ - const struct firmware *avp_fw; - int ret; - struct trpc_endpoint *ep; - - avp->nvmap_libs = nvmap_create_client(nvmap_dev, "avp_libs"); - if (IS_ERR(avp->nvmap_libs)) { - pr_err("%s: cannot create libs nvmap client\n", __func__); - ret = PTR_ERR(avp->nvmap_libs); - goto err_nvmap_create_libs_client; - } - - /* put the address of the shared mem area into the mailbox for AVP - * to read out when its kernel boots. */ - mbox_writel(avp->msg, MBOX_TO_AVP); - - ret = request_firmware(&avp_fw, fw_file, avp->misc_dev.this_device); - if (ret) { - pr_err("%s: Cannot read firmware '%s'\n", __func__, fw_file); - goto err_req_fw; - } - pr_info("%s: read firmware from '%s' (%d bytes)\n", __func__, - fw_file, avp_fw->size); - memcpy(avp->kernel_data, avp_fw->data, avp_fw->size); - memset(avp->kernel_data + avp_fw->size, 0, SZ_1M - avp_fw->size); - wmb(); - release_firmware(avp_fw); - - ret = avp_reset(avp, AVP_KERNEL_VIRT_BASE); - if (ret) { - pr_err("%s: cannot reset the AVP.. aborting..\n", __func__); - goto err_reset; - } - - enable_irq(avp->mbox_from_avp_pend_irq); - /* Initialize the avp_svc *first*. This creates RPC_CPU_PORT to be - * ready for remote commands. Then, connect to the - * remote RPC_AVP_PORT to be able to send library load/unload and - * suspend commands to it */ - ret = avp_svc_start(avp->avp_svc); - if (ret) - goto err_avp_svc_start; - - ep = trpc_create_connect(avp->rpc_node, "RPC_AVP_PORT", NULL, - NULL, -1); - if (IS_ERR(ep)) { - pr_err("%s: can't connect to RPC_AVP_PORT server\n", __func__); - ret = PTR_ERR(ep); - goto err_rpc_avp_port; - } - avp->avp_ep = ep; - - avp->initialized = true; - smp_wmb(); - pr_info("%s: avp init done\n", __func__); - return 0; - -err_rpc_avp_port: - avp_svc_stop(avp->avp_svc); -err_avp_svc_start: - disable_irq(avp->mbox_from_avp_pend_irq); -err_reset: - avp_halt(avp); -err_req_fw: - nvmap_client_put(avp->nvmap_libs); -err_nvmap_create_libs_client: - avp->nvmap_libs = NULL; - return ret; -} - -static void avp_uninit(struct avp_info *avp) -{ - unsigned long flags; - struct rb_node *n; - struct remote_info *rinfo; - - spin_lock_irqsave(&avp->state_lock, flags); - avp->initialized = false; - avp->shutdown = true; - spin_unlock_irqrestore(&avp->state_lock, flags); - - disable_irq(avp->mbox_from_avp_pend_irq); - cancel_work_sync(&avp->recv_work); - - avp_halt(avp); - - spin_lock_irqsave(&avp->state_lock, flags); - while ((n = rb_first(&avp->endpoints)) != NULL) { - rinfo = rb_entry(n, struct remote_info, rb_node); - rinfo_get(rinfo); - remote_remove(avp, rinfo); - spin_unlock_irqrestore(&avp->state_lock, flags); - - remote_close(rinfo); - rinfo_put(rinfo); - - spin_lock_irqsave(&avp->state_lock, flags); - } - spin_unlock_irqrestore(&avp->state_lock, flags); - - avp_svc_stop(avp->avp_svc); - - if (avp->avp_ep) { - trpc_close(avp->avp_ep); - avp->avp_ep = NULL; - } - - libs_cleanup(avp); - - avp->shutdown = false; - smp_wmb(); - pr_info("%s: avp teardown done\n", __func__); -} - -/* returns the remote lib handle in lib->handle */ -static int _load_lib(struct avp_info *avp, struct tegra_avp_lib *lib) -{ - struct svc_lib_attach svc; - struct svc_lib_attach_resp resp; - const struct firmware *fw; - void *args; - struct nvmap_handle_ref *lib_handle; - void *lib_data; - unsigned long lib_phys; - int ret; - - DBG(AVP_DBG_TRACE_LIB, "avp_lib: loading library '%s'\n", lib->name); - - args = kmalloc(lib->args_len, GFP_KERNEL); - if (!args) { - pr_err("avp_lib: can't alloc mem for args (%d)\n", - lib->args_len); - return -ENOMEM; - } - if (copy_from_user(args, lib->args, lib->args_len)) { - pr_err("avp_lib: can't copy lib args\n"); - ret = -EFAULT; - goto err_cp_args; - } - - ret = request_firmware(&fw, lib->name, avp->misc_dev.this_device); - if (ret) { - pr_err("avp_lib: Cannot read firmware '%s'\n", lib->name); - goto err_req_fw; - } - - lib_handle = nvmap_alloc(avp->nvmap_libs, fw->size, L1_CACHE_BYTES, - NVMAP_HANDLE_WRITE_COMBINE); - if (IS_ERR(lib_handle)) { - pr_err("avp_lib: can't nvmap alloc for lib '%s'\n", lib->name); - ret = PTR_ERR(lib_handle); - goto err_nvmap_alloc; - } - - lib_data = nvmap_mmap(lib_handle); - if (!lib_data) { - pr_err("avp_lib: can't nvmap map for lib '%s'\n", lib->name); - ret = -ENOMEM; - goto err_nvmap_mmap; - } - - lib_phys = nvmap_pin(avp->nvmap_libs, lib_handle); - if (IS_ERR((void *)lib_phys)) { - pr_err("avp_lib: can't nvmap pin for lib '%s'\n", lib->name); - ret = PTR_ERR(lib_handle); - goto err_nvmap_pin; - } - - memcpy(lib_data, fw->data, fw->size); - - svc.svc_id = SVC_LIBRARY_ATTACH; - svc.address = lib_phys; - svc.args_len = lib->args_len; - svc.lib_size = fw->size; - svc.reason = lib->greedy ? AVP_LIB_REASON_ATTACH_GREEDY : - AVP_LIB_REASON_ATTACH; - memcpy(svc.args, args, lib->args_len); - wmb(); - - /* send message, wait for reply */ - ret = trpc_send_msg(avp->rpc_node, avp->avp_ep, &svc, sizeof(svc), - GFP_KERNEL); - if (ret) - goto err_send_msg; - - ret = trpc_recv_msg(avp->rpc_node, avp->avp_ep, &resp, - sizeof(resp), -1); - if (ret != sizeof(resp)) { - pr_err("avp_lib: Couldn't get lib load reply (%d)\n", ret); - goto err_recv_msg; - } else if (resp.err) { - pr_err("avp_lib: got remote error (%d) while loading lib %s\n", - resp.err, lib->name); - ret = -EPROTO; - goto err_recv_msg; - } - lib->handle = resp.lib_id; - ret = 0; - DBG(AVP_DBG_TRACE_LIB, - "avp_lib: Successfully loaded library %s (lib_id=%x)\n", - lib->name, resp.lib_id); - - /* We free the memory here because by this point the AVP has already - * requested memory for the library for all the sections since it does - * it's own relocation and memory management. So, our allocations were - * temporary to hand the library code over to the AVP. - */ - -err_recv_msg: -err_send_msg: - nvmap_unpin(avp->nvmap_libs, lib_handle); -err_nvmap_pin: - nvmap_munmap(lib_handle, lib_data); -err_nvmap_mmap: - nvmap_free(avp->nvmap_libs, lib_handle); -err_nvmap_alloc: - release_firmware(fw); -err_req_fw: -err_cp_args: - kfree(args); - return ret; -} - -static int send_unload_lib_msg(struct avp_info *avp, u32 handle, - const char *name) -{ - struct svc_lib_detach svc; - struct svc_lib_detach_resp resp; - int ret; - - svc.svc_id = SVC_LIBRARY_DETACH; - svc.reason = AVP_LIB_REASON_DETACH; - svc.lib_id = handle; - - ret = trpc_send_msg(avp->rpc_node, avp->avp_ep, &svc, sizeof(svc), - GFP_KERNEL); - if (ret) { - pr_err("avp_lib: can't send unload message to avp for '%s'\n", - name); - goto err; - } - - ret = trpc_recv_msg(avp->rpc_node, avp->avp_ep, &resp, - sizeof(resp), -1); - if (ret != sizeof(resp)) { - pr_err("avp_lib: Couldn't get unload reply for '%s' (%d)\n", - name, ret); - } else if (resp.err) { - pr_err("avp_lib: remote error (%d) while unloading lib %s\n", - resp.err, name); - ret = -EPROTO; - } else - ret = 0; -err: - return ret; -} - -static struct lib_item *_find_lib_locked(struct avp_info *avp, u32 handle) -{ - struct lib_item *item; - - list_for_each_entry(item, &avp->libs, list) { - if (item->handle == handle) - return item; - } - return NULL; -} - -static int _insert_lib_locked(struct avp_info *avp, u32 handle, char *name) -{ - struct lib_item *item; - - item = kzalloc(sizeof(struct lib_item), GFP_KERNEL); - if (!item) - return -ENOMEM; - item->handle = handle; - strlcpy(item->name, name, TEGRA_AVP_LIB_MAX_NAME); - list_add_tail(&item->list, &avp->libs); - return 0; -} - -static void _delete_lib_locked(struct avp_info *avp, struct lib_item *item) -{ - list_del(&item->list); - kfree(item); -} - -static int handle_load_lib_ioctl(struct avp_info *avp, unsigned long arg) -{ - struct tegra_avp_lib lib; - int ret; - - if (copy_from_user(&lib, (void __user *)arg, sizeof(lib))) - return -EFAULT; - lib.name[TEGRA_AVP_LIB_MAX_NAME - 1] = '\0'; - - if (lib.args_len > TEGRA_AVP_LIB_MAX_ARGS) { - pr_err("%s: library args too long (%d)\n", __func__, - lib.args_len); - return -E2BIG; - } - - mutex_lock(&avp->libs_lock); - ret = _load_lib(avp, &lib); - if (ret) - goto err_load_lib; - - if (copy_to_user((void __user *)arg, &lib, sizeof(lib))) { - /* TODO: probably need to free the library from remote - * we just loaded */ - ret = -EFAULT; - goto err_copy_to_user; - } - ret = _insert_lib_locked(avp, lib.handle, lib.name); - if (ret) { - pr_err("%s: can't insert lib (%d)\n", __func__, ret); - goto err_insert_lib; - } - - mutex_unlock(&avp->libs_lock); - return 0; - -err_insert_lib: -err_copy_to_user: - send_unload_lib_msg(avp, lib.handle, lib.name); -err_load_lib: - mutex_unlock(&avp->libs_lock); - return ret; -} - -static int handle_unload_lib_ioctl(struct avp_info *avp, unsigned long arg) -{ - struct lib_item *item; - int ret; - - mutex_lock(&avp->libs_lock); - item = _find_lib_locked(avp, (u32)arg); - if (!item) { - pr_err("avp_lib: avp lib with handle 0x%x not found\n", - (u32)arg); - ret = -ENOENT; - goto err_find; - } - ret = send_unload_lib_msg(avp, item->handle, item->name); - if (!ret) - DBG(AVP_DBG_TRACE_LIB, "avp_lib: unloaded '%s'\n", item->name); - else - pr_err("avp_lib: can't unload lib '%s'/0x%x (%d)\n", item->name, - item->handle, ret); - _delete_lib_locked(avp, item); - -err_find: - mutex_unlock(&avp->libs_lock); - return ret; -} - -static void libs_cleanup(struct avp_info *avp) -{ - struct lib_item *lib; - struct lib_item *lib_tmp; - - mutex_lock(&avp->libs_lock); - list_for_each_entry_safe(lib, lib_tmp, &avp->libs, list) { - _delete_lib_locked(avp, lib); - } - - nvmap_client_put(avp->nvmap_libs); - avp->nvmap_libs = NULL; - mutex_unlock(&avp->libs_lock); -} - -static long tegra_avp_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct avp_info *avp = tegra_avp; - int ret; - - if (_IOC_TYPE(cmd) != TEGRA_AVP_IOCTL_MAGIC || - _IOC_NR(cmd) < TEGRA_AVP_IOCTL_MIN_NR || - _IOC_NR(cmd) > TEGRA_AVP_IOCTL_MAX_NR) - return -ENOTTY; - - switch (cmd) { - case TEGRA_AVP_IOCTL_LOAD_LIB: - ret = handle_load_lib_ioctl(avp, arg); - break; - case TEGRA_AVP_IOCTL_UNLOAD_LIB: - ret = handle_unload_lib_ioctl(avp, arg); - break; - default: - pr_err("avp_lib: Unknown tegra_avp ioctl 0x%x\n", _IOC_NR(cmd)); - ret = -ENOTTY; - break; - } - return ret; -} - -static int tegra_avp_open(struct inode *inode, struct file *file) -{ - struct avp_info *avp = tegra_avp; - int ret = 0; - - nonseekable_open(inode, file); - - mutex_lock(&avp->open_lock); - /* only one userspace client at a time */ - if (avp->opened) { - pr_err("%s: already have client, aborting\n", __func__); - ret = -EBUSY; - goto out; - } - - ret = avp_init(avp, TEGRA_AVP_KERNEL_FW); - avp->opened = !ret; -out: - mutex_unlock(&avp->open_lock); - return ret; -} - -static int tegra_avp_release(struct inode *inode, struct file *file) -{ - struct avp_info *avp = tegra_avp; - int ret = 0; - - pr_info("%s: release\n", __func__); - mutex_lock(&avp->open_lock); - if (!avp->opened) { - pr_err("%s: releasing while in invalid state\n", __func__); - ret = -EINVAL; - goto out; - } - - avp_uninit(avp); - - avp->opened = false; -out: - mutex_unlock(&avp->open_lock); - return ret; -} - -static int avp_enter_lp0(struct avp_info *avp) -{ - volatile u32 *avp_suspend_done = - avp->iram_backup_data + TEGRA_IRAM_SIZE; - struct svc_enter_lp0 svc; - unsigned long endtime; - int ret; - - svc.svc_id = SVC_ENTER_LP0; - svc.src_addr = (u32)TEGRA_IRAM_BASE; - svc.buf_addr = (u32)avp->iram_backup_phys; - svc.buf_size = TEGRA_IRAM_SIZE; - - *avp_suspend_done = 0; - wmb(); - - ret = trpc_send_msg(avp->rpc_node, avp->avp_ep, &svc, sizeof(svc), - GFP_KERNEL); - if (ret) { - pr_err("%s: cannot send AVP suspend message\n", __func__); - return ret; - } - - endtime = jiffies + msecs_to_jiffies(1000); - rmb(); - while ((*avp_suspend_done == 0) && time_before(jiffies, endtime)) { - udelay(10); - rmb(); - } - - rmb(); - if (*avp_suspend_done == 0) { - pr_err("%s: AVP failed to suspend\n", __func__); - ret = -ETIMEDOUT; - goto err; - } - - return 0; - -err: - return ret; -} - -static int tegra_avp_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct avp_info *avp = tegra_avp; - unsigned long flags; - int ret; - - pr_info("%s()+\n", __func__); - spin_lock_irqsave(&avp->state_lock, flags); - if (!avp->initialized) { - spin_unlock_irqrestore(&avp->state_lock, flags); - return 0; - } - avp->suspending = true; - spin_unlock_irqrestore(&avp->state_lock, flags); - - ret = avp_enter_lp0(avp); - if (ret) - goto err; - - avp->resume_addr = readl(TEGRA_AVP_RESUME_ADDR); - if (!avp->resume_addr) { - pr_err("%s: AVP failed to set it's resume address\n", __func__); - ret = -EINVAL; - goto err; - } - - disable_irq(avp->mbox_from_avp_pend_irq); - - pr_info("avp_suspend: resume_addr=%lx\n", avp->resume_addr); - avp->resume_addr &= 0xfffffffeUL; - pr_info("%s()-\n", __func__); - - return 0; - -err: - /* TODO: we need to kill the AVP so that when we come back - * it could be reinitialized.. We'd probably need to kill - * the users of it so they don't have the wrong state. - */ - return ret; -} - -static int tegra_avp_resume(struct platform_device *pdev) -{ - struct avp_info *avp = tegra_avp; - int ret = 0; - - pr_info("%s()+\n", __func__); - smp_rmb(); - if (!avp->initialized) - goto out; - - BUG_ON(!avp->resume_addr); - - avp_reset(avp, avp->resume_addr); - avp->resume_addr = 0; - avp->suspending = false; - smp_wmb(); - enable_irq(avp->mbox_from_avp_pend_irq); - - pr_info("%s()-\n", __func__); - -out: - return ret; -} - -static const struct file_operations tegra_avp_fops = { - .owner = THIS_MODULE, - .open = tegra_avp_open, - .release = tegra_avp_release, - .unlocked_ioctl = tegra_avp_ioctl, -}; - -static struct trpc_node avp_trpc_node = { - .name = "avp-remote", - .type = TRPC_NODE_REMOTE, - .try_connect = avp_node_try_connect, -}; - -static int tegra_avp_probe(struct platform_device *pdev) -{ - void *msg_area; - struct avp_info *avp; - int ret = 0; - int irq; - - irq = platform_get_irq_byname(pdev, "mbox_from_avp_pending"); - if (irq < 0) { - pr_err("%s: invalid platform data\n", __func__); - return -EINVAL; - } - - avp = kzalloc(sizeof(struct avp_info), GFP_KERNEL); - if (!avp) { - pr_err("%s: cannot allocate avp_info\n", __func__); - return -ENOMEM; - } - - avp->nvmap_drv = nvmap_create_client(nvmap_dev, "avp_core"); - if (IS_ERR(avp->nvmap_drv)) { - pr_err("%s: cannot create drv nvmap client\n", __func__); - ret = PTR_ERR(avp->nvmap_drv); - goto err_nvmap_create_drv_client; - } - - avp->kernel_handle = nvmap_alloc(avp->nvmap_drv, SZ_1M, SZ_1M, - NVMAP_HANDLE_WRITE_COMBINE); - if (IS_ERR(avp->kernel_handle)) { - pr_err("%s: cannot create handle\n", __func__); - ret = PTR_ERR(avp->kernel_handle); - goto err_nvmap_alloc; - } - - avp->kernel_data = nvmap_mmap(avp->kernel_handle); - if (!avp->kernel_data) { - pr_err("%s: cannot map kernel handle\n", __func__); - ret = -ENOMEM; - goto err_nvmap_mmap; - } - - avp->kernel_phys = nvmap_pin(avp->nvmap_drv, avp->kernel_handle); - if (IS_ERR((void *)avp->kernel_phys)) { - pr_err("%s: cannot pin kernel handle\n", __func__); - ret = PTR_ERR((void *)avp->kernel_phys); - goto err_nvmap_pin; - } - - /* allocate an extra 4 bytes at the end which AVP uses to signal to - * us that it is done suspending. - */ - avp->iram_backup_handle = - nvmap_alloc(avp->nvmap_drv, TEGRA_IRAM_SIZE + 4, - L1_CACHE_BYTES, NVMAP_HANDLE_WRITE_COMBINE); - if (IS_ERR(avp->iram_backup_handle)) { - pr_err("%s: cannot create handle for iram backup\n", __func__); - ret = PTR_ERR(avp->iram_backup_handle); - goto err_iram_nvmap_alloc; - } - avp->iram_backup_data = nvmap_mmap(avp->iram_backup_handle); - if (!avp->iram_backup_data) { - pr_err("%s: cannot map iram backup handle\n", __func__); - ret = -ENOMEM; - goto err_iram_nvmap_mmap; - } - avp->iram_backup_phys = nvmap_pin(avp->nvmap_drv, - avp->iram_backup_handle); - if (IS_ERR((void *)avp->iram_backup_phys)) { - pr_err("%s: cannot pin iram backup handle\n", __func__); - ret = PTR_ERR((void *)avp->iram_backup_phys); - goto err_iram_nvmap_pin; - } - - avp->mbox_from_avp_pend_irq = irq; - avp->endpoints = RB_ROOT; - spin_lock_init(&avp->state_lock); - mutex_init(&avp->open_lock); - mutex_init(&avp->to_avp_lock); - mutex_init(&avp->from_avp_lock); - INIT_WORK(&avp->recv_work, process_avp_message); - - mutex_init(&avp->libs_lock); - INIT_LIST_HEAD(&avp->libs); - - avp->recv_wq = alloc_workqueue("avp-msg-recv", - WQ_NON_REENTRANT | WQ_HIGHPRI, 1); - if (!avp->recv_wq) { - pr_err("%s: can't create recve workqueue\n", __func__); - ret = -ENOMEM; - goto err_create_wq; - } - - avp->cop_clk = clk_get(&pdev->dev, "cop"); - if (IS_ERR(avp->cop_clk)) { - pr_err("%s: Couldn't get cop clock\n", TEGRA_AVP_NAME); - ret = -ENOENT; - goto err_get_cop_clk; - } - - msg_area = dma_alloc_coherent(&pdev->dev, AVP_MSG_AREA_SIZE * 2, - &avp->msg_area_addr, GFP_KERNEL); - if (!msg_area) { - pr_err("%s: cannot allocate msg_area\n", __func__); - ret = -ENOMEM; - goto err_alloc_msg_area; - } - memset(msg_area, 0, AVP_MSG_AREA_SIZE * 2); - avp->msg = ((avp->msg_area_addr >> 4) | - MBOX_MSG_VALID | MBOX_MSG_PENDING_INT_EN); - avp->msg_to_avp = msg_area; - avp->msg_from_avp = msg_area + AVP_MSG_AREA_SIZE; - - avp_halt(avp); - - avp_trpc_node.priv = avp; - ret = trpc_node_register(&avp_trpc_node); - if (ret) { - pr_err("%s: Can't register avp rpc node\n", __func__); - goto err_node_reg; - } - avp->rpc_node = &avp_trpc_node; - - avp->avp_svc = avp_svc_init(pdev, avp->rpc_node); - if (IS_ERR(avp->avp_svc)) { - pr_err("%s: Cannot initialize avp_svc\n", __func__); - ret = PTR_ERR(avp->avp_svc); - goto err_avp_svc_init; - } - - avp->misc_dev.minor = MISC_DYNAMIC_MINOR; - avp->misc_dev.name = "tegra_avp"; - avp->misc_dev.fops = &tegra_avp_fops; - - ret = misc_register(&avp->misc_dev); - if (ret) { - pr_err("%s: Unable to register misc device!\n", TEGRA_AVP_NAME); - goto err_misc_reg; - } - - ret = request_irq(irq, avp_mbox_pending_isr, 0, TEGRA_AVP_NAME, avp); - if (ret) { - pr_err("%s: cannot register irq handler\n", __func__); - goto err_req_irq_pend; - } - disable_irq(avp->mbox_from_avp_pend_irq); - - tegra_avp = avp; - - pr_info("%s: driver registered, kernel %lx(%p), msg area %lx/%lx\n", - __func__, avp->kernel_phys, avp->kernel_data, - (unsigned long)avp->msg_area_addr, - (unsigned long)avp->msg_area_addr + AVP_MSG_AREA_SIZE); - - return 0; - -err_req_irq_pend: - misc_deregister(&avp->misc_dev); -err_misc_reg: - avp_svc_destroy(avp->avp_svc); -err_avp_svc_init: - trpc_node_unregister(avp->rpc_node); -err_node_reg: - dma_free_coherent(&pdev->dev, AVP_MSG_AREA_SIZE * 2, msg_area, - avp->msg_area_addr); -err_alloc_msg_area: - clk_put(avp->cop_clk); -err_get_cop_clk: - destroy_workqueue(avp->recv_wq); -err_create_wq: - nvmap_unpin(avp->nvmap_drv, avp->iram_backup_handle); -err_iram_nvmap_pin: - nvmap_munmap(avp->iram_backup_handle, avp->iram_backup_data); -err_iram_nvmap_mmap: - nvmap_free(avp->nvmap_drv, avp->iram_backup_handle); -err_iram_nvmap_alloc: - nvmap_unpin(avp->nvmap_drv, avp->kernel_handle); -err_nvmap_pin: - nvmap_munmap(avp->kernel_handle, avp->kernel_data); -err_nvmap_mmap: - nvmap_free(avp->nvmap_drv, avp->kernel_handle); -err_nvmap_alloc: - nvmap_client_put(avp->nvmap_drv); -err_nvmap_create_drv_client: - kfree(avp); - tegra_avp = NULL; - return ret; -} - -static int tegra_avp_remove(struct platform_device *pdev) -{ - struct avp_info *avp = tegra_avp; - - if (!avp) - return 0; - - mutex_lock(&avp->open_lock); - if (avp->opened) { - mutex_unlock(&avp->open_lock); - return -EBUSY; - } - /* ensure that noone can open while we tear down */ - avp->opened = true; - mutex_unlock(&avp->open_lock); - - misc_deregister(&avp->misc_dev); - - avp_halt(avp); - - avp_svc_destroy(avp->avp_svc); - trpc_node_unregister(avp->rpc_node); - dma_free_coherent(&pdev->dev, AVP_MSG_AREA_SIZE * 2, avp->msg_to_avp, - avp->msg_area_addr); - clk_put(avp->cop_clk); - destroy_workqueue(avp->recv_wq); - nvmap_unpin(avp->nvmap_drv, avp->iram_backup_handle); - nvmap_munmap(avp->iram_backup_handle, avp->iram_backup_data); - nvmap_free(avp->nvmap_drv, avp->iram_backup_handle); - nvmap_unpin(avp->nvmap_drv, avp->kernel_handle); - nvmap_munmap(avp->kernel_handle, avp->kernel_data); - nvmap_free(avp->nvmap_drv, avp->kernel_handle); - nvmap_client_put(avp->nvmap_drv); - kfree(avp); - tegra_avp = NULL; - return 0; -} - -static struct platform_driver tegra_avp_driver = { - .probe = tegra_avp_probe, - .remove = tegra_avp_remove, - .suspend = tegra_avp_suspend, - .resume = tegra_avp_resume, - .driver = { - .name = TEGRA_AVP_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init tegra_avp_init(void) -{ - return platform_driver_register(&tegra_avp_driver); -} - -static void __exit tegra_avp_exit(void) -{ - platform_driver_unregister(&tegra_avp_driver); -} - -module_init(tegra_avp_init); -module_exit(tegra_avp_exit); diff --git a/drivers/media/video/tegra/avp/avp.h b/drivers/media/video/tegra/avp/avp.h deleted file mode 100644 index 4f2287743a06..000000000000 --- a/drivers/media/video/tegra/avp/avp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MEDIA_VIDEO_TEGRA_AVP_H -#define __MEDIA_VIDEO_TEGRA_AVP_H - -#include -#include - -#include "trpc.h" - -struct avp_svc_info; - -struct avp_svc_info *avp_svc_init(struct platform_device *pdev, - struct trpc_node *rpc_node); -void avp_svc_destroy(struct avp_svc_info *avp_svc); -int avp_svc_start(struct avp_svc_info *svc); -void avp_svc_stop(struct avp_svc_info *svc); - -#endif diff --git a/drivers/media/video/tegra/avp/avp_msg.h b/drivers/media/video/tegra/avp/avp_msg.h deleted file mode 100644 index 54d3a63793f1..000000000000 --- a/drivers/media/video/tegra/avp/avp_msg.h +++ /dev/null @@ -1,342 +0,0 @@ -/* drivers/media/video/tegra/avp/avp_msg.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MEDIA_VIDEO_TEGRA_AVP_MSG_H -#define __MEDIA_VIDEO_TEGRA_AVP_MSG_H - -#include -#include - -/* Note: the port name string is not NUL terminated, so make sure to - * allocate appropriate space locally when operating on the string */ -#define XPC_PORT_NAME_LEN 16 - -#define SVC_ARGS_MAX_LEN 220 -#define SVC_MAX_STRING_LEN 200 - -#define AVP_ERR_ENOTSUP 0x2 -#define AVP_ERR_EINVAL 0x4 -#define AVP_ERR_ENOMEM 0x6 -#define AVP_ERR_EACCES 0x00030010 - -enum { - SVC_NVMAP_CREATE = 0, - SVC_NVMAP_CREATE_RESPONSE = 1, - SVC_NVMAP_FREE = 3, - SVC_NVMAP_ALLOC = 4, - SVC_NVMAP_ALLOC_RESPONSE = 5, - SVC_NVMAP_PIN = 6, - SVC_NVMAP_PIN_RESPONSE = 7, - SVC_NVMAP_UNPIN = 8, - SVC_NVMAP_UNPIN_RESPONSE = 9, - SVC_NVMAP_GET_ADDRESS = 10, - SVC_NVMAP_GET_ADDRESS_RESPONSE = 11, - SVC_NVMAP_FROM_ID = 12, - SVC_NVMAP_FROM_ID_RESPONSE = 13, - SVC_MODULE_CLOCK = 14, - SVC_MODULE_CLOCK_RESPONSE = 15, - SVC_MODULE_RESET = 16, - SVC_MODULE_RESET_RESPONSE = 17, - SVC_POWER_REGISTER = 18, - SVC_POWER_UNREGISTER = 19, - SVC_POWER_STARVATION = 20, - SVC_POWER_BUSY_HINT = 21, - SVC_POWER_BUSY_HINT_MULTI = 22, - SVC_DFS_GETSTATE = 23, - SVC_DFS_GETSTATE_RESPONSE = 24, - SVC_POWER_RESPONSE = 25, - SVC_POWER_MAXFREQ = 26, - SVC_ENTER_LP0 = 27, - SVC_ENTER_LP0_RESPONSE = 28, - SVC_PRINTF = 29, - SVC_LIBRARY_ATTACH = 30, - SVC_LIBRARY_ATTACH_RESPONSE = 31, - SVC_LIBRARY_DETACH = 32, - SVC_LIBRARY_DETACH_RESPONSE = 33, - SVC_AVP_WDT_RESET = 34, - SVC_DFS_GET_CLK_UTIL = 35, - SVC_DFS_GET_CLK_UTIL_RESPONSE = 36, -}; - -struct svc_msg { - u32 svc_id; - u8 data[0]; -}; - -struct svc_common_resp { - u32 svc_id; - u32 err; -}; - -struct svc_printf { - u32 svc_id; - const char str[SVC_MAX_STRING_LEN]; -}; - -struct svc_enter_lp0 { - u32 svc_id; - u32 src_addr; - u32 buf_addr; - u32 buf_size; -}; - -/* nvmap messages */ -struct svc_nvmap_create { - u32 svc_id; - u32 size; -}; - -struct svc_nvmap_create_resp { - u32 svc_id; - u32 handle_id; - u32 err; -}; - -enum { - AVP_NVMAP_HEAP_EXTERNAL = 1, - AVP_NVMAP_HEAP_GART = 2, - AVP_NVMAP_HEAP_EXTERNAL_CARVEOUT = 3, - AVP_NVMAP_HEAP_IRAM = 4, -}; - -struct svc_nvmap_alloc { - u32 svc_id; - u32 handle_id; - u32 heaps[4]; - u32 num_heaps; - u32 align; - u32 mapping_type; -}; - -struct svc_nvmap_free { - u32 svc_id; - u32 handle_id; -}; - -struct svc_nvmap_pin { - u32 svc_id; - u32 handle_id; -}; - -struct svc_nvmap_pin_resp { - u32 svc_id; - u32 addr; -}; - -struct svc_nvmap_unpin { - u32 svc_id; - u32 handle_id; -}; - -struct svc_nvmap_from_id { - u32 svc_id; - u32 handle_id; -}; - -struct svc_nvmap_get_addr { - u32 svc_id; - u32 handle_id; - u32 offs; -}; - -struct svc_nvmap_get_addr_resp { - u32 svc_id; - u32 addr; -}; - -/* library management messages */ -enum { - AVP_LIB_REASON_ATTACH = 0, - AVP_LIB_REASON_DETACH = 1, - AVP_LIB_REASON_ATTACH_GREEDY = 2, -}; - -struct svc_lib_attach { - u32 svc_id; - u32 address; - u32 args_len; - u32 lib_size; - u8 args[SVC_ARGS_MAX_LEN]; - u32 reason; -}; - -struct svc_lib_attach_resp { - u32 svc_id; - u32 err; - u32 lib_id; -}; - -struct svc_lib_detach { - u32 svc_id; - u32 reason; - u32 lib_id; -}; - -struct svc_lib_detach_resp { - u32 svc_id; - u32 err; -}; - -/* hw module management from the AVP side */ -enum { - AVP_MODULE_ID_AVP = 2, - AVP_MODULE_ID_VCP = 3, - AVP_MODULE_ID_BSEA = 27, - AVP_MODULE_ID_VDE = 28, - AVP_MODULE_ID_MPE = 29, -}; - -struct svc_module_ctrl { - u32 svc_id; - u32 module_id; - u32 client_id; - u8 enable; -}; - -/* power messages */ -struct svc_pwr_register { - u32 svc_id; - u32 client_id; - u32 unused; -}; - -struct svc_pwr_register_resp { - u32 svc_id; - u32 err; - u32 client_id; -}; - -struct svc_pwr_starve_hint { - u32 svc_id; - u32 dfs_clk_id; - u32 client_id; - u8 starving; -}; - -struct svc_pwr_busy_hint { - u32 svc_id; - u32 dfs_clk_id; - u32 client_id; - u32 boost_ms; /* duration */ - u32 boost_freq; /* in khz */ -}; - -struct svc_pwr_max_freq { - u32 svc_id; - u32 module_id; -}; - -struct svc_pwr_max_freq_resp { - u32 svc_id; - u32 freq; -}; - -/* dfs related messages */ -enum { - AVP_DFS_STATE_INVALID = 0, - AVP_DFS_STATE_DISABLED = 1, - AVP_DFS_STATE_STOPPED = 2, - AVP_DFS_STATE_CLOSED_LOOP = 3, - AVP_DFS_STATE_PROFILED_LOOP = 4, -}; - -struct svc_dfs_get_state_resp { - u32 svc_id; - u32 state; -}; - -enum { - AVP_DFS_CLK_CPU = 1, - AVP_DFS_CLK_AVP = 2, - AVP_DFS_CLK_SYSTEM = 3, - AVP_DFS_CLK_AHB = 4, - AVP_DFS_CLK_APB = 5, - AVP_DFS_CLK_VDE = 6, - /* external memory controller */ - AVP_DFS_CLK_EMC = 7, -}; - -struct avp_clk_usage { - u32 min; - u32 max; - u32 curr_min; - u32 curr_max; - u32 curr; - u32 avg; /* average activity.. whatever that means */ -}; - -struct svc_dfs_get_clk_util { - u32 svc_id; - u32 dfs_clk_id; -}; - -/* all units are in kHz */ -struct svc_dfs_get_clk_util_resp { - u32 svc_id; - u32 err; - struct avp_clk_usage usage; -}; - -/************************/ - -enum { - CMD_ACK = 0, - CMD_CONNECT = 2, - CMD_DISCONNECT = 3, - CMD_MESSAGE = 4, - CMD_RESPONSE = 5, -}; - -struct msg_data { - u32 cmd; - u8 data[0]; -}; - -struct msg_ack { - u32 cmd; - u32 arg; -}; - -struct msg_connect { - u32 cmd; - u32 port_id; - /* not NUL terminated, just 0 padded */ - char name[XPC_PORT_NAME_LEN]; -}; - -struct msg_connect_reply { - u32 cmd; - u32 port_id; -}; - -struct msg_disconnect { - u32 cmd; - u32 port_id; -}; - -struct msg_disconnect_reply { - u32 cmd; - u32 ack; -}; - -struct msg_port_data { - u32 cmd; - u32 port_id; - u32 msg_len; - u8 data[0]; -}; - -#endif diff --git a/drivers/media/video/tegra/avp/avp_svc.c b/drivers/media/video/tegra/avp/avp_svc.c deleted file mode 100644 index 2eed2891e556..000000000000 --- a/drivers/media/video/tegra/avp/avp_svc.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../../../../video/tegra/nvmap/nvmap.h" - -#include "avp_msg.h" -#include "trpc.h" -#include "avp.h" - -enum { - AVP_DBG_TRACE_SVC = 1U << 0, -}; - -static u32 debug_mask = 0; -module_param_named(debug_mask, debug_mask, uint, S_IWUSR | S_IRUGO); - -#define DBG(flag, args...) \ - do { if (unlikely(debug_mask & (flag))) pr_info(args); } while (0) - -enum { - CLK_REQUEST_VCP = 0, - CLK_REQUEST_BSEA = 1, - CLK_REQUEST_VDE = 2, - NUM_CLK_REQUESTS, -}; - -struct avp_module { - const char *name; - u32 clk_req; -}; - -static struct avp_module avp_modules[] = { - [AVP_MODULE_ID_VCP] = { - .name = "vcp", - .clk_req = CLK_REQUEST_VCP, - }, - [AVP_MODULE_ID_BSEA] = { - .name = "bsea", - .clk_req = CLK_REQUEST_BSEA, - }, - [AVP_MODULE_ID_VDE] = { - .name = "vde", - .clk_req = CLK_REQUEST_VDE, - }, -}; -#define NUM_AVP_MODULES ARRAY_SIZE(avp_modules) - -struct avp_clk { - struct clk *clk; - int refcnt; - struct avp_module *mod; -}; - -struct avp_svc_info { - struct avp_clk clks[NUM_CLK_REQUESTS]; - /* used for dvfs */ - struct clk *sclk; - struct clk *emcclk; - - struct mutex clk_lock; - - struct trpc_endpoint *cpu_ep; - struct task_struct *svc_thread; - - /* client for remote allocations, for easy tear down */ - struct nvmap_client *nvmap_remote; - struct trpc_node *rpc_node; -}; - -static void do_svc_nvmap_create(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_create *msg = (struct svc_nvmap_create *)_msg; - struct svc_nvmap_create_resp resp; - struct nvmap_handle_ref *handle; - u32 handle_id = 0; - u32 err = 0; - - handle = nvmap_create_handle(avp_svc->nvmap_remote, msg->size); - if (unlikely(IS_ERR(handle))) { - pr_err("avp_svc: error creating handle (%d bytes) for remote\n", - msg->size); - err = AVP_ERR_ENOMEM; - } else - handle_id = (u32)nvmap_ref_to_id(handle); - - resp.svc_id = SVC_NVMAP_CREATE_RESPONSE; - resp.err = err; - resp.handle_id = handle_id; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); - /* TODO: do we need to put the handle if send_msg failed? */ -} - -static void do_svc_nvmap_alloc(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_alloc *msg = (struct svc_nvmap_alloc *)_msg; - struct svc_common_resp resp; - struct nvmap_handle *handle; - u32 err = 0; - u32 heap_mask = 0; - int i; - size_t align; - - handle = nvmap_get_handle_id(avp_svc->nvmap_remote, msg->handle_id); - if (IS_ERR(handle)) { - pr_err("avp_svc: unknown remote handle 0x%x\n", msg->handle_id); - err = AVP_ERR_EACCES; - goto out; - } - - if (msg->num_heaps > 4) { - pr_err("avp_svc: invalid remote alloc request (%d heaps?!)\n", - msg->num_heaps); - /* TODO: should we error out instead ? */ - msg->num_heaps = 0; - } - if (msg->num_heaps == 0) - heap_mask = NVMAP_HEAP_CARVEOUT_GENERIC | NVMAP_HEAP_SYSMEM; - - for (i = 0; i < msg->num_heaps; i++) { - switch (msg->heaps[i]) { - case AVP_NVMAP_HEAP_EXTERNAL: - heap_mask |= NVMAP_HEAP_SYSMEM; - break; - case AVP_NVMAP_HEAP_GART: - heap_mask |= NVMAP_HEAP_IOVMM; - break; - case AVP_NVMAP_HEAP_EXTERNAL_CARVEOUT: - heap_mask |= NVMAP_HEAP_CARVEOUT_GENERIC; - break; - case AVP_NVMAP_HEAP_IRAM: - heap_mask |= NVMAP_HEAP_CARVEOUT_IRAM; - break; - default: - break; - } - } - - align = max_t(size_t, L1_CACHE_BYTES, msg->align); - err = nvmap_alloc_handle_id(avp_svc->nvmap_remote, msg->handle_id, - heap_mask, align, 0); - nvmap_handle_put(handle); - if (err) { - pr_err("avp_svc: can't allocate for handle 0x%x (%d)\n", - msg->handle_id, err); - err = AVP_ERR_ENOMEM; - } - -out: - resp.svc_id = SVC_NVMAP_ALLOC_RESPONSE; - resp.err = err; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_nvmap_free(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_free *msg = (struct svc_nvmap_free *)_msg; - - nvmap_free_handle_id(avp_svc->nvmap_remote, msg->handle_id); -} - -static void do_svc_nvmap_pin(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_pin *msg = (struct svc_nvmap_pin *)_msg; - struct svc_nvmap_pin_resp resp; - struct nvmap_handle_ref *handle; - unsigned long addr = ~0UL; - unsigned long id = msg->handle_id; - int err; - - handle = nvmap_duplicate_handle_id(avp_svc->nvmap_remote, id); - if (IS_ERR(handle)) { - pr_err("avp_svc: can't dup handle %lx\n", id); - goto out; - } - err = nvmap_pin_ids(avp_svc->nvmap_remote, 1, &id); - if (err) { - pr_err("avp_svc: can't pin for handle %lx (%d)\n", id, err); - goto out; - } - addr = nvmap_handle_address(avp_svc->nvmap_remote, id); - -out: - resp.svc_id = SVC_NVMAP_PIN_RESPONSE; - resp.addr = addr; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_nvmap_unpin(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_unpin *msg = (struct svc_nvmap_unpin *)_msg; - struct svc_common_resp resp; - unsigned long id = msg->handle_id; - - nvmap_unpin_ids(avp_svc->nvmap_remote, 1, &id); - nvmap_free_handle_id(avp_svc->nvmap_remote, id); - - resp.svc_id = SVC_NVMAP_UNPIN_RESPONSE; - resp.err = 0; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_nvmap_from_id(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_from_id *msg = (struct svc_nvmap_from_id *)_msg; - struct svc_common_resp resp; - struct nvmap_handle_ref *handle; - int err = 0; - - handle = nvmap_duplicate_handle_id(avp_svc->nvmap_remote, - msg->handle_id); - if (IS_ERR(handle)) { - pr_err("avp_svc: can't duplicate handle for id 0x%x (%d)\n", - msg->handle_id, (int)PTR_ERR(handle)); - err = AVP_ERR_ENOMEM; - } - - resp.svc_id = SVC_NVMAP_FROM_ID_RESPONSE; - resp.err = err; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_nvmap_get_addr(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_nvmap_get_addr *msg = (struct svc_nvmap_get_addr *)_msg; - struct svc_nvmap_get_addr_resp resp; - - resp.svc_id = SVC_NVMAP_GET_ADDRESS_RESPONSE; - resp.addr = nvmap_handle_address(avp_svc->nvmap_remote, msg->handle_id); - resp.addr += msg->offs; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_pwr_register(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_pwr_register *msg = (struct svc_pwr_register *)_msg; - struct svc_pwr_register_resp resp; - - resp.svc_id = SVC_POWER_RESPONSE; - resp.err = 0; - resp.client_id = msg->client_id; - - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static struct avp_module *find_avp_module(struct avp_svc_info *avp_svc, u32 id) -{ - if (id < NUM_AVP_MODULES && avp_modules[id].name) - return &avp_modules[id]; - return NULL; -} - -static void do_svc_module_reset(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_module_ctrl *msg = (struct svc_module_ctrl *)_msg; - struct svc_common_resp resp; - struct avp_module *mod; - struct avp_clk *aclk; - - mod = find_avp_module(avp_svc, msg->module_id); - if (!mod) { - if (msg->module_id == AVP_MODULE_ID_AVP) - pr_err("avp_svc: AVP suicidal?!?!\n"); - else - pr_err("avp_svc: Unknown module reset requested: %d\n", - msg->module_id); - /* other side doesn't handle errors for reset */ - resp.err = 0; - goto send_response; - } - - aclk = &avp_svc->clks[mod->clk_req]; - tegra_periph_reset_assert(aclk->clk); - udelay(10); - tegra_periph_reset_deassert(aclk->clk); - resp.err = 0; - -send_response: - resp.svc_id = SVC_MODULE_RESET_RESPONSE; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_module_clock(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_module_ctrl *msg = (struct svc_module_ctrl *)_msg; - struct svc_common_resp resp; - struct avp_module *mod; - struct avp_clk *aclk; - - mod = find_avp_module(avp_svc, msg->module_id); - if (!mod) { - pr_err("avp_svc: unknown module clock requested: %d\n", - msg->module_id); - resp.err = AVP_ERR_EINVAL; - goto send_response; - } - - mutex_lock(&avp_svc->clk_lock); - aclk = &avp_svc->clks[mod->clk_req]; - if (msg->enable) { - if (aclk->refcnt++ == 0) { - clk_enable(avp_svc->emcclk); - clk_enable(avp_svc->sclk); - clk_enable(aclk->clk); - } - } else { - if (unlikely(aclk->refcnt == 0)) { - pr_err("avp_svc: unbalanced clock disable for '%s'\n", - aclk->mod->name); - } else if (--aclk->refcnt == 0) { - clk_disable(aclk->clk); - clk_disable(avp_svc->sclk); - clk_disable(avp_svc->emcclk); - } - } - mutex_unlock(&avp_svc->clk_lock); - resp.err = 0; - -send_response: - resp.svc_id = SVC_MODULE_CLOCK_RESPONSE; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_null_response(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len, u32 resp_svc_id) -{ - struct svc_common_resp resp; - resp.svc_id = resp_svc_id; - resp.err = 0; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_dfs_get_state(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_dfs_get_state_resp resp; - resp.svc_id = SVC_DFS_GETSTATE_RESPONSE; - resp.state = AVP_DFS_STATE_STOPPED; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_dfs_get_clk_util(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_dfs_get_clk_util_resp resp; - - resp.svc_id = SVC_DFS_GET_CLK_UTIL_RESPONSE; - resp.err = 0; - memset(&resp.usage, 0, sizeof(struct avp_clk_usage)); - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_pwr_max_freq(struct avp_svc_info *avp_svc, - struct svc_msg *_msg, - size_t len) -{ - struct svc_pwr_max_freq_resp resp; - - resp.svc_id = SVC_POWER_MAXFREQ; - resp.freq = 0; - trpc_send_msg(avp_svc->rpc_node, avp_svc->cpu_ep, &resp, - sizeof(resp), GFP_KERNEL); -} - -static void do_svc_printf(struct avp_svc_info *avp_svc, struct svc_msg *_msg, - size_t len) -{ - struct svc_printf *msg = (struct svc_printf *)_msg; - char tmp_str[SVC_MAX_STRING_LEN]; - - /* ensure we null terminate the source */ - strlcpy(tmp_str, msg->str, SVC_MAX_STRING_LEN); - pr_info("[AVP]: %s", tmp_str); -} - -static int dispatch_svc_message(struct avp_svc_info *avp_svc, - struct svc_msg *msg, - size_t len) -{ - int ret = 0; - - switch (msg->svc_id) { - case SVC_NVMAP_CREATE: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_create\n", __func__); - do_svc_nvmap_create(avp_svc, msg, len); - break; - case SVC_NVMAP_ALLOC: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_alloc\n", __func__); - do_svc_nvmap_alloc(avp_svc, msg, len); - break; - case SVC_NVMAP_FREE: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_free\n", __func__); - do_svc_nvmap_free(avp_svc, msg, len); - break; - case SVC_NVMAP_PIN: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_pin\n", __func__); - do_svc_nvmap_pin(avp_svc, msg, len); - break; - case SVC_NVMAP_UNPIN: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_unpin\n", __func__); - do_svc_nvmap_unpin(avp_svc, msg, len); - break; - case SVC_NVMAP_FROM_ID: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_from_id\n", __func__); - do_svc_nvmap_from_id(avp_svc, msg, len); - break; - case SVC_NVMAP_GET_ADDRESS: - DBG(AVP_DBG_TRACE_SVC, "%s: got nvmap_get_addr\n", __func__); - do_svc_nvmap_get_addr(avp_svc, msg, len); - break; - case SVC_POWER_REGISTER: - DBG(AVP_DBG_TRACE_SVC, "%s: got power_register\n", __func__); - do_svc_pwr_register(avp_svc, msg, len); - break; - case SVC_POWER_UNREGISTER: - DBG(AVP_DBG_TRACE_SVC, "%s: got power_unregister\n", __func__); - /* nothing to do */ - break; - case SVC_POWER_BUSY_HINT_MULTI: - DBG(AVP_DBG_TRACE_SVC, "%s: got power_busy_hint_multi\n", - __func__); - /* nothing to do */ - break; - case SVC_POWER_BUSY_HINT: - case SVC_POWER_STARVATION: - DBG(AVP_DBG_TRACE_SVC, "%s: got power busy/starve hint\n", - __func__); - do_svc_null_response(avp_svc, msg, len, SVC_POWER_RESPONSE); - break; - case SVC_POWER_MAXFREQ: - DBG(AVP_DBG_TRACE_SVC, "%s: got power get_max_freq\n", - __func__); - do_svc_pwr_max_freq(avp_svc, msg, len); - break; - case SVC_DFS_GETSTATE: - DBG(AVP_DBG_TRACE_SVC, "%s: got dfs_get_state\n", __func__); - do_svc_dfs_get_state(avp_svc, msg, len); - break; - case SVC_MODULE_RESET: - DBG(AVP_DBG_TRACE_SVC, "%s: got module_reset\n", __func__); - do_svc_module_reset(avp_svc, msg, len); - break; - case SVC_MODULE_CLOCK: - DBG(AVP_DBG_TRACE_SVC, "%s: got module_clock\n", __func__); - do_svc_module_clock(avp_svc, msg, len); - break; - case SVC_DFS_GET_CLK_UTIL: - DBG(AVP_DBG_TRACE_SVC, "%s: got get_clk_util\n", __func__); - do_svc_dfs_get_clk_util(avp_svc, msg, len); - break; - case SVC_PRINTF: - DBG(AVP_DBG_TRACE_SVC, "%s: got remote printf\n", __func__); - do_svc_printf(avp_svc, msg, len); - break; - case SVC_AVP_WDT_RESET: - pr_err("avp_svc: AVP has been reset by watchdog\n"); - break; - default: - pr_err("avp_svc: invalid SVC call 0x%x\n", msg->svc_id); - ret = -ENOMSG; - break; - } - - return ret; -} - -static int avp_svc_thread(void *data) -{ - struct avp_svc_info *avp_svc = data; - u8 buf[TEGRA_RPC_MAX_MSG_LEN]; - struct svc_msg *msg = (struct svc_msg *)buf; - int ret; - - BUG_ON(!avp_svc->cpu_ep); - - ret = trpc_wait_peer(avp_svc->cpu_ep, -1); - if (ret) { - /* XXX: teardown?! */ - pr_err("%s: no connection from AVP (%d)\n", __func__, ret); - goto err; - } - - pr_info("%s: got remote peer\n", __func__); - - while (!kthread_should_stop()) { - DBG(AVP_DBG_TRACE_SVC, "%s: waiting for message\n", __func__); - ret = trpc_recv_msg(avp_svc->rpc_node, avp_svc->cpu_ep, buf, - TEGRA_RPC_MAX_MSG_LEN, -1); - DBG(AVP_DBG_TRACE_SVC, "%s: got message\n", __func__); - if (ret < 0) { - pr_err("%s: couldn't receive msg\n", __func__); - /* XXX: port got closed? we should exit? */ - goto err; - } else if (!ret) { - pr_err("%s: received msg of len 0?!\n", __func__); - continue; - } - dispatch_svc_message(avp_svc, msg, ret); - } - -err: - trpc_put(avp_svc->cpu_ep); - pr_info("%s: done\n", __func__); - return ret; -} - -int avp_svc_start(struct avp_svc_info *avp_svc) -{ - struct trpc_endpoint *ep; - int ret; - - avp_svc->nvmap_remote = nvmap_create_client(nvmap_dev, "avp_remote"); - if (IS_ERR(avp_svc->nvmap_remote)) { - pr_err("%s: cannot create remote nvmap client\n", __func__); - ret = PTR_ERR(avp_svc->nvmap_remote); - goto err_nvmap_create_remote_client; - } - - ep = trpc_create(avp_svc->rpc_node, "RPC_CPU_PORT", NULL, NULL); - if (IS_ERR(ep)) { - pr_err("%s: can't create RPC_CPU_PORT\n", __func__); - ret = PTR_ERR(ep); - goto err_cpu_port_create; - } - - /* TODO: protect this */ - avp_svc->cpu_ep = ep; - - /* the service thread should get an extra reference for the port */ - trpc_get(avp_svc->cpu_ep); - avp_svc->svc_thread = kthread_run(avp_svc_thread, avp_svc, - "avp_svc_thread"); - if (IS_ERR_OR_NULL(avp_svc->svc_thread)) { - avp_svc->svc_thread = NULL; - pr_err("%s: can't create svc thread\n", __func__); - ret = -ENOMEM; - goto err_kthread; - } - return 0; - -err_kthread: - trpc_close(avp_svc->cpu_ep); - trpc_put(avp_svc->cpu_ep); - avp_svc->cpu_ep = NULL; -err_cpu_port_create: - nvmap_client_put(avp_svc->nvmap_remote); -err_nvmap_create_remote_client: - avp_svc->nvmap_remote = NULL; - return ret; -} - -void avp_svc_stop(struct avp_svc_info *avp_svc) -{ - int ret; - int i; - - trpc_close(avp_svc->cpu_ep); - ret = kthread_stop(avp_svc->svc_thread); - if (ret == -EINTR) { - /* the thread never started, drop it's extra reference */ - trpc_put(avp_svc->cpu_ep); - } - avp_svc->cpu_ep = NULL; - - nvmap_client_put(avp_svc->nvmap_remote); - avp_svc->nvmap_remote = NULL; - - mutex_lock(&avp_svc->clk_lock); - for (i = 0; i < NUM_CLK_REQUESTS; i++) { - struct avp_clk *aclk = &avp_svc->clks[i]; - BUG_ON(aclk->refcnt < 0); - if (aclk->refcnt > 0) { - pr_info("%s: remote left clock '%s' on\n", __func__, - aclk->mod->name); - clk_disable(aclk->clk); - /* sclk/emcclk was enabled once for every clock */ - clk_disable(avp_svc->sclk); - clk_disable(avp_svc->emcclk); - } - aclk->refcnt = 0; - } - mutex_unlock(&avp_svc->clk_lock); -} - -struct avp_svc_info *avp_svc_init(struct platform_device *pdev, - struct trpc_node *rpc_node) -{ - struct avp_svc_info *avp_svc; - int ret; - int i; - int cnt = 0; - - BUG_ON(!rpc_node); - - avp_svc = kzalloc(sizeof(struct avp_svc_info), GFP_KERNEL); - if (!avp_svc) { - ret = -ENOMEM; - goto err_alloc; - } - - BUILD_BUG_ON(NUM_CLK_REQUESTS > BITS_PER_LONG); - - for (i = 0; i < NUM_AVP_MODULES; i++) { - struct avp_module *mod = &avp_modules[i]; - struct clk *clk; - if (!mod->name) - continue; - BUG_ON(mod->clk_req >= NUM_CLK_REQUESTS || - cnt++ >= NUM_CLK_REQUESTS); - - clk = clk_get(&pdev->dev, mod->name); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - pr_err("avp_svc: Couldn't get required clocks\n"); - goto err_get_clks; - } - avp_svc->clks[mod->clk_req].clk = clk; - avp_svc->clks[mod->clk_req].mod = mod; - avp_svc->clks[mod->clk_req].refcnt = 0; - } - - avp_svc->sclk = clk_get(&pdev->dev, "sclk"); - if (IS_ERR(avp_svc->sclk)) { - pr_err("avp_svc: Couldn't get sclk for dvfs\n"); - ret = -ENOENT; - goto err_get_clks; - } - - avp_svc->emcclk = clk_get(&pdev->dev, "emc"); - if (IS_ERR(avp_svc->emcclk)) { - pr_err("avp_svc: Couldn't get emcclk for dvfs\n"); - ret = -ENOENT; - goto err_get_clks; - } - - /* - * The emc is a shared clock, it will be set to the highest - * requested rate from any user. Set the rate to ULONG_MAX to - * always request the max rate whenever this request is enabled - */ - clk_set_rate(avp_svc->emcclk, ULONG_MAX); - - avp_svc->rpc_node = rpc_node; - - mutex_init(&avp_svc->clk_lock); - - return avp_svc; - -err_get_clks: - for (i = 0; i < NUM_CLK_REQUESTS; i++) - if (avp_svc->clks[i].clk) - clk_put(avp_svc->clks[i].clk); - if (!IS_ERR_OR_NULL(avp_svc->sclk)) - clk_put(avp_svc->sclk); - if (!IS_ERR_OR_NULL(avp_svc->emcclk)) - clk_put(avp_svc->emcclk); -err_alloc: - return ERR_PTR(ret); -} - -void avp_svc_destroy(struct avp_svc_info *avp_svc) -{ - int i; - - for (i = 0; i < NUM_CLK_REQUESTS; i++) - clk_put(avp_svc->clks[i].clk); - clk_put(avp_svc->sclk); - clk_put(avp_svc->emcclk); - - kfree(avp_svc); -} diff --git a/drivers/media/video/tegra/avp/headavp.S b/drivers/media/video/tegra/avp/headavp.S deleted file mode 100644 index 5304067f0d83..000000000000 --- a/drivers/media/video/tegra/avp/headavp.S +++ /dev/null @@ -1,66 +0,0 @@ -/* - * arch/arm/mach-tegra/headavp.S - * - * AVP kernel launcher stub; programs the AVP MMU and jumps to the - * kernel code. Must use ONLY ARMv4 instructions, and must be compiled - * in ARM mode. - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include "headavp.h" - -#define PTE0_COMPARE 0 -/* the default translation will translate any VA within - * 0x0010:0000..0x001f:ffff to the (megabyte-aligned) value written to - * _tegra_avp_boot_stub_data.map_phys_addr - */ -#define PTE0_DEFAULT (AVP_KERNEL_VIRT_BASE | 0x3ff0) - -#define PTE0_TRANSLATE 4 - -#define TRANSLATE_DATA (1 << 11) -#define TRANSLATE_CODE (1 << 10) -#define TRANSLATE_WR (1 << 9) -#define TRANSLATE_RD (1 << 8) -#define TRANSLATE_HIT (1 << 7) -#define TRANSLATE_EN (1 << 2) - -#define TRANSLATE_OPT (TRANSLATE_DATA | TRANSLATE_CODE | TRANSLATE_WR | \ - TRANSLATE_RD | TRANSLATE_HIT) - -ENTRY(_tegra_avp_boot_stub) - adr r4, _tegra_avp_boot_stub_data - ldmia r4, {r0-r3} - str r2, [r0, #PTE0_COMPARE] - bic r3, r3, #0xff0 - bic r3, r3, #0x00f - orr r3, r3, #TRANSLATE_OPT - orr r3, r3, #TRANSLATE_EN - str r3, [r0, #PTE0_TRANSLATE] - bx r1 - b . -ENDPROC(_tegra_avp_boot_stub) - .type _tegra_avp_boot_stub_data, %object -ENTRY(_tegra_avp_boot_stub_data) - .long AVP_MMU_TLB_BASE - .long 0xdeadbeef - .long PTE0_DEFAULT - .long 0xdeadd00d - .size _tegra_avp_boot_stub_data, . - _tegra_avp_boot_stub_data diff --git a/drivers/media/video/tegra/avp/headavp.h b/drivers/media/video/tegra/avp/headavp.h deleted file mode 100644 index 2bcc3297bfa4..000000000000 --- a/drivers/media/video/tegra/avp/headavp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/arm/mach-tegra/headavp.h - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _MACH_TEGRA_HEADAVP_H -#define _MACH_TEGRA_HEADAVP_H - -#define AVP_MMU_TLB_BASE 0xF000F000 -#define AVP_KERNEL_VIRT_BASE 0x00100000 - -#ifndef __ASSEMBLY__ - -struct tegra_avp_boot_stub_data { - unsigned long mmu_tlb_base; - unsigned long jump_addr; - unsigned long map_virt_addr; - unsigned long map_phys_addr; -}; - -extern void _tegra_avp_boot_stub(void); -extern struct tegra_avp_boot_stub_data _tegra_avp_boot_stub_data; - -#endif - -#endif diff --git a/drivers/media/video/tegra/avp/tegra_rpc.c b/drivers/media/video/tegra/avp/tegra_rpc.c deleted file mode 100644 index 6110d0bd066c..000000000000 --- a/drivers/media/video/tegra/avp/tegra_rpc.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Dima Zavin - * - * Based on original NVRM code from NVIDIA, and a partial rewrite by: - * Gary King - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trpc.h" - -struct trpc_port; -struct trpc_endpoint { - struct list_head msg_list; - wait_queue_head_t msg_waitq; - - struct trpc_endpoint *out; - struct trpc_port *port; - - struct trpc_node *owner; - - struct completion *connect_done; - bool ready; - struct trpc_ep_ops *ops; - void *priv; -}; - -struct trpc_port { - char name[TEGRA_RPC_MAX_NAME_LEN]; - - /* protects peer and closed state */ - spinlock_t lock; - struct trpc_endpoint peers[2]; - bool closed; - - /* private */ - struct kref ref; - struct rb_node rb_node; -}; - -enum { - TRPC_TRACE_MSG = 1U << 0, - TRPC_TRACE_CONN = 1U << 1, - TRPC_TRACE_PORT = 1U << 2, -}; - -static u32 trpc_debug_mask = 0; -module_param_named(debug_mask, trpc_debug_mask, uint, S_IWUSR | S_IRUGO); - -#define DBG(flag, args...) \ - do { if (trpc_debug_mask & (flag)) pr_info(args); } while (0) - -struct tegra_rpc_info { - struct kmem_cache *msg_cache; - - spinlock_t ports_lock; - struct rb_root ports; - - struct list_head node_list; - struct mutex node_lock; -}; - -struct trpc_msg { - struct list_head list; - - size_t len; - u8 payload[TEGRA_RPC_MAX_MSG_LEN]; -}; - -static struct tegra_rpc_info *tegra_rpc; -static struct dentry *trpc_debug_root; - -static struct trpc_msg *dequeue_msg_locked(struct trpc_endpoint *ep); - -/* a few accessors for the outside world to keep the trpc_endpoint struct - * definition private to this module */ -void *trpc_priv(struct trpc_endpoint *ep) -{ - return ep->priv; -} - -struct trpc_endpoint *trpc_peer(struct trpc_endpoint *ep) -{ - return ep->out; -} - -const char *trpc_name(struct trpc_endpoint *ep) -{ - return ep->port->name; -} - -static inline bool is_connected(struct trpc_port *port) -{ - return port->peers[0].ready && port->peers[1].ready; -} - -static inline bool is_closed(struct trpc_port *port) -{ - return port->closed; -} - -static void rpc_port_free(struct tegra_rpc_info *info, struct trpc_port *port) -{ - struct trpc_msg *msg; - int i; - - for (i = 0; i < 2; ++i) { - struct list_head *list = &port->peers[i].msg_list; - while (!list_empty(list)) { - msg = list_first_entry(list, struct trpc_msg, list); - list_del(&msg->list); - kmem_cache_free(info->msg_cache, msg); - } - } - kfree(port); -} - -static void _rpc_port_release(struct kref *kref) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_port *port = container_of(kref, struct trpc_port, ref); - unsigned long flags; - - DBG(TRPC_TRACE_PORT, "%s: releasing port '%s' (%p)\n", __func__, - port->name, port); - spin_lock_irqsave(&info->ports_lock, flags); - rb_erase(&port->rb_node, &info->ports); - spin_unlock_irqrestore(&info->ports_lock, flags); - rpc_port_free(info, port); -} - -/* note that the refcount is actually on the port and not on the endpoint */ -void trpc_put(struct trpc_endpoint *ep) -{ - kref_put(&ep->port->ref, _rpc_port_release); -} - -void trpc_get(struct trpc_endpoint *ep) -{ - kref_get(&ep->port->ref); -} - -/* Searches the rb_tree for a port with the provided name. If one is not found, - * the new port in inserted. Otherwise, the existing port is returned. - * Must be called with the ports_lock held */ -static struct trpc_port *rpc_port_find_insert(struct tegra_rpc_info *info, - struct trpc_port *port) -{ - struct rb_node **p; - struct rb_node *parent; - struct trpc_port *tmp; - int ret = 0; - - p = &info->ports.rb_node; - parent = NULL; - while (*p) { - parent = *p; - tmp = rb_entry(parent, struct trpc_port, rb_node); - - ret = strncmp(port->name, tmp->name, TEGRA_RPC_MAX_NAME_LEN); - if (ret < 0) - p = &(*p)->rb_left; - else if (ret > 0) - p = &(*p)->rb_right; - else - return tmp; - } - rb_link_node(&port->rb_node, parent, p); - rb_insert_color(&port->rb_node, &info->ports); - DBG(TRPC_TRACE_PORT, "%s: inserted port '%s' (%p)\n", __func__, - port->name, port); - return port; -} - -static int nodes_try_connect(struct tegra_rpc_info *info, - struct trpc_node *src, - struct trpc_endpoint *from) -{ - struct trpc_node *node; - int ret; - - mutex_lock(&info->node_lock); - list_for_each_entry(node, &info->node_list, list) { - if (!node->try_connect) - continue; - ret = node->try_connect(node, src, from); - if (!ret) { - mutex_unlock(&info->node_lock); - return 0; - } - } - mutex_unlock(&info->node_lock); - return -ECONNREFUSED; -} - -static struct trpc_port *rpc_port_alloc(const char *name) -{ - struct trpc_port *port; - int i; - - port = kzalloc(sizeof(struct trpc_port), GFP_KERNEL); - if (!port) { - pr_err("%s: can't alloc rpc_port\n", __func__); - return NULL; - } - BUILD_BUG_ON(2 != ARRAY_SIZE(port->peers)); - - spin_lock_init(&port->lock); - kref_init(&port->ref); - strlcpy(port->name, name, TEGRA_RPC_MAX_NAME_LEN); - for (i = 0; i < 2; i++) { - struct trpc_endpoint *ep = port->peers + i; - INIT_LIST_HEAD(&ep->msg_list); - init_waitqueue_head(&ep->msg_waitq); - ep->port = port; - } - port->peers[0].out = &port->peers[1]; - port->peers[1].out = &port->peers[0]; - - return port; -} - -/* must be holding the ports lock */ -static inline void handle_port_connected(struct trpc_port *port) -{ - int i; - - DBG(TRPC_TRACE_CONN, "tegra_rpc: port '%s' connected\n", port->name); - - for (i = 0; i < 2; i++) - if (port->peers[i].connect_done) - complete(port->peers[i].connect_done); -} - -static inline void _ready_ep(struct trpc_endpoint *ep, - struct trpc_node *owner, - struct trpc_ep_ops *ops, - void *priv) -{ - ep->ready = true; - ep->owner = owner; - ep->ops = ops; - ep->priv = priv; -} - -/* this keeps a reference on the port */ -static struct trpc_endpoint *_create_peer(struct tegra_rpc_info *info, - struct trpc_node *owner, - struct trpc_endpoint *ep, - struct trpc_ep_ops *ops, - void *priv) -{ - struct trpc_port *port = ep->port; - struct trpc_endpoint *peer = ep->out; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - BUG_ON(port->closed); - if (peer->ready || !ep->ready) { - peer = NULL; - goto out; - } - _ready_ep(peer, owner, ops, priv); - if (WARN_ON(!is_connected(port))) - pr_warning("%s: created peer but no connection established?!\n", - __func__); - else - handle_port_connected(port); - trpc_get(peer); -out: - spin_unlock_irqrestore(&port->lock, flags); - return peer; -} - -/* Exported code. This is out interface to the outside world */ -struct trpc_endpoint *trpc_create(struct trpc_node *owner, const char *name, - struct trpc_ep_ops *ops, void *priv) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_endpoint *ep; - struct trpc_port *new_port; - struct trpc_port *port; - unsigned long flags; - - BUG_ON(!owner); - - /* we always allocate a new port even if one already might exist. This - * is slightly inefficient, but it allows us to do the allocation - * without holding our ports_lock spinlock. */ - new_port = rpc_port_alloc(name); - if (!new_port) { - pr_err("%s: can't allocate memory for '%s'\n", __func__, name); - return ERR_PTR(-ENOMEM); - } - - spin_lock_irqsave(&info->ports_lock, flags); - port = rpc_port_find_insert(info, new_port); - if (port != new_port) { - rpc_port_free(info, new_port); - /* There was already a port by that name in the rb_tree, - * so just try to create its peer[1], i.e. peer for peer[0] - */ - ep = _create_peer(info, owner, &port->peers[0], ops, priv); - if (!ep) { - pr_err("%s: port '%s' is not in a connectable state\n", - __func__, port->name); - ep = ERR_PTR(-EINVAL); - } - goto out; - } - /* don't need to grab the individual port lock here since we must be - * holding the ports_lock to add the new element, and never dropped - * it, and thus noone could have gotten a reference to this port - * and thus the state couldn't have been touched */ - ep = &port->peers[0]; - _ready_ep(ep, owner, ops, priv); -out: - spin_unlock_irqrestore(&info->ports_lock, flags); - return ep; -} - -struct trpc_endpoint *trpc_create_peer(struct trpc_node *owner, - struct trpc_endpoint *ep, - struct trpc_ep_ops *ops, - void *priv) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_endpoint *peer; - unsigned long flags; - - BUG_ON(!owner); - - spin_lock_irqsave(&info->ports_lock, flags); - peer = _create_peer(info, owner, ep, ops, priv); - spin_unlock_irqrestore(&info->ports_lock, flags); - return peer; -} - -/* timeout == -1, waits forever - * timeout == 0, return immediately - */ -int trpc_connect(struct trpc_endpoint *from, long timeout) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_port *port = from->port; - struct trpc_node *src = from->owner; - int ret; - bool no_retry = !timeout; - unsigned long endtime = jiffies + msecs_to_jiffies(timeout); - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - /* XXX: add state for connections and ports to prevent invalid - * states like multiple connections, etc. ? */ - if (unlikely(is_closed(port))) { - ret = -ECONNRESET; - pr_err("%s: can't connect to %s, closed\n", __func__, - port->name); - goto out; - } else if (is_connected(port)) { - ret = 0; - goto out; - } - spin_unlock_irqrestore(&port->lock, flags); - - do { - ret = nodes_try_connect(info, src, from); - - spin_lock_irqsave(&port->lock, flags); - if (is_connected(port)) { - ret = 0; - goto out; - } else if (no_retry) { - goto out; - } else if (signal_pending(current)) { - ret = -EINTR; - goto out; - } - spin_unlock_irqrestore(&port->lock, flags); - usleep_range(5000, 20000); - } while (timeout < 0 || time_before(jiffies, endtime)); - - return -ETIMEDOUT; - -out: - spin_unlock_irqrestore(&port->lock, flags); - return ret; -} - -/* convenience function for doing this common pattern in a single call */ -struct trpc_endpoint *trpc_create_connect(struct trpc_node *src, - char *name, - struct trpc_ep_ops *ops, - void *priv, - long timeout) -{ - struct trpc_endpoint *ep; - int ret; - - ep = trpc_create(src, name, ops, priv); - if (IS_ERR(ep)) - return ep; - - ret = trpc_connect(ep, timeout); - if (ret) { - trpc_close(ep); - return ERR_PTR(ret); - } - - return ep; -} - -void trpc_close(struct trpc_endpoint *ep) -{ - struct trpc_port *port = ep->port; - struct trpc_endpoint *peer = ep->out; - bool need_close_op = false; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - BUG_ON(!ep->ready); - ep->ready = false; - port->closed = true; - if (peer->ready) { - need_close_op = true; - /* the peer may be waiting for a message */ - wake_up_all(&peer->msg_waitq); - if (peer->connect_done) - complete(peer->connect_done); - } - spin_unlock_irqrestore(&port->lock, flags); - if (need_close_op && peer->ops && peer->ops->close) - peer->ops->close(peer); - trpc_put(ep); -} - -int trpc_wait_peer(struct trpc_endpoint *ep, long timeout) -{ - struct trpc_port *port = ep->port; - DECLARE_COMPLETION_ONSTACK(event); - int ret; - unsigned long flags; - - if (timeout < 0) - timeout = MAX_SCHEDULE_TIMEOUT; - else if (timeout > 0) - timeout = msecs_to_jiffies(timeout); - - spin_lock_irqsave(&port->lock, flags); - if (ep->connect_done) { - ret = -EBUSY; - goto done; - } else if (is_connected(port)) { - ret = 0; - goto done; - } else if (is_closed(port)) { - ret = -ECONNRESET; - goto done; - } else if (!timeout) { - ret = -EAGAIN; - goto done; - } - ep->connect_done = &event; - spin_unlock_irqrestore(&port->lock, flags); - - ret = wait_for_completion_interruptible_timeout(&event, timeout); - - spin_lock_irqsave(&port->lock, flags); - ep->connect_done = NULL; - - if (is_connected(port)) { - ret = 0; - } else { - if (is_closed(port)) - ret = -ECONNRESET; - else if (ret == -ERESTARTSYS) - ret = -EINTR; - else if (!ret) - ret = -ETIMEDOUT; - } - -done: - spin_unlock_irqrestore(&port->lock, flags); - return ret; -} - -static inline int _ep_id(struct trpc_endpoint *ep) -{ - return ep - ep->port->peers; -} - -static int queue_msg(struct trpc_node *src, struct trpc_endpoint *from, - void *buf, size_t len, gfp_t gfp_flags) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_endpoint *peer = from->out; - struct trpc_port *port = from->port; - struct trpc_msg *msg; - unsigned long flags; - int ret; - - BUG_ON(len > TEGRA_RPC_MAX_MSG_LEN); - /* shouldn't be enqueueing to the endpoint */ - BUG_ON(peer->ops && peer->ops->send); - - DBG(TRPC_TRACE_MSG, "%s: queueing message for %s.%d\n", __func__, - port->name, _ep_id(peer)); - - msg = kmem_cache_alloc(info->msg_cache, gfp_flags); - if (!msg) { - pr_err("%s: can't alloc memory for msg\n", __func__); - return -ENOMEM; - } - - memcpy(msg->payload, buf, len); - msg->len = len; - - spin_lock_irqsave(&port->lock, flags); - if (is_closed(port)) { - pr_err("%s: cannot send message for closed port %s.%d\n", - __func__, port->name, _ep_id(peer)); - ret = -ECONNRESET; - goto err; - } else if (!is_connected(port)) { - pr_err("%s: cannot send message for unconnected port %s.%d\n", - __func__, port->name, _ep_id(peer)); - ret = -ENOTCONN; - goto err; - } - - list_add_tail(&msg->list, &peer->msg_list); - if (peer->ops && peer->ops->notify_recv) - peer->ops->notify_recv(peer); - wake_up_all(&peer->msg_waitq); - spin_unlock_irqrestore(&port->lock, flags); - return 0; - -err: - spin_unlock_irqrestore(&port->lock, flags); - kmem_cache_free(info->msg_cache, msg); - return ret; -} - -/* Returns -ENOMEM if failed to allocate memory for the message. */ -int trpc_send_msg(struct trpc_node *src, struct trpc_endpoint *from, - void *buf, size_t len, gfp_t gfp_flags) -{ - struct trpc_endpoint *peer = from->out; - struct trpc_port *port = from->port; - - BUG_ON(len > TEGRA_RPC_MAX_MSG_LEN); - - DBG(TRPC_TRACE_MSG, "%s: sending message from %s.%d to %s.%d\n", - __func__, port->name, _ep_id(from), port->name, _ep_id(peer)); - - if (peer->ops && peer->ops->send) { - might_sleep(); - return peer->ops->send(peer, buf, len); - } else { - might_sleep_if(gfp_flags & __GFP_WAIT); - return queue_msg(src, from, buf, len, gfp_flags); - } -} - -static inline struct trpc_msg *dequeue_msg_locked(struct trpc_endpoint *ep) -{ - struct trpc_msg *msg = NULL; - - if (!list_empty(&ep->msg_list)) { - msg = list_first_entry(&ep->msg_list, struct trpc_msg, list); - list_del_init(&msg->list); - } - - return msg; -} - -static bool __should_wake(struct trpc_endpoint *ep) -{ - struct trpc_port *port = ep->port; - unsigned long flags; - bool ret; - - spin_lock_irqsave(&port->lock, flags); - ret = !list_empty(&ep->msg_list) || is_closed(port); - spin_unlock_irqrestore(&port->lock, flags); - return ret; -} - -int trpc_recv_msg(struct trpc_node *src, struct trpc_endpoint *ep, - void *buf, size_t buf_len, long timeout) -{ - struct tegra_rpc_info *info = tegra_rpc; - struct trpc_port *port = ep->port; - struct trpc_msg *msg; - size_t len; - long ret; - unsigned long flags; - - BUG_ON(buf_len > TEGRA_RPC_MAX_MSG_LEN); - - spin_lock_irqsave(&port->lock, flags); - /* we allow closed ports to finish receiving already-queued messages */ - msg = dequeue_msg_locked(ep); - if (msg) { - goto got_msg; - } else if (is_closed(port)) { - ret = -ECONNRESET; - goto out; - } else if (!is_connected(port)) { - ret = -ENOTCONN; - goto out; - } - - if (timeout == 0) { - ret = 0; - goto out; - } else if (timeout < 0) { - timeout = MAX_SCHEDULE_TIMEOUT; - } else { - timeout = msecs_to_jiffies(timeout); - } - spin_unlock_irqrestore(&port->lock, flags); - DBG(TRPC_TRACE_MSG, "%s: waiting for message for %s.%d\n", __func__, - port->name, _ep_id(ep)); - - ret = wait_event_interruptible_timeout(ep->msg_waitq, __should_wake(ep), - timeout); - - DBG(TRPC_TRACE_MSG, "%s: woke up for %s\n", __func__, port->name); - spin_lock_irqsave(&port->lock, flags); - msg = dequeue_msg_locked(ep); - if (!msg) { - if (is_closed(port)) - ret = -ECONNRESET; - else if (!ret) - ret = -ETIMEDOUT; - else if (ret == -ERESTARTSYS) - ret = -EINTR; - else - pr_err("%s: error (%d) while receiving msg for '%s'\n", - __func__, (int)ret, port->name); - goto out; - } - -got_msg: - spin_unlock_irqrestore(&port->lock, flags); - len = min(buf_len, msg->len); - memcpy(buf, msg->payload, len); - kmem_cache_free(info->msg_cache, msg); - return len; - -out: - spin_unlock_irqrestore(&port->lock, flags); - return ret; -} - -int trpc_node_register(struct trpc_node *node) -{ - struct tegra_rpc_info *info = tegra_rpc; - - if (!info) - return -ENOMEM; - - pr_info("%s: Adding '%s' to node list\n", __func__, node->name); - - mutex_lock(&info->node_lock); - if (node->type == TRPC_NODE_LOCAL) - list_add(&node->list, &info->node_list); - else - list_add_tail(&node->list, &info->node_list); - mutex_unlock(&info->node_lock); - return 0; -} - -void trpc_node_unregister(struct trpc_node *node) -{ - struct tegra_rpc_info *info = tegra_rpc; - - mutex_lock(&info->node_lock); - list_del(&node->list); - mutex_unlock(&info->node_lock); -} - -static int trpc_debug_ports_show(struct seq_file *s, void *data) -{ - struct tegra_rpc_info *info = s->private; - struct rb_node *n; - unsigned long flags; - int i; - - spin_lock_irqsave(&info->ports_lock, flags); - for (n = rb_first(&info->ports); n; n = rb_next(n)) { - struct trpc_port *port = rb_entry(n, struct trpc_port, rb_node); - seq_printf(s, "port: %s\n closed:%s\n", port->name, - port->closed ? "yes" : "no"); - - spin_lock(&port->lock); - for (i = 0; i < ARRAY_SIZE(port->peers); i++) { - struct trpc_endpoint *ep = &port->peers[i]; - seq_printf(s, " peer%d: %s\n ready:%s\n", i, - ep->owner ? ep->owner->name: "", - ep->ready ? "yes" : "no"); - if (ep->ops && ep->ops->show) - ep->ops->show(s, ep); - } - spin_unlock(&port->lock); - } - spin_unlock_irqrestore(&info->ports_lock, flags); - - return 0; -} - -static int trpc_debug_ports_open(struct inode *inode, struct file *file) -{ - return single_open(file, trpc_debug_ports_show, inode->i_private); -} - -static struct file_operations trpc_debug_ports_fops = { - .open = trpc_debug_ports_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void trpc_debug_init(struct tegra_rpc_info *info) -{ - trpc_debug_root = debugfs_create_dir("tegra_rpc", NULL); - if (IS_ERR_OR_NULL(trpc_debug_root)) { - pr_err("%s: couldn't create debug files\n", __func__); - return; - } - - debugfs_create_file("ports", 0664, trpc_debug_root, info, - &trpc_debug_ports_fops); -} - -static int __init tegra_rpc_init(void) -{ - struct tegra_rpc_info *rpc_info; - int ret; - - rpc_info = kzalloc(sizeof(struct tegra_rpc_info), GFP_KERNEL); - if (!rpc_info) { - pr_err("%s: error allocating rpc_info\n", __func__); - return -ENOMEM; - } - - rpc_info->ports = RB_ROOT; - spin_lock_init(&rpc_info->ports_lock); - INIT_LIST_HEAD(&rpc_info->node_list); - mutex_init(&rpc_info->node_lock); - - rpc_info->msg_cache = KMEM_CACHE(trpc_msg, 0); - if (!rpc_info->msg_cache) { - pr_err("%s: unable to create message cache\n", __func__); - ret = -ENOMEM; - goto err_kmem_cache; - } - - trpc_debug_init(rpc_info); - tegra_rpc = rpc_info; - - return 0; - -err_kmem_cache: - kfree(rpc_info); - return ret; -} - -subsys_initcall(tegra_rpc_init); diff --git a/drivers/media/video/tegra/avp/trpc.h b/drivers/media/video/tegra/avp/trpc.h deleted file mode 100644 index e7b0d2d55788..000000000000 --- a/drivers/media/video/tegra/avp/trpc.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Dima Zavin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARM_MACH_TEGRA_RPC_H -#define __ARM_MACH_TEGRA_RPC_H - -#include -#include -#include - -struct trpc_endpoint; -struct trpc_ep_ops { - /* send is allowed to sleep */ - int (*send)(struct trpc_endpoint *ep, void *buf, size_t len); - /* notify_recv is NOT allowed to sleep */ - void (*notify_recv)(struct trpc_endpoint *ep); - /* close is allowed to sleep */ - void (*close)(struct trpc_endpoint *ep); - /* not allowed to sleep, not allowed to call back into trpc */ - void (*show)(struct seq_file *s, struct trpc_endpoint *ep); -}; - -enum { - TRPC_NODE_LOCAL, - TRPC_NODE_REMOTE, -}; - -struct trpc_node { - struct list_head list; - const char *name; - int type; - void *priv; - - int (*try_connect)(struct trpc_node *node, - struct trpc_node *src, - struct trpc_endpoint *from); -}; - -struct trpc_endpoint *trpc_peer(struct trpc_endpoint *ep); -void *trpc_priv(struct trpc_endpoint *ep); -const char *trpc_name(struct trpc_endpoint *ep); - -void trpc_put(struct trpc_endpoint *ep); -void trpc_get(struct trpc_endpoint *ep); - -int trpc_send_msg(struct trpc_node *src, struct trpc_endpoint *ep, void *buf, - size_t len, gfp_t gfp_flags); -int trpc_recv_msg(struct trpc_node *src, struct trpc_endpoint *ep, - void *buf, size_t len, long timeout); -struct trpc_endpoint *trpc_create(struct trpc_node *owner, const char *name, - struct trpc_ep_ops *ops, void *priv); -struct trpc_endpoint *trpc_create_connect(struct trpc_node *src, char *name, - struct trpc_ep_ops *ops, void *priv, - long timeout); -int trpc_connect(struct trpc_endpoint *from, long timeout); -struct trpc_endpoint *trpc_create_peer(struct trpc_node *owner, - struct trpc_endpoint *ep, - struct trpc_ep_ops *ops, - void *priv); -void trpc_close(struct trpc_endpoint *ep); -int trpc_wait_peer(struct trpc_endpoint *ep, long timeout); - -int trpc_node_register(struct trpc_node *node); -void trpc_node_unregister(struct trpc_node *node); - -#endif diff --git a/drivers/media/video/tegra/avp/trpc_local.c b/drivers/media/video/tegra/avp/trpc_local.c deleted file mode 100644 index 5a941a78fc40..000000000000 --- a/drivers/media/video/tegra/avp/trpc_local.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Dima Zavin - * - * Based on original NVRM code from NVIDIA, and a partial rewrite by - * Gary King - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trpc.h" -#include "trpc_sema.h" - -struct rpc_info { - struct trpc_endpoint *rpc_ep; - struct file *sema_file; -}; - -/* ports names reserved for system functions, i.e. communicating with the - * AVP */ -static const char reserved_ports[][TEGRA_RPC_MAX_NAME_LEN] = { - "RPC_AVP_PORT", - "RPC_CPU_PORT", -}; -static int num_reserved_ports = ARRAY_SIZE(reserved_ports); - -static void rpc_notify_recv(struct trpc_endpoint *ep); - -/* TODO: do we need to do anything when port is closed from the other side? */ -static struct trpc_ep_ops ep_ops = { - .notify_recv = rpc_notify_recv, -}; - -static struct trpc_node rpc_node = { - .name = "local", - .type = TRPC_NODE_LOCAL, -}; - -static void rpc_notify_recv(struct trpc_endpoint *ep) -{ - struct rpc_info *info = trpc_priv(ep); - - if (WARN_ON(!info)) - return; - if (info->sema_file) - trpc_sema_signal(info->sema_file); -} - -static int local_rpc_open(struct inode *inode, struct file *file) -{ - struct rpc_info *info; - - info = kzalloc(sizeof(struct rpc_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - nonseekable_open(inode, file); - file->private_data = info; - return 0; -} - -static int local_rpc_release(struct inode *inode, struct file *file) -{ - struct rpc_info *info = file->private_data; - - if (info->rpc_ep) - trpc_close(info->rpc_ep); - if (info->sema_file) - fput(info->sema_file); - kfree(info); - file->private_data = NULL; - return 0; -} - -static int __get_port_desc(struct tegra_rpc_port_desc *desc, - unsigned int cmd, unsigned long arg) -{ - unsigned int size = _IOC_SIZE(cmd); - - if (size != sizeof(struct tegra_rpc_port_desc)) - return -EINVAL; - if (copy_from_user(desc, (void __user *)arg, sizeof(*desc))) - return -EFAULT; - - desc->name[TEGRA_RPC_MAX_NAME_LEN - 1] = '\0'; - return 0; -} - -static char uniq_name[] = "aaaaaaaa+"; -static const int uniq_len = sizeof(uniq_name) - 1; -static DEFINE_MUTEX(uniq_lock); - -static void _gen_port_name(char *new_name) -{ - int i; - - mutex_lock(&uniq_lock); - for (i = 0; i < uniq_len - 1; i++) { - ++uniq_name[i]; - if (uniq_name[i] != 'z') - break; - uniq_name[i] = 'a'; - } - strlcpy(new_name, uniq_name, TEGRA_RPC_MAX_NAME_LEN); - mutex_unlock(&uniq_lock); -} - -static int _validate_port_name(const char *name) -{ - int i; - - for (i = 0; i < num_reserved_ports; i++) - if (!strncmp(name, reserved_ports[i], TEGRA_RPC_MAX_NAME_LEN)) - return -EINVAL; - return 0; -} - -static long local_rpc_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct rpc_info *info = file->private_data; - struct tegra_rpc_port_desc desc; - struct trpc_endpoint *ep; - int ret = 0; - - if (_IOC_TYPE(cmd) != TEGRA_RPC_IOCTL_MAGIC || - _IOC_NR(cmd) < TEGRA_RPC_IOCTL_MIN_NR || - _IOC_NR(cmd) > TEGRA_RPC_IOCTL_MAX_NR) { - ret = -ENOTTY; - goto err; - } - - switch (cmd) { - case TEGRA_RPC_IOCTL_PORT_CREATE: - if (info->rpc_ep) { - ret = -EINVAL; - goto err; - } - ret = __get_port_desc(&desc, cmd, arg); - if (ret) - goto err; - if (desc.name[0]) { - ret = _validate_port_name(desc.name); - if (ret) - goto err; - } else { - _gen_port_name(desc.name); - } - if (desc.notify_fd != -1) { - /* grab a reference to the trpc_sema fd */ - info->sema_file = trpc_sema_get_from_fd(desc.notify_fd); - if (IS_ERR(info->sema_file)) { - ret = PTR_ERR(info->sema_file); - info->sema_file = NULL; - goto err; - } - } - ep = trpc_create(&rpc_node, desc.name, &ep_ops, info); - if (IS_ERR(ep)) { - ret = PTR_ERR(ep); - if (info->sema_file) - fput(info->sema_file); - info->sema_file = NULL; - goto err; - } - info->rpc_ep = ep; - break; - case TEGRA_RPC_IOCTL_PORT_GET_NAME: - if (!info->rpc_ep) { - ret = -EINVAL; - goto err; - } - if (copy_to_user((void __user *)arg, - trpc_name(info->rpc_ep), - TEGRA_RPC_MAX_NAME_LEN)) { - ret = -EFAULT; - goto err; - } - break; - case TEGRA_RPC_IOCTL_PORT_CONNECT: - if (!info->rpc_ep) { - ret = -EINVAL; - goto err; - } - ret = trpc_connect(info->rpc_ep, (long)arg); - if (ret) { - pr_err("%s: can't connect to '%s' (%d)\n", __func__, - trpc_name(info->rpc_ep), ret); - goto err; - } - break; - case TEGRA_RPC_IOCTL_PORT_LISTEN: - if (!info->rpc_ep) { - ret = -EINVAL; - goto err; - } - ret = trpc_wait_peer(info->rpc_ep, (long)arg); - if (ret) { - pr_err("%s: error waiting for peer for '%s' (%d)\n", - __func__, trpc_name(info->rpc_ep), ret); - goto err; - } - break; - default: - pr_err("%s: unknown cmd %d\n", __func__, _IOC_NR(cmd)); - ret = -EINVAL; - goto err; - } - - return 0; - -err: - if (ret && ret != -ERESTARTSYS) - pr_err("tegra_rpc: pid=%d ioctl=%x/%lx (%x) ret=%d\n", - current->pid, cmd, arg, _IOC_NR(cmd), ret); - return (long)ret; -} - -static ssize_t local_rpc_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct rpc_info *info = file->private_data; - u8 data[TEGRA_RPC_MAX_MSG_LEN]; - int ret; - - if (!info) - return -EINVAL; - else if (count > TEGRA_RPC_MAX_MSG_LEN) - return -EINVAL; - - if (copy_from_user(data, buf, count)) - return -EFAULT; - - ret = trpc_send_msg(&rpc_node, info->rpc_ep, data, count, - GFP_KERNEL); - if (ret) - return ret; - return count; -} - -static ssize_t local_rpc_read(struct file *file, char __user *buf, size_t max, - loff_t *ppos) -{ - struct rpc_info *info = file->private_data; - int ret; - u8 data[TEGRA_RPC_MAX_MSG_LEN]; - - if (max > TEGRA_RPC_MAX_MSG_LEN) - return -EINVAL; - - ret = trpc_recv_msg(&rpc_node, info->rpc_ep, data, - TEGRA_RPC_MAX_MSG_LEN, 0); - if (ret == 0) - return 0; - else if (ret < 0) - return ret; - else if (ret > max) - return -ENOSPC; - else if (copy_to_user(buf, data, ret)) - return -EFAULT; - - return ret; -} - -static const struct file_operations local_rpc_misc_fops = { - .owner = THIS_MODULE, - .open = local_rpc_open, - .release = local_rpc_release, - .unlocked_ioctl = local_rpc_ioctl, - .write = local_rpc_write, - .read = local_rpc_read, -}; - -static struct miscdevice local_rpc_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "tegra_rpc", - .fops = &local_rpc_misc_fops, -}; - -int __init rpc_local_init(void) -{ - int ret; - - ret = trpc_sema_init(); - if (ret) { - pr_err("%s: error in trpc_sema_init\n", __func__); - goto err_sema_init; - } - - ret = misc_register(&local_rpc_misc_device); - if (ret) { - pr_err("%s: can't register misc device\n", __func__); - goto err_misc; - } - - ret = trpc_node_register(&rpc_node); - if (ret) { - pr_err("%s: can't register rpc node\n", __func__); - goto err_node_reg; - } - return 0; - -err_node_reg: - misc_deregister(&local_rpc_misc_device); -err_misc: -err_sema_init: - return ret; -} - -module_init(rpc_local_init); diff --git a/drivers/media/video/tegra/avp/trpc_sema.c b/drivers/media/video/tegra/avp/trpc_sema.c deleted file mode 100644 index b8772573d956..000000000000 --- a/drivers/media/video/tegra/avp/trpc_sema.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Dima Zavin - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trpc_sema.h" - -struct trpc_sema { - wait_queue_head_t wq; - spinlock_t lock; - int count; -}; - -static int rpc_sema_minor = -1; - -static inline bool is_trpc_sema_file(struct file *file) -{ - dev_t rdev = file->f_dentry->d_inode->i_rdev; - - if (MAJOR(rdev) == MISC_MAJOR && MINOR(rdev) == rpc_sema_minor) - return true; - return false; -} - -struct file *trpc_sema_get_from_fd(int fd) -{ - struct file *file; - - file = fget(fd); - if (unlikely(file == NULL)) { - pr_err("%s: fd %d is invalid\n", __func__, fd); - return ERR_PTR(-EINVAL); - } - - if (!is_trpc_sema_file(file)) { - pr_err("%s: fd (%d) is not a trpc_sema file\n", __func__, fd); - fput(file); - return ERR_PTR(-EINVAL); - } - - return file; -} - -int trpc_sema_signal(struct file *file) -{ - struct trpc_sema *info = file->private_data; - unsigned long flags; - - if (!info) - return -EINVAL; - - spin_lock_irqsave(&info->lock, flags); - info->count++; - wake_up_interruptible_all(&info->wq); - spin_unlock_irqrestore(&info->lock, flags); - return 0; -} - -static int trpc_sema_wait(struct trpc_sema *info, long *timeleft) -{ - unsigned long flags; - int ret = 0; - unsigned long endtime; - long timeout = *timeleft; - - *timeleft = 0; - if (timeout < 0) { - timeout = MAX_SCHEDULE_TIMEOUT; - } else if (timeout > 0) { - timeout = msecs_to_jiffies(timeout); - endtime = jiffies + timeout; - } - -again: - if (timeout) - ret = wait_event_interruptible_timeout(info->wq, - info->count > 0, - timeout); - spin_lock_irqsave(&info->lock, flags); - if (info->count > 0) { - info->count--; - ret = 0; - } else if (ret == 0 || timeout == 0) { - ret = -ETIMEDOUT; - } else if (ret < 0) { - ret = -EINTR; - if (timeout != MAX_SCHEDULE_TIMEOUT && - time_before(jiffies, endtime)) - *timeleft = jiffies_to_msecs(endtime - jiffies); - else - *timeleft = 0; - } else { - /* we woke up but someone else got the semaphore and we have - * time left, try again */ - timeout = ret; - spin_unlock_irqrestore(&info->lock, flags); - goto again; - } - spin_unlock_irqrestore(&info->lock, flags); - return ret; -} - -static int trpc_sema_open(struct inode *inode, struct file *file) -{ - struct trpc_sema *info; - - info = kzalloc(sizeof(struct trpc_sema), GFP_KERNEL); - if (!info) - return -ENOMEM; - - nonseekable_open(inode, file); - init_waitqueue_head(&info->wq); - spin_lock_init(&info->lock); - file->private_data = info; - return 0; -} - -static int trpc_sema_release(struct inode *inode, struct file *file) -{ - struct trpc_sema *info = file->private_data; - - file->private_data = NULL; - kfree(info); - return 0; -} - -static long trpc_sema_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct trpc_sema *info = file->private_data; - int ret; - long timeout; - - if (_IOC_TYPE(cmd) != TEGRA_SEMA_IOCTL_MAGIC || - _IOC_NR(cmd) < TEGRA_SEMA_IOCTL_MIN_NR || - _IOC_NR(cmd) > TEGRA_SEMA_IOCTL_MAX_NR) - return -ENOTTY; - else if (!info) - return -EINVAL; - - switch (cmd) { - case TEGRA_SEMA_IOCTL_WAIT: - if (copy_from_user(&timeout, (void __user *)arg, sizeof(long))) - return -EFAULT; - ret = trpc_sema_wait(info, &timeout); - if (ret != -EINTR) - break; - if (copy_to_user((void __user *)arg, &timeout, sizeof(long))) - ret = -EFAULT; - break; - case TEGRA_SEMA_IOCTL_SIGNAL: - ret = trpc_sema_signal(file); - break; - default: - pr_err("%s: Unknown tegra_sema ioctl 0x%x\n", __func__, - _IOC_NR(cmd)); - ret = -ENOTTY; - break; - } - return ret; -} - -static const struct file_operations trpc_sema_misc_fops = { - .owner = THIS_MODULE, - .open = trpc_sema_open, - .release = trpc_sema_release, - .unlocked_ioctl = trpc_sema_ioctl, -}; - -static struct miscdevice trpc_sema_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "tegra_sema", - .fops = &trpc_sema_misc_fops, -}; - -int __init trpc_sema_init(void) -{ - int ret; - - if (rpc_sema_minor >= 0) { - pr_err("%s: trpc_sema already registered\n", __func__); - return -EBUSY; - } - - ret = misc_register(&trpc_sema_misc_device); - if (ret) { - pr_err("%s: can't register misc device\n", __func__); - return ret; - } - - rpc_sema_minor = trpc_sema_misc_device.minor; - pr_info("%s: registered misc dev %d:%d\n", __func__, MISC_MAJOR, - rpc_sema_minor); - - return 0; -} diff --git a/drivers/media/video/tegra/avp/trpc_sema.h b/drivers/media/video/tegra/avp/trpc_sema.h deleted file mode 100644 index 566bbdbe739e..000000000000 --- a/drivers/media/video/tegra/avp/trpc_sema.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Dima Zavin - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARM_MACH_TEGRA_RPC_SEMA_H -#define __ARM_MACH_TEGRA_RPC_SEMA_H - -#include -#include - -struct file *trpc_sema_get_from_fd(int fd); -int trpc_sema_signal(struct file *file); -int __init trpc_sema_init(void); - -#endif diff --git a/drivers/media/video/tegra/dw9714l.c b/drivers/media/video/tegra/dw9714l.c deleted file mode 100644 index e940501d92ab..000000000000 --- a/drivers/media/video/tegra/dw9714l.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * DW9714L focuser driver. - * - * Copyright (C) 2010 Motorola Inc. - * - * Contributors: - * Andrei Warkentin - * - * Based on ov5650.c. - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#define POS_LOW (144) -#define POS_HIGH (520) -#define SETTLETIME_MS (50) -#define FOCAL_LENGTH (4.42f) -#define FNUMBER (2.8f) -#define DEFAULT_MODE (MODE_LSC); - -#define PROT_OFF (0xECA3) -#define PROT_ON (0xDC51) -#define DLC_MCLK (0x2) -#define DLC_TSRC (0x17) -#define LSC_MCLK (0x1) -#define LSC_S10 (0x3) -#define LSC_S32 (0x3) -#define LSC_TSRC (0x3) -#define LSC_GOAL(pos) ((pos << 4) | (LSC_S32 << 2) | LSC_S10) -#define GOAL(pos) (pos << 4) - -#define DW9714L_MAX_RETRIES (3) - -struct dw9714l_info { - struct i2c_client *i2c_client; - struct regulator *regulator; - struct dw9714l_config config; -}; - -static u16 dlc_pre_set_pos[] = -{ - PROT_OFF, - 0xA10C | DLC_MCLK, - 0xF200 | (DLC_TSRC << 3), - PROT_ON -}; - -static u16 lsc_pre_set_pos[] = -{ - PROT_OFF, - 0xA104 | LSC_MCLK, - 0xF200 | (LSC_TSRC << 3), - PROT_ON -}; - -static int dw9714l_write(struct i2c_client *client, u16 value) -{ - int count; - struct i2c_msg msg[1]; - unsigned char data[2]; - int retry = 0; - - if (!client->adapter) - return -ENODEV; - - data[0] = (u8) (value >> 8); - data[1] = (u8) (value & 0xFF); - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = ARRAY_SIZE(data); - msg[0].buf = data; - - do { - count = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); - if (count == ARRAY_SIZE(msg)) - return 0; - retry++; - pr_err("dw9714l: i2c transfer failed, retrying %x\n", - value); - msleep(3); - } while (retry <= DW9714L_MAX_RETRIES); - return -EIO; -} - -static int dw9714l_write_many(struct i2c_client *client, - u16 *values, - size_t count) -{ - int ix = 0; - int ret = 0; - while (ix < count && ret == 0) - ret = dw9714l_write(client, values[ix++]); - - return ret; -} - -static int dw9714l_set_position(struct dw9714l_info *info, u32 position) -{ - int ret; - - if (position < info->config.pos_low || - position > info->config.pos_high) - return -EINVAL; - - /* - As we calibrate the focuser, we might go back and forth on - the actual mode of setting the position. To - make this least painful, we'll make the mode a settable - parameter exposed to the focuser HAL. - */ - - switch(info->config.mode) - { - case MODE_LSC: - ret = dw9714l_write_many(info->i2c_client, - lsc_pre_set_pos, - ARRAY_SIZE(lsc_pre_set_pos)); - - if (ret) - return ret; - - ret = dw9714l_write(info->i2c_client, - LSC_GOAL(position)); - - break; - case MODE_DLC: - ret = dw9714l_write_many(info->i2c_client, - dlc_pre_set_pos, - ARRAY_SIZE(dlc_pre_set_pos)); - - if (ret) - return ret; - - /* Fall through */ - case MODE_DIRECT: - ret = dw9714l_write(info->i2c_client, - GOAL(position)); - break; - case MODE_INVALID: - default: - WARN_ON(info->config.mode); - } - - return ret; -} - -static long dw9714l_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct dw9714l_info *info = file->private_data; - - switch (cmd) { - case DW9714L_IOCTL_GET_CONFIG: - { - if (copy_to_user((void __user *) arg, - &info->config, - sizeof(info->config))) { - pr_err("%s: 0x%x\n", __func__, __LINE__); - return -EFAULT; - } - - break; - } - case DW9714L_IOCTL_SET_CAL: - { - struct dw9714l_cal cal; - if (copy_from_user(&cal, - (const void __user *) arg, - sizeof(cal))) { - pr_err("%s: 0x%x\n", __func__, __LINE__); - return -EFAULT; - } - - if (cal.mode >= MODE_INVALID) - return -EINVAL; - - info->config.mode = cal.mode; - break; - } - case DW9714L_IOCTL_SET_POSITION: - return dw9714l_set_position(info, (u32) arg); - default: - return -EINVAL; - } - - return 0; -} - -struct dw9714l_info *info = NULL; - -static int dw9714l_open(struct inode *inode, struct file *file) -{ - - file->private_data = info; - if (info->regulator) - regulator_enable(info->regulator); - return 0; -} - -int dw9714l_release(struct inode *inode, struct file *file) -{ - if (info->regulator) - regulator_disable(info->regulator); - file->private_data = NULL; - return 0; -} - - -static const struct file_operations dw9714l_fileops = { - .owner = THIS_MODULE, - .open = dw9714l_open, - .unlocked_ioctl = dw9714l_ioctl, - .release = dw9714l_release, -}; - -static struct miscdevice dw9714l_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "dw9714l", - .fops = &dw9714l_fileops, -}; - -static int dw9714l_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err; - - pr_info("dw9714l: probing sensor.\n"); - - info = kzalloc(sizeof(struct dw9714l_info), GFP_KERNEL); - if (!info) { - pr_err("dw9714l: Unable to allocate memory!\n"); - return -ENOMEM; - } - - err = misc_register(&dw9714l_device); - if (err) { - pr_err("dw9714l: Unable to register misc device!\n"); - kfree(info); - return err; - } - - info->regulator = regulator_get(&client->dev, "vcc"); - if (IS_ERR_OR_NULL(info->regulator)) { - dev_err(&client->dev, "unable to get regulator %s\n", - dev_name(&client->dev)); - info->regulator = NULL; - } else { - regulator_enable(info->regulator); - } - - info->i2c_client = client; - info->config.settle_time = SETTLETIME_MS; - info->config.focal_length = FOCAL_LENGTH; - info->config.fnumber = FNUMBER; - info->config.pos_low = POS_LOW; - info->config.pos_high = POS_HIGH; - info->config.mode = DEFAULT_MODE; - i2c_set_clientdata(client, info); - return 0; -} - -static int dw9714l_remove(struct i2c_client *client) -{ - struct dw9714l_info *info; - info = i2c_get_clientdata(client); - misc_deregister(&dw9714l_device); - kfree(info); - return 0; -} - -static const struct i2c_device_id dw9714l_id[] = { - { "dw9714l", 0 }, - { }, -}; - -MODULE_DEVICE_TABLE(i2c, dw9714l_id); - -static struct i2c_driver dw9714l_i2c_driver = { - .driver = { - .name = "dw9714l", - .owner = THIS_MODULE, - }, - .probe = dw9714l_probe, - .remove = dw9714l_remove, - .id_table = dw9714l_id, -}; - -static int __init dw9714l_init(void) -{ - pr_info("dw9714l sensor driver loading\n"); - return i2c_add_driver(&dw9714l_i2c_driver); -} - -static void __exit dw9714l_exit(void) -{ - i2c_del_driver(&dw9714l_i2c_driver); -} - -module_init(dw9714l_init); -module_exit(dw9714l_exit); - diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c deleted file mode 100644 index c423fd8b911d..000000000000 --- a/drivers/media/video/tegra/ov5650.c +++ /dev/null @@ -1,873 +0,0 @@ -/* - * ov5650.c - ov5650 sensor driver - * - * Copyright (C) 2010 Google Inc. - * - * Contributors: - * Rebecca Schultz Zavin - * Andrei Warkentin - * - * Leverage OV9640.c - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -struct ov5650_reg { - u16 addr; - u16 val; -}; - -struct ov5650_info { - int mode; - struct i2c_client *i2c_client; - struct ov5650_platform_data *pdata; - struct ov5650_otp_data otp_data; - bool otp_valid; -}; - -#define OV5650_TABLE_WAIT_MS 0 -#define OV5650_TABLE_END 1 -#define OV5650_MAX_RETRIES 3 - -static struct ov5650_reg tp_none_seq[] = { - {0x5046, 0x00}, /* isp_off */ - {OV5650_TABLE_END, 0} -}; - -static struct ov5650_reg tp_cbars_seq[] = { - {0x503D, 0xC0}, - {0x503E, 0x00}, - {0x5046, 0x01}, /* isp_on */ - {OV5650_TABLE_END, 0} -}; - -static struct ov5650_reg tp_checker_seq[] = { - {0x503D, 0xC0}, - {0x503E, 0x0A}, - {0x5046, 0x01}, /* isp_on */ - {OV5650_TABLE_END, 0} -}; - -static struct ov5650_reg reset_seq[] = { - {0x3008, 0x82}, /* reset registers pg 72 */ - {OV5650_TABLE_WAIT_MS, 5}, - {0x3008, 0x42}, /* register power down pg 72 */ - {OV5650_TABLE_WAIT_MS, 5}, - {OV5650_TABLE_END, 0x0}, -}; - -static struct ov5650_reg otp_reset_seq[] = { - {0x3008, 0x82}, /* reset registers pg 72 */ - {OV5650_TABLE_WAIT_MS, 5}, - {0x3008, 0x42}, /* register power down pg 72 */ - {OV5650_TABLE_WAIT_MS, 5}, - {0x3008, 0x02}, /* register power down pg 72 */ - {OV5650_TABLE_WAIT_MS, 5}, - {OV5650_TABLE_END, 0x0}, -}; - -static struct ov5650_reg *test_pattern_modes[] = { - tp_none_seq, - tp_cbars_seq, - tp_checker_seq, -}; - -static struct ov5650_reg mode_start[] = { - {0x3103, 0x93}, /* power up system clock from PLL page 77 */ - {0x3017, 0xff}, /* PAD output enable page 100 */ - {0x3018, 0xfc}, /* PAD output enable page 100 */ - - {0x3600, 0x50}, /* analog pg 108 */ - {0x3601, 0x0d}, /* analog pg 108 */ - {0x3604, 0x50}, /* analog pg 108 */ - {0x3605, 0x04}, /* analog pg 108 */ - {0x3606, 0x3f}, /* analog pg 108 */ - {0x3612, 0x1a}, /* analog pg 108 */ - {0x3630, 0x22}, /* analog pg 108 */ - {0x3631, 0x22}, /* analog pg 108 */ - {0x3702, 0x3a}, /* analog pg 108 */ - {0x3704, 0x18}, /* analog pg 108 */ - {0x3705, 0xda}, /* analog pg 108 */ - {0x3706, 0x41}, /* analog pg 108 */ - {0x370a, 0x80}, /* analog pg 108 */ - {0x370b, 0x40}, /* analog pg 108 */ - {0x370e, 0x00}, /* analog pg 108 */ - {0x3710, 0x28}, /* analog pg 108 */ - {0x3712, 0x13}, /* analog pg 108 */ - {0x3830, 0x50}, /* manual exposure gain bit [0] */ - {0x3a18, 0x00}, /* AEC gain ceiling bit 8 pg 114 */ - {0x3a19, 0xf8}, /* AEC gain ceiling pg 114 */ - {0x3a00, 0x38}, /* AEC control 0 debug mode band low - limit mode band func pg 112 */ - - {0x3603, 0xa7}, /* analog pg 108 */ - {0x3615, 0x50}, /* analog pg 108 */ - {0x3620, 0x56}, /* analog pg 108 */ - {0x3810, 0x00}, /* TIMING HVOFFS both are zero pg 80 */ - {0x3836, 0x00}, /* TIMING HVPAD both are zero pg 82 */ - {0x3a1a, 0x06}, /* DIFF MAX an AEC register??? pg 114 */ - {0x4000, 0x01}, /* BLC enabled pg 120 */ - {0x401c, 0x48}, /* reserved pg 120 */ - {0x401d, 0x28}, /* BLC control pg 120 */ - {0x5000, 0x00}, /* ISP control00 features are disabled. pg 132 */ - {0x5001, 0x00}, /* ISP control01 awb disabled. pg 132 */ - {0x5002, 0x00}, /* ISP control02 debug mode disabled pg 132 */ - {0x503d, 0x00}, /* ISP control3D features disabled pg 133 */ - {0x5046, 0x00}, /* ISP control isp disable awbg disable pg 133 */ - - {0x300f, 0x8f}, /* PLL control00 R_SELD5 [7:6] div by 4 R_DIVL [2] - two lane div 1 SELD2P5 [1:0] div 2.5 pg 99 */ - {0x3010, 0x10}, /* PLL control01 DIVM [3:0] DIVS [7:4] div 1 pg 99 */ - {0x3011, 0x18}, /* PLL control02 R_DIVP [5:0] div 24 pg 99 (20Mhz Mclk*/ - {0x3012, 0x02}, /* PLL CTR 03, default */ - {0x3815, 0x82}, /* PCLK to SCLK ratio bit[4:0] is set to 2 pg 81 */ - {0x3503, 0x33}, /* AEC auto AGC auto gain has no latch delay. pg 38 */ - /* {FAST_SETMODE_START, 0}, */ - {0x3613, 0x44}, /* analog pg 108 */ - {OV5650_TABLE_END, 0x0}, -}; - -static struct ov5650_reg mode_2592x1944[] = { - {0x3621, 0x2f}, /* analog horizontal binning/sampling not enabled. - pg 108 */ - {0x3632, 0x55}, /* analog pg 108 */ - {0x3703, 0xe6}, /* analog pg 108 */ - {0x370c, 0xa0}, /* analog pg 108 */ - {0x370d, 0x04}, /* analog pg 108 */ - {0x3713, 0x2f}, /* analog pg 108 */ - {0x3800, 0x02}, /* HREF start point higher 4 bits [3:0] pg 108 */ - {0x3801, 0x58}, /* HREF start point lower 8 bits [7:0] pg 108 */ - {0x3802, 0x00}, /* VREF start point higher 4 bits [3:0] pg 108 */ - {0x3803, 0x0c}, /* VREF start point [7:0] pg 108 */ - {0x3804, 0x0a}, /* HREF width higher 4 bits [3:0] pg 108 */ - {0x3805, 0x20}, /* HREF width lower 8 bits [7:0] pg 108 */ - {0x3806, 0x07}, /* VREF height higher 4 bits [3:0] pg 109 */ - {0x3807, 0xa0}, /* VREF height lower 8 bits [7:0] pg 109 */ - {0x3808, 0x0a}, /* DVP horizontal output size higher 4 bits [3:0] - pg 109 */ - {0x3809, 0x20}, /* DVP horizontal output size lower 8 bits [7:0] - pg 109 */ - {0x380a, 0x07}, /* DVP vertical output size higher 4 bits [3:0] - pg 109 */ - {0x380b, 0xa0}, /* DVP vertical output size lower 8 bits [7:0] - pg 109 */ - {0x380c, 0x0c}, /* total horizontal size higher 5 bits [4:0] pg 109, - line length */ - {0x380d, 0xb4}, /* total horizontal size lower 8 bits [7:0] pg 109, - line length */ - {0x380e, 0x07}, /* total vertical size higher 5 bits [4:0] pg 109, - frame length */ - {0x380f, 0xb0}, /* total vertical size lower 8 bits [7:0] pg 109, - frame length */ - {0x3818, 0xc0}, /* timing control reg18 mirror & dkhf pg 110 */ - {0x381a, 0x3c}, /* HS mirror adjustment pg 110 */ - {0x3a0d, 0x06}, /* b60 max pg 113 */ - {0x3c01, 0x00}, /* 5060HZ_CTRL01 pg 116 */ - {0x3007, 0x3f}, /* clock enable03 pg 98 */ - {0x5059, 0x80}, /* => NOT found */ - {0x3003, 0x03}, /* reset MIPI and DVP pg 97 */ - {0x3500, 0x00}, /* long exp 1/3 in unit of 1/16 line, pg 38 */ - {0x3501, 0x7a}, /* long exp 2/3 in unit of 1/16 line, pg 38, - note frame length start with 0x7b0, - and SENSOR_BAYER_DEFAULT_MAX_COARSE_DIFF=3 */ - {0x3502, 0xd0}, /* long exp 3/3 in unit of 1/16 line, pg 38. - Two lines of integration time. */ - {0x350a, 0x00}, /* gain output to sensor, pg 38 */ - {0x350b, 0x00}, /* gain output to sensor, pg 38 */ - {0x4801, 0x0f}, /* MIPI control01 pg 125 */ - {0x300e, 0x0c}, /* SC_MIPI_SC_CTRL0 pg 73 */ - {0x4803, 0x50}, /* MIPI CTRL3 pg 91 */ - {0x4800, 0x34}, /* MIPI CTRl0 idle and short line pg 89 */ - {OV5650_TABLE_END, 0x0000} -}; - -static struct ov5650_reg mode_1296x972[] = { - {0x3621, 0xaf}, /* analog horizontal binning/sampling not enabled. - pg 108 */ - {0x3632, 0x5a}, /* analog pg 108 */ - {0x3703, 0xb0}, /* analog pg 108 */ - {0x370c, 0xc5}, /* analog pg 108 */ - {0x370d, 0x42}, /* analog pg 108 */ - {0x3713, 0x2f}, /* analog pg 108 */ - {0x3800, 0x03}, /* HREF start point higher 4 bits [3:0] pg 108 */ - {0x3801, 0x3c}, /* HREF start point lower 8 bits [7:0] pg 108 */ - {0x3802, 0x00}, /* VREF start point higher 4 bits [3:0] pg 108 */ - {0x3803, 0x06}, /* VREF start point [7:0] pg 108 */ - {0x3804, 0x05}, /* HREF width higher 4 bits [3:0] pg 108 */ - {0x3805, 0x10}, /* HREF width lower 8 bits [7:0] pg 108 */ - {0x3806, 0x03}, /* VREF height higher 4 bits [3:0] pg 109 */ - {0x3807, 0xd0}, /* VREF height lower 8 bits [7:0] pg 109 */ - {0x3808, 0x05}, /* DVP horizontal output size higher 4 bits [3:0] - pg 109 */ - {0x3809, 0x10}, /* DVP horizontal output size lower 8 bits [7:0] - pg 109 */ - {0x380a, 0x03}, /* DVP vertical output size higher 4 bits [3:0] - pg 109 */ - {0x380b, 0xd0}, /* DVP vertical output size lower 8 bits [7:0] - pg 109 */ - {0x380c, 0x08}, /* total horizontal size higher 5 bits [4:0] - pg 109, line length */ - {0x380d, 0xa8}, /* total horizontal size lower 8 bits [7:0] pg 109, - line length */ - {0x380e, 0x05}, /* total vertical size higher 5 bits [4:0] pg 109, - frame length */ - {0x380f, 0xa4}, /* total horizontal size lower 8 bits [7:0] pg 109, - frame length */ - {0x3818, 0xc1}, /* timing control reg18 mirror & dkhf pg 110 */ - {0x381a, 0x00}, /* HS mirror adjustment pg 110 */ - {0x3a0d, 0x08}, /* b60 max pg 113 */ - {0x3c01, 0x00}, /* 5060HZ_CTRL01 pg 116 */ - {0x3007, 0x3b}, /* clock enable03 pg 98 */ - {0x5059, 0x80}, /* => NOT found. added */ - {0x3003, 0x03}, /* reset MIPI and DVP pg 97 */ - {0x3500, 0x00}, /* long exp 1/3 in unit of 1/16 line, pg 38, - note frame length is from 0x5a4, - and SENSOR_BAYER_DEFAULT_MAX_COARSE_DIFF=3 */ - {0x3501, 0x5a}, /* long exp 2/3 in unit of 1/16 line, pg 38 */ - {0x3502, 0x10}, /* long exp 3/3 in unit of 1/16 line, pg 38 */ - {0x350a, 0x00}, /* gain output to sensor, pg 38 */ - {0x350b, 0x10}, /* gain output to sensor, pg 38 */ - {0x4801, 0x0f}, /* MIPI control01 pg 125 */ - {0x300e, 0x0c}, /* SC_MIPI_SC_CTRL0 pg 73 */ - {0x4803, 0x50}, /* MIPI CTRL3 pg 91 */ - {0x4800, 0x34}, /* MIPI CTRl0 idle and short line pg 89 */ - {OV5650_TABLE_END, 0x0000} -}; - -static struct ov5650_reg mode_2080x1164[] = { - {0x3103, 0x93}, // power up system clock from PLL page 77 - {0x3007, 0x3b}, // clock enable03 pg 98 - {0x3017, 0xff}, // PAD output enable page 100 - {0x3018, 0xfc}, // PAD output enable page 100 - - {0x3600, 0x54}, // analog pg 108 - {0x3601, 0x05}, // analog pg 108 - {0x3603, 0xa7}, // analog pg 108 - {0x3604, 0x40}, // analog pg 108 - {0x3605, 0x04}, // analog pg 108 - {0x3606, 0x3f}, // analog pg 108 - {0x3612, 0x1a}, // analog pg 108 - {0x3613, 0x44}, // analog pg 108 - {0x3615, 0x52}, // analog pg 108 - {0x3620, 0x56}, // analog pg 108 - {0x3623, 0x01}, // analog pg 108 - {0x3630, 0x22}, // analog pg 108 - {0x3631, 0x36}, // analog pg 108 - {0x3632, 0x5f}, // analog pg 108 - {0x3633, 0x24}, // analog pg 108 - - {0x3702, 0x3a}, // analog pg 108 - {0x3704, 0x18}, // analog pg 108 - {0x3706, 0x41}, // analog pg 108 - {0x370b, 0x40}, // analog pg 108 - {0x370e, 0x00}, // analog pg 108 - {0x3710, 0x28}, // analog pg 108 - {0x3711, 0x24}, - {0x3712, 0x13}, // analog pg 108 - - {0x3810, 0x00}, // TIMING HVOFFS both are zero pg 80 - {0x3815, 0x82}, // PCLK to SCLK ratio bit[4:0] is set to 2 pg 81 - {0x3830, 0x50}, // manual exposure gain bit [0] - {0x3836, 0x00}, // TIMING HVPAD both are zero pg 82 - - {0x3a1a, 0x06}, // DIFF MAX an AEC register??? pg 114 - {0x3a18, 0x00}, // AEC gain ceiling bit 8 pg 114 - {0x3a19, 0xf8}, // AEC gain ceiling pg 114 - {0x3a00, 0x38}, // AEC control 0 debug mode band low limit mode band func pg 112 - {0x3a0d, 0x06}, // b60 max pg 113 - {0x3c01, 0x34}, // 5060HZ_CTRL01 pg 116 - - {0x401f, 0x03}, // BLC enabled pg 120 - {0x4000, 0x05}, // BLC enabled pg 120 - {0x401d, 0x08}, // reserved pg 120 - {0x4001, 0x02}, // BLC control pg 120 - - {0x5000, 0x00}, // ISP control00 features are disabled. pg 132 - {0x5001, 0x00}, // ISP control01 awb disabled. pg 132 - {0x5002, 0x00}, // ISP control02 debug mode disabled pg 132 - {0x503d, 0x00}, // ISP control3D features disabled pg 133 - {0x5046, 0x00}, // ISP control isp disable awbg disable pg 133 - - {0x300f, 0x8f}, // PLL control00 R_SELD5 [7:6] div by 4 R_DIVL [2] two lane div 1 SELD2P5 [1:0] div 2.5 pg 99 - {0x3010, 0x10}, // PLL control01 DIVM [3:0] DIVS [7:4] div 1 pg 99 - {0x3011, 0x18}, // PLL control02 R_DIVP [5:0] div 24 pg 99 (20Mhz Mclk) - {0x3012, 0x02}, // PLL CTR 03, default - {0x3503, 0x33}, // AEC auto AGC auto gain has delay of 2 frames. pg 38 - - {0x3621, 0x2f}, // analog horizontal binning/sampling not enabled. pg 108 - {0x3703, 0xe6}, // analog pg 108 - {0x370c, 0x00}, // analog pg 108 - {0x370d, 0x04}, // analog pg 108 - {0x3713, 0x22}, // analog pg 108 - {0x3714, 0x27}, - {0x3705, 0xda}, - {0x370a, 0x80}, - - {0x3800, 0x02}, // HREF start point higher 4 bits [3:0] pg 108 - {0x3801, 0x12}, // HREF start point lower 8 bits [7:0] pg 108 - {0x3802, 0x00}, // VREF start point higher 4 bits [3:0] pg 108 - {0x3803, 0x0a}, // VREF start point [7:0] pg 108 - {0x3804, 0x08}, // HREF width higher 4 bits [3:0] pg 108 - {0x3805, 0x20}, // HREF width lower 8 bits [7:0] pg 108 - {0x3806, 0x04}, // VREF height higher 4 bits [3:0] pg 109 - {0x3807, 0x92}, // VREF height lower 8 bits [7:0] pg 109 - {0x3808, 0x08}, // DVP horizontal output size higher 4 bits [3:0] pg 109 - {0x3809, 0x20}, // DVP horizontal output size lower 8 bits [7:0] pg 109 - {0x380a, 0x04}, // DVP vertical output size higher 4 bits [3:0] pg 109 - {0x380b, 0x92}, // DVP vertical output size lower 8 bits [7:0] pg 109 - {0x380c, 0x0a}, // total horizontal size higher 5 bits [4:0] pg 109, line length - {0x380d, 0x96}, // total horizontal size lower 8 bits [7:0] pg 109, line length - {0x380e, 0x04}, // total vertical size higher 5 bits [4:0] pg 109, frame length - {0x380f, 0x9e}, // total vertical size lower 8 bits [7:0] pg 109, frame length - {0x3818, 0xc0}, // timing control reg18 mirror & dkhf pg 110 - {0x381a, 0x3c}, // HS mirror adjustment pg 110 - {0x381c, 0x31}, - {0x381d, 0x8e}, - {0x381e, 0x04}, - {0x381f, 0x92}, - {0x3820, 0x04}, - {0x3821, 0x19}, - {0x3824, 0x01}, - {0x3827, 0x0a}, - {0x401c, 0x46}, - - {0x3003, 0x03}, // reset MIPI and DVP pg 97 - {0x3500, 0x00}, // long exp 1/3 in unit of 1/16 line, pg 38 - {0x3501, 0x49}, // long exp 2/3 in unit of 1/16 line, pg 38 - {0x3502, 0xa0}, // long exp 3/3 in unit of 1/16 line, pg 38 - {0x350a, 0x00}, // gain output to sensor, pg 38 - {0x350b, 0x00}, // gain output to sensor, pg 38 - {0x4801, 0x0f}, // MIPI control01 pg 125 - {0x300e, 0x0c}, // SC_MIPI_SC_CTRL0 pg 73 - {0x4803, 0x50}, // MIPI CTRL3 pg 91 - {0x4800, 0x34}, // MIPI CTRl0 idle and short line pg 89 - - {OV5650_TABLE_END, 0x0000} -}; - -static struct ov5650_reg mode_end[] = { - {0x3212, 0x00}, /* SRM_GROUP_ACCESS (group hold begin) */ - {0x3003, 0x01}, /* reset DVP pg 97 */ - {0x3212, 0x10}, /* SRM_GROUP_ACCESS (group hold end) */ - {0x3212, 0xa0}, /* SRM_GROUP_ACCESS (group hold launch) */ - {0x3008, 0x02}, /* SYSTEM_CTRL0 mipi suspend mask pg 98 */ - - /* {FAST_SETMODE_END, 0}, */ - {OV5650_TABLE_END, 0x0000} -}; - -enum { - OV5650_MODE_2592x1944, - OV5650_MODE_1296x972, - OV5650_MODE_2080x1164 -}; - -static struct ov5650_reg *mode_table[] = { - [OV5650_MODE_2592x1944] = mode_2592x1944, - [OV5650_MODE_1296x972] = mode_1296x972, - [OV5650_MODE_2080x1164] = mode_2080x1164 -}; - -/* 2 regs to program frame length */ -static inline void ov5650_get_frame_length_regs(struct ov5650_reg *regs, - u32 frame_length) -{ - regs->addr = 0x380e; - regs->val = (frame_length >> 8) & 0xff; - (regs + 1)->addr = 0x380f; - (regs + 1)->val = (frame_length) & 0xff; -} - -/* 3 regs to program coarse time */ -static inline void ov5650_get_coarse_time_regs(struct ov5650_reg *regs, - u32 coarse_time) -{ - regs->addr = 0x3500; - regs->val = (coarse_time >> 12) & 0xff; - (regs + 1)->addr = 0x3501; - (regs + 1)->val = (coarse_time >> 4) & 0xff; - (regs + 2)->addr = 0x3502; - (regs + 2)->val = (coarse_time & 0xf) << 4; -} - -/* 1 reg to program gain */ -static inline void ov5650_get_gain_reg(struct ov5650_reg *regs, u16 gain) -{ - regs->addr = 0x350b; - regs->val = gain; -} - -static int ov5650_read_reg(struct i2c_client *client, u16 addr, u8 *val) -{ - int err; - struct i2c_msg msg[2]; - unsigned char data[3]; - - if (!client->adapter) - return -ENODEV; - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = data; - - /* high byte goes out first */ - data[0] = (u8) (addr >> 8);; - data[1] = (u8) (addr & 0xff); - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = data + 2; - err = i2c_transfer(client->adapter, msg, 2); - - if (err != 2) - return -EINVAL; - - *val = data[2]; - - return 0; -} - -static int ov5650_write_reg(struct i2c_client *client, u16 addr, u8 val) -{ - int err; - struct i2c_msg msg; - unsigned char data[3]; - int retry = 0; - - if (!client->adapter) - return -ENODEV; - - data[0] = (u8) (addr >> 8);; - data[1] = (u8) (addr & 0xff); - data[2] = (u8) (val & 0xff); - - msg.addr = client->addr; - msg.flags = 0; - msg.len = 3; - msg.buf = data; - - do { - err = i2c_transfer(client->adapter, &msg, 1); - if (err == 1) - return 0; - retry++; - pr_err("ov5650: i2c transfer failed, retrying %x %x\n", - addr, val); - msleep(3); - } while (retry <= OV5650_MAX_RETRIES); - - return err; -} - -static int ov5650_write_table(struct i2c_client *client, - const struct ov5650_reg table[], - const struct ov5650_reg override_list[], - int num_override_regs) -{ - int err; - const struct ov5650_reg *next; - int i; - u16 val; - - for (next = table; next->addr != OV5650_TABLE_END; next++) { - if (next->addr == OV5650_TABLE_WAIT_MS) { - msleep(next->val); - continue; - } - - val = next->val; - - /* When an override list is passed in, replace the reg */ - /* value to write if the reg is in the list */ - if (override_list) { - for (i = 0; i < num_override_regs; i++) { - if (next->addr == override_list[i].addr) { - val = override_list[i].val; - break; - } - } - } - - err = ov5650_write_reg(client, next->addr, val); - if (err) - return err; - } - return 0; -} - -static int ov5650_set_mode(struct ov5650_info *info, struct ov5650_mode *mode) -{ - int sensor_mode; - int err; - struct ov5650_reg reg_list[6]; - - pr_info("%s: xres %u yres %u framelength %u coarsetime %u gain %u\n", - __func__, mode->xres, mode->yres, mode->frame_length, - mode->coarse_time, mode->gain); - if (mode->xres == 2592 && mode->yres == 1944) - sensor_mode = OV5650_MODE_2592x1944; - else if (mode->xres == 1296 && mode->yres == 972) - sensor_mode = OV5650_MODE_1296x972; - else if (mode->xres == 2080 && mode->yres == 1164) - sensor_mode = OV5650_MODE_2080x1164; - else { - pr_err("%s: invalid resolution supplied to set mode %d %d\n", - __func__, mode->xres, mode->yres); - return -EINVAL; - } - - /* get a list of override regs for the asking frame length, */ - /* coarse integration time, and gain. */ - ov5650_get_frame_length_regs(reg_list, mode->frame_length); - ov5650_get_coarse_time_regs(reg_list + 2, mode->coarse_time); - ov5650_get_gain_reg(reg_list + 5, mode->gain); - - err = ov5650_write_table(info->i2c_client, reset_seq, NULL, 0); - if (err) - return err; - err = ov5650_write_table(info->i2c_client, mode_start, NULL, 0); - - if (err) - return err; - err = ov5650_write_table(info->i2c_client, mode_table[sensor_mode], - reg_list, 6); - if (err) - return err; - err = ov5650_write_table(info->i2c_client, mode_end, NULL, 0); - if (err) - return err; - info->mode = sensor_mode; - return 0; -} - -static int ov5650_set_frame_length(struct ov5650_info *info, u32 frame_length) -{ - struct ov5650_reg reg_list[2]; - int i = 0; - int ret; - - ov5650_get_frame_length_regs(reg_list, frame_length); - - for (i = 0; i < 2; i++) { - ret = ov5650_write_reg(info->i2c_client, reg_list[i].addr, - reg_list[i].val); - if (ret) - return ret; - } - - return 0; -} - -static int ov5650_set_coarse_time(struct ov5650_info *info, u32 coarse_time) -{ - int ret; - - struct ov5650_reg reg_list[3]; - int i = 0; - - ov5650_get_coarse_time_regs(reg_list, coarse_time); - - ret = ov5650_write_reg(info->i2c_client, 0x3212, 0x01); - if (ret) - return ret; - - for (i = 0; i < 3; i++) { - ret = ov5650_write_reg(info->i2c_client, reg_list[i].addr, - reg_list[i].val); - if (ret) - return ret; - } - - ret = ov5650_write_reg(info->i2c_client, 0x3212, 0x11); - if (ret) - return ret; - - ret = ov5650_write_reg(info->i2c_client, 0x3212, 0xa1); - if (ret) - return ret; - - return 0; -} - -static int ov5650_set_gain(struct ov5650_info *info, u16 gain) -{ - int ret; - struct ov5650_reg reg_list; - - ov5650_get_gain_reg(®_list, gain); - - ret = ov5650_write_reg(info->i2c_client, reg_list.addr, reg_list.val); - - return ret; -} - -static int ov5650_get_status(struct ov5650_info *info, u8 *status) -{ - int err; - - *status = 0; - err = ov5650_read_reg(info->i2c_client, 0x002, status); - pr_info("%s: %u %d\n", __func__, *status, err); - return err; -} - -static int ov5650_get_otp(struct ov5650_info *info, void __user *ubuffer) -{ - int err; - uint8_t i; - uint8_t *otpp; - uint16_t computed_crc = 0; - - BUILD_BUG_ON(sizeof(struct ov5650_otp_data) != 256); - - otpp = (uint8_t *)&info->otp_data; - - /* If we've already read the OTP successfully (and CRC matched). - Alternatively this is set also if ignore_otp was provided in - platform data, so we don't try to read OTP on known-bad hardware. */ - if (info->otp_valid) - goto end; - - err = ov5650_write_table(info->i2c_client, otp_reset_seq, NULL, 0); - if (err) - return err; - - /* Read OTP byte by byte. */ - i = (uint8_t) offsetof(struct ov5650_otp_data, sensor_serial_num); - err = ov5650_write_reg(info->i2c_client, 0x3D00, i); - if (err) - return err; - - while (i < offsetof(struct ov5650_otp_data, reserved2)) { - err = ov5650_read_reg(info->i2c_client, 0x3D04, otpp + i); - if (err) - return err; - - computed_crc = crc16_byte(computed_crc, *(otpp + i)); - i++; - } - - /* Serial number is BE. */ - info->otp_data.module_serial_num = - __be32_to_cpu(info->otp_data.module_serial_num); - - /* Read the CRC and compared to computed. */ - i = offsetof(struct ov5650_otp_data, crc); - err = ov5650_write_reg(info->i2c_client, 0x3D00, i); - if (err) - return err; - - while (i < offsetof(struct ov5650_otp_data, reserved3)) { - err = ov5650_read_reg(info->i2c_client, 0x3D04, otpp + i); - if (err) - return err; - i++; - } - - /* CRC is BE, so convert... */ - info->otp_data.crc = __be16_to_cpu(info->otp_data.crc); - if (info->otp_data.crc != computed_crc) { - pr_info("CRC mismatch - OTP 0x%x Calc 0x%x\n", - info->otp_data.crc, computed_crc); - return -EIO; - } - info->otp_valid = true; - -end: - if (copy_to_user(ubuffer, &info->otp_data, sizeof(info->otp_data))) { - pr_info("%s %d\n", __func__, __LINE__); - return -EFAULT; - } - - return 0; -} - -static int ov5650_test_pattern(struct ov5650_info *info, - enum ov5650_test_pattern pattern) -{ - if (pattern >= ARRAY_SIZE(test_pattern_modes)) - return -EINVAL; - - return ov5650_write_table(info->i2c_client, - test_pattern_modes[pattern], - NULL, 0); -} - -static long ov5650_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int err; - struct ov5650_info *info = file->private_data; - - switch (cmd) { - case OV5650_IOCTL_SET_MODE: - { - struct ov5650_mode mode; - if (copy_from_user(&mode, - (const void __user *)arg, - sizeof(struct ov5650_mode))) { - pr_info("%s %d\n", __func__, __LINE__); - return -EFAULT; - } - - return ov5650_set_mode(info, &mode); - } - case OV5650_IOCTL_SET_FRAME_LENGTH: - return ov5650_set_frame_length(info, (u32)arg); - case OV5650_IOCTL_SET_COARSE_TIME: - return ov5650_set_coarse_time(info, (u32)arg); - case OV5650_IOCTL_SET_GAIN: - return ov5650_set_gain(info, (u16)arg); - case OV5650_IOCTL_GET_STATUS: - { - u8 status; - - err = ov5650_get_status(info, &status); - if (err) - return err; - if (copy_to_user((void __user *)arg, &status, - 2)) { - pr_info("%s %d\n", __func__, __LINE__); - return -EFAULT; - } - return 0; - } - case OV5650_IOCTL_GET_OTP: - { - err = ov5650_get_otp(info, (void __user *) arg); - if (err) - pr_err("%s %d %d\n", __func__, __LINE__, err); - return err; - } - case OV5650_IOCTL_TEST_PATTERN: - { - err = ov5650_test_pattern(info, (enum ov5650_test_pattern) arg); - if (err) - pr_err("%s %d %d\n", __func__, __LINE__, err); - return err; - } - default: - return -EINVAL; - } - return 0; -} - -static struct ov5650_info *info; - -static int ov5650_open(struct inode *inode, struct file *file) -{ - u8 status; - - pr_info("%s\n", __func__); - file->private_data = info; - if (info->pdata && info->pdata->power_on) - info->pdata->power_on(); - ov5650_get_status(info, &status); - return 0; -} - -int ov5650_release(struct inode *inode, struct file *file) -{ - pr_info("%s\n", __func__); - if (info->pdata && info->pdata->power_off) - info->pdata->power_off(); - file->private_data = NULL; - return 0; -} - - -static const struct file_operations ov5650_fileops = { - .owner = THIS_MODULE, - .open = ov5650_open, - .unlocked_ioctl = ov5650_ioctl, - .release = ov5650_release, -}; - -static struct miscdevice ov5650_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "ov5650", - .fops = &ov5650_fileops, -}; - -static int ov5650_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err; - - pr_info("ov5650: probing sensor.\n"); - - info = kzalloc(sizeof(struct ov5650_info), GFP_KERNEL); - if (!info) { - pr_err("ov5650: Unable to allocate memory!\n"); - return -ENOMEM; - } - - err = misc_register(&ov5650_device); - if (err) { - pr_err("ov5650: Unable to register misc device!\n"); - kfree(info); - return err; - } - - info->pdata = client->dev.platform_data; - info->i2c_client = client; - if (info->pdata->ignore_otp) - info->otp_valid = true; - - i2c_set_clientdata(client, info); - return 0; -} - -static int ov5650_remove(struct i2c_client *client) -{ - struct ov5650_info *info; - info = i2c_get_clientdata(client); - misc_deregister(&ov5650_device); - kfree(info); - return 0; -} - -static const struct i2c_device_id ov5650_id[] = { - { "ov5650", 0 }, - { }, -}; - -MODULE_DEVICE_TABLE(i2c, ov5650_id); - -static struct i2c_driver ov5650_i2c_driver = { - .driver = { - .name = "ov5650", - .owner = THIS_MODULE, - }, - .probe = ov5650_probe, - .remove = ov5650_remove, - .id_table = ov5650_id, -}; - -static int __init ov5650_init(void) -{ - pr_info("ov5650 sensor driver loading\n"); - return i2c_add_driver(&ov5650_i2c_driver); -} - -static void __exit ov5650_exit(void) -{ - i2c_del_driver(&ov5650_i2c_driver); -} - -module_init(ov5650_init); -module_exit(ov5650_exit); - diff --git a/drivers/media/video/tegra/soc2030.c b/drivers/media/video/tegra/soc2030.c deleted file mode 100644 index a4c98a586cf9..000000000000 --- a/drivers/media/video/tegra/soc2030.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - * soc2030.c - soc2030 sensor driver - * - * Copyright (C) 2010 Google Inc. - * - * Contributors: - * Rebecca Schultz Zavin - * - * Leverage OV9640.c - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -struct soc2030_info { - int mode; - struct mutex lock; - struct i2c_client *i2c_client; - struct soc2030_platform_data *pdata; -}; - -/* 10-30fps */ -#define INDEX_30FPS 4 -#define INDEX_24FPS 5 -#define INDEX_20FPS 6 -#define INDEX_17FPS 7 -#define INDEX_15FPS 8 -#define INDEX_13FPS 9 -#define INDEX_12FPS 10 -#define INDEX_11FPS 11 -#define INDEX_10FPS 12 - -/* - * SetMode Sequence for 1600X1200/800X600 base settings. - * Phase 0. Sensor Dependent. - * This sequence should set sensor for Full/Qtr res - * This is usually given by the FAE or the sensor vendor. - * 1600X1200 15fps (Max), 800X600 30fps (Max) - */ -static struct soc2030_regs base_mode[] = { - {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/ - {WRITE_REG_DATA, 0x990, 0x0320}, /* = 800*/ - {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/ - {WRITE_REG_DATA, 0x990, 0x0258}, /* = 600*/ - {WRITE_REG_DATA, 0x98C, 0x2707}, /*Output Width (B)*/ - {WRITE_REG_DATA, 0x990, 0x0640}, /* = 1600*/ - {WRITE_REG_DATA, 0x98C, 0x2709}, /*Output Height (B)*/ - {WRITE_REG_DATA, 0x990, 0x04B0}, /* = 1200*/ - {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/ - {WRITE_REG_DATA, 0x990, 0x04BD}, /* = 1213*/ - {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/ - {WRITE_REG_DATA, 0x990, 0x064D}, /* = 1613*/ - {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/ - {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/ - {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/ - {WRITE_REG_DATA, 0x990, 0x046C}, /* = 1132*/ - {WRITE_REG_DATA, 0x98C, 0x2719}, /*fine_corr (A)*/ - {WRITE_REG_DATA, 0x990, 0x005A}, /* = 90*/ - {WRITE_REG_DATA, 0x98C, 0x271B}, /*sensor_fine_IT_min (A)*/ - {WRITE_REG_DATA, 0x990, 0x01BE}, /* = 446*/ - {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/ - {WRITE_REG_DATA, 0x990, 0x0131}, /* = 305*/ - {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/ - {WRITE_REG_DATA, 0x990, 0x02B3}, /* = 691*/ - {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/ - {WRITE_REG_DATA, 0x990, 0x07EA}, /* = 2026*/ - {WRITE_REG_DATA, 0x98C, 0x2723}, /*Row Start (B)*/ - {WRITE_REG_DATA, 0x990, 0x0004}, /* = 4*/ - {WRITE_REG_DATA, 0x98C, 0x2725}, /*Column Start (B)*/ - {WRITE_REG_DATA, 0x990, 0x0004}, /* = 4*/ - {WRITE_REG_DATA, 0x98C, 0x2727}, /*Row End (B)*/ - {WRITE_REG_DATA, 0x990, 0x04BB}, /* = 1211*/ - {WRITE_REG_DATA, 0x98C, 0x2729}, /*Column End (B)*/ - {WRITE_REG_DATA, 0x990, 0x064B}, /* = 1611*/ - {WRITE_REG_DATA, 0x98C, 0x272B}, /*Row Speed (B)*/ - {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/ - {WRITE_REG_DATA, 0x98C, 0x272D}, /*Read Mode (B)*/ - {WRITE_REG_DATA, 0x990, 0x0024}, /* = 36*/ - {WRITE_REG_DATA, 0x98C, 0x272F}, /*sfine_corr (B)*/ - {WRITE_REG_DATA, 0x990, 0x003A}, /* = 58*/ - {WRITE_REG_DATA, 0x98C, 0x2731}, /*fine_IT_min (B)*/ - {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/ - {WRITE_REG_DATA, 0x98C, 0x2733}, /*fine_IT_max_mrgn (B)*/ - {WRITE_REG_DATA, 0x990, 0x008B}, /* = 139*/ - {WRITE_REG_DATA, 0x98C, 0x2735}, /*Frame Lines (B)*/ - {WRITE_REG_DATA, 0x990, 0x050D}, /* = 1293*/ - {WRITE_REG_DATA, 0x98C, 0x2737}, /*Line Length (B)*/ - {WRITE_REG_DATA, 0x990, 0x08A9}, /* = 2217*/ - {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x031F}, /* = 799*/ - {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0257}, /* = 599*/ - {WRITE_REG_DATA, 0x98C, 0x2747}, /*Crop_X0 (B)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x2749}, /*Crop_X1 (B)*/ - {WRITE_REG_DATA, 0x990, 0x063F}, /* = 1599*/ - {WRITE_REG_DATA, 0x98C, 0x274B}, /*Crop_Y0 (B)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x274D}, /*Crop_Y1 (B)*/ - {WRITE_REG_DATA, 0x990, 0x04AF}, /* = 1199*/ - {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/ - {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/ - {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/ - {WRITE_REG_DATA, 0x990, 0x002A}, /* = 42*/ - {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/ - {WRITE_REG_DATA, 0x990, 0x002C}, /* = 44*/ - {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/ - {WRITE_REG_DATA, 0x990, 0x0032}, /* = 50*/ - {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/ - {WRITE_REG_DATA, 0x990, 0x0034}, /* = 52*/ - {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/ - {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00CF}, /* = 207*/ - {WRITE_REG_DATA, 0x98C, 0x2415}, /*R9_Step_60 (B)*/ - {WRITE_REG_DATA, 0x990, 0x009E}, /* = 158*/ - {WRITE_REG_DATA, 0x98C, 0x2417}, /*R9_Step_50 (B)*/ - {WRITE_REG_DATA, 0x990, 0x00BD}, /* = 189*/ - {WRITE_REG_DATA, 0x98C, 0xA404}, /*FD Mode*/ - {WRITE_REG_DATA, 0x990, 0x0010}, /* = 16*/ - {WRITE_REG_DATA, 0x98C, 0xA40D}, /*Stat_min*/ - {WRITE_REG_DATA, 0x990, 0x0002}, /* = 2*/ - {WRITE_REG_DATA, 0x98C, 0xA40E}, /*Stat_max*/ - {WRITE_REG_DATA, 0x990, 0x0003}, /* = 3*/ - {WRITE_REG_DATA, 0x98C, 0xA410}, /*Min_amplitude*/ - {WRITE_REG_DATA, 0x990, 0x000A}, /* = 10*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * Refresh Sequencer Mode - */ -static struct soc2030_regs refresh_mode[] = { - {WRITE_REG_DATA, 0x098C, 0xa103}, /* Refresh Mode */ - {WRITE_REG_DATA, 0x0990, 0x0006}, - {POLL_VAR_DATA, 0xa103, 0x0000}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * Refresh Sequencer State - */ -static struct soc2030_regs refresh_state[] = { - {WRITE_REG_DATA, 0x098C, 0xa103}, /* Refresh Seq */ - {WRITE_REG_DATA, 0x0990, 0x0005}, - {POLL_VAR_DATA, 0xa103, 0x0000}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for context A (800X600, preview). - * Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - * 800X600 15-30fps - */ -static struct soc2030_regs mode_800x600[] = { - {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/ - {WRITE_REG_DATA, 0x990, 0x0320}, /* = 800*/ - {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/ - {WRITE_REG_DATA, 0x990, 0x0258}, /* = 600*/ - {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/ - {WRITE_REG_DATA, 0x990, 0x04BD}, /* = 1213*/ - {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/ - {WRITE_REG_DATA, 0x990, 0x064D}, /* = 1613*/ - {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/ - {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/ - {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/ - {WRITE_REG_DATA, 0x990, 0x046C}, /* = 1132*/ - {WRITE_REG_DATA, 0x98C, 0x2719}, /*fine_corr (A)*/ - {WRITE_REG_DATA, 0x990, 0x005A}, /* = 90*/ - {WRITE_REG_DATA, 0x98C, 0x271B}, /*_fine_IT_min (A)*/ - {WRITE_REG_DATA, 0x990, 0x01BE}, /* = 446*/ - {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/ - {WRITE_REG_DATA, 0x990, 0x0131}, /* = 305*/ - {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/ - {WRITE_REG_DATA, 0x990, 0x02B3}, /* = 691*/ - {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/ - {WRITE_REG_DATA, 0x990, 0x07EA}, /* = 2026*/ - {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x031F}, /* = 799*/ - {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0257}, /* = 599*/ - {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/ - {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/ - {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/ - {WRITE_REG_DATA, 0x990, 0x002A}, /* = 42*/ - {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/ - {WRITE_REG_DATA, 0x990, 0x002C}, /* = 44*/ - {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/ - {WRITE_REG_DATA, 0x990, 0x0032}, /* = 50*/ - {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/ - {WRITE_REG_DATA, 0x990, 0x0034}, /* = 52*/ - {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00AD}, /* = 173*/ - {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00CF}, /* = 207*/ - {WRITE_REG_BIT_L, 0x3040, 0x1000}, /* Disable Bin Sum */ - {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, - {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */ - {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP off in cntx B */ - {WRITE_REG_DATA, 0x0990, 0x0000}, - {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context A preview */ - {WRITE_REG_DATA, 0x0990, 0x0001}, - {POLL_VAR_DATA, 0xa104, 0x0003}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for context B (1600X1200, capture). - * Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - * 1600X1200 10-15fps - */ -static struct soc2030_regs mode_1600x1200[] = { - {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */ - {WRITE_REG_DATA, 0x0990, INDEX_10FPS}, - {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */ - {WRITE_REG_DATA, 0x0990, INDEX_10FPS}, /* 10-15 fps */ - {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP in Context B */ - {WRITE_REG_DATA, 0x0990, 0x0072}, - {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context B full */ - {WRITE_REG_DATA, 0x0990, 0x0002}, - {POLL_VAR_DATA, 0xa104, 0x0007}, - {POLL_VAR_DATA, 0xa103, 0x0000}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for 720P in context A (1280X720). - * Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - * 1280X720 15-30fps - */ -static struct soc2030_regs mode_1280x720[] = { - {WRITE_REG_DATA, 0x98C, 0x2703}, /*Output Width (A)*/ - {WRITE_REG_DATA, 0x990, 0x0500}, /* = 1280*/ - {WRITE_REG_DATA, 0x98C, 0x2705}, /*Output Height (A)*/ - {WRITE_REG_DATA, 0x990, 0x02D0}, /* = 720*/ - {WRITE_REG_DATA, 0x98C, 0x270D}, /*Row Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/ - {WRITE_REG_DATA, 0x98C, 0x270F}, /*Column Start (A)*/ - {WRITE_REG_DATA, 0x990, 0x00A6}, /* = 166*/ - {WRITE_REG_DATA, 0x98C, 0x2711}, /*Row End (A)*/ - {WRITE_REG_DATA, 0x990, 0x03CD}, /* = 973*/ - {WRITE_REG_DATA, 0x98C, 0x2713}, /*Column End (A)*/ - {WRITE_REG_DATA, 0x990, 0x05AD}, /* = 1453*/ - {WRITE_REG_DATA, 0x98C, 0x2715}, /*Row Speed (A)*/ - {WRITE_REG_DATA, 0x990, 0x0111}, /* = 273*/ - {WRITE_REG_DATA, 0x98C, 0x2717}, /*Read Mode (A)*/ - {WRITE_REG_DATA, 0x990, 0x0024}, /* = 36*/ - {WRITE_REG_DATA, 0x98C, 0x2719}, /*_fine_correction (A)*/ - {WRITE_REG_DATA, 0x990, 0x003A}, /* = 58*/ - {WRITE_REG_DATA, 0x98C, 0x271B}, /*fine_IT_min (A)*/ - {WRITE_REG_DATA, 0x990, 0x00F6}, /* = 246*/ - {WRITE_REG_DATA, 0x98C, 0x271D}, /*fine_IT_max_mrgn (A)*/ - {WRITE_REG_DATA, 0x990, 0x008B}, /* = 139*/ - {WRITE_REG_DATA, 0x98C, 0x271F}, /*Frame Lines (A)*/ - {WRITE_REG_DATA, 0x990, 0x032D}, /* = 813*/ - {WRITE_REG_DATA, 0x98C, 0x2721}, /*Line Length (A)*/ - {WRITE_REG_DATA, 0x990, 0x06BA}, /* = 1722*/ - {WRITE_REG_DATA, 0x98C, 0x2739}, /*Crop_X0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273B}, /*Crop_X1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x04FF}, /* = 1279*/ - {WRITE_REG_DATA, 0x98C, 0x273D}, /*Crop_Y0 (A)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x273F}, /*Crop_Y1 (A)*/ - {WRITE_REG_DATA, 0x990, 0x02CF}, /* = 719*/ - {WRITE_REG_DATA, 0x98C, 0x2747}, /*Crop_X0 (B)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x2749}, /*Crop_X1 (B)*/ - {WRITE_REG_DATA, 0x990, 0x063F}, /* = 1599*/ - {WRITE_REG_DATA, 0x98C, 0x274B}, /*Crop_Y0 (B)*/ - {WRITE_REG_DATA, 0x990, 0x0000}, /* = 0*/ - {WRITE_REG_DATA, 0x98C, 0x274D}, /*Crop_Y1 (B)*/ - {WRITE_REG_DATA, 0x990, 0x04AF}, /* = 1199*/ - {WRITE_REG_DATA, 0x98C, 0x222D}, /*R9 Step*/ - {WRITE_REG_DATA, 0x990, 0x00CB}, /* = 203*/ - {WRITE_REG_DATA, 0x98C, 0xA408}, /*search_f1_50*/ - {WRITE_REG_DATA, 0x990, 0x0031}, /* = 49*/ - {WRITE_REG_DATA, 0x98C, 0xA409}, /*search_f2_50*/ - {WRITE_REG_DATA, 0x990, 0x0033}, /* = 51*/ - {WRITE_REG_DATA, 0x98C, 0xA40A}, /*search_f1_60*/ - {WRITE_REG_DATA, 0x990, 0x003C}, /* = 60*/ - {WRITE_REG_DATA, 0x98C, 0xA40B}, /*search_f2_60*/ - {WRITE_REG_DATA, 0x990, 0x003E}, /* = 62*/ - {WRITE_REG_DATA, 0x98C, 0x2411}, /*R9_Step_60 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00CB}, /* = 203*/ - {WRITE_REG_DATA, 0x98C, 0x2413}, /*R9_Step_50 (A)*/ - {WRITE_REG_DATA, 0x990, 0x00F4}, /* = 244*/ - {WRITE_REG_DATA, 0x98C, 0xA404}, /*FD Mode*/ - {WRITE_REG_DATA, 0x990, 0x0010}, /* = 16*/ - {WRITE_REG_DATA, 0x98C, 0xA40D}, /*Stat_min*/ - {WRITE_REG_DATA, 0x990, 0x0002}, /* = 2*/ - {WRITE_REG_DATA, 0x98C, 0xA40E}, /*Stat_max*/ - {WRITE_REG_DATA, 0x990, 0x0003}, /* = 3*/ - {WRITE_REG_DATA, 0x98C, 0xA410}, /*Min_amplitude*/ - {WRITE_REG_DATA, 0x990, 0x000A}, /* = 10*/ - {WRITE_REG_BIT_H, 0x3040, 0x1000}, /* Enable Bin Summing */ - {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, - {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */ - {WRITE_REG_DATA, 0x098C, 0xA115}, /* ISP off in cntx B */ - {WRITE_REG_DATA, 0x0990, 0x0000}, - {WRITE_REG_DATA, 0x098C, 0xA103}, /* Context A preview */ - {WRITE_REG_DATA, 0x0990, 0x0001}, - {POLL_VAR_DATA, 0xa104, 0x0003}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for PLL. Phase 0. Sensor Dependent. - * This sequence should configure the PLL. - * This is usually given by the FAE or the sensor vendor. - * 24MCLK_81SCLK - */ -static struct soc2030_regs pll_table[] = { - {WRITE_REG_DATA, 0x001e, 0x0503}, /*Pad Slew rate*/ - {WRITE_REG_DATA, 0x0014, 0x2545}, /*PLL_CONTROL*/ - {WRITE_REG_DATA, 0x0010, 0x0a56}, /*PLL_DIVIDERS 43mhz*/ - {WRITE_REG_DATA, 0x0012, 0x10F7}, /*PLL_P_DIVIDERS*/ - {WRITE_REG_DATA, 0x0014, 0x2547}, /*PLL_CONTROL*/ - {WRITE_REG_DATA, 0x0014, 0x2447}, /*PLL_CONTROL*/ - {DELAY_MS, 0x0000, 0x0010}, /*wait for pll lck*/ - {WRITE_REG_DATA, 0x0014, 0x2047}, /*PLL_CONTROL*/ - {WRITE_REG_BIT_L, 0x0014, 0x0001}, /*enable the pll*/ - {WRITE_REG_BIT_H, 0x001a, 0x0200}, /*en parallel out*/ - {WRITE_REG_BIT_L, 0x001a, 0x0004}, /*disable mipi*/ - {WRITE_REG_BIT_H, 0x0018, 0x0004}, /*disable mcu*/ - {WRITE_REG_BIT_L, 0x0018, 0x0001}, /*leave standby*/ - {POLL_REG_BIT_L, 0x0018, 0x4000}, /*wait for !stdby*/ - {WRITE_REG_DATA, 0x321C, 0x0000}, /*By Pass TxFIFO = 0*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for errata. Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs WakeMcuSequence[] = { - {WRITE_VAR_DATA, 0x2755, 0x0200}, /*Invert Pclk*/ - {WRITE_VAR_DATA, 0x2757, 0x0200}, /*Invert Pclk*/ - {WRITE_REG_BIT_L, 0x0018, 0x0004}, /*enable the MCU*/ - {POLL_VAR_DATA, 0xa104, 0x0003}, /*wait for preview*/ - {POLL_REG_BIT_L, 0x0018, 0x4000}, /*wait for !stdby*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for errata. Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetRev2ErrataSequence[] = { - {WRITE_REG_DATA, 0x3084, 0x240C}, - {WRITE_REG_DATA, 0x3092, 0x0A4C}, - {WRITE_REG_DATA, 0x3094, 0x4C4C}, - {WRITE_REG_DATA, 0x3096, 0x4C54}, - {REG_TABLE_END, 0x0000, 0x0000} - -}; - - -/* - * SetMode Sequence for LCC. Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetLensCorrectionSequence[] = { - {WRITE_REG_DATA, 0x3210, 0x01B8}, /*Enable gamma/sharpen/ccm/LC*/ - {REG_TABLE_END, 0x0000, 0x0000} - -}; -/* - * SetMode Sequence for low light. Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetLowLightSequence[] = { - {WRITE_REG_DATA, 0x098C, 0x2B28}, /*MCU_ADDRESS[HG_LL_BRTNSTRT]*/ - {WRITE_REG_DATA, 0x0990, 0x35E8}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0x2B2A}, /*MCU_ADDRESS [HG_LL_BRTNSSTP]*/ - {WRITE_REG_DATA, 0x0990, 0xB3B0}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB20}, /*MCU_ADDRESS [HG_LL_SAT1]*/ - {WRITE_REG_DATA, 0x0990, 0x004B}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB24}, /*MCU_ADDRESS [HG_LL_SAT2]*/ - {WRITE_REG_DATA, 0x0990, 0x0000}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB25}, /*MCU_ADDRESS[HG_LL_INTRPTHR2]*/ - {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB30}, /*MCU_ADDRESS [HG_NR_STOP_R]*/ - {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB31}, /*MCU_ADDRESS [HG_NR_STOP_G]*/ - {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB32}, /*MCU_ADDRESS [HG_NR_STOP_B]*/ - {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB33}, /*MCU_ADDRESS [HG_NR_STOP_OL]*/ - {WRITE_REG_DATA, 0x0990, 0x0057}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB34}, /*MCU_ADDRESS[HG_NR_GAINSTRT]*/ - {WRITE_REG_DATA, 0x0990, 0x0080}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB35}, /*MCU_ADDRESS [HG_NR_GAINSTP]*/ - {WRITE_REG_DATA, 0x0990, 0x00FF}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB36}, /*MCU_ADDRESS[HG_CLSTERDC_TH]*/ - {WRITE_REG_DATA, 0x0990, 0x0014}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xAB37}, /*MCU_ADDR[HG_GAMA_MORPH_CTRL]*/ - {WRITE_REG_DATA, 0x0990, 0x0003}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0x2B38}, /*MCU_ADDR[HG_GAMASTARTMORPH]*/ - {WRITE_REG_DATA, 0x0990, 0x32C8}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0x2B3A}, /*MCU_ADDRESS[HG_GAMASTPMORPH]*/ - {WRITE_REG_DATA, 0x0990, 0x7918}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0x2B62}, /*MCU_ADDRESS[HG_FTB_STRT_BM]*/ - {WRITE_REG_DATA, 0x0990, 0xFFFE}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0x2B64}, /*MCU_ADDRESS[HG_FTB_STP_BM]*/ - {WRITE_REG_DATA, 0x0990, 0xFFFF}, /*MCU_DATA_0 {SEQ_END,0x0000}*/ - {REG_TABLE_END, 0x0000, 0x0000} - -}; -/* - * SetMode Sequence for CCM. Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetCCMCommonSequence[] = { - {WRITE_REG_DATA, 0x098c, 0xA11F}, /*turn on AWB in preview*/ - {WRITE_REG_DATA, 0x0990, 0x0001}, - {WRITE_REG_DATA, 0x098c, 0xA20B}, /*AE_MIN_INDEX*/ - {WRITE_REG_DATA, 0x0990, 0x0000}, - {WRITE_REG_DATA, 0x098C, 0xA215}, /* Fix FPS */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, - {WRITE_REG_DATA, 0x098C, 0xA20C}, /* AE_MAX_INDEX */ - {WRITE_REG_DATA, 0x0990, INDEX_15FPS}, /* 15-30 FPS */ - {REG_TABLE_END, 0x0000, 0x0000} - -}; - -/* - * SetMode Sequence for AWB. Phase 0. Sensor Dependent. - * Place your module specific tuning here. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetCCMAutoSequence[] = { - - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * SetMode Sequence for noise optimizations. - * Phase 0. Sensor Dependent. - * Place your module specific tuning here. - * This is usually given by the FAE or the sensor vendor. - */ -static struct soc2030_regs SetDenoiseSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} - -}; - -/* - * SetMode Sequence for vendor's patch. - * Phase 0. Sensor Dependent. - * This is usually given by the FAE or the sensor vendor. - * K25A_REV03_PATCH01_REV3 - */ -static struct soc2030_regs SetRev3PatchSequence[] = { - {WRITE_REG_DATA, 0x098C, 0x0415}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0xF601}, - {WRITE_REG_DATA, 0x0992, 0x42C1}, - {WRITE_REG_DATA, 0x0994, 0x0326}, - {WRITE_REG_DATA, 0x0996, 0x11F6}, - {WRITE_REG_DATA, 0x0998, 0x0143}, - {WRITE_REG_DATA, 0x099A, 0xC104}, - {WRITE_REG_DATA, 0x099C, 0x260A}, - {WRITE_REG_DATA, 0x099E, 0xCC04}, - {WRITE_REG_DATA, 0x098C, 0x0425}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x33BD}, - {WRITE_REG_DATA, 0x0992, 0xA362}, - {WRITE_REG_DATA, 0x0994, 0xBD04}, - {WRITE_REG_DATA, 0x0996, 0x3339}, - {WRITE_REG_DATA, 0x0998, 0xC6FF}, - {WRITE_REG_DATA, 0x099A, 0xF701}, - {WRITE_REG_DATA, 0x099C, 0x6439}, - {WRITE_REG_DATA, 0x099E, 0xFE01}, - {WRITE_REG_DATA, 0x098C, 0x0435}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x6918}, - {WRITE_REG_DATA, 0x0992, 0xCE03}, - {WRITE_REG_DATA, 0x0994, 0x25CC}, - {WRITE_REG_DATA, 0x0996, 0x0013}, - {WRITE_REG_DATA, 0x0998, 0xBDC2}, - {WRITE_REG_DATA, 0x099A, 0xB8CC}, - {WRITE_REG_DATA, 0x099C, 0x0489}, - {WRITE_REG_DATA, 0x099E, 0xFD03}, - {WRITE_REG_DATA, 0x098C, 0x0445}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x27CC}, - {WRITE_REG_DATA, 0x0992, 0x0325}, - {WRITE_REG_DATA, 0x0994, 0xFD01}, - {WRITE_REG_DATA, 0x0996, 0x69FE}, - {WRITE_REG_DATA, 0x0998, 0x02BD}, - {WRITE_REG_DATA, 0x099A, 0x18CE}, - {WRITE_REG_DATA, 0x099C, 0x0339}, - {WRITE_REG_DATA, 0x099E, 0xCC00}, - {WRITE_REG_DATA, 0x098C, 0x0455}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x11BD}, - {WRITE_REG_DATA, 0x0992, 0xC2B8}, - {WRITE_REG_DATA, 0x0994, 0xCC04}, - {WRITE_REG_DATA, 0x0996, 0xC8FD}, - {WRITE_REG_DATA, 0x0998, 0x0347}, - {WRITE_REG_DATA, 0x099A, 0xCC03}, - {WRITE_REG_DATA, 0x099C, 0x39FD}, - {WRITE_REG_DATA, 0x099E, 0x02BD}, - {WRITE_REG_DATA, 0x098C, 0x0465}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0xDE00}, - {WRITE_REG_DATA, 0x0992, 0x18CE}, - {WRITE_REG_DATA, 0x0994, 0x00C2}, - {WRITE_REG_DATA, 0x0996, 0xCC00}, - {WRITE_REG_DATA, 0x0998, 0x37BD}, - {WRITE_REG_DATA, 0x099A, 0xC2B8}, - {WRITE_REG_DATA, 0x099C, 0xCC04}, - {WRITE_REG_DATA, 0x099E, 0xEFDD}, - {WRITE_REG_DATA, 0x098C, 0x0475}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0xE6CC}, - {WRITE_REG_DATA, 0x0992, 0x00C2}, - {WRITE_REG_DATA, 0x0994, 0xDD00}, - {WRITE_REG_DATA, 0x0996, 0xC601}, - {WRITE_REG_DATA, 0x0998, 0xF701}, - {WRITE_REG_DATA, 0x099A, 0x64C6}, - {WRITE_REG_DATA, 0x099C, 0x03F7}, - {WRITE_REG_DATA, 0x099E, 0x0165}, - {WRITE_REG_DATA, 0x098C, 0x0485}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x7F01}, - {WRITE_REG_DATA, 0x0992, 0x6639}, - {WRITE_REG_DATA, 0x0994, 0x3C3C}, - {WRITE_REG_DATA, 0x0996, 0x3C34}, - {WRITE_REG_DATA, 0x0998, 0xCC32}, - {WRITE_REG_DATA, 0x099A, 0x3EBD}, - {WRITE_REG_DATA, 0x099C, 0xA558}, - {WRITE_REG_DATA, 0x099E, 0x30ED}, - {WRITE_REG_DATA, 0x098C, 0x0495}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x04BD}, - {WRITE_REG_DATA, 0x0992, 0xB2D7}, - {WRITE_REG_DATA, 0x0994, 0x30E7}, - {WRITE_REG_DATA, 0x0996, 0x06CC}, - {WRITE_REG_DATA, 0x0998, 0x323E}, - {WRITE_REG_DATA, 0x099A, 0xED00}, - {WRITE_REG_DATA, 0x099C, 0xEC04}, - {WRITE_REG_DATA, 0x099E, 0xBDA5}, - {WRITE_REG_DATA, 0x098C, 0x04A5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x44CC}, - {WRITE_REG_DATA, 0x0992, 0x3244}, - {WRITE_REG_DATA, 0x0994, 0xBDA5}, - {WRITE_REG_DATA, 0x0996, 0x585F}, - {WRITE_REG_DATA, 0x0998, 0x30ED}, - {WRITE_REG_DATA, 0x099A, 0x02CC}, - {WRITE_REG_DATA, 0x099C, 0x3244}, - {WRITE_REG_DATA, 0x099E, 0xED00}, - {WRITE_REG_DATA, 0x098C, 0x04B5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0xF601}, - {WRITE_REG_DATA, 0x0992, 0xD54F}, - {WRITE_REG_DATA, 0x0994, 0xEA03}, - {WRITE_REG_DATA, 0x0996, 0xAA02}, - {WRITE_REG_DATA, 0x0998, 0xBDA5}, - {WRITE_REG_DATA, 0x099A, 0x4430}, - {WRITE_REG_DATA, 0x099C, 0xE606}, - {WRITE_REG_DATA, 0x099E, 0x3838}, - {WRITE_REG_DATA, 0x098C, 0x04C5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x3831}, - {WRITE_REG_DATA, 0x0992, 0x39BD}, - {WRITE_REG_DATA, 0x0994, 0xD661}, - {WRITE_REG_DATA, 0x0996, 0xF602}, - {WRITE_REG_DATA, 0x0998, 0xF4C1}, - {WRITE_REG_DATA, 0x099A, 0x0126}, - {WRITE_REG_DATA, 0x099C, 0x0BFE}, - {WRITE_REG_DATA, 0x099E, 0x02BD}, - {WRITE_REG_DATA, 0x098C, 0x04D5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0xEE10}, - {WRITE_REG_DATA, 0x0992, 0xFC02}, - {WRITE_REG_DATA, 0x0994, 0xF5AD}, - {WRITE_REG_DATA, 0x0996, 0x0039}, - {WRITE_REG_DATA, 0x0998, 0xF602}, - {WRITE_REG_DATA, 0x099A, 0xF4C1}, - {WRITE_REG_DATA, 0x099C, 0x0226}, - {WRITE_REG_DATA, 0x099E, 0x0AFE}, - {WRITE_REG_DATA, 0x098C, 0x04E5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x02BD}, - {WRITE_REG_DATA, 0x0992, 0xEE10}, - {WRITE_REG_DATA, 0x0994, 0xFC02}, - {WRITE_REG_DATA, 0x0996, 0xF7AD}, - {WRITE_REG_DATA, 0x0998, 0x0039}, - {WRITE_REG_DATA, 0x099A, 0x3CBD}, - {WRITE_REG_DATA, 0x099C, 0xB059}, - {WRITE_REG_DATA, 0x099E, 0xCC00}, - {WRITE_REG_DATA, 0x098C, 0x04F5}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x28BD}, - {WRITE_REG_DATA, 0x0992, 0xA558}, - {WRITE_REG_DATA, 0x0994, 0x8300}, - {WRITE_REG_DATA, 0x0996, 0x0027}, - {WRITE_REG_DATA, 0x0998, 0x0BCC}, - {WRITE_REG_DATA, 0x099A, 0x0026}, - {WRITE_REG_DATA, 0x099C, 0x30ED}, - {WRITE_REG_DATA, 0x099E, 0x00C6}, - {WRITE_REG_DATA, 0x098C, 0x0505}, /*MCU_ADDRESS*/ - {WRITE_REG_DATA, 0x0990, 0x03BD}, - {WRITE_REG_DATA, 0x0992, 0xA544}, - {WRITE_REG_DATA, 0x0994, 0x3839}, - {WRITE_REG_DATA, 0x098C, 0x2006}, /*MCU_ADDRESS [MON_ARG1]*/ - {WRITE_REG_DATA, 0x0990, 0x0415}, /*MCU_DATA_0*/ - {WRITE_REG_DATA, 0x098C, 0xA005}, /*MCU_ADDRESS [MON_CMD]*/ - {WRITE_REG_DATA, 0x0990, 0x0001}, /*MCU_DATA_0*/ - {DELAY_MS, 0x0000, 100}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -/* - * Stock AWB CCM from Aptina Demo2 Dev kit. - */ -static struct soc2030_regs WbAutoSequence[] = { - {WRITE_REG_DATA, 0x098C, 0x2306}, /* [AWB_CCM_L_0] */ - {WRITE_REG_DATA, 0x0990, 0x0180}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2308}, /* [AWB_CCM_L_1] */ - {WRITE_REG_DATA, 0x0990, 0xFF00}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x230A}, /* [AWB_CCM_L_2] */ - {WRITE_REG_DATA, 0x0990, 0x0080}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x230C}, /* [AWB_CCM_L_3] */ - {WRITE_REG_DATA, 0x0990, 0xFF66}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x230E}, /* [AWB_CCM_L_4] */ - {WRITE_REG_DATA, 0x0990, 0x0180}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2310}, /* [AWB_CCM_L_5] */ - {WRITE_REG_DATA, 0x0990, 0xFFEE}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2312}, /* [AWB_CCM_L_6] */ - {WRITE_REG_DATA, 0x0990, 0xFFCD}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2314}, /* [AWB_CCM_L_7] */ - {WRITE_REG_DATA, 0x0990, 0xFECD}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2316}, /* [AWB_CCM_L_8] */ - {WRITE_REG_DATA, 0x0990, 0x019A}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2318}, /* [AWB_CCM_L_9] */ - {WRITE_REG_DATA, 0x0990, 0x0020}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x231A}, /* [AWB_CCM_L_10] */ - {WRITE_REG_DATA, 0x0990, 0x0033}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x231C}, /* [AWB_CCM_RL_0] */ - {WRITE_REG_DATA, 0x0990, 0x0100}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x231E}, /* [AWB_CCM_RL_1] */ - {WRITE_REG_DATA, 0x0990, 0xFF9A}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2320}, /* [AWB_CCM_RL_2] */ - {WRITE_REG_DATA, 0x0990, 0x0000}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2322}, /* [AWB_CCM_RL_3] */ - {WRITE_REG_DATA, 0x0990, 0x004D}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2324}, /* [AWB_CCM_RL_4] */ - {WRITE_REG_DATA, 0x0990, 0xFFCD}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2326}, /* [AWB_CCM_RL_5] */ - {WRITE_REG_DATA, 0x0990, 0xFFB8}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2328}, /* [AWB_CCM_RL_6] */ - {WRITE_REG_DATA, 0x0990, 0x004D}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x232A}, /* [AWB_CCM_RL_7] */ - {WRITE_REG_DATA, 0x0990, 0x0080}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x232C}, /* [AWB_CCM_RL_8] */ - {WRITE_REG_DATA, 0x0990, 0xFF66}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x232E}, /* [AWB_CCM_RL_9] */ - {WRITE_REG_DATA, 0x0990, 0x0008}, /* MCU_DATA_0 */ - {WRITE_REG_DATA, 0x098C, 0x2330}, /* [AWB_CCM_RL_10] */ - {WRITE_REG_DATA, 0x0990, 0xFFF7}, /* MCU_DATA_0 */ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs WbIncandescentSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs WbFluorescentSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs WbDaylightSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs WbCloudydaylightSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs WbNightSequence[] = { - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs *wb_table[] = { - [WB_AUTO] = WbAutoSequence, - [WB_INCANDESCENT] = WbIncandescentSequence, - [WB_FLUORESCENT] = WbFluorescentSequence, - [WB_DAYLIGHT] = WbDaylightSequence, - [WB_CLOUDYDAYLIGHT] = WbCloudydaylightSequence, - [WB_NIGHT] = WbNightSequence, -}; - -static struct soc2030_regs EffectNoneSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x6440}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x6440}, /*EFFECTS_B*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectBwSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x6441}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x6441}, /*EFFECTS_B*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectNegativeSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x6443}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x6443}, /*EFFECTS_B*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectPosterizeSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x2044}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x2044}, /*EFFECTS_B*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectSepiaSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x6442}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x6442}, /*EFFECTS_B*/ - {WRITE_VAR_DATA, 0x2763, 0xB023}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectSolarizeSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x4444}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x4444}, /*EFFECTS_B*/ - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs EffectAquaSequence[] = { - {WRITE_VAR_DATA, 0x2759, 0x6442}, /*EFFECTS_A*/ - {WRITE_VAR_DATA, 0x275B, 0x6442}, /*EFFECTS_B*/ - {WRITE_VAR_DATA, 0x2763, 0x1DE3}, - {REG_TABLE_END, 0x0000, 0x0000} -}; - -static struct soc2030_regs *effect_table[] = { - [EFFECT_NONE] = EffectNoneSequence, - [EFFECT_BW] = EffectBwSequence, - [EFFECT_NEGATIVE] = EffectNegativeSequence, - [EFFECT_POSTERIZE] = EffectPosterizeSequence, - [EFFECT_SEPIA] = EffectSepiaSequence, - [EFFECT_SOLARIZE] = EffectSolarizeSequence, - [EFFECT_AQUA] = EffectAquaSequence, -}; - -static struct soc2030_mode modes[] = { - {800, 600, 30, mode_800x600}, - {1600, 1200, 15, mode_1600x1200}, - {1280, 720, 30, mode_1280x720}, -}; - -static int soc2030_read_reg(struct i2c_client *client, u16 addr, u16 *val) -{ - int err; - struct i2c_msg msg[2]; - unsigned char data[4]; - - if (!client->adapter) - return -ENODEV; - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = data; - data[0] = (u8) (addr >> 8); - data[1] = (u8) (addr & 0xff); - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 2; - msg[1].buf = data + 2; - err = i2c_transfer(client->adapter, msg, 2); - - if (err != 2) - return -EIO; - - *val = ((u16)(data[2] << 8)) | data[3]; - - return 0; -} - -static int soc2030_write_reg(struct i2c_client *client, u16 addr, u16 val) -{ - int err; - struct i2c_msg msg; - unsigned char data[4]; - int retry = 0; - - if (!client->adapter) - return -ENODEV; - - data[0] = (u8) (addr >> 8); - data[1] = (u8) (addr & 0xff); - data[2] = (u8) (val >> 8); - data[3] = (u8) (val & 0xff); - - msg.addr = client->addr; - msg.flags = 0; - msg.len = 4; - msg.buf = data; - - do { - err = i2c_transfer(client->adapter, &msg, 1); - if (err == 1) - return 0; - retry++; - pr_err("soc2030: i2c transfer failed, retrying %x %x\n", - addr, val); - msleep(3); - } while (retry <= SOC2030_MAX_RETRIES); - - return retry > SOC2030_MAX_RETRIES ? -EIO : err; -} - -static int soc2030_write_bits(struct i2c_client *client, u16 addr, u16 val, - u16 mask) -{ - u16 rval, wval; - int err; - - err = soc2030_read_reg(client, addr, &rval); - if (err) { - pr_err("soc2030: error reading from %x\n", addr); - return err; - } - wval = ((~mask) & rval) | val; - err = soc2030_write_reg(client, addr, wval); - return err; -} - -static int soc2030_clear_bits(struct i2c_client *client, u16 addr, u16 bits) -{ - return soc2030_write_bits(client, addr, 0, bits); -} - -static int soc2030_set_bits(struct i2c_client *client, u16 addr, u16 bits) -{ - return soc2030_write_bits(client, addr, bits, bits); -} - -static int soc2030_poll(struct i2c_client *client, u16 addr, u16 expected, - u16 mask) -{ - u16 val; - int try, err; - - for (try = 0; try < SOC2030_POLL_RETRIES; try++) { - err = soc2030_read_reg(client, addr, &val); - if (err) - return err; - if (expected == (val & mask)) { - pr_info("poll success %x: %x == %x & %x\n", addr, - expected, val, mask); - return 0; - } - msleep(SOC2030_POLL_WAITMS); - } - pr_err("soc2030: poll for %x == ([%x]=%x) & %x failed\n", expected, - addr, val, mask); - return -EIO; - -} - -static int soc2030_poll_bit_set(struct i2c_client *client, u16 addr, u16 bit) -{ - return soc2030_poll(client, addr, bit, bit); -} - -static int soc2030_poll_bit_clear(struct i2c_client *client, u16 addr, u16 bit) -{ - return soc2030_poll(client, addr, 0, bit); -} - -static int soc2030_write_xdma_reg(struct i2c_client *client, u16 addr, u16 val) -{ - int err; - - err = soc2030_write_reg(client, 0x098c, addr); - if (err) - return err; - err = soc2030_write_reg(client, 0x0990, val); - if (err) - return err; - return 0; -} - -static int soc2030_read_xdma_reg(struct i2c_client *client, u16 addr, u16 *val) -{ - int err; - - err = soc2030_write_reg(client, 0x098c, addr); - if (err) - return err; - err = soc2030_read_reg(client, 0x0990, val); - if (err) - return err; - return 0; -} - -static int soc2030_poll_xdma_reg(struct i2c_client *client, u16 addr, - u16 expected) -{ - int try, err; - u16 val; - - for (try = 0; try < SOC2030_POLL_RETRIES; try++) { - err = soc2030_read_xdma_reg(client, addr, &val); - if (err) - return err; - if (expected == val) { - pr_info("poll success %x: %x == %x\n", addr, - expected, val); - return 0; - } - msleep(SOC2030_POLL_WAITMS); - } - pr_err("soc2030: xdma poll for %x == ([%x]=%x) failed\n", expected, - addr, val); - return -EINVAL; -} - -static int soc2030_write_table(struct i2c_client *client, - const struct soc2030_regs table[]) -{ - int err = -EIO; - const struct soc2030_regs *next; - - for (next = table; next->op != REG_TABLE_END; next++) { - - switch (next->op) { - case WRITE_REG_DATA: - { - err = soc2030_write_reg(client, next->addr, - next->val); - if (err) - return err; - break; - } - case WRITE_REG_BIT_H: - { - err = soc2030_set_bits(client, next->addr, - next->val); - if (err) - return err; - break; - } - case WRITE_REG_BIT_L: - { - err = soc2030_clear_bits(client, next->addr, - next->val); - if (err) - return err; - break; - } - case POLL_REG_DATA: - { - err = soc2030_poll(client, next->addr, - next->val, 0xFFFF); - if (err) - return err; - break; - } - case POLL_REG_BIT_H: - { - err = soc2030_poll_bit_set(client, next->addr, - next->val); - if (err) - return err; - break; - } - case POLL_REG_BIT_L: - { - err = soc2030_poll_bit_clear(client, next->addr, - next->val); - if (err) - return err; - break; - } - case WRITE_VAR_DATA: - { - err = soc2030_write_xdma_reg(client, next->addr, - next->val); - if (err) - return err; - break; - } - case POLL_VAR_DATA: - { - err = soc2030_poll_xdma_reg(client, next->addr, - next->val); - if (err) - return err; - break; - } - case DELAY_MS: - { - msleep(next->val); - break; - } - default: - pr_err("%s: invalid operation 0x%x\n", __func__, - next->op); - return err; - } - } - return 0; -} - -static int soc2030_set_mode(struct soc2030_info *info, - struct soc2030_mode *mode) -{ - int sensor_mode, err; - int index; - int mode_count; - - mode_count = ARRAY_SIZE(modes); - for (index = 0; index < mode_count; index++) { - if ((mode->fps == modes[index].fps) && - (mode->xres == modes[index].xres) && - (mode->yres == modes[index].yres)) - break; - } - if (index == mode_count) { - pr_err("%s: invalid resolution supplied to set mode %d %d\n", - __func__, mode->xres, mode->yres); - return -EINVAL; - } - sensor_mode = index; - - if (info->mode == -1) { - - /* write the pll table */ - soc2030_write_table(info->i2c_client, pll_table); - - err = soc2030_write_table(info->i2c_client, base_mode); - if (err) - return err; - - /* load errata settings */ - err = soc2030_write_table(info->i2c_client, - SetRev2ErrataSequence); - if (err) - return err; - - /* load lens correction */ - err = soc2030_write_table(info->i2c_client, - SetLensCorrectionSequence); - if (err) - return err; - - /* low light optimization settings */ - err = soc2030_write_table(info->i2c_client, - SetLowLightSequence); - if (err) - return err; - - /* Base denoise settings (for all resolutions) */ - err = soc2030_write_table(info->i2c_client, - SetDenoiseSequence); - if (err) - return err; - - /* white balance common settings */ - err = soc2030_write_table(info->i2c_client, - SetCCMCommonSequence); - if (err) - return err; - - /* auto white balance settings */ - err = soc2030_write_table(info->i2c_client, - SetCCMAutoSequence); - if (err) - return err; - - /* load patch */ - err = soc2030_write_table(info->i2c_client, - SetRev3PatchSequence); - if (err) - return err; - - /* Wake MCU */ - err = soc2030_write_table(info->i2c_client, - WakeMcuSequence); - if (err) - return err; - } - - /* set context */ - err = soc2030_write_table(info->i2c_client, modes[sensor_mode].regset); - if (err) - return err; - - err = soc2030_write_table(info->i2c_client, refresh_mode); - if (err) - return err; - - err = soc2030_write_table(info->i2c_client, refresh_state); - if (err) - return err; - - info->mode = sensor_mode; - return 0; -} - - -static int soc2030_get_status(struct soc2030_info *info, u16 *status) -{ - int err; - - *status = 0; - err = soc2030_read_xdma_reg(info->i2c_client, 0x0, status); - if (err) - return err; - err = soc2030_read_xdma_reg(info->i2c_client, 0x2104, status + 1); - if (err) - return err; - err = soc2030_read_xdma_reg(info->i2c_client, 0x2703, status + 2); - if (err) - return err; - err = soc2030_read_xdma_reg(info->i2c_client, 0x2705, status + 3); - if (err) - return err; - err = soc2030_read_xdma_reg(info->i2c_client, 0x2737, status + 4); - if (err) - return err; - pr_info("%s: [0]=%x [2104]=%x [2703]=%x [2705]=%x [2737]=%x\n" - , __func__, status[0], status[1], status[2], status[3], - status[4]); - return 0; -} - - -static long soc2030_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int err = 0; - struct soc2030_info *info = file->private_data; - - err = mutex_lock_interruptible(&info->lock); - if (err) - return err; - - switch (cmd) { - case SOC2030_IOCTL_SET_MODE: - { - struct soc2030_mode mode; - if (copy_from_user(&mode, - (const void __user *)arg, - sizeof(struct soc2030_mode))) { - pr_info("%s: Error copying from user\n", __func__); - err = -EFAULT; - break; - } - - err = soc2030_set_mode(info, &mode); - break; - } - case SOC2030_IOCTL_SET_PRIVATE: - { - int size = SOC2030_MAX_PRIVATE_SIZE * - sizeof(struct soc2030_regs); - struct soc2030_regs *reg_sequence = - kzalloc(size, GFP_KERNEL); - - if (NULL == reg_sequence) { - pr_info("%s: Error allocating memory\n", __func__); - err = -ENOMEM; - break; - } - - if (copy_from_user(reg_sequence, - (const void __user *)arg, size)) { - pr_info("%s: Error copying from user\n", __func__); - kfree(reg_sequence); - err = -EFAULT; - break; - } - err = soc2030_write_table(info->i2c_client, reg_sequence); - kfree(reg_sequence); - break; - } - case SOC2030_IOCTL_GET_STATUS: - { - u16 status[5]; - - err = soc2030_get_status(info, status); - if (err) - break; - if (copy_to_user((void __user *)arg, &status, - 10)) { - pr_info("%s: Error copying to user\n", __func__); - err = -EFAULT; - } - break; - } - case SOC2030_IOCTL_GET_MODES: - { - if (copy_to_user((void __user *)arg, &modes, - sizeof(modes))) { - pr_info("%s: Error copying to user\n", __func__); - err = -EFAULT; - } - break; - } - case SOC2030_IOCTL_GET_NUM_MODES: - { - unsigned int num_modes = ARRAY_SIZE(modes); - if (copy_to_user((void __user *)arg, &num_modes, - sizeof(num_modes))) { - pr_info("%s: Error copying to user\n", __func__); - err = -EFAULT; - } - break; - } - case SOC2030_IOCTL_SET_EFFECT: - { - - if ((unsigned int)arg >= EFFECT_MAX) { - err = -EINVAL; - break; - } - err = soc2030_write_table(info->i2c_client, - effect_table[(unsigned int)arg]); - if (err) - break; - - err = soc2030_write_table(info->i2c_client, refresh_state); - break; - } - case SOC2030_IOCTL_SET_WHITEBALANCE: - { - - if ((unsigned int)arg >= WB_MAX) { - err = -EINVAL; - break; - } - - /* Re-set context, this insures MAX AE Index is set correctly */ - /* As night mode may have been previously set */ - err = soc2030_write_table(info->i2c_client, - modes[info->mode].regset); - if (err) - break; - - err = soc2030_write_table(info->i2c_client, - SetCCMCommonSequence); - if (err) - break; - - err = soc2030_write_table(info->i2c_client, - wb_table[(unsigned int)arg]); - break; - } - - case SOC2030_IOCTL_SET_EXP_COMP: - { - int req_ev = (int)arg; - int step; - int step_size = 0; - int ev_step = 0; - int new_target = EXP_TARGET; - - if ((req_ev > SOC_EV_MAX) || (req_ev < SOC_EV_MIN)) { - pr_err("%s: Invalid exposure parameter %i\n", - __func__, req_ev); - err = -EINVAL; - break; - } - - if (req_ev < 0) { - ev_step = -EXP_TARGET; - /* step a little less than 1 f-stop */ - step_size = 2; - } else if (req_ev > 0) { - ev_step = 0x100 - EXP_TARGET; - /* step 1/2 f-stop */ - step_size = 4; - } - - new_target = EXP_TARGET; - - /* adjust exposure target by 1 f-stop for each requested step */ - for (step = 1; step <= abs(req_ev); step++) { - ev_step /= step_size; - new_target += ev_step; - } - if (new_target < 0) { - pr_err("%s: Bad exposure target %i (0x%x)\n", - __func__, new_target, - (u16)new_target); - err = -EINVAL; - break; - } - - err = soc2030_write_xdma_reg(info->i2c_client, - 0xA24F, (u16)new_target); - if (err) { - pr_err("%s: Failed to update EV parameter\n", __func__); - break; - } - err = soc2030_write_table(info->i2c_client, refresh_state); - if (err) - pr_err("%s: Failed to update EV parameter\n", __func__); - break; - } - - default: - err = -EINVAL; - pr_err("%s: unknown IOCTL cmd 0x%x\n", __func__, cmd); - break; - } - - mutex_unlock(&info->lock); - return err; -} - -static struct soc2030_info *info; - -static int soc2030_open(struct inode *inode, struct file *file) -{ - info->mode = -1; - file->private_data = info; - if (info->pdata && info->pdata->power_on) - info->pdata->power_on(); - return 0; -} - -int soc2030_release(struct inode *inode, struct file *file) -{ - if (info->pdata && info->pdata->power_off) - info->pdata->power_off(); - file->private_data = NULL; - return 0; -} - - -static const struct file_operations soc2030_fileops = { - .owner = THIS_MODULE, - .open = soc2030_open, - .unlocked_ioctl = soc2030_ioctl, - .release = soc2030_release, -}; - -static struct miscdevice soc2030_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "soc2030", - .fops = &soc2030_fileops, -}; - -static int soc2030_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err; - - pr_info("soc2030: probing sensor.\n"); - - info = kzalloc(sizeof(struct soc2030_info), GFP_KERNEL); - if (!info) { - pr_err("soc2030: Unable to allocate memory!\n"); - return -ENOMEM; - } - - err = misc_register(&soc2030_device); - if (err) { - pr_err("soc2030: Unable to register misc device!\n"); - kfree(info); - return err; - } - - mutex_init(&info->lock); - info->pdata = client->dev.platform_data; - info->i2c_client = client; - i2c_set_clientdata(client, info); - return 0; -} - -static int soc2030_remove(struct i2c_client *client) -{ - struct soc2030_info *info; - info = i2c_get_clientdata(client); - misc_deregister(&soc2030_device); - kfree(info); - return 0; -} - -static const struct i2c_device_id soc2030_id[] = { - { "soc2030", 0 }, - { }, -}; - -MODULE_DEVICE_TABLE(i2c, soc2030_id); - -static struct i2c_driver soc2030_i2c_driver = { - .driver = { - .name = "soc2030", - .owner = THIS_MODULE, - }, - .probe = soc2030_probe, - .remove = soc2030_remove, - .id_table = soc2030_id, -}; - -static int __init soc2030_init(void) -{ - return i2c_add_driver(&soc2030_i2c_driver); -} - -static void __exit soc2030_exit(void) -{ - i2c_del_driver(&soc2030_i2c_driver); -} - -module_init(soc2030_init); -module_exit(soc2030_exit); - diff --git a/drivers/media/video/tegra/tegra_camera.c b/drivers/media/video/tegra/tegra_camera.c deleted file mode 100644 index f310d0f5619f..000000000000 --- a/drivers/media/video/tegra/tegra_camera.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * drivers/media/video/tegra/tegra_camera.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Eventually this should handle all clock and reset calls for the isp, vi, - * vi_sensor, and csi modules, replacing nvrm and nvos completely for camera - */ -#define TEGRA_CAMERA_NAME "tegra_camera" -DEFINE_MUTEX(tegra_camera_lock); - -struct tegra_camera_block { - int (*enable) (void); - int (*disable) (void); - bool is_enabled; -}; - - -static struct clk *isp_clk; -static struct clk *vi_clk; -static struct clk *vi_sensor_clk; -static struct clk *csus_clk; -static struct clk *csi_clk; -static struct regulator *tegra_camera_regulator_csi; - -static int tegra_camera_enable_isp(void) -{ - return clk_enable(isp_clk); -} - -static int tegra_camera_disable_isp(void) -{ - clk_disable(isp_clk); - return 0; -} - -static int tegra_camera_enable_vi(void) -{ - clk_enable(vi_clk); - clk_enable(vi_sensor_clk); - clk_enable(csus_clk); - return 0; -} - -static int tegra_camera_disable_vi(void) -{ - clk_disable(vi_clk); - clk_disable(vi_sensor_clk); - clk_disable(csus_clk); - return 0; -} - -static int tegra_camera_enable_csi(void) -{ - int ret; - - ret = regulator_enable(tegra_camera_regulator_csi); - if (ret) - return ret; - clk_enable(csi_clk); - return 0; -} - -static int tegra_camera_disable_csi(void) -{ - int ret; - - ret = regulator_disable(tegra_camera_regulator_csi); - if (ret) - return ret; - clk_disable(csi_clk); - return 0; -} - -struct tegra_camera_block tegra_camera_block[] = { - [TEGRA_CAMERA_MODULE_ISP] = {tegra_camera_enable_isp, - tegra_camera_disable_isp, false}, - [TEGRA_CAMERA_MODULE_VI] = {tegra_camera_enable_vi, - tegra_camera_disable_vi, false}, - [TEGRA_CAMERA_MODULE_CSI] = {tegra_camera_enable_csi, - tegra_camera_disable_csi, false}, -}; - -#define TEGRA_CAMERA_VI_CLK_SEL_INTERNAL 0 -#define TEGRA_CAMERA_VI_CLK_SEL_EXTERNAL (1<<24) -#define TEGRA_CAMERA_PD2VI_CLK_SEL_VI_SENSOR_CLK (1<<25) -#define TEGRA_CAMERA_PD2VI_CLK_SEL_PD2VI_CLK 0 - -static int tegra_camera_clk_set_rate(struct tegra_camera_clk_info *info) -{ - u32 offset; - struct clk *clk; - - if (info->id != TEGRA_CAMERA_MODULE_VI) { - pr_err("%s: Set rate only aplies to vi module %d\n", __func__, - info->id); - return -EINVAL; - } - - switch (info->clk_id) { - case TEGRA_CAMERA_VI_CLK: - clk = vi_clk; - offset = 0x148; - break; - case TEGRA_CAMERA_VI_SENSOR_CLK: - clk = vi_sensor_clk; - offset = 0x1a8; - break; - default: - pr_err("%s: invalid clk id for set rate %d\n", __func__, - info->clk_id); - return -EINVAL; - } - - clk_set_rate(clk, info->rate); - - if (info->clk_id == TEGRA_CAMERA_VI_CLK) { - u32 val; - void __iomem *car = IO_ADDRESS(TEGRA_CLK_RESET_BASE); - void __iomem *apb_misc = IO_ADDRESS(TEGRA_APB_MISC_BASE); - - writel(0x2, car + offset); - - val = readl(apb_misc + 0x42c); - writel(val | 0x1, apb_misc + 0x42c); - } - - info->rate = clk_get_rate(clk); - return 0; - -} -static int tegra_camera_reset(uint id) -{ - struct clk *clk; - - switch (id) { - case TEGRA_CAMERA_MODULE_VI: - clk = vi_clk; - break; - case TEGRA_CAMERA_MODULE_ISP: - clk = isp_clk; - break; - case TEGRA_CAMERA_MODULE_CSI: - clk = csi_clk; - break; - default: - return -EINVAL; - } - tegra_periph_reset_assert(clk); - udelay(10); - tegra_periph_reset_deassert(clk); - - return 0; -} - -static long tegra_camera_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - uint id; - - /* first element of arg must be u32 with id of module to talk to */ - if (copy_from_user(&id, (const void __user *)arg, sizeof(uint))) { - pr_err("%s: Failed to copy arg from user", __func__); - return -EFAULT; - } - - if (id >= ARRAY_SIZE(tegra_camera_block)) { - pr_err("%s: Invalid id to tegra isp ioctl%d\n", __func__, id); - return -EINVAL; - } - - switch (cmd) { - case TEGRA_CAMERA_IOCTL_ENABLE: - { - int ret = 0; - - mutex_lock(&tegra_camera_lock); - if (!tegra_camera_block[id].is_enabled) { - ret = tegra_camera_block[id].enable(); - tegra_camera_block[id].is_enabled = true; - } - mutex_unlock(&tegra_camera_lock); - return ret; - } - case TEGRA_CAMERA_IOCTL_DISABLE: - { - int ret = 0; - - mutex_lock(&tegra_camera_lock); - if (tegra_camera_block[id].is_enabled) { - ret = tegra_camera_block[id].disable(); - tegra_camera_block[id].is_enabled = false; - } - mutex_unlock(&tegra_camera_lock); - return ret; - } - case TEGRA_CAMERA_IOCTL_CLK_SET_RATE: - { - struct tegra_camera_clk_info info; - int ret; - - if (copy_from_user(&info, (const void __user *)arg, - sizeof(struct tegra_camera_clk_info))) { - pr_err("%s: Failed to copy arg from user\n", __func__); - return -EFAULT; - } - ret = tegra_camera_clk_set_rate(&info); - if (ret) - return ret; - if (copy_to_user((void __user *)arg, &info, - sizeof(struct tegra_camera_clk_info))) { - pr_err("%s: Failed to copy arg to user\n", __func__); - return -EFAULT; - } - return 0; - } - case TEGRA_CAMERA_IOCTL_RESET: - return tegra_camera_reset(id); - default: - pr_err("%s: Unknown tegra_camera ioctl.\n", TEGRA_CAMERA_NAME); - return -EINVAL; - } - return 0; -} - -static int tegra_camera_release(struct inode *inode, struct file *file) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(tegra_camera_block); i++) - if (tegra_camera_block[i].is_enabled) { - tegra_camera_block[i].disable(); - tegra_camera_block[i].is_enabled = false; - } - - return 0; -} - -static const struct file_operations tegra_camera_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = tegra_camera_ioctl, - .release = tegra_camera_release, -}; - -static struct miscdevice tegra_camera_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = TEGRA_CAMERA_NAME, - .fops = &tegra_camera_fops, -}; - -static int tegra_camera_clk_get(struct platform_device *pdev, const char *name, - struct clk **clk) -{ - *clk = clk_get(&pdev->dev, name); - if (IS_ERR_OR_NULL(*clk)) { - pr_err("%s: unable to get clock for %s\n", __func__, name); - *clk = NULL; - return PTR_ERR(*clk); - } - return 0; -} - -static int tegra_camera_probe(struct platform_device *pdev) -{ - int err; - - pr_info("%s: probe\n", TEGRA_CAMERA_NAME); - tegra_camera_regulator_csi = regulator_get(&pdev->dev, "vcsi"); - if (IS_ERR_OR_NULL(tegra_camera_regulator_csi)) { - pr_err("%s: Couldn't get regulator vcsi\n", TEGRA_CAMERA_NAME); - return PTR_ERR(tegra_camera_regulator_csi); - } - - err = misc_register(&tegra_camera_device); - if (err) { - pr_err("%s: Unable to register misc device!\n", - TEGRA_CAMERA_NAME); - goto misc_register_err; - } - - err = tegra_camera_clk_get(pdev, "isp", &isp_clk); - if (err) - goto misc_register_err; - err = tegra_camera_clk_get(pdev, "vi", &vi_clk); - if (err) - goto vi_clk_get_err; - err = tegra_camera_clk_get(pdev, "vi_sensor", &vi_sensor_clk); - if (err) - goto vi_sensor_clk_get_err; - err = tegra_camera_clk_get(pdev, "csus", &csus_clk); - if (err) - goto csus_clk_get_err; - err = tegra_camera_clk_get(pdev, "csi", &csi_clk); - if (err) - goto csi_clk_get_err; - - return 0; - -csi_clk_get_err: - clk_put(csus_clk); -csus_clk_get_err: - clk_put(vi_sensor_clk); -vi_sensor_clk_get_err: - clk_put(vi_clk); -vi_clk_get_err: - clk_put(isp_clk); -misc_register_err: - regulator_put(tegra_camera_regulator_csi); - return err; -} - -static int tegra_camera_remove(struct platform_device *pdev) -{ - clk_put(isp_clk); - clk_put(vi_clk); - clk_put(vi_sensor_clk); - clk_put(csus_clk); - clk_put(csi_clk); - - regulator_put(tegra_camera_regulator_csi); - misc_deregister(&tegra_camera_device); - return 0; -} - -static struct platform_driver tegra_camera_driver = { - .probe = tegra_camera_probe, - .remove = tegra_camera_remove, - .driver = { .name = TEGRA_CAMERA_NAME } -}; - -static int __init tegra_camera_init(void) -{ - return platform_driver_register(&tegra_camera_driver); -} - -static void __exit tegra_camera_exit(void) -{ - platform_driver_unregister(&tegra_camera_driver); -} - -module_init(tegra_camera_init); -module_exit(tegra_camera_exit); - diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d2924a2cf3cd..db51ea1c6082 100755 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -523,12 +523,6 @@ config MFD_RDC321X southbridge which provides access to GPIOs and Watchdog using the southbridge PCI device configuration space. -config MFD_CPCAP - tristate "Support for CPCAP" - depends on SPI && FIRMWARE_IN_KERNEL - help - Say yes here if you want to include drivers for the CPCAP chip. - config MFD_JANZ_CMODIO tristate "Support for Janz CMOD-IO PCI MODULbus Carrier Board" select MFD_CORE @@ -548,8 +542,8 @@ config MFD_JZ4740_ADC This driver is necessary for jz4740-battery and jz4740-hwmon driver. config MFD_TPS6586X - bool "TPS6586x Power Management chips" - depends on I2C && GPIOLIB && GENERIC_HARDIRQS + tristate "TPS6586x Power Management chips" + depends on I2C && GPIOLIB select MFD_CORE help If you say yes here you get support for the TPS6586X series of diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a28fc814aea6..feaeeaeeddb7 100755 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -76,16 +76,3 @@ obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o - -cpcap-objs := cpcap-core.o \ - cpcap-irq.o \ - cpcap-regacc.o \ - cpcap-key.o \ - cpcap-whisper.o \ - cpcap-adc.o \ - cpcap-uc.o \ - cpcap-3mm5.o \ - tegra-cpcap-audio.o \ - cpcap-audio-core.o - -obj-$(CONFIG_MFD_CPCAP) += cpcap.o diff --git a/drivers/mfd/cpcap-3mm5.c b/drivers/mfd/cpcap-3mm5.c deleted file mode 100644 index 088230563775..000000000000 --- a/drivers/mfd/cpcap-3mm5.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2009-2011 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -enum { - NO_DEVICE, - HEADSET_WITH_MIC, - HEADSET_WITHOUT_MIC, -}; - -struct cpcap_3mm5_data { - struct cpcap_device *cpcap; - struct switch_dev sdev; - unsigned int key_state; - unsigned int mb2_idle; - struct regulator *regulator; - unsigned char audio_low_pwr_det; - unsigned char audio_low_pwr_mac13; - struct delayed_work work; -}; - -static ssize_t print_name(struct switch_dev *sdev, char *buf) -{ - switch (switch_get_state(sdev)) { - case NO_DEVICE: - return sprintf(buf, "No Device\n"); - case HEADSET_WITH_MIC: - return sprintf(buf, "Headset with mic\n"); - case HEADSET_WITHOUT_MIC: - return sprintf(buf, "Headset without mic\n"); - } - - return -EINVAL; -} - -static void audio_low_power_set(struct cpcap_3mm5_data *data, - unsigned char *flag) -{ - if (!(*flag)) { - regulator_set_mode(data->regulator, REGULATOR_MODE_STANDBY); - *flag = 1; - } -} - -static void audio_low_power_clear(struct cpcap_3mm5_data *data, - unsigned char *flag) -{ - if (*flag) { - regulator_set_mode(data->regulator, REGULATOR_MODE_NORMAL); - *flag = 0; - } -} - -static void send_key_event(struct cpcap_3mm5_data *data, unsigned int state) -{ - dev_info(&data->cpcap->spi->dev, "Headset key event: old=%d, new=%d\n", - data->key_state, state); - - if (data->key_state != state) { - data->key_state = state; - cpcap_broadcast_key_event(data->cpcap, KEY_MEDIA, state); - } -} - -static void hs_handler(enum cpcap_irqs irq, void *data) -{ - struct cpcap_3mm5_data *data_3mm5 = data; - int new_state = NO_DEVICE; - - if (irq != CPCAP_IRQ_HS) - return; - - /* HS sense of 1 means no headset present, 0 means headset attached. */ - if (cpcap_irq_sense(data_3mm5->cpcap, CPCAP_IRQ_HS, 1) == 1) { - cpcap_regacc_write(data_3mm5->cpcap, CPCAP_REG_TXI, 0, - (CPCAP_BIT_MB_ON2 | CPCAP_BIT_PTT_CMP_EN)); - cpcap_regacc_write(data_3mm5->cpcap, CPCAP_REG_RXOA, 0, - CPCAP_BIT_ST_HS_CP_EN); - audio_low_power_set(data_3mm5, &data_3mm5->audio_low_pwr_det); - - cpcap_irq_mask(data_3mm5->cpcap, CPCAP_IRQ_MB2); - cpcap_irq_mask(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - - cpcap_irq_clear(data_3mm5->cpcap, CPCAP_IRQ_MB2); - cpcap_irq_clear(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_HS); - - send_key_event(data_3mm5, 0); - - cpcap_uc_stop(data_3mm5->cpcap, CPCAP_MACRO_5); - } else { - cpcap_regacc_write(data_3mm5->cpcap, CPCAP_REG_TXI, - (CPCAP_BIT_MB_ON2 | CPCAP_BIT_PTT_CMP_EN), - (CPCAP_BIT_MB_ON2 | CPCAP_BIT_PTT_CMP_EN)); - cpcap_regacc_write(data_3mm5->cpcap, CPCAP_REG_RXOA, - CPCAP_BIT_ST_HS_CP_EN, - CPCAP_BIT_ST_HS_CP_EN); - audio_low_power_clear(data_3mm5, &data_3mm5->audio_low_pwr_det); - - /* Give PTTS time to settle */ - mdelay(2); - - if (cpcap_irq_sense(data_3mm5->cpcap, CPCAP_IRQ_PTT, 1) <= 0) { - /* Headset without mic and MFB is detected. (May also - * be a headset with the MFB pressed.) */ - new_state = HEADSET_WITHOUT_MIC; - } else { - new_state = HEADSET_WITH_MIC; - data_3mm5->mb2_idle = cpcap_irq_sense(data_3mm5->cpcap, - CPCAP_IRQ_MB2, 1); - } - - cpcap_irq_clear(data_3mm5->cpcap, CPCAP_IRQ_MB2); - cpcap_irq_clear(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_HS); - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_MB2); - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - - cpcap_uc_start(data_3mm5->cpcap, CPCAP_MACRO_5); - } - - switch_set_state(&data_3mm5->sdev, new_state); - if (data_3mm5->cpcap->h2w_new_state) - data_3mm5->cpcap->h2w_new_state(new_state); - - dev_info(&data_3mm5->cpcap->spi->dev, "New headset state: %d\n", - new_state); -} - -static void mb2_handler(enum cpcap_irqs irq, void *data) -{ - struct cpcap_3mm5_data *data_3mm5 = data; - - if (irq != CPCAP_IRQ_MB2) - return; - - if ((cpcap_irq_sense(data_3mm5->cpcap, CPCAP_IRQ_HS, 1) == 1) || - (switch_get_state(&data_3mm5->sdev) != HEADSET_WITH_MIC)) { - hs_handler(CPCAP_IRQ_HS, data_3mm5); - return; - } - - send_key_event(data_3mm5, (data_3mm5->mb2_idle ? 1 : 0)); - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_MB2); -} - -static void mac5_handler(enum cpcap_irqs irq, void *data) -{ - struct cpcap_3mm5_data *data_3mm5 = data; - - if (irq != CPCAP_IRQ_UC_PRIMACRO_5) - return; - - if ((cpcap_irq_sense(data_3mm5->cpcap, CPCAP_IRQ_HS, 1) == 1) || - (switch_get_state(&data_3mm5->sdev) != HEADSET_WITH_MIC)) { - hs_handler(CPCAP_IRQ_HS, data_3mm5); - return; - } - - send_key_event(data_3mm5, (data_3mm5->mb2_idle ? 0 : 1)); - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); -} - -static void mac13_work(struct work_struct *work) -{ - struct cpcap_3mm5_data *data_3mm5 = - container_of(work, struct cpcap_3mm5_data, work.work); - - audio_low_power_set(data_3mm5, &data_3mm5->audio_low_pwr_mac13); - cpcap_irq_unmask(data_3mm5->cpcap, CPCAP_IRQ_UC_PRIMACRO_13); -} - -static void mac13_handler(enum cpcap_irqs irq, void *data) -{ - struct cpcap_3mm5_data *data_3mm5 = data; - - if (irq != CPCAP_IRQ_UC_PRIMACRO_13) - return; - - audio_low_power_clear(data_3mm5, &data_3mm5->audio_low_pwr_mac13); - schedule_delayed_work(&data_3mm5->work, msecs_to_jiffies(200)); -} - -static int cpcap_3mm5_probe(struct platform_device *pdev) -{ - int retval = 0; - struct cpcap_3mm5_data *data; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->cpcap = pdev->dev.platform_data; - data->audio_low_pwr_det = 1; - data->audio_low_pwr_mac13 = 1; - data->sdev.name = "h2w"; - data->sdev.print_name = print_name; - switch_dev_register(&data->sdev); - INIT_DELAYED_WORK(&data->work, mac13_work); - platform_set_drvdata(pdev, data); - - data->regulator = regulator_get(NULL, "vaudio"); - if (IS_ERR(data->regulator)) { - dev_err(&pdev->dev, "Could not get regulator for cpcap_3mm5\n"); - retval = PTR_ERR(data->regulator); - goto free_mem; - } - - regulator_set_voltage(data->regulator, 2775000, 2775000); - - retval = cpcap_irq_clear(data->cpcap, CPCAP_IRQ_HS); - retval |= cpcap_irq_clear(data->cpcap, CPCAP_IRQ_MB2); - retval |= cpcap_irq_clear(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - retval |= cpcap_irq_clear(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_13); - if (retval) - goto reg_put; - - retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_HS, hs_handler, - data); - if (retval) - goto reg_put; - - retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_MB2, mb2_handler, - data); - if (retval) - goto free_hs; - - retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_5, - mac5_handler, data); - if (retval) - goto free_mb2; - - if (data->cpcap->vendor == CPCAP_VENDOR_ST) { - retval = cpcap_irq_register(data->cpcap, - CPCAP_IRQ_UC_PRIMACRO_13, - mac13_handler, data); - if (retval) - goto free_mac5; - - cpcap_uc_start(data->cpcap, CPCAP_MACRO_13); - } - - hs_handler(CPCAP_IRQ_HS, data); - - return 0; - -free_mac5: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); -free_mb2: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_MB2); -free_hs: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_HS); -reg_put: - regulator_put(data->regulator); -free_mem: - kfree(data); - - return retval; -} - -static int __exit cpcap_3mm5_remove(struct platform_device *pdev) -{ - struct cpcap_3mm5_data *data = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&data->work); - - cpcap_irq_free(data->cpcap, CPCAP_IRQ_MB2); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_HS); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_5); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIMACRO_13); - - switch_dev_unregister(&data->sdev); - regulator_put(data->regulator); - - kfree(data); - return 0; -} - -static struct platform_driver cpcap_3mm5_driver = { - .probe = cpcap_3mm5_probe, - .remove = __exit_p(cpcap_3mm5_remove), - .driver = { - .name = "cpcap_3mm5", - .owner = THIS_MODULE, - }, -}; - -static int __init cpcap_3mm5_init(void) -{ - return platform_driver_register(&cpcap_3mm5_driver); -} -module_init(cpcap_3mm5_init); - -static void __exit cpcap_3mm5_exit(void) -{ - platform_driver_unregister(&cpcap_3mm5_driver); -} -module_exit(cpcap_3mm5_exit); - -MODULE_ALIAS("platform:cpcap_3mm5"); -MODULE_DESCRIPTION("CPCAP 3.5mm detection driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/cpcap-adc.c b/drivers/mfd/cpcap-adc.c deleted file mode 100644 index 98b5f3c4cc89..000000000000 --- a/drivers/mfd/cpcap-adc.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright (C) 2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#define MAX_ADC_FIFO_DEPTH 8 /* this must be a power of 2 */ -#define MAX_TEMP_LVL 27 - -struct cpcap_adc { - struct cpcap_device *cpcap; - - /* Private stuff */ - struct cpcap_adc_request *queue[MAX_ADC_FIFO_DEPTH]; - int queue_head; - int queue_tail; - struct mutex queue_mutex; - struct delayed_work work; -}; - -struct phasing_tbl { - short offset; - unsigned short multiplier; - unsigned short divider; - short min; - short max; -}; - -static struct phasing_tbl bank0_phasing[CPCAP_ADC_BANK0_NUM] = { - [CPCAP_ADC_AD0_BATTDETB] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_BATTP] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_VBUS] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_AD3] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_BPLUS_AD4] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_CHG_ISENSE] = {0, 0x80, 0x80, -512, 511}, - [CPCAP_ADC_BATTI_ADC] = {0, 0x80, 0x80, -512, 511}, - [CPCAP_ADC_USB_ID] = {0, 0x80, 0x80, 0, 1023}, -}; - -static struct phasing_tbl bank1_phasing[CPCAP_ADC_BANK1_NUM] = { - [CPCAP_ADC_AD8] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_AD9] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_LICELL] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_HV_BATTP] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_TSX1_AD12] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_TSX2_AD13] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_TSY1_AD14] = {0, 0x80, 0x80, 0, 1023}, - [CPCAP_ADC_TSY2_AD15] = {0, 0x80, 0x80, 0, 1023}, -}; - -enum conv_type { - CONV_TYPE_NONE, - CONV_TYPE_DIRECT, - CONV_TYPE_MAPPING, -}; - -struct conversion_tbl { - enum conv_type conv_type; - int align_offset; - int conv_offset; - int multiplier; - int divider; -}; - -static struct conversion_tbl bank0_conversion[CPCAP_ADC_BANK0_NUM] = { - [CPCAP_ADC_AD0_BATTDETB] = {CONV_TYPE_MAPPING, 0, 0, 1, 1}, - [CPCAP_ADC_BATTP] = {CONV_TYPE_DIRECT, 0, 2400, 2300, 1023}, - [CPCAP_ADC_VBUS] = {CONV_TYPE_DIRECT, 0, 0, 10000, 1023}, - [CPCAP_ADC_AD3] = {CONV_TYPE_MAPPING, 0, 0, 1, 1}, - [CPCAP_ADC_BPLUS_AD4] = {CONV_TYPE_DIRECT, 0, 2400, 2300, 1023}, - [CPCAP_ADC_CHG_ISENSE] = {CONV_TYPE_DIRECT, -512, 2, 5000, 1023}, - [CPCAP_ADC_BATTI_ADC] = {CONV_TYPE_DIRECT, -512, 2, 5000, 1023}, - [CPCAP_ADC_USB_ID] = {CONV_TYPE_NONE, 0, 0, 1, 1}, -}; - -static struct conversion_tbl bank1_conversion[CPCAP_ADC_BANK1_NUM] = { - [CPCAP_ADC_AD8] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_AD9] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_LICELL] = {CONV_TYPE_DIRECT, 0, 0, 3400, 1023}, - [CPCAP_ADC_HV_BATTP] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_TSX1_AD12] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_TSX2_AD13] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_TSY1_AD14] = {CONV_TYPE_NONE, 0, 0, 1, 1}, - [CPCAP_ADC_TSY2_AD15] = {CONV_TYPE_NONE, 0, 0, 1, 1}, -}; - -static const unsigned short temp_map[MAX_TEMP_LVL][2] = { - {0x03ff, 233}, /* -40C */ - {0x03ff, 238}, /* -35C */ - {0x03ef, 243}, /* -30C */ - {0x03b2, 248}, /* -25C */ - {0x036c, 253}, /* -20C */ - {0x0320, 258}, /* -15C */ - {0x02d0, 263}, /* -10C */ - {0x027f, 268}, /* -5C */ - {0x022f, 273}, /* 0C */ - {0x01e4, 278}, /* 5C */ - {0x019f, 283}, /* 10C */ - {0x0161, 288}, /* 15C */ - {0x012b, 293}, /* 20C */ - {0x00fc, 298}, /* 25C */ - {0x00d4, 303}, /* 30C */ - {0x00b2, 308}, /* 35C */ - {0x0095, 313}, /* 40C */ - {0x007d, 318}, /* 45C */ - {0x0069, 323}, /* 50C */ - {0x0059, 328}, /* 55C */ - {0x004b, 333}, /* 60C */ - {0x003f, 338}, /* 65C */ - {0x0036, 343}, /* 70C */ - {0x002e, 348}, /* 75C */ - {0x0027, 353}, /* 80C */ - {0x0022, 358}, /* 85C */ - {0x001d, 363}, /* 90C */ -}; - -static unsigned short convert_to_kelvins(unsigned short value) -{ - int i; - unsigned short result = 0; - signed short alpha = 0; - - if (value <= temp_map[MAX_TEMP_LVL - 1][0]) - return temp_map[MAX_TEMP_LVL - 1][1]; - - if (value >= temp_map[0][0]) - return temp_map[0][1]; - - for (i = 0; i < MAX_TEMP_LVL - 1; i++) { - if ((value <= temp_map[i][0]) && - (value >= temp_map[i+1][0])) { - if (value == temp_map[i][0]) - result = temp_map[i][1]; - else if (value == temp_map[i+1][0]) - result = temp_map[i+1][1]; - else { - alpha = ((value - temp_map[i][0])*1000)/ - (temp_map[i+1][0] - temp_map[i][0]); - - result = temp_map[i][1] + - ((alpha*(temp_map[i+1][1] - - temp_map[i][1]))/1000); - } - break; - } - } - return result; -} - -static void adc_setup(struct cpcap_device *cpcap, - struct cpcap_adc_request *req) -{ - struct cpcap_adc_ato *ato; - struct cpcap_platform_data *data; - unsigned short value1 = 0; - unsigned short value2 = 0; - - data = cpcap->spi->controller_data; - ato = data->adc_ato; - - if (req->type == CPCAP_ADC_TYPE_BANK_1) - value1 |= CPCAP_BIT_AD_SEL1; - else if (req->type == CPCAP_ADC_TYPE_BATT_PI) - value1 |= CPCAP_BIT_RAND1; - - switch (req->timing) { - case CPCAP_ADC_TIMING_IN: - value1 |= ato->ato_in; - value1 |= ato->atox_in; - value2 |= ato->adc_ps_factor_in; - value2 |= ato->atox_ps_factor_in; - break; - - case CPCAP_ADC_TIMING_OUT: - value1 |= ato->ato_out; - value1 |= ato->atox_out; - value2 |= ato->adc_ps_factor_out; - value2 |= ato->atox_ps_factor_out; - break; - - case CPCAP_ADC_TIMING_IMM: - default: - break; - } - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC1, value1, - (CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX | - CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 | - CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 | - CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 | - CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 | - CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0)); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, value2, - (CPCAP_BIT_ATOX_PS_FACTOR | - CPCAP_BIT_ADC_PS_FACTOR1 | - CPCAP_BIT_ADC_PS_FACTOR0)); - - if (req->timing == CPCAP_ADC_TIMING_IMM) { - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ADTRIG_DIS, - CPCAP_BIT_ADTRIG_DIS); - cpcap_irq_clear(cpcap, CPCAP_IRQ_ADCDONE); - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ASC, - CPCAP_BIT_ASC); - } else { - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ADTRIG_ONESHOT, - CPCAP_BIT_ADTRIG_ONESHOT); - cpcap_irq_clear(cpcap, CPCAP_IRQ_ADCDONE); - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - 0, - CPCAP_BIT_ADTRIG_DIS); - } - - schedule_delayed_work(&((struct cpcap_adc *)(cpcap->adcdata))->work, - msecs_to_jiffies(500)); - - cpcap_irq_unmask(cpcap, CPCAP_IRQ_ADCDONE); -} - -static void adc_setup_calibrate(struct cpcap_device *cpcap, - enum cpcap_adc_bank0 chan) -{ - unsigned short value = 0; - unsigned long timeout = jiffies + msecs_to_jiffies(11); - - if ((chan != CPCAP_ADC_CHG_ISENSE) && - (chan != CPCAP_ADC_BATTI_ADC)) - return; - - value |= CPCAP_BIT_CAL_MODE | CPCAP_BIT_RAND0; - value |= ((chan << 4) & - (CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 | CPCAP_BIT_ADA0)); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC1, value, - (CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX | - CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 | - CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 | - CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 | - CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 | - CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0)); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, 0, - (CPCAP_BIT_ATOX_PS_FACTOR | - CPCAP_BIT_ADC_PS_FACTOR1 | - CPCAP_BIT_ADC_PS_FACTOR0)); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ADTRIG_DIS, - CPCAP_BIT_ADTRIG_DIS); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ASC, - CPCAP_BIT_ASC); - - do { - schedule_timeout_uninterruptible(1); - cpcap_regacc_read(cpcap, CPCAP_REG_ADCC2, &value); - } while ((value & CPCAP_BIT_ASC) && time_before(jiffies, timeout)); - - if (value & CPCAP_BIT_ASC) - dev_err(&(cpcap->spi->dev), - "Timeout waiting for calibration to complete\n"); - - cpcap_irq_clear(cpcap, CPCAP_IRQ_ADCDONE); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC1, 0, CPCAP_BIT_CAL_MODE); -} - -static void trigger_next_adc_job_if_any(struct cpcap_device *cpcap) -{ - struct cpcap_adc *adc = cpcap->adcdata; - int head; - - mutex_lock(&adc->queue_mutex); - - head = adc->queue_head; - - if (!adc->queue[head]) { - mutex_unlock(&adc->queue_mutex); - return; - } - mutex_unlock(&adc->queue_mutex); - - adc_setup(cpcap, adc->queue[head]); -} - -static int -adc_enqueue_request(struct cpcap_device *cpcap, struct cpcap_adc_request *req) -{ - struct cpcap_adc *adc = cpcap->adcdata; - int head; - int tail; - int running; - - mutex_lock(&adc->queue_mutex); - - head = adc->queue_head; - tail = adc->queue_tail; - running = (head != tail); - - if (adc->queue[tail]) { - mutex_unlock(&adc->queue_mutex); - return -EBUSY; - } - - adc->queue[tail] = req; - adc->queue_tail = (tail + 1) & (MAX_ADC_FIFO_DEPTH - 1); - - mutex_unlock(&adc->queue_mutex); - - if (!running) - trigger_next_adc_job_if_any(cpcap); - - return 0; -} - -static void -cpcap_adc_sync_read_callback(struct cpcap_device *cpcap, void *param) -{ - struct cpcap_adc_request *req = param; - - complete(&req->completion); -} - -int cpcap_adc_sync_read(struct cpcap_device *cpcap, - struct cpcap_adc_request *request) -{ - int ret; - - request->callback = cpcap_adc_sync_read_callback; - request->callback_param = request; - init_completion(&request->completion); - ret = adc_enqueue_request(cpcap, request); - if (ret) - return ret; - wait_for_completion(&request->completion); - - return 0; -} -EXPORT_SYMBOL_GPL(cpcap_adc_sync_read); - -int cpcap_adc_async_read(struct cpcap_device *cpcap, - struct cpcap_adc_request *request) -{ - return adc_enqueue_request(cpcap, request); -} -EXPORT_SYMBOL_GPL(cpcap_adc_async_read); - -void cpcap_adc_phase(struct cpcap_device *cpcap, struct cpcap_adc_phase *phase) -{ - bank0_phasing[CPCAP_ADC_BATTI_ADC].offset = phase->offset_batti; - bank0_phasing[CPCAP_ADC_BATTI_ADC].multiplier = phase->slope_batti; - - bank0_phasing[CPCAP_ADC_CHG_ISENSE].offset = phase->offset_chrgi; - bank0_phasing[CPCAP_ADC_CHG_ISENSE].multiplier = phase->slope_chrgi; - - bank0_phasing[CPCAP_ADC_BATTP].offset = phase->offset_battp; - bank0_phasing[CPCAP_ADC_BATTP].multiplier = phase->slope_battp; - - bank0_phasing[CPCAP_ADC_BPLUS_AD4].offset = phase->offset_bp; - bank0_phasing[CPCAP_ADC_BPLUS_AD4].multiplier = phase->slope_bp; - - bank0_phasing[CPCAP_ADC_AD0_BATTDETB].offset = phase->offset_battt; - bank0_phasing[CPCAP_ADC_AD0_BATTDETB].multiplier = phase->slope_battt; - - bank0_phasing[CPCAP_ADC_VBUS].offset = phase->offset_chrgv; - bank0_phasing[CPCAP_ADC_VBUS].multiplier = phase->slope_chrgv; -} -EXPORT_SYMBOL_GPL(cpcap_adc_phase); - -static void adc_phase(struct cpcap_adc_request *req, int index) -{ - struct conversion_tbl *conv_tbl = bank0_conversion; - struct phasing_tbl *phase_tbl = bank0_phasing; - int tbl_index = index; - - if (req->type == CPCAP_ADC_TYPE_BANK_1) { - conv_tbl = bank1_conversion; - phase_tbl = bank1_phasing; - } - - if (req->type == CPCAP_ADC_TYPE_BATT_PI) - tbl_index = (tbl_index % 2) ? CPCAP_ADC_BATTI_ADC : - CPCAP_ADC_BATTP; - - req->result[index] += conv_tbl[tbl_index].align_offset; - req->result[index] *= phase_tbl[tbl_index].multiplier; - req->result[index] /= phase_tbl[tbl_index].divider; - req->result[index] += phase_tbl[tbl_index].offset; - - if (req->result[index] < phase_tbl[tbl_index].min) - req->result[index] = phase_tbl[tbl_index].min; - else if (req->result[index] > phase_tbl[tbl_index].max) - req->result[index] = phase_tbl[tbl_index].max; -} - -static void adc_convert(struct cpcap_adc_request *req, int index) -{ - struct conversion_tbl *conv_tbl = bank0_conversion; - int tbl_index = index; - - if (req->type == CPCAP_ADC_TYPE_BANK_1) - conv_tbl = bank1_conversion; - - if (req->type == CPCAP_ADC_TYPE_BATT_PI) - tbl_index = (tbl_index % 2) ? CPCAP_ADC_BATTI_ADC : - CPCAP_ADC_BATTP; - - if (conv_tbl[tbl_index].conv_type == CONV_TYPE_DIRECT) { - req->result[index] *= conv_tbl[tbl_index].multiplier; - req->result[index] /= conv_tbl[tbl_index].divider; - req->result[index] += conv_tbl[tbl_index].conv_offset; - } else if (conv_tbl[tbl_index].conv_type == CONV_TYPE_MAPPING) - req->result[index] = convert_to_kelvins(req->result[tbl_index]); -} - -static void adc_raw(struct cpcap_adc_request *req, int index) -{ - struct conversion_tbl *conv_tbl = bank0_conversion; - struct phasing_tbl *phase_tbl = bank0_phasing; - int tbl_index = index; - - if (req->type == CPCAP_ADC_TYPE_BANK_1) - return; - - if (req->type == CPCAP_ADC_TYPE_BATT_PI) - tbl_index = (tbl_index % 2) ? CPCAP_ADC_BATTI_ADC : - CPCAP_ADC_BATTP; - - req->result[index] += conv_tbl[tbl_index].align_offset; - - if (req->result[index] < phase_tbl[tbl_index].min) - req->result[index] = phase_tbl[tbl_index].min; - else if (req->result[index] > phase_tbl[tbl_index].max) - req->result[index] = phase_tbl[tbl_index].max; -} - -static void adc_result(struct cpcap_device *cpcap, - struct cpcap_adc_request *req) -{ - int i; - int j; - - for (i = CPCAP_REG_ADCD0; i <= CPCAP_REG_ADCD7; i++) { - j = i - CPCAP_REG_ADCD0; - cpcap_regacc_read(cpcap, i, (unsigned short *)&req->result[j]); - req->result[j] &= 0x3FF; - - switch (req->format) { - case CPCAP_ADC_FORMAT_PHASED: - adc_phase(req, j); - break; - - case CPCAP_ADC_FORMAT_CONVERTED: - adc_phase(req, j); - adc_convert(req, j); - break; - - case CPCAP_ADC_FORMAT_RAW: - adc_raw(req, j); - break; - - default: - break; - } - } -} - -static void cpcap_adc_irq(enum cpcap_irqs irq, void *data) -{ - struct cpcap_adc *adc = data; - struct cpcap_device *cpcap = adc->cpcap; - struct cpcap_adc_request *req; - int head; - - cancel_delayed_work_sync(&adc->work); - - cpcap_regacc_write(cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ADTRIG_DIS, - CPCAP_BIT_ADTRIG_DIS); - - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - - req = adc->queue[head]; - if (!req) { - dev_info(&(cpcap->spi->dev), - "cpcap_adc_irq: ADC queue empty!\n"); - mutex_unlock(&adc->queue_mutex); - return; - } - adc->queue[head] = NULL; - adc->queue_head = (head + 1) & (MAX_ADC_FIFO_DEPTH - 1); - - mutex_unlock(&adc->queue_mutex); - - adc_result(cpcap, req); - - trigger_next_adc_job_if_any(cpcap); - - req->status = 0; - - req->callback(cpcap, req->callback_param); -} - -static void cpcap_adc_cancel(struct work_struct *work) -{ - int head; - struct cpcap_adc_request *req; - struct cpcap_adc *adc = - container_of(work, struct cpcap_adc, work.work); - - cpcap_irq_mask(adc->cpcap, CPCAP_IRQ_ADCDONE); - - cpcap_regacc_write(adc->cpcap, CPCAP_REG_ADCC2, - CPCAP_BIT_ADTRIG_DIS, - CPCAP_BIT_ADTRIG_DIS); - - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - - req = adc->queue[head]; - if (!req) { - dev_info(&(adc->cpcap->spi->dev), - "cpcap_adc_cancel: ADC queue empty!\n"); - mutex_unlock(&adc->queue_mutex); - return; - } - adc->queue[head] = NULL; - adc->queue_head = (head + 1) & (MAX_ADC_FIFO_DEPTH - 1); - - mutex_unlock(&adc->queue_mutex); - - req->status = -ETIMEDOUT; - - req->callback(adc->cpcap, req->callback_param); - - trigger_next_adc_job_if_any(adc->cpcap); -} - -static int __devinit cpcap_adc_probe(struct platform_device *pdev) -{ - struct cpcap_adc *adc; - unsigned short cal_data; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - adc = kzalloc(sizeof(*adc), GFP_KERNEL); - if (!adc) - return -ENOMEM; - - adc->cpcap = pdev->dev.platform_data; - - platform_set_drvdata(pdev, adc); - adc->cpcap->adcdata = adc; - - mutex_init(&adc->queue_mutex); - - adc_setup_calibrate(adc->cpcap, CPCAP_ADC_CHG_ISENSE); - adc_setup_calibrate(adc->cpcap, CPCAP_ADC_BATTI_ADC); - - cal_data = 0; - cpcap_regacc_read(adc->cpcap, CPCAP_REG_ADCAL1, &cal_data); - bank0_conversion[CPCAP_ADC_CHG_ISENSE].align_offset = - ((short)cal_data * -1); - cal_data = 0; - cpcap_regacc_read(adc->cpcap, CPCAP_REG_ADCAL2, &cal_data); - bank0_conversion[CPCAP_ADC_BATTI_ADC].align_offset = - ((short)cal_data * -1); - - INIT_DELAYED_WORK(&adc->work, cpcap_adc_cancel); - - cpcap_irq_register(adc->cpcap, CPCAP_IRQ_ADCDONE, - cpcap_adc_irq, adc); - - return 0; -} - -static int __devexit cpcap_adc_remove(struct platform_device *pdev) -{ - struct cpcap_adc *adc = platform_get_drvdata(pdev); - int head; - - cancel_delayed_work_sync(&adc->work); - - cpcap_irq_free(adc->cpcap, CPCAP_IRQ_ADCDONE); - - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - - if (WARN_ON(adc->queue[head])) - dev_err(&pdev->dev, - "adc driver removed with request pending\n"); - - mutex_unlock(&adc->queue_mutex); - kfree(adc); - - return 0; -} - -static struct platform_driver cpcap_adc_driver = { - .driver = { - .name = "cpcap_adc", - }, - .probe = cpcap_adc_probe, - .remove = __devexit_p(cpcap_adc_remove), -}; - -static int __init cpcap_adc_init(void) -{ - return platform_driver_register(&cpcap_adc_driver); -} -module_init(cpcap_adc_init); - -static void __exit cpcap_adc_exit(void) -{ - platform_driver_unregister(&cpcap_adc_driver); -} -module_exit(cpcap_adc_exit); - -MODULE_ALIAS("platform:cpcap_adc"); -MODULE_DESCRIPTION("CPCAP ADC driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/cpcap-audio-core.c b/drivers/mfd/cpcap-audio-core.c deleted file mode 100644 index 620deafdbd04..000000000000 --- a/drivers/mfd/cpcap-audio-core.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * Copyright (C) 2007 - 2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MICBIAS_WARMUP_TIME_MS 39 -#define SLEEP_ACTIVATE_POWER_DELAY_MS 2 -#define STM_STDAC_ACTIVATE_RAMP_TIME 1 -#define CLOCK_TREE_RESET_DELAY_MS 1 - -#define CPCAP_AUDIO_SPI_READBACK 1 - -#define STM_STDAC_EN_TEST_PRE 0x090C -#define STM_STDAC_EN_TEST_POST 0x0000 -#define STM_STDAC_EN_ST_TEST1_PRE 0x2400 -#define STM_STDAC_EN_ST_TEST1_POST 0x0400 - -#define E(args...) pr_err("cpcap-audio: " args) - -static struct cpcap_audio_state current_state = { - .cpcap = NULL, - .mode = CPCAP_AUDIO_MODE_NORMAL, - - .codec_mode = CPCAP_AUDIO_CODEC_OFF, - .codec_rate = CPCAP_AUDIO_CODEC_RATE_8000_HZ, - .codec_mute = CPCAP_AUDIO_CODEC_MUTE, - - .stdac_mode = CPCAP_AUDIO_STDAC_OFF, - .stdac_rate = CPCAP_AUDIO_STDAC_RATE_8000_HZ, - .stdac_mute = CPCAP_AUDIO_STDAC_MUTE, - - .analog_source = CPCAP_AUDIO_ANALOG_SOURCE_OFF, - - .codec_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .codec_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - - .stdac_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .stdac_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - - .ext_primary_speaker = CPCAP_AUDIO_OUT_NONE, - .ext_secondary_speaker = CPCAP_AUDIO_OUT_NONE, - - .codec_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - .stdac_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - .ext_primary_balance = CPCAP_AUDIO_BALANCE_NEUTRAL, - - .output_gain = 0, - .microphone = CPCAP_AUDIO_IN_NONE, - .input_gain = 0, - .rat_type = CPCAP_AUDIO_RAT_NONE -}; - -/* Define regulator to turn on the audio portion of cpcap */ -struct regulator *audio_reg; - -static inline bool is_mic_stereo(int microphone) -{ - return microphone == CPCAP_AUDIO_IN_DUAL_INTERNAL || - microphone == CPCAP_AUDIO_IN_DUAL_EXTERNAL; -} - -static inline bool is_codec_changed(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - return state->codec_mode != prev->codec_mode || - state->codec_rate != prev->codec_rate || - state->rat_type != prev->rat_type || - state->microphone != prev->microphone; -} - -static inline bool is_stdac_changed(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - return state->stdac_mode != prev->stdac_mode || - state->rat_type != prev->rat_type || - state->stdac_rate != prev->stdac_rate; -} - -static inline bool is_output_bt_only(struct cpcap_audio_state *state) -{ - if (state->codec_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO && - state->codec_secondary_speaker == CPCAP_AUDIO_OUT_NONE) - return true; - - if (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO && - state->stdac_secondary_speaker == CPCAP_AUDIO_OUT_NONE) - return true; - - if (state->ext_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO && - state->ext_secondary_speaker == CPCAP_AUDIO_OUT_NONE) - return true; - - return false; -} - -static inline bool is_output_headset(struct cpcap_audio_state *state) -{ - if (state->codec_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->codec_primary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET || - state->codec_secondary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->codec_secondary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET) - return true; - - if (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->stdac_primary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET || - state->stdac_secondary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->stdac_secondary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET) - return true; - - if (state->ext_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->ext_primary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET || - state->ext_secondary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET || - state->ext_secondary_speaker == - CPCAP_AUDIO_OUT_MONO_HEADSET) - return true; - - return false; -} - -static inline int is_output_whisper_emu(struct cpcap_audio_state *state) -{ - if (state->codec_primary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO - || state->codec_secondary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO - || state->stdac_primary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO - || state->stdac_secondary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO - || state->ext_primary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO - || state->ext_secondary_speaker == CPCAP_AUDIO_OUT_EMU_STEREO) { - pr_debug("%s() returning TRUE\n", __func__); - return 1; - } - - pr_debug("%s() returning FALSE\n", __func__); - return 0; -} - -static inline bool is_speaker_turning_off(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - return (prev->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE && - state->codec_primary_speaker == - CPCAP_AUDIO_OUT_NONE) || - (prev->codec_secondary_speaker != CPCAP_AUDIO_OUT_NONE && - state->codec_secondary_speaker == - CPCAP_AUDIO_OUT_NONE) || - (prev->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE && - state->stdac_primary_speaker == - CPCAP_AUDIO_OUT_NONE) || - (prev->stdac_secondary_speaker != CPCAP_AUDIO_OUT_NONE && - state->stdac_secondary_speaker == - CPCAP_AUDIO_OUT_NONE) || - (prev->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE && - state->ext_primary_speaker == - CPCAP_AUDIO_OUT_NONE) || - (prev->ext_secondary_speaker != CPCAP_AUDIO_OUT_NONE && - state->ext_secondary_speaker == - CPCAP_AUDIO_OUT_NONE); -} - -static inline bool is_output_changed(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - if (state->codec_primary_speaker != prev->codec_primary_speaker || - state->codec_primary_balance != - prev->codec_primary_balance || - state->codec_secondary_speaker != - prev->codec_secondary_speaker) - return true; - - if (state->stdac_primary_speaker != prev->stdac_primary_speaker || - state->stdac_primary_balance != - prev->stdac_primary_balance || - state->stdac_secondary_speaker != - prev->stdac_secondary_speaker) - return true; - - if (state->ext_primary_speaker != prev->ext_primary_speaker || - state->ext_primary_balance != - prev->ext_primary_balance || - state->ext_secondary_speaker != - prev->ext_secondary_speaker) - return true; - - return false; -} - -/* this is only true for audio registers, but those are the only ones we use */ -#define CPCAP_REG_FOR_POWERIC_REG(a) ((a) + (0x200 - CPCAP_REG_VAUDIOC)) - -static void logged_cpcap_write(struct cpcap_device *cpcap, unsigned int reg, - unsigned short int value, unsigned short int mask) -{ - if (mask != 0) { - int ret_val = 0; - pr_debug("%s: audio: reg %u, value 0x%x,mask 0x%x\n", __func__, - CPCAP_REG_FOR_POWERIC_REG(reg), value, mask); - ret_val = cpcap_regacc_write(cpcap, reg, value, mask); - if (ret_val != 0) - E("%s: w %04x m %04x -> r %u failed: %d\n", __func__, - value, mask, reg, ret_val); -#if CPCAP_AUDIO_SPI_READBACK - ret_val = cpcap_regacc_read(cpcap, reg, &value); - if (ret_val == 0) - pr_debug("%s: audio verify: reg %u: value 0x%x\n", - __func__, - CPCAP_REG_FOR_POWERIC_REG(reg), value); - else - E("%s: audio verify: reg %u FAILED\n", __func__, - CPCAP_REG_FOR_POWERIC_REG(reg)); -#endif - } -} - -static unsigned short int cpcap_audio_get_codec_output_amp_switches( - int speaker, int balance) -{ - unsigned short int value = CPCAP_BIT_PGA_CDC_EN; - - pr_debug("%s() called with speaker = %d\n", __func__, - speaker); - - switch (speaker) { - case CPCAP_AUDIO_OUT_HANDSET: - value |= CPCAP_BIT_A1_EAR_CDC_SW; - break; - - case CPCAP_AUDIO_OUT_LOUDSPEAKER: - value |= CPCAP_BIT_A2_LDSP_L_CDC_SW; - break; - - case CPCAP_AUDIO_OUT_MONO_HEADSET: - case CPCAP_AUDIO_OUT_STEREO_HEADSET: - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value |= CPCAP_BIT_ARIGHT_HS_CDC_SW; - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_ALEFT_HS_CDC_SW; - break; - - case CPCAP_AUDIO_OUT_EMU_STEREO: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_PGA_OUTR_USBDP_CDC_SW; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value |= CPCAP_BIT_PGA_OUTL_USBDN_CDC_SW; - break; - - case CPCAP_AUDIO_OUT_LINEOUT: - value |= CPCAP_BIT_A4_LINEOUT_R_CDC_SW | - CPCAP_BIT_A4_LINEOUT_L_CDC_SW; - break; - - case CPCAP_AUDIO_OUT_BT_MONO: - default: - value = 0; - break; - } - - pr_debug("Exiting %s() with return value = %d\n", __func__, - value); - return value; -} - -static unsigned short int cpcap_audio_get_stdac_output_amp_switches( - int speaker, int balance) -{ - unsigned short int value = CPCAP_BIT_PGA_DAC_EN; - - pr_debug("%s() called with speaker = %d\n", __func__, - speaker); - - switch (speaker) { - case CPCAP_AUDIO_OUT_HANDSET: - value |= CPCAP_BIT_A1_EAR_DAC_SW; - break; - - case CPCAP_AUDIO_OUT_MONO_HEADSET: - case CPCAP_AUDIO_OUT_STEREO_HEADSET: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_ALEFT_HS_DAC_SW; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value |= CPCAP_BIT_ARIGHT_HS_DAC_SW; - break; - - case CPCAP_AUDIO_OUT_EMU_STEREO: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_PGA_OUTR_USBDP_DAC_SW; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value |= CPCAP_BIT_PGA_OUTL_USBDN_DAC_SW; - break; - - case CPCAP_AUDIO_OUT_LOUDSPEAKER: - value |= CPCAP_BIT_A2_LDSP_L_DAC_SW | CPCAP_BIT_MONO_DAC0 | - CPCAP_BIT_MONO_DAC1; - break; - - case CPCAP_AUDIO_OUT_LINEOUT: - value |= CPCAP_BIT_A4_LINEOUT_R_DAC_SW | - CPCAP_BIT_A4_LINEOUT_L_DAC_SW; - break; - - case CPCAP_AUDIO_OUT_BT_MONO: - default: - value = 0; - break; - } - - pr_debug("Exiting %s() with return value = %d\n", __func__, - value); - return value; -} - -static unsigned short int cpcap_audio_get_ext_output_amp_switches( - int speaker, int balance) -{ - unsigned short int value = 0; - pr_debug("%s() called with speaker %d\n", __func__, - speaker); - switch (speaker) { - case CPCAP_AUDIO_OUT_HANDSET: - value = CPCAP_BIT_A1_EAR_EXT_SW | CPCAP_BIT_PGA_EXT_R_EN; - break; - - case CPCAP_AUDIO_OUT_MONO_HEADSET: - case CPCAP_AUDIO_OUT_STEREO_HEADSET: - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value = CPCAP_BIT_ARIGHT_HS_EXT_SW | - CPCAP_BIT_PGA_EXT_R_EN; - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_ALEFT_HS_EXT_SW | - CPCAP_BIT_PGA_EXT_L_EN; - break; - - case CPCAP_AUDIO_OUT_EMU_STEREO: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - value |= CPCAP_BIT_PGA_OUTR_USBDP_EXT_SW; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - value |= CPCAP_BIT_PGA_OUTL_USBDN_EXT_SW; - break; - - case CPCAP_AUDIO_OUT_LOUDSPEAKER: - value = CPCAP_BIT_A2_LDSP_L_EXT_SW | CPCAP_BIT_PGA_EXT_L_EN; - break; - - case CPCAP_AUDIO_OUT_LINEOUT: - value = CPCAP_BIT_A4_LINEOUT_R_EXT_SW | - CPCAP_BIT_A4_LINEOUT_L_EXT_SW | - CPCAP_BIT_PGA_EXT_L_EN | CPCAP_BIT_PGA_EXT_R_EN; - break; - - case CPCAP_AUDIO_OUT_BT_MONO: - default: - value = 0; - break; - } - - pr_debug("Exiting %s() with return value = %d\n", __func__, - value); - return value; -} - -static void cpcap_audio_set_output_amp_switches(struct cpcap_audio_state *state) -{ - static unsigned int codec_prev_settings; - static unsigned int stdac_prev_settings; - static unsigned int ext_prev_settings; - - struct cpcap_regacc reg_changes; - unsigned short int value1 = 0, value2 = 0; - - /* First set codec output amp switches */ - value1 = cpcap_audio_get_codec_output_amp_switches(state-> - codec_primary_speaker, state->codec_primary_balance); - value2 = cpcap_audio_get_codec_output_amp_switches(state-> - codec_secondary_speaker, state->codec_primary_balance); - - reg_changes.mask = value1 | value2 | codec_prev_settings; - reg_changes.value = value1 | value2; - codec_prev_settings = reg_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA, reg_changes.value, - reg_changes.mask); - - /* Second Stdac switches */ - value1 = cpcap_audio_get_stdac_output_amp_switches(state-> - stdac_primary_speaker, state->stdac_primary_balance); - value2 = cpcap_audio_get_stdac_output_amp_switches(state-> - stdac_secondary_speaker, state->stdac_primary_balance); - - reg_changes.mask = value1 | value2 | stdac_prev_settings; - reg_changes.value = value1 | value2; - - if ((state->stdac_primary_speaker == CPCAP_AUDIO_OUT_STEREO_HEADSET && - state->stdac_secondary_speaker == CPCAP_AUDIO_OUT_LOUDSPEAKER) - || (state->stdac_primary_speaker == CPCAP_AUDIO_OUT_LOUDSPEAKER - && state->stdac_secondary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET)) - reg_changes.value &= ~(CPCAP_BIT_MONO_DAC0 | - CPCAP_BIT_MONO_DAC1); - - stdac_prev_settings = reg_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA, reg_changes.value, - reg_changes.mask); - - /* Last External source switches */ - value1 = - cpcap_audio_get_ext_output_amp_switches(state-> - ext_primary_speaker, - state->ext_primary_balance); - value2 = - cpcap_audio_get_ext_output_amp_switches(state-> - ext_secondary_speaker, - state->ext_primary_balance); - - reg_changes.mask = value1 | value2 | ext_prev_settings; - reg_changes.value = value1 | value2; - ext_prev_settings = reg_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA, - reg_changes.value, reg_changes.mask); -} - -static bool cpcap_audio_set_bits_for_speaker(int speaker, int balance, - unsigned short int *message) -{ - /* Get the data required to enable each possible path */ - switch (speaker) { - case CPCAP_AUDIO_OUT_HANDSET: - (*message) |= CPCAP_BIT_A1_EAR_EN; - break; - - case CPCAP_AUDIO_OUT_MONO_HEADSET: - case CPCAP_AUDIO_OUT_STEREO_HEADSET: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - (*message) |= CPCAP_BIT_HS_L_EN; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - (*message) |= CPCAP_BIT_HS_R_EN; - break; - - case CPCAP_AUDIO_OUT_EMU_STEREO: - if (balance != CPCAP_AUDIO_BALANCE_R_ONLY) - (*message) |= CPCAP_BIT_EMU_SPKR_R_EN; - if (balance != CPCAP_AUDIO_BALANCE_L_ONLY) - (*message) |= CPCAP_BIT_EMU_SPKR_L_EN; - break; - - case CPCAP_AUDIO_OUT_LOUDSPEAKER: - (*message) |= CPCAP_BIT_A2_LDSP_L_EN; - break; - - case CPCAP_AUDIO_OUT_LINEOUT: - (*message) |= CPCAP_BIT_A4_LINEOUT_R_EN | - CPCAP_BIT_A4_LINEOUT_L_EN; - break; - - case CPCAP_AUDIO_OUT_BT_MONO: - default: - (*message) |= 0; - break; - } - - return false; /* There is no external loudspeaker on this product */ -} - -static void cpcap_audio_configure_aud_mute(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - struct cpcap_regacc reg_changes = { 0 }; - unsigned short int value1 = 0, value2 = 0; - - if (state->codec_mute != prev->codec_mute) { - value1 = cpcap_audio_get_codec_output_amp_switches( - prev->codec_primary_speaker, - prev->codec_primary_balance); - - value2 = cpcap_audio_get_codec_output_amp_switches( - prev->codec_secondary_speaker, - prev->codec_primary_balance); - - reg_changes.mask = value1 | value2 | CPCAP_BIT_CDC_SW; - - if (state->codec_mute == CPCAP_AUDIO_CODEC_UNMUTE) - reg_changes.value = reg_changes.mask; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA, - reg_changes.value, reg_changes.mask); - } - - if (state->stdac_mute != prev->stdac_mute) { - value1 = cpcap_audio_get_stdac_output_amp_switches( - prev->stdac_primary_speaker, - prev->stdac_primary_balance); - - value2 = cpcap_audio_get_stdac_output_amp_switches( - prev->stdac_secondary_speaker, - prev->stdac_primary_balance); - - reg_changes.mask = value1 | value2 | CPCAP_BIT_ST_DAC_SW; - - if (state->stdac_mute == CPCAP_AUDIO_STDAC_UNMUTE) - reg_changes.value = reg_changes.mask; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA, - reg_changes.value, reg_changes.mask); - } -} - -static void cpcap_audio_configure_codec(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - unsigned int temp_codec_rate = state->codec_rate; - struct cpcap_regacc cdai_changes = { 0 }; - struct cpcap_regacc codec_changes = { 0 }; - int codec_freq_config = 0; - - const unsigned int CODEC_FREQ_MASK = CPCAP_BIT_CDC_CLK0 - | CPCAP_BIT_CDC_CLK1 | CPCAP_BIT_CDC_CLK2; - const unsigned int CODEC_RESET_FREQ_MASK = CODEC_FREQ_MASK - | CPCAP_BIT_CDC_CLOCK_TREE_RESET; - - static unsigned int prev_codec_data = 0x0, prev_cdai_data = 0x0; - - if (!is_codec_changed(state, prev)) - return; - - if (state->rat_type == CPCAP_AUDIO_RAT_CDMA) - codec_freq_config = (CPCAP_BIT_CDC_CLK0 - | CPCAP_BIT_CDC_CLK1) ; /* 19.2Mhz */ - else - codec_freq_config = CPCAP_BIT_CDC_CLK2 ; /* 26Mhz */ - - /* If a codec is already in use, reset codec to initial state */ - if (prev->codec_mode != CPCAP_AUDIO_CODEC_OFF) { - codec_changes.mask = prev_codec_data - | CPCAP_BIT_DF_RESET - | CPCAP_BIT_CDC_CLOCK_TREE_RESET; - - logged_cpcap_write(state->cpcap, CPCAP_REG_CC, - codec_changes.value, codec_changes.mask); - - prev_codec_data = 0; - prev->codec_mode = CPCAP_AUDIO_CODEC_OFF; - } - - temp_codec_rate &= 0x0000000F; - temp_codec_rate = temp_codec_rate << 9; - - switch (state->codec_mode) { - case CPCAP_AUDIO_CODEC_LOOPBACK: - case CPCAP_AUDIO_CODEC_ON: - if (state->codec_primary_speaker != - CPCAP_AUDIO_OUT_NONE) { - codec_changes.value |= CPCAP_BIT_CDC_EN_RX; - } - - /* Turning on the input HPF */ - if (state->microphone != CPCAP_AUDIO_IN_NONE) - codec_changes.value |= CPCAP_BIT_AUDIHPF_0 | - CPCAP_BIT_AUDIHPF_1; - -#if 1 - if (state->microphone != CPCAP_AUDIO_IN_NONE) { - codec_changes.value |= CPCAP_BIT_MIC1_CDC_EN; - codec_changes.value |= CPCAP_BIT_MIC2_CDC_EN; - } -#else - if (state->microphone != CPCAP_AUDIO_IN_AUX_INTERNAL && - state->microphone != CPCAP_AUDIO_IN_NONE) - codec_changes.value |= CPCAP_BIT_MIC1_CDC_EN | - CPCAP_BIT_MIC2_CDC_EN; - - if (state->microphone == CPCAP_AUDIO_IN_AUX_INTERNAL || - is_mic_stereo(state->microphone)) - codec_changes.value |= CPCAP_BIT_MIC2_CDC_EN; -#endif - - /* falling through intentionally */ - case CPCAP_AUDIO_CODEC_CLOCK_ONLY: - codec_changes.value |= - (codec_freq_config | temp_codec_rate | - CPCAP_BIT_DF_RESET); - cdai_changes.value |= CPCAP_BIT_CDC_CLK_EN; - break; - - case CPCAP_AUDIO_CODEC_OFF: - cdai_changes.value |= CPCAP_BIT_SMB_CDC; - break; - - default: - break; - } - - /* Multimedia uses CLK_IN0, incall uses CLK_IN1 */ - if (state->rat_type != CPCAP_AUDIO_RAT_NONE) - cdai_changes.value |= CPCAP_BIT_CLK_IN_SEL; - - cdai_changes.value |= CPCAP_BIT_CDC_PLL_SEL; -#if 0 - cdai_changes.value |= CPCAP_BIT_DIG_AUD_IN; -#endif - -#ifdef CODEC_IS_I2S_MODE - cdai_changes.value |= CPCAP_BIT_CLK_INV; - /* Setting I2S mode */ - cdai_changes.value |= CPCAP_BIT_CDC_DIG_AUD_FS0 | - CPCAP_BIT_CDC_DIG_AUD_FS1 | - CPCAP_BIT_MIC2_TIMESLOT0; -#else - /* Setting CODEC mode */ - /* FS: Not inverted. - * Clk: Not inverted. - * TS2/TS1/TS0 not set, using timeslot 0 for mic1. - */ - cdai_changes.value |= CPCAP_BIT_CDC_DIG_AUD_FS0; -#endif - - /* OK, now start paranoid codec sequence */ - /* FIRST, make sure the frequency config is right... */ - logged_cpcap_write(state->cpcap, CPCAP_REG_CC, - codec_freq_config, CODEC_FREQ_MASK); - - /* Next, write the CDAI if it's changed */ - if (prev_cdai_data != cdai_changes.value) { - cdai_changes.mask = cdai_changes.value - | prev_cdai_data; - prev_cdai_data = cdai_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_CDI, - cdai_changes.value, cdai_changes.mask); - - /* Clock tree change -- reset and wait */ - codec_freq_config |= CPCAP_BIT_CDC_CLOCK_TREE_RESET; - - logged_cpcap_write(state->cpcap, CPCAP_REG_CC, - codec_freq_config, CODEC_RESET_FREQ_MASK); - - /* Wait for clock tree reset to complete */ - mdelay(CLOCK_TREE_RESET_DELAY_MS); - } - - /* Clear old settings */ - codec_changes.mask = codec_changes.value | prev_codec_data; - prev_codec_data = codec_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_CC, - codec_changes.value, codec_changes.mask); -} - -static void cpcap_audio_configure_stdac(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - const unsigned int SDAC_FREQ_MASK = CPCAP_BIT_ST_DAC_CLK0 - | CPCAP_BIT_ST_DAC_CLK1 | CPCAP_BIT_ST_DAC_CLK2; - const unsigned int SDAC_RESET_FREQ_MASK = SDAC_FREQ_MASK - | CPCAP_BIT_ST_CLOCK_TREE_RESET; - static unsigned int prev_stdac_data, prev_sdai_data; - - if (is_stdac_changed(state, prev)) { - unsigned int temp_stdac_rate = state->stdac_rate; - struct cpcap_regacc sdai_changes = { 0 }; - struct cpcap_regacc stdac_changes = { 0 }; - - int stdac_freq_config = 0; - if (state->rat_type == CPCAP_AUDIO_RAT_CDMA) - stdac_freq_config = (CPCAP_BIT_ST_DAC_CLK0 - | CPCAP_BIT_ST_DAC_CLK1) ; /*19.2Mhz*/ - else - stdac_freq_config = CPCAP_BIT_ST_DAC_CLK2 ; /* 26Mhz */ - - /* We need to turn off stdac before changing its settings */ - if (prev->stdac_mode != CPCAP_AUDIO_STDAC_OFF) { - stdac_changes.mask = prev_stdac_data | - CPCAP_BIT_DF_RESET_ST_DAC | - CPCAP_BIT_ST_CLOCK_TREE_RESET; - - logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, - stdac_changes.value, stdac_changes.mask); - - prev_stdac_data = 0; - prev->stdac_mode = CPCAP_AUDIO_STDAC_OFF; - } - - temp_stdac_rate &= 0x0000000F; - temp_stdac_rate = temp_stdac_rate << 4; - - switch (state->stdac_mode) { - case CPCAP_AUDIO_STDAC_ON: - stdac_changes.value |= CPCAP_BIT_ST_DAC_EN; - /* falling through intentionally */ - case CPCAP_AUDIO_STDAC_CLOCK_ONLY: - stdac_changes.value |= temp_stdac_rate | - CPCAP_BIT_DF_RESET_ST_DAC | stdac_freq_config; - sdai_changes.value |= CPCAP_BIT_ST_CLK_EN; - break; - - case CPCAP_AUDIO_STDAC_OFF: - default: - break; - } - - if (state->rat_type != CPCAP_AUDIO_RAT_NONE) - sdai_changes.value |= CPCAP_BIT_ST_DAC_CLK_IN_SEL; - /* begin everest change */ - /* - sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 | - CPCAP_BIT_DIG_AUD_IN_ST_DAC | CPCAP_BIT_ST_L_TIMESLOT0; - */ - /* I2S Mode, ignore timeslots, invert bit clock */ - sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 | - CPCAP_BIT_DIG_AUD_IN_ST_DAC | - CPCAP_BIT_ST_DIG_AUD_FS1 | CPCAP_BIT_ST_CLK_INV; - /* end everest change */ - - logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, - stdac_freq_config, SDAC_FREQ_MASK); - - /* Next, write the SDACDI if it's changed */ - if (prev_sdai_data != sdai_changes.value) { - sdai_changes.mask = sdai_changes.value - | prev_sdai_data; - prev_sdai_data = sdai_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI, - sdai_changes.value, sdai_changes.mask); - - /* Clock tree change -- reset and wait */ - stdac_freq_config |= CPCAP_BIT_ST_CLOCK_TREE_RESET; - - logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, - stdac_freq_config, SDAC_RESET_FREQ_MASK); - - /* Wait for clock tree reset to complete */ - mdelay(CLOCK_TREE_RESET_DELAY_MS); - } - - /* Clear old settings */ - stdac_changes.mask = stdac_changes.value | prev_stdac_data; - prev_stdac_data = stdac_changes.value; - - if ((stdac_changes.value | CPCAP_BIT_ST_DAC_EN) && - (state->cpcap->vendor == CPCAP_VENDOR_ST)) { - logged_cpcap_write(state->cpcap, CPCAP_REG_TEST, - STM_STDAC_EN_TEST_PRE, 0xFFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_ST_TEST1, - STM_STDAC_EN_ST_TEST1_PRE, 0xFFFF); - } - - logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, - stdac_changes.value, stdac_changes.mask); - - if ((stdac_changes.value | CPCAP_BIT_ST_DAC_EN) && - (state->cpcap->vendor == CPCAP_VENDOR_ST)) { - msleep(STM_STDAC_ACTIVATE_RAMP_TIME); - logged_cpcap_write(state->cpcap, CPCAP_REG_ST_TEST1, - STM_STDAC_EN_ST_TEST1_POST, 0xFFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_TEST, - STM_STDAC_EN_TEST_POST, 0xFFFF); - } - } -} - -static void cpcap_audio_configure_analog_source( - struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - if (state->analog_source != prev->analog_source) { - struct cpcap_regacc ext_changes = { 0 }; - static unsigned int prev_ext_data; - switch (state->analog_source) { - case CPCAP_AUDIO_ANALOG_SOURCE_STEREO: - ext_changes.value |= CPCAP_BIT_MONO_EXT0 | - CPCAP_BIT_PGA_IN_R_SW | CPCAP_BIT_PGA_IN_L_SW; - break; - case CPCAP_AUDIO_ANALOG_SOURCE_L: - ext_changes.value |= CPCAP_BIT_MONO_EXT1 | - CPCAP_BIT_PGA_IN_L_SW; - break; - case CPCAP_AUDIO_ANALOG_SOURCE_R: - ext_changes.value |= CPCAP_BIT_MONO_EXT1 | - CPCAP_BIT_PGA_IN_R_SW; - break; - default: - break; - } - - ext_changes.mask = ext_changes.value | prev_ext_data; - - prev_ext_data = ext_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA, - ext_changes.value, ext_changes.mask); - } -} - -static void cpcap_audio_configure_input_gains( - struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - if (state->input_gain != prev->input_gain) { - struct cpcap_regacc reg_changes = { 0 }; - unsigned int temp_input_gain = state->input_gain & 0x0000001F; - - reg_changes.value |= ((temp_input_gain << 5) | temp_input_gain); - - reg_changes.mask = 0x3FF; - - logged_cpcap_write(state->cpcap, CPCAP_REG_TXMP, - reg_changes.value, reg_changes.mask); - } -} - -static void cpcap_audio_configure_output_gains( - struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - if (state->output_gain != prev->output_gain) { - struct cpcap_regacc reg_changes = { 0 }; - unsigned int temp_output_gain = state->output_gain & 0x0000000F; - - reg_changes.value |= - ((temp_output_gain << 2) | (temp_output_gain << 8)); - /* VOL_EXTx is disabled, it's not connected, disable to reduce - * noise. If you need it, add | (temp_output_gain << 12) - */ - reg_changes.mask = 0xFF3C; - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXVC, - reg_changes.value, reg_changes.mask); - } -} - -static void cpcap_audio_configure_output( - struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - static unsigned int prev_aud_out_data; - - bool activate_ext_loudspeaker = false; - struct cpcap_regacc reg_changes = { 0 }; - - if (!is_output_changed(prev, state) && - !is_codec_changed(prev, state) && - !is_stdac_changed(prev, state)) - return; - - cpcap_audio_set_output_amp_switches(state); - - activate_ext_loudspeaker = cpcap_audio_set_bits_for_speaker( - state->codec_primary_speaker, - state->codec_primary_balance, - &(reg_changes.value)); - - activate_ext_loudspeaker = activate_ext_loudspeaker || - cpcap_audio_set_bits_for_speaker( - state->codec_secondary_speaker, - CPCAP_AUDIO_BALANCE_NEUTRAL, - &(reg_changes.value)); - - activate_ext_loudspeaker = activate_ext_loudspeaker || - cpcap_audio_set_bits_for_speaker( - state->stdac_primary_speaker, - state->stdac_primary_balance, - &(reg_changes.value)); - - activate_ext_loudspeaker = activate_ext_loudspeaker || - cpcap_audio_set_bits_for_speaker( - state->stdac_secondary_speaker, - CPCAP_AUDIO_BALANCE_NEUTRAL, - &(reg_changes.value)); - - activate_ext_loudspeaker = activate_ext_loudspeaker || - cpcap_audio_set_bits_for_speaker( - state->ext_primary_speaker, - state->ext_primary_balance, - &(reg_changes.value)); - - activate_ext_loudspeaker = activate_ext_loudspeaker || - cpcap_audio_set_bits_for_speaker( - state->ext_secondary_speaker, - CPCAP_AUDIO_BALANCE_NEUTRAL, - &(reg_changes.value)); - - reg_changes.mask = reg_changes.value | prev_aud_out_data; - - prev_aud_out_data = reg_changes.value; - - /* Sleep for 300ms if we are getting into a call to allow the switch to - * settle. If we don't do this, it causes a loud pop at the beginning - * of the call. - */ - if (state->rat_type == CPCAP_AUDIO_RAT_CDMA && - state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE && - prev->ext_primary_speaker == CPCAP_AUDIO_OUT_NONE) - msleep(300); - - logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA, - reg_changes.value, reg_changes.mask); -} - -static inline bool codec_loopback_changed(struct cpcap_audio_state *new, - struct cpcap_audio_state *old) -{ - return (new->codec_mode != old->codec_mode) && - (new->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK || - old->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK); -} - -static void cpcap_audio_configure_input(struct cpcap_audio_state *state, - struct cpcap_audio_state *prev) -{ - static unsigned int prev_input_data = 0x0; - struct cpcap_regacc reg_changes = { 0 }; - bool bias_settle = false; - - if (state->microphone == prev->microphone && - !codec_loopback_changed(state, prev)) - return; - - if (state->codec_mode == CPCAP_AUDIO_CODEC_LOOPBACK) - reg_changes.value |= CPCAP_BIT_DLM; - - if (prev->microphone == CPCAP_AUDIO_IN_HEADSET) - logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4, - 0, CPCAP_BIT_GPIO4DRV); - - switch (state->microphone) { - case CPCAP_AUDIO_IN_HANDSET: - pr_debug("%s: handset\n", __func__); - reg_changes.value |= CPCAP_BIT_MB_ON1R - | CPCAP_BIT_MIC1_MUX | CPCAP_BIT_MIC1_PGA_EN; - bias_settle = true; - break; - - case CPCAP_AUDIO_IN_HEADSET: - pr_debug("%s: headset\n", __func__); - reg_changes.value |= CPCAP_BIT_HS_MIC_MUX - | CPCAP_BIT_MIC1_PGA_EN; - if (state->rat_type == CPCAP_AUDIO_RAT_CDMA) - logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4, - CPCAP_BIT_GPIO4DRV, CPCAP_BIT_GPIO4DRV); - bias_settle = true; - break; - - case CPCAP_AUDIO_IN_EXT_BUS: - reg_changes.value |= CPCAP_BIT_EMU_MIC_MUX - | CPCAP_BIT_MIC1_PGA_EN; - break; - - case CPCAP_AUDIO_IN_AUX_INTERNAL: - reg_changes.value |= CPCAP_BIT_MB_ON1L - | CPCAP_BIT_MIC2_MUX | CPCAP_BIT_MIC2_PGA_EN; - break; - - case CPCAP_AUDIO_IN_DUAL_INTERNAL: - reg_changes.value |= CPCAP_BIT_MB_ON1R - | CPCAP_BIT_MIC1_MUX | CPCAP_BIT_MIC1_PGA_EN - | CPCAP_BIT_MB_ON1L | CPCAP_BIT_MIC2_MUX - | CPCAP_BIT_MIC2_PGA_EN; - break; - - case CPCAP_AUDIO_IN_DUAL_EXTERNAL: - reg_changes.value |= CPCAP_BIT_RX_R_ENCODE - | CPCAP_BIT_RX_L_ENCODE; - break; - - case CPCAP_AUDIO_IN_BT_MONO: - default: - reg_changes.value = 0; - break; - } - - reg_changes.mask = reg_changes.value | prev_input_data; - prev_input_data = reg_changes.value; - - logged_cpcap_write(state->cpcap, CPCAP_REG_TXI, - reg_changes.value, reg_changes.mask); - if (bias_settle) - msleep(MICBIAS_WARMUP_TIME_MS); -} - -static void cpcap_audio_configure_power(int power) -{ - static int previous_power; - - pr_debug("%s() called with power= %d\n", __func__, power); - - if (power == previous_power) - return; - - if (IS_ERR_OR_NULL(audio_reg)) { - E("audio_reg not valid for regulator setup\n"); - return; - } - - if (power) { - pr_info("%s: regulator -> enable\n", __func__); - regulator_enable(audio_reg); - regulator_set_mode(audio_reg, REGULATOR_MODE_NORMAL); - mdelay(SLEEP_ACTIVATE_POWER_DELAY_MS); - } else { - pr_info("%s: regulator -> standby\n", __func__); - regulator_set_mode(audio_reg, REGULATOR_MODE_STANDBY); - regulator_disable(audio_reg); - } - - previous_power = power; -} - -static void cpcap_activate_whisper_emu_audio(struct cpcap_audio_state *state) -{ - struct cpcap_regacc reg_changes; - - pr_debug("%s() called\n", __func__); - - if (is_output_whisper_emu(state)) { - reg_changes.mask |= CPCAP_BIT_DIG_AUD_IN; - reg_changes.value = 0; - logged_cpcap_write(state->cpcap, CPCAP_REG_CDI, - reg_changes.value, reg_changes.mask); - } -} - -void cpcap_audio_state_dump(struct cpcap_audio_state *state) -{ - pr_info("mode = %d", state->mode); - pr_info("codec_mode = %d", state->codec_mode); - pr_info("codec_rate = %d", state->codec_rate); - pr_info("codec_mute = %d", state->codec_mute); - pr_info("stdac_mode = %d", state->stdac_mode); - pr_info("stdac_rate = %d", state->stdac_rate); - pr_info("stdac_mute = %d", state->stdac_mute); - pr_info("analog_source = %d", state->analog_source); - pr_info("codec_primary_speaker = %d", state->codec_primary_speaker); - pr_info("codec_secondary_speaker = %d", state->codec_secondary_speaker); - pr_info("stdac_primary_speaker = %d", state->stdac_primary_speaker); - pr_info("stdac_secondary_speaker = %d", state->stdac_secondary_speaker); - pr_info("ext_primary_speaker = %d", state->ext_primary_speaker); - pr_info("ext_secondary_speaker = %d", state->ext_secondary_speaker); - pr_info("codec_primary_balance = %d", state->codec_primary_balance); - pr_info("stdac_primary_balance = %d", state->stdac_primary_balance); - pr_info("ext_primary_balance = %d", state->ext_primary_balance); - pr_info("output_gain = %d", state->output_gain); - pr_info("microphone = %d", state->microphone); - pr_info("input_gain = %d", state->input_gain); - pr_info("rat_type = %d\n", state->rat_type); -} - -void cpcap_audio_register_dump(struct cpcap_audio_state *state) -{ - unsigned short reg_val = 0; - - cpcap_regacc_read(state->cpcap, CPCAP_REG_VAUDIOC, ®_val); - printk(KERN_INFO "0x200[512] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_CC, ®_val); - printk(KERN_INFO "0x201[513] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_CDI, ®_val); - printk(KERN_INFO "0x202[514] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_SDAC, ®_val); - printk(KERN_INFO "0x203[515] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_SDACDI, ®_val); - printk(KERN_INFO "0x204[516] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_TXI, ®_val); - printk(KERN_INFO "0x205[517] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_TXMP, ®_val); - printk(KERN_INFO "0x206[518] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXOA, ®_val); - printk(KERN_INFO "0x207[519] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXVC, ®_val); - printk(KERN_INFO "0x208[520] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXCOA, ®_val); - printk(KERN_INFO "0x209[521] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXSDOA, ®_val); - printk(KERN_INFO "0x20A[522] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXEPOA, ®_val); - printk(KERN_INFO "0x20B[523] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_RXLL, ®_val); - printk(KERN_INFO "0x20C[524] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_A2LA, ®_val); - printk(KERN_INFO "0x20D[525] = %x\n", reg_val); - cpcap_regacc_read(state->cpcap, CPCAP_REG_USBC2, ®_val); - printk(KERN_INFO "0x381[897] = %x\n", reg_val); -} - -static inline bool should_power_on(struct cpcap_audio_state *state) -{ - if (state->codec_mode != CPCAP_AUDIO_CODEC_OFF && - state->codec_mode != CPCAP_AUDIO_CODEC_CLOCK_ONLY) - return true; - - if (state->stdac_mode != CPCAP_AUDIO_STDAC_OFF) - return true; - - if (state->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE && - state->codec_primary_speaker != - CPCAP_AUDIO_OUT_BT_MONO) - return true; - - if (state->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE) - return true; - - if (state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE) - return true; - - if (state->microphone != CPCAP_AUDIO_IN_NONE && - state->microphone != CPCAP_AUDIO_IN_BT_MONO) - return true; - - return false; -} - -void cpcap_audio_set_audio_state(struct cpcap_audio_state *state) -{ - bool power_on; - struct cpcap_audio_state *prev = ¤t_state; - - if (state->codec_mute == CPCAP_AUDIO_CODEC_BYPASS_LOOP) - state->codec_mode = CPCAP_AUDIO_CODEC_ON; - - if (state->codec_mode == CPCAP_AUDIO_CODEC_OFF || - state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY || - state->rat_type == CPCAP_AUDIO_RAT_CDMA) - state->codec_mute = CPCAP_AUDIO_CODEC_MUTE; - else - state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE; - - if (state->stdac_mode != CPCAP_AUDIO_STDAC_ON) - state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE; - else - state->stdac_mute = CPCAP_AUDIO_STDAC_UNMUTE; - - if (state->stdac_mode == CPCAP_AUDIO_STDAC_CLOCK_ONLY) - state->stdac_mode = CPCAP_AUDIO_STDAC_ON; - - power_on = should_power_on(state); - - if (power_on) - cpcap_audio_configure_power(1); - - if (is_speaker_turning_off(state, prev)) - cpcap_audio_configure_output(state, prev); - - cpcap_audio_configure_analog_source(state, prev); - - cpcap_audio_configure_input(state, prev); - - cpcap_audio_configure_input_gains(state, prev); - - if (is_codec_changed(state, prev) || is_stdac_changed(state, prev)) { - int codec_mute = state->codec_mute; - int stdac_mute = state->stdac_mute; - - if (is_codec_changed(state, prev)) - state->codec_mute = CPCAP_AUDIO_CODEC_MUTE; - if (is_stdac_changed(state, prev)) - state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE; - - cpcap_audio_configure_aud_mute(state, prev); - - prev->codec_mute = state->codec_mute; - prev->stdac_mute = state->stdac_mute; - - state->codec_mute = codec_mute; - state->stdac_mute = stdac_mute; - - cpcap_audio_configure_codec(state, prev); - cpcap_audio_configure_stdac(state, prev); - } - - cpcap_audio_configure_output(state, prev); - - cpcap_audio_configure_output_gains(state, prev); - - cpcap_audio_configure_aud_mute(state, prev); - - cpcap_activate_whisper_emu_audio(state); - - if (!power_on) - cpcap_audio_configure_power(0); - - current_state = *state; -} - -int cpcap_audio_init(struct cpcap_audio_state *state, const char *regulator) -{ - logged_cpcap_write(state->cpcap, CPCAP_REG_CC, 0, 0xFFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_CDI, 0, 0xBFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC, 0, 0xFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI, 0, 0x3FFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_TXI, 0, 0xFDF); - logged_cpcap_write(state->cpcap, CPCAP_REG_TXMP, 0, 0xFFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA, 0, 0x1FF); - /* logged_cpcap_write(state->cpcap, CPCAP_REG_RXVC, 0, 0xFFF); */ - logged_cpcap_write(state->cpcap, CPCAP_REG_RXCOA, 0, 0x7FF); - logged_cpcap_write(state->cpcap, CPCAP_REG_RXSDOA, 0, 0x1FFF); - logged_cpcap_write(state->cpcap, CPCAP_REG_RXEPOA, 0, 0x7FFF); - - /* Use free running clock for amplifiers */ - logged_cpcap_write(state->cpcap, CPCAP_REG_A2LA, - CPCAP_BIT_A2_FREE_RUN, - CPCAP_BIT_A2_FREE_RUN); - - logged_cpcap_write(state->cpcap, CPCAP_REG_GPIO4, - CPCAP_BIT_GPIO4DIR, CPCAP_BIT_GPIO4DIR); - - audio_reg = regulator_get(NULL, regulator); - - if (IS_ERR(audio_reg)) { - E("could not get regulator for audio\n"); - return PTR_ERR(audio_reg); - } - - return 0; -} - -#ifdef CONFIG_DEBUG_FS - -#include -#include - -enum { - DEBUG_CPCAP_AUDIO_MODE, - DEBUG_CPCAP_AUDIO_CODEC_MODE, - DEBUG_CPCAP_AUDIO_CODEC_RATE, - DEBUG_CPCAP_AUDIO_CODEC_MUTE, - DEBUG_CPCAP_AUDIO_STDAC_MODE, - DEBUG_CPCAP_AUDIO_STDAC_RATE, - DEBUG_CPCAP_AUDIO_STDAC_MUTE, - DEBUG_CPCAP_AUDIO_ANALOG_SOURCE, - DEBUG_CPCAP_AUDIO_CODEC_PRIMARY_SPEAKER, - DEBUG_CPCAP_AUDIO_CODEC_SECONDARY_SPEAKER, - DEBUG_CPCAP_AUDIO_STDAC_PRIMARY_SPEAKER, - DEBUG_CPCAP_AUDIO_STDAC_SECONDARY_SPEAKER, - DEBUG_CPCAP_AUDIO_EXT_PRIMARY_SPEAKER, - DEBUG_CPCAP_AUDIO_EXT_SECONDARY_SPEAKER, - DEBUG_CPCAP_AUDIO_CODEC_PRIMARY_BALANCE, - DEBUG_CPCAP_AUDIO_STDAC_PRIMARY_BALANCE, - DEBUG_CPCAP_AUDIO_EXT_PRIMARY_BALANCE, - DEBUG_CPCAP_AUDIO_OUTPUT_GAIN, - DEBUG_CPCAP_AUDIO_MICROPHONE, - DEBUG_CPCAP_AUDIO_INPUT_GAIN, - DEBUG_CPCAP_RAT_TYPE, - DEBUG_CPCAP_NUM_FIELDS, -}; -static struct cpcap_audio_state debug_state; - -struct debug_audio_entry { - int id; - char *name; - int min; - int max; - int *dbg_val; - int *cur_val; -}; - -#define DBG_ENTRY(_id, _min, _max, _fld) \ -{ \ - .id = _id, \ - .name = #_fld, \ - .min = _min, \ - .max = _max, \ - .dbg_val = &debug_state._fld, \ - .cur_val = ¤t_state._fld, \ -} - -static struct debug_audio_entry values[] = { - DBG_ENTRY(DEBUG_CPCAP_AUDIO_MODE, - CPCAP_AUDIO_MODE_NORMAL, CPCAP_AUDIO_MODE_TTY, - mode), - - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_MODE, - CPCAP_AUDIO_CODEC_OFF, CPCAP_AUDIO_CODEC_LOOPBACK, - codec_mode), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_RATE, - CPCAP_AUDIO_CODEC_RATE_8000_HZ, - CPCAP_AUDIO_CODEC_RATE_48000_HZ, - codec_rate), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_MUTE, - CPCAP_AUDIO_CODEC_UNMUTE, CPCAP_AUDIO_CODEC_BYPASS_LOOP, - codec_mute), - - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_MODE, - CPCAP_AUDIO_STDAC_OFF, CPCAP_AUDIO_STDAC_ON, - stdac_mode), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_RATE, - CPCAP_AUDIO_STDAC_RATE_8000_HZ, - CPCAP_AUDIO_STDAC_RATE_48000_HZ, - stdac_rate), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_MUTE, - CPCAP_AUDIO_STDAC_UNMUTE, CPCAP_AUDIO_STDAC_MUTE, - stdac_mute), - - DBG_ENTRY(DEBUG_CPCAP_AUDIO_ANALOG_SOURCE, - CPCAP_AUDIO_ANALOG_SOURCE_OFF, - CPCAP_AUDIO_ANALOG_SOURCE_STEREO, - analog_source), - - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_PRIMARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1, codec_primary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_SECONDARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1 , codec_secondary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_PRIMARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1, stdac_primary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_SECONDARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1, stdac_secondary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_EXT_PRIMARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1, ext_primary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_EXT_SECONDARY_SPEAKER, - CPCAP_AUDIO_OUT_NONE, - CPCAP_AUDIO_OUT_NUM_OF_PATHS - 1, ext_secondary_speaker), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_CODEC_PRIMARY_BALANCE, - CPCAP_AUDIO_BALANCE_NEUTRAL, - CPCAP_AUDIO_BALANCE_L_ONLY, codec_primary_balance), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_STDAC_PRIMARY_BALANCE, - CPCAP_AUDIO_BALANCE_NEUTRAL, - CPCAP_AUDIO_BALANCE_L_ONLY, stdac_primary_balance), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_EXT_PRIMARY_BALANCE, - CPCAP_AUDIO_BALANCE_NEUTRAL, - CPCAP_AUDIO_BALANCE_L_ONLY, ext_primary_balance), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_OUTPUT_GAIN, 0, 50, output_gain), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_MICROPHONE, CPCAP_AUDIO_IN_NONE, - CPCAP_AUDIO_IN_NUM_OF_PATHS - 1, microphone), - DBG_ENTRY(DEBUG_CPCAP_AUDIO_INPUT_GAIN, 0, 50, input_gain), - DBG_ENTRY(DEBUG_CPCAP_RAT_TYPE, - CPCAP_AUDIO_RAT_NONE, CPCAP_AUDIO_RAT_CDMA, - rat_type), -}; - -static int tegra_audio_debug_show(struct seq_file *s, void *data) -{ - int field = (int) s->private; - - if (field < DEBUG_CPCAP_NUM_FIELDS) - seq_printf(s, "%d\n", *values[field].cur_val); - - return 0; -} - -static int tegra_audio_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_audio_debug_show, inode->i_private); -} - -static int tegra_audio_debug_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - char buf[32]; - int buf_sz; - long ival; - struct seq_file *s = file->private_data; - int field = (int) s->private; - - buf_sz = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_sz)) - return -EFAULT; - buf[buf_sz] = 0; - - debug_state = current_state; - - if (strict_strtol(buf, 0, &ival)) - return -EINVAL; - if (ival < values[field].min || ival > values[field].max) { - pr_err("%s: invalid value %ld\n", __func__, ival); - return -EINVAL; - } - - *values[field].dbg_val = ival; - - pr_info("%s setting %s to %ld\n", __func__, - values[field].name, ival); - - cpcap_audio_set_audio_state(&debug_state); - return count; -} - -static const struct file_operations tegra_audio_debug_fops = { - .open = tegra_audio_debug_open, - .write = tegra_audio_debug_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init tegra_audio_debug_init(void) -{ - int i; - struct dentry *d, *f; - - d = debugfs_create_dir("cpcap_audio", NULL); - - for (i = 0; i < DEBUG_CPCAP_NUM_FIELDS; i++) { - f = debugfs_create_file(values[i].name, 0755, d, - (void *) values[i].id, - &tegra_audio_debug_fops); - } - - return 0; -} - -late_initcall(tegra_audio_debug_init); -#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/mfd/cpcap-core.c b/drivers/mfd/cpcap-core.c deleted file mode 100644 index c56d688b0509..000000000000 --- a/drivers/mfd/cpcap-core.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (C) 2007-2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct cpcap_driver_info { - struct list_head list; - struct platform_device *pdev; -}; - -static long ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static int __devinit cpcap_probe(struct spi_device *spi); -static int __devexit cpcap_remove(struct spi_device *spi); - -#ifdef CONFIG_PM -static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg); -static int cpcap_resume(struct spi_device *spi); -#endif - -const static struct file_operations cpcap_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = ioctl, -}; - -static struct miscdevice cpcap_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = CPCAP_DEV_NAME, - .fops = &cpcap_fops, -}; - -static struct spi_driver cpcap_driver = { - .driver = { - .name = "cpcap", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = cpcap_probe, - .remove = __devexit_p(cpcap_remove), -#ifdef CONFIG_PM - .suspend = cpcap_suspend, - .resume = cpcap_resume, -#endif -}; - -static struct platform_device cpcap_adc_device = { - .name = "cpcap_adc", - .id = -1, - .dev.platform_data = NULL, -}; - - -static struct platform_device cpcap_key_device = { - .name = "cpcap_key", - .id = -1, - .dev.platform_data = NULL, -}; - -static struct platform_device cpcap_uc_device = { - .name = "cpcap_uc", - .id = -1, - .dev.platform_data = NULL, -}; - -static struct platform_device cpcap_rtc_device = { - .name = "cpcap_rtc", - .id = -1, - .dev.platform_data = NULL, -}; - -/* List of required CPCAP devices that will ALWAYS be present. - * - * DO NOT ADD NEW DEVICES TO THIS LIST! You must use cpcap_driver_register() - * for any new drivers for non-core functionality of CPCAP. - */ -static struct platform_device *cpcap_devices[] = { - &cpcap_uc_device, - &cpcap_adc_device, - &cpcap_key_device, - &cpcap_rtc_device, -}; - -static struct cpcap_device *misc_cpcap; - -static LIST_HEAD(cpcap_device_list); -static DEFINE_MUTEX(cpcap_driver_lock); - -static int cpcap_reboot(struct notifier_block *this, unsigned long code, - void *cmd) -{ - int ret = -1; - int result = NOTIFY_DONE; - - /* Disable the USB transceiver */ - ret = cpcap_regacc_write(misc_cpcap, CPCAP_REG_USBC2, 0, - CPCAP_BIT_USBXCVREN); - - if (ret) { - dev_err(&(misc_cpcap->spi->dev), - "Disable Transciever failure.\n"); - result = NOTIFY_BAD; - } - - if (code == SYS_RESTART) - cpcap_regacc_write(misc_cpcap, CPCAP_REG_MI2, 0, 0xFFFF); - - /* Always clear the power cut bit on SW Shutdown*/ - ret = cpcap_regacc_write(misc_cpcap, CPCAP_REG_PC1, - 0, CPCAP_BIT_PC1_PCEN); - if (ret) { - dev_err(&(misc_cpcap->spi->dev), - "Clear Power Cut bit failure.\n"); - result = NOTIFY_BAD; - } - - /* Clear the charger and charge path settings to avoid a false turn on - * event in caused by CPCAP. After clearing these settings, 100ms is - * needed to before SYSRSTRTB is pulled low to avoid the false turn on - * event. - */ - cpcap_regacc_write(misc_cpcap, CPCAP_REG_CRM, 0, 0x3FFF); - mdelay(100); - - return result; -} -static struct notifier_block cpcap_reboot_notifier = { - .notifier_call = cpcap_reboot, -}; - -static int __init cpcap_init(void) -{ - return spi_register_driver(&cpcap_driver); -} - -static void cpcap_vendor_read(struct cpcap_device *cpcap) -{ - unsigned short value; - - (void)cpcap_regacc_read(cpcap, CPCAP_REG_VERSC1, &value); - - cpcap->vendor = (enum cpcap_vendor)((value >> 6) & 0x0007); - cpcap->revision = (enum cpcap_revision)(((value >> 3) & 0x0007) | - ((value << 3) & 0x0038)); -} - - -int cpcap_device_unregister(struct platform_device *pdev) -{ - struct cpcap_driver_info *info; - struct cpcap_driver_info *tmp; - int found; - - - found = 0; - mutex_lock(&cpcap_driver_lock); - - list_for_each_entry_safe(info, tmp, &cpcap_device_list, list) { - if (info->pdev == pdev) { - list_del(&info->list); - - /* - * misc_cpcap != NULL suggests pdev - * already registered - */ - if (misc_cpcap) { - printk(KERN_INFO "CPCAP: unregister %s\n", - pdev->name); - platform_device_unregister(pdev); - } - info->pdev = NULL; - kfree(info); - found = 1; - } - } - - mutex_unlock(&cpcap_driver_lock); - - BUG_ON(!found); - return 0; -} - -int cpcap_device_register(struct platform_device *pdev) -{ - int retval; - struct cpcap_driver_info *info; - - retval = 0; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "Cannot save device %s\n", pdev->name); - return -ENOMEM; - } - - mutex_lock(&cpcap_driver_lock); - - info->pdev = pdev; - list_add_tail(&info->list, &cpcap_device_list); - - /* If misc_cpcap is valid, the CPCAP driver has already been probed. - * Therefore, call platform_device_register() to probe the device. - */ - if (misc_cpcap) { - dev_info(&(misc_cpcap->spi->dev), - "Probing CPCAP device %s\n", pdev->name); - - /* - * platform_data is non-empty indicates - * CPCAP client devices need to pass their own data - * In that case we put cpcap data in driver_data - */ - if (pdev->dev.platform_data != NULL) - platform_set_drvdata(pdev, misc_cpcap); - else - pdev->dev.platform_data = misc_cpcap; - retval = platform_device_register(pdev); - } else - printk(KERN_INFO "CPCAP: delaying %s probe\n", - pdev->name); - mutex_unlock(&cpcap_driver_lock); - - return retval; -} - -static int __devinit cpcap_probe(struct spi_device *spi) -{ - int retval = -EINVAL; - struct cpcap_device *cpcap; - struct cpcap_platform_data *data; - int i; - struct cpcap_driver_info *info; - - cpcap = kzalloc(sizeof(*cpcap), GFP_KERNEL); - if (cpcap == NULL) - return -ENOMEM; - - cpcap->spi = spi; - data = spi->controller_data; - spi_set_drvdata(spi, cpcap); - - retval = cpcap_regacc_init(cpcap); - if (retval < 0) - goto free_mem; - retval = cpcap_irq_init(cpcap); - if (retval < 0) - goto free_cpcap_irq; - - cpcap_vendor_read(cpcap); - - for (i = 0; i < ARRAY_SIZE(cpcap_devices); i++) - cpcap_devices[i]->dev.platform_data = cpcap; - - retval = misc_register(&cpcap_dev); - if (retval < 0) - goto free_cpcap_irq; - - /* loop twice becuase cpcap_regulator_probe may refer to other devices - * in this list to handle dependencies between regulators. Create them - * all and then add them */ - for (i = 0; i < CPCAP_NUM_REGULATORS; i++) { - struct platform_device *pdev; - - pdev = platform_device_alloc("cpcap-regltr", i); - if (!pdev) { - dev_err(&(spi->dev), "Cannot create regulator\n"); - continue; - } - - pdev->dev.parent = &(spi->dev); - pdev->dev.platform_data = &data->regulator_init[i]; - platform_set_drvdata(pdev, cpcap); - cpcap->regulator_pdev[i] = pdev; - } - - for (i = 0; i < CPCAP_NUM_REGULATORS; i++) - platform_device_add(cpcap->regulator_pdev[i]); - - platform_add_devices(cpcap_devices, ARRAY_SIZE(cpcap_devices)); - - mutex_lock(&cpcap_driver_lock); - misc_cpcap = cpcap; /* kept for misc device */ - - list_for_each_entry(info, &cpcap_device_list, list) { - dev_info(&(spi->dev), "Probing CPCAP device %s\n", - info->pdev->name); - if (info->pdev->dev.platform_data != NULL) - platform_set_drvdata(info->pdev, cpcap); - else - info->pdev->dev.platform_data = cpcap; - platform_device_register(info->pdev); - } - mutex_unlock(&cpcap_driver_lock); - - register_reboot_notifier(&cpcap_reboot_notifier); - - return 0; - -free_cpcap_irq: - cpcap_irq_shutdown(cpcap); -free_mem: - kfree(cpcap); - return retval; -} - -static int __devexit cpcap_remove(struct spi_device *spi) -{ - struct cpcap_device *cpcap = spi_get_drvdata(spi); - struct cpcap_driver_info *info; - int i; - - unregister_reboot_notifier(&cpcap_reboot_notifier); - - mutex_lock(&cpcap_driver_lock); - list_for_each_entry(info, &cpcap_device_list, list) { - dev_info(&(spi->dev), "Removing CPCAP device %s\n", - info->pdev->name); - platform_device_unregister(info->pdev); - } - misc_cpcap = NULL; - mutex_unlock(&cpcap_driver_lock); - - for (i = ARRAY_SIZE(cpcap_devices); i > 0; i--) - platform_device_unregister(cpcap_devices[i-1]); - - for (i = 0; i < CPCAP_NUM_REGULATORS; i++) - platform_device_unregister(cpcap->regulator_pdev[i]); - - misc_deregister(&cpcap_dev); - cpcap_irq_shutdown(cpcap); - kfree(cpcap); - return 0; -} - - -static long test_ioctl(unsigned int cmd, unsigned long arg) -{ - int retval = -EINVAL; - struct cpcap_regacc read_data; - struct cpcap_regacc write_data; - - switch (cmd) { - case CPCAP_IOCTL_TEST_READ_REG: - if (copy_from_user((void *)&read_data, (void *)arg, - sizeof(read_data))) - return -EFAULT; - retval = cpcap_regacc_read(misc_cpcap, read_data.reg, - &read_data.value); - if (retval < 0) - return retval; - if (copy_to_user((void *)arg, (void *)&read_data, - sizeof(read_data))) - return -EFAULT; - return 0; - break; - - case CPCAP_IOCTL_TEST_WRITE_REG: - if (copy_from_user((void *) &write_data, - (void *) arg, - sizeof(write_data))) - return -EFAULT; - retval = cpcap_regacc_write(misc_cpcap, write_data.reg, - write_data.value, write_data.mask); - break; - - default: - retval = -ENOTTY; - break; - } - - return retval; -} - -static long adc_ioctl(unsigned int cmd, unsigned long arg) -{ - int retval = -EINVAL; - struct cpcap_adc_phase phase; - - switch (cmd) { - case CPCAP_IOCTL_ADC_PHASE: - if (copy_from_user((void *) &phase, (void *) arg, - sizeof(phase))) - return -EFAULT; - - cpcap_adc_phase(misc_cpcap, &phase); - retval = 0; - break; - - default: - retval = -ENOTTY; - break; - } - - return retval; -} - -static long accy_ioctl(unsigned int cmd, unsigned long arg) -{ - int retval = -EINVAL; - struct cpcap_whisper_request read_data; - - switch (cmd) { - case CPCAP_IOCTL_ACCY_WHISPER: - if (copy_from_user((void *) &read_data, (void *) arg, - sizeof(read_data))) - return -EFAULT; - read_data.dock_id[CPCAP_WHISPER_ID_SIZE - 1] = '\0'; - read_data.dock_prop[CPCAP_WHISPER_PROP_SIZE - 1] = '\0'; - retval = cpcap_accy_whisper(misc_cpcap, &read_data); - break; - - default: - retval = -ENOTTY; - break; - } - - return retval; -} - -static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int retval = -ENOTTY; - unsigned int cmd_num; - - cmd_num = _IOC_NR(cmd); - - if ((cmd_num > CPCAP_IOCTL_NUM_TEST__START) && - (cmd_num < CPCAP_IOCTL_NUM_TEST__END)) { - retval = test_ioctl(cmd, arg); - } - if ((cmd_num > CPCAP_IOCTL_NUM_ADC__START) && - (cmd_num < CPCAP_IOCTL_NUM_ADC__END)) { - retval = adc_ioctl(cmd, arg); - } - if ((cmd_num > CPCAP_IOCTL_NUM_ACCY__START) && - (cmd_num < CPCAP_IOCTL_NUM_ACCY__END)) { - retval = accy_ioctl(cmd, arg); - } - - return retval; -} - -static void cpcap_shutdown(void) -{ - spi_unregister_driver(&cpcap_driver); -} - -#ifdef CONFIG_PM -static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg) -{ - - struct cpcap_device *cpcap = spi_get_drvdata(spi); - - return cpcap_irq_suspend(cpcap); -} - -static int cpcap_resume(struct spi_device *spi) -{ - struct cpcap_device *cpcap = spi_get_drvdata(spi); - - return cpcap_irq_resume(cpcap); -} -#endif - -subsys_initcall(cpcap_init); -module_exit(cpcap_shutdown); - -MODULE_ALIAS("platform:cpcap"); -MODULE_DESCRIPTION("CPCAP driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/cpcap-irq.c b/drivers/mfd/cpcap-irq.c deleted file mode 100644 index 18f42875df20..000000000000 --- a/drivers/mfd/cpcap-irq.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2009 - 2010, Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define NUM_INT_REGS 5 -#define NUM_INTS_PER_REG 16 - -#define CPCAP_INT1_VALID_BITS 0xFFFB -#define CPCAP_INT2_VALID_BITS 0xFFFF -#define CPCAP_INT3_VALID_BITS 0xFFFF -#define CPCAP_INT4_VALID_BITS 0x03FF -#define CPCAP_INT5_VALID_BITS 0xFFFF - -struct cpcap_event_handler { - void (*func)(enum cpcap_irqs, void *); - void *data; -}; - -struct cpcap_irq_info { - uint8_t registered; - uint8_t enabled; - uint32_t count; -}; - -struct cpcap_irqdata { - struct mutex lock; - struct work_struct work; - struct workqueue_struct *workqueue; - struct cpcap_device *cpcap; - struct cpcap_event_handler event_handler[CPCAP_IRQ__NUM]; - struct cpcap_irq_info irq_info[CPCAP_IRQ__NUM]; - struct wake_lock wake_lock; -}; - -#define EVENT_MASK(event) (1 << ((event) % NUM_INTS_PER_REG)) - -enum pwrkey_states { - PWRKEY_RELEASE, /* Power key released state. */ - PWRKEY_PRESS, /* Power key pressed state. */ - PWRKEY_UNKNOWN, /* Unknown power key state. */ -}; - -static irqreturn_t event_isr(int irq, void *data) -{ - struct cpcap_irqdata *irq_data = data; - disable_irq_nosync(irq); - wake_lock(&irq_data->wake_lock); - queue_work(irq_data->workqueue, &irq_data->work); - - return IRQ_HANDLED; -} - -static unsigned short get_int_reg(enum cpcap_irqs event) -{ - unsigned short ret; - - if ((event) >= CPCAP_IRQ_INT5_INDEX) - ret = CPCAP_REG_MI1; - else if ((event) >= CPCAP_IRQ_INT4_INDEX) - ret = CPCAP_REG_INT4; - else if ((event) >= CPCAP_IRQ_INT3_INDEX) - ret = CPCAP_REG_INT3; - else if ((event) >= CPCAP_IRQ_INT2_INDEX) - ret = CPCAP_REG_INT2; - else - ret = CPCAP_REG_INT1; - - return ret; -} - -static unsigned short get_mask_reg(enum cpcap_irqs event) -{ - unsigned short ret; - - if (event >= CPCAP_IRQ_INT5_INDEX) - ret = CPCAP_REG_MIM1; - else if (event >= CPCAP_IRQ_INT4_INDEX) - ret = CPCAP_REG_INTM4; - else if (event >= CPCAP_IRQ_INT3_INDEX) - ret = CPCAP_REG_INTM3; - else if (event >= CPCAP_IRQ_INT2_INDEX) - ret = CPCAP_REG_INTM2; - else - ret = CPCAP_REG_INTM1; - - return ret; -} - -static unsigned short get_sense_reg(enum cpcap_irqs event) -{ - unsigned short ret; - - if (event >= CPCAP_IRQ_INT5_INDEX) - ret = CPCAP_REG_MI2; - else if (event >= CPCAP_IRQ_INT4_INDEX) - ret = CPCAP_REG_INTS4; - else if (event >= CPCAP_IRQ_INT3_INDEX) - ret = CPCAP_REG_INTS3; - else if (event >= CPCAP_IRQ_INT2_INDEX) - ret = CPCAP_REG_INTS2; - else - ret = CPCAP_REG_INTS1; - - return ret; -} - -void cpcap_irq_mask_all(struct cpcap_device *cpcap) -{ - int i; - - static const struct { - unsigned short mask_reg; - unsigned short valid; - } int_reg[NUM_INT_REGS] = { - {CPCAP_REG_INTM1, CPCAP_INT1_VALID_BITS}, - {CPCAP_REG_INTM2, CPCAP_INT2_VALID_BITS}, - {CPCAP_REG_INTM3, CPCAP_INT3_VALID_BITS}, - {CPCAP_REG_INTM4, CPCAP_INT4_VALID_BITS}, - {CPCAP_REG_MIM1, CPCAP_INT5_VALID_BITS} - }; - - for (i = 0; i < NUM_INT_REGS; i++) { - cpcap_regacc_write(cpcap, int_reg[i].mask_reg, - int_reg[i].valid, - int_reg[i].valid); - } -} - -struct pwrkey_data { - struct cpcap_device *cpcap; - enum pwrkey_states state; - struct wake_lock wake_lock; -}; - -static void pwrkey_handler(enum cpcap_irqs irq, void *data) -{ - struct pwrkey_data *pwrkey_data = data; - enum pwrkey_states new_state, last_state = pwrkey_data->state; - struct cpcap_device *cpcap = pwrkey_data->cpcap; - - new_state = (enum pwrkey_states) cpcap_irq_sense(cpcap, irq, 0); - - - if ((new_state < PWRKEY_UNKNOWN) && (new_state != last_state)) { - wake_lock_timeout(&pwrkey_data->wake_lock, 20); - cpcap_broadcast_key_event(cpcap, KEY_END, new_state); - pwrkey_data->state = new_state; - } else if ((last_state == PWRKEY_RELEASE) && - (new_state == PWRKEY_RELEASE)) { - /* Key must have been released before press was handled. Send - * both the press and the release. */ - wake_lock_timeout(&pwrkey_data->wake_lock, 20); - cpcap_broadcast_key_event(cpcap, KEY_END, PWRKEY_PRESS); - cpcap_broadcast_key_event(cpcap, KEY_END, PWRKEY_RELEASE); - } - cpcap_irq_unmask(cpcap, CPCAP_IRQ_ON); -} - -static int pwrkey_init(struct cpcap_device *cpcap) -{ - struct pwrkey_data *data = kmalloc(sizeof(struct pwrkey_data), - GFP_KERNEL); - int retval; - - if (!data) - return -ENOMEM; - data->cpcap = cpcap; - data->state = PWRKEY_RELEASE; - retval = cpcap_irq_register(cpcap, CPCAP_IRQ_ON, pwrkey_handler, data); - if (retval) - kfree(data); - wake_lock_init(&data->wake_lock, WAKE_LOCK_SUSPEND, "pwrkey"); - return retval; -} - -static void pwrkey_remove(struct cpcap_device *cpcap) -{ - struct pwrkey_data *data; - - cpcap_irq_get_data(cpcap, CPCAP_IRQ_ON, (void **)&data); - if (!data) - return; - cpcap_irq_free(cpcap, CPCAP_IRQ_ON); - wake_lock_destroy(&data->wake_lock); - kfree(data); -} - -static int int_read_and_clear(struct cpcap_device *cpcap, - unsigned short status_reg, - unsigned short mask_reg, - unsigned short valid_mask, - unsigned short *en) -{ - unsigned short ireg_val, mreg_val; - int ret; - ret = cpcap_regacc_read(cpcap, status_reg, &ireg_val); - if (ret) - return ret; - ret = cpcap_regacc_read(cpcap, mask_reg, &mreg_val); - if (ret) - return ret; - *en |= ireg_val & ~mreg_val; - *en &= valid_mask; - ret = cpcap_regacc_write(cpcap, mask_reg, *en, *en); - if (ret) - return ret; - ret = cpcap_regacc_write(cpcap, status_reg, *en, *en); - if (ret) - return ret; - return 0; -} - - -static void irq_work_func(struct work_struct *work) -{ - int retval = 0; - unsigned short en_ints[NUM_INT_REGS]; - int i; - struct cpcap_irqdata *data; - struct cpcap_device *cpcap; - struct spi_device *spi; - - static const struct { - unsigned short status_reg; - unsigned short mask_reg; - unsigned short valid; - } int_reg[NUM_INT_REGS] = { - {CPCAP_REG_INT1, CPCAP_REG_INTM1, CPCAP_INT1_VALID_BITS}, - {CPCAP_REG_INT2, CPCAP_REG_INTM2, CPCAP_INT2_VALID_BITS}, - {CPCAP_REG_INT3, CPCAP_REG_INTM3, CPCAP_INT3_VALID_BITS}, - {CPCAP_REG_INT4, CPCAP_REG_INTM4, CPCAP_INT4_VALID_BITS}, - {CPCAP_REG_MI1, CPCAP_REG_MIM1, CPCAP_INT5_VALID_BITS} - }; - - for (i = 0; i < NUM_INT_REGS; ++i) - en_ints[i] = 0; - - data = container_of(work, struct cpcap_irqdata, work); - cpcap = data->cpcap; - spi = cpcap->spi; - - for (i = 0; i < NUM_INT_REGS; ++i) { - retval = int_read_and_clear(cpcap, - int_reg[i].status_reg, - int_reg[i].mask_reg, - int_reg[i].valid, - &en_ints[i]); - if (retval < 0) { - dev_err(&spi->dev, "Error reading interrupts\n"); - break; - } - } - enable_irq(spi->irq); - - /* lock protects event handlers and data */ - mutex_lock(&data->lock); - for (i = 0; i < NUM_INT_REGS; ++i) { - unsigned char index; - - while (en_ints[i] > 0) { - struct cpcap_event_handler *event_handler; - - /* find the first set bit */ - index = (unsigned char)(ffs(en_ints[i]) - 1); - if (index >= CPCAP_IRQ__NUM) - goto error; - /* clear the bit */ - en_ints[i] &= ~(1 << index); - /* find the event that occurred */ - index += CPCAP_IRQ__START + (i * NUM_INTS_PER_REG); - event_handler = &data->event_handler[index]; - - if (event_handler->func) - event_handler->func(index, event_handler->data); - - data->irq_info[index].count++; - } - } -error: - mutex_unlock(&data->lock); - wake_unlock(&data->wake_lock); -} - -#ifdef CONFIG_DEBUG_FS -static int cpcap_dbg_irq_show(struct seq_file *s, void *data) -{ - static const char *irq_name[] = { - [CPCAP_IRQ_HSCLK] = "HSCLK", - [CPCAP_IRQ_PRIMAC] = "PRIMAC", - [CPCAP_IRQ_SECMAC] = "SECMAC", - [CPCAP_IRQ_LOWBPL] = "LOWBPL", - [CPCAP_IRQ_SEC2PRI] = "SEC2PRI", - [CPCAP_IRQ_LOWBPH] = "LOWBPH", - [CPCAP_IRQ_EOL] = "EOL", - [CPCAP_IRQ_TS] = "TS", - [CPCAP_IRQ_ADCDONE] = "ADCDONE", - [CPCAP_IRQ_HS] = "HS", - [CPCAP_IRQ_MB2] = "MB2", - [CPCAP_IRQ_VBUSOV] = "VBUSOV", - [CPCAP_IRQ_RVRS_CHRG] = "RVRS_CHRG", - [CPCAP_IRQ_CHRG_DET] = "CHRG_DET", - [CPCAP_IRQ_IDFLOAT] = "IDFLOAT", - [CPCAP_IRQ_IDGND] = "IDGND", - - [CPCAP_IRQ_SE1] = "SE1", - [CPCAP_IRQ_SESSEND] = "SESSEND", - [CPCAP_IRQ_SESSVLD] = "SESSVLD", - [CPCAP_IRQ_VBUSVLD] = "VBUSVLD", - [CPCAP_IRQ_CHRG_CURR1] = "CHRG_CURR1", - [CPCAP_IRQ_CHRG_CURR2] = "CHRG_CURR2", - [CPCAP_IRQ_RVRS_MODE] = "RVRS_MODE", - [CPCAP_IRQ_ON] = "ON", - [CPCAP_IRQ_ON2] = "ON2", - [CPCAP_IRQ_CLK] = "CLK", - [CPCAP_IRQ_1HZ] = "1HZ", - [CPCAP_IRQ_PTT] = "PTT", - [CPCAP_IRQ_SE0CONN] = "SE0CONN", - [CPCAP_IRQ_CHRG_SE1B] = "CHRG_SE1B", - [CPCAP_IRQ_UART_ECHO_OVERRUN] = "UART_ECHO_OVERRUN", - [CPCAP_IRQ_EXTMEMHD] = "EXTMEMHD", - - [CPCAP_IRQ_WARM] = "WARM", - [CPCAP_IRQ_SYSRSTR] = "SYSRSTR", - [CPCAP_IRQ_SOFTRST] = "SOFTRST", - [CPCAP_IRQ_DIEPWRDWN] = "DIEPWRDWN", - [CPCAP_IRQ_DIETEMPH] = "DIETEMPH", - [CPCAP_IRQ_PC] = "PC", - [CPCAP_IRQ_OFLOWSW] = "OFLOWSW", - [CPCAP_IRQ_TODA] = "TODA", - [CPCAP_IRQ_OPT_SEL_DTCH] = "OPT_SEL_DTCH", - [CPCAP_IRQ_OPT_SEL_STATE] = "OPT_SEL_STATE", - [CPCAP_IRQ_ONEWIRE1] = "ONEWIRE1", - [CPCAP_IRQ_ONEWIRE2] = "ONEWIRE2", - [CPCAP_IRQ_ONEWIRE3] = "ONEWIRE3", - [CPCAP_IRQ_UCRESET] = "UCRESET", - [CPCAP_IRQ_PWRGOOD] = "PWRGOOD", - [CPCAP_IRQ_USBDPLLCLK] = "USBDPLLCLK", - - [CPCAP_IRQ_DPI] = "DPI", - [CPCAP_IRQ_DMI] = "DMI", - [CPCAP_IRQ_UCBUSY] = "UCBUSY", - [CPCAP_IRQ_GCAI_CURR1] = "GCAI_CURR1", - [CPCAP_IRQ_GCAI_CURR2] = "GCAI_CURR2", - [CPCAP_IRQ_SB_MAX_RETRANSMIT_ERR] = "SB_MAX_RETRANSMIT_ERR", - [CPCAP_IRQ_BATTDETB] = "BATTDETB", - [CPCAP_IRQ_PRIHALT] = "PRIHALT", - [CPCAP_IRQ_SECHALT] = "SECHALT", - [CPCAP_IRQ_CC_CAL] = "CC_CAL", - - [CPCAP_IRQ_UC_PRIROMR] = "UC_PRIROMR", - [CPCAP_IRQ_UC_PRIRAMW] = "UC_PRIRAMW", - [CPCAP_IRQ_UC_PRIRAMR] = "UC_PRIRAMR", - [CPCAP_IRQ_UC_USEROFF] = "UC_USEROFF", - [CPCAP_IRQ_UC_PRIMACRO_4] = "UC_PRIMACRO_4", - [CPCAP_IRQ_UC_PRIMACRO_5] = "UC_PRIMACRO_5", - [CPCAP_IRQ_UC_PRIMACRO_6] = "UC_PRIMACRO_6", - [CPCAP_IRQ_UC_PRIMACRO_7] = "UC_PRIMACRO_7", - [CPCAP_IRQ_UC_PRIMACRO_8] = "UC_PRIMACRO_8", - [CPCAP_IRQ_UC_PRIMACRO_9] = "UC_PRIMACRO_9", - [CPCAP_IRQ_UC_PRIMACRO_10] = "UC_PRIMACRO_10", - [CPCAP_IRQ_UC_PRIMACRO_11] = "UC_PRIMACRO_11", - [CPCAP_IRQ_UC_PRIMACRO_12] = "UC_PRIMACRO_12", - [CPCAP_IRQ_UC_PRIMACRO_13] = "UC_PRIMACRO_13", - [CPCAP_IRQ_UC_PRIMACRO_14] = "UC_PRIMACRO_14", - [CPCAP_IRQ_UC_PRIMACRO_15] = "UC_PRIMACRO_15", - }; - unsigned int i; - struct cpcap_irqdata *irqdata = s->private; - - seq_printf(s, "%21s%9s%12s%10s\n", - "CPCAP IRQ", "Enabled", "Registered", "Count"); - - for (i = 0; i < CPCAP_IRQ__NUM; i++) { - if ((i <= CPCAP_IRQ_CC_CAL) || (i >= CPCAP_IRQ_UC_PRIROMR)) { - seq_printf(s, "%21s%9d%12d%10d\n", - irq_name[i], - irqdata->irq_info[i].enabled, - irqdata->irq_info[i].registered, - irqdata->irq_info[i].count); - } - } - return 0; -} - -static int cpcap_dbg_irq_open(struct inode *inode, struct file *file) -{ - return single_open(file, cpcap_dbg_irq_show, inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = cpcap_dbg_irq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -int cpcap_irq_init(struct cpcap_device *cpcap) -{ - int retval; - struct spi_device *spi = cpcap->spi; - struct cpcap_irqdata *data; - - data = kzalloc(sizeof(struct cpcap_irqdata), GFP_KERNEL); - if (!data) - return -ENOMEM; - - cpcap_irq_mask_all(cpcap); - - data->workqueue = create_singlethread_workqueue("cpcap_irq"); - INIT_WORK(&data->work, irq_work_func); - mutex_init(&data->lock); - wake_lock_init(&data->wake_lock, WAKE_LOCK_SUSPEND, "cpcap-irq"); - data->cpcap = cpcap; - - retval = request_irq(spi->irq, event_isr, IRQF_DISABLED | - IRQF_TRIGGER_HIGH, "cpcap-irq", data); - if (retval) { - printk(KERN_ERR "cpcap_irq: Failed requesting irq.\n"); - goto error; - } - - enable_irq_wake(spi->irq); - - cpcap->irqdata = data; - retval = pwrkey_init(cpcap); - if (retval) { - printk(KERN_ERR "cpcap_irq: Failed initializing pwrkey.\n"); - goto error; - } -#ifdef CONFIG_DEBUG_FS - (void)debugfs_create_file("cpcap-irq", S_IRUGO, NULL, data, - &debug_fops); -#endif - return 0; - -error: - free_irq(spi->irq, data); - kfree(data); - printk(KERN_ERR "cpcap_irq: Error registering cpcap irq.\n"); - return retval; -} - -void cpcap_irq_shutdown(struct cpcap_device *cpcap) -{ - struct spi_device *spi = cpcap->spi; - struct cpcap_irqdata *data = cpcap->irqdata; - - pwrkey_remove(cpcap); - cancel_work_sync(&data->work); - destroy_workqueue(data->workqueue); - free_irq(spi->irq, data); - kfree(data); -} - -int cpcap_irq_register(struct cpcap_device *cpcap, - enum cpcap_irqs irq, - void (*cb_func) (enum cpcap_irqs, void *), - void *data) -{ - struct cpcap_irqdata *irqdata = cpcap->irqdata; - int retval = 0; - - if ((irq >= CPCAP_IRQ__NUM) || (!cb_func)) - return -EINVAL; - - mutex_lock(&irqdata->lock); - - if (irqdata->event_handler[irq].func == NULL) { - irqdata->irq_info[irq].registered = 1; - cpcap_irq_unmask(cpcap, irq); - irqdata->event_handler[irq].func = cb_func; - irqdata->event_handler[irq].data = data; - } else - retval = -EPERM; - - mutex_unlock(&irqdata->lock); - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_register); - -int cpcap_irq_free(struct cpcap_device *cpcap, enum cpcap_irqs irq) -{ - struct cpcap_irqdata *data = cpcap->irqdata; - int retval; - - if (irq >= CPCAP_IRQ__NUM) - return -EINVAL; - - mutex_lock(&data->lock); - retval = cpcap_irq_mask(cpcap, irq); - data->event_handler[irq].func = NULL; - data->event_handler[irq].data = NULL; - data->irq_info[irq].registered = 0; - mutex_unlock(&data->lock); - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_free); - -int cpcap_irq_get_data(struct cpcap_device *cpcap, - enum cpcap_irqs irq, - void **data) -{ - struct cpcap_irqdata *irqdata = cpcap->irqdata; - - if (irq >= CPCAP_IRQ__NUM) - return -EINVAL; - - mutex_lock(&irqdata->lock); - *data = irqdata->event_handler[irq].data; - mutex_unlock(&irqdata->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(cpcap_irq_get_data); - -int cpcap_irq_clear(struct cpcap_device *cpcap, - enum cpcap_irqs irq) -{ - int retval = -EINVAL; - - if ((irq < CPCAP_IRQ__NUM) && (irq != CPCAP_IRQ_SECMAC)) { - retval = cpcap_regacc_write(cpcap, - get_int_reg(irq), - EVENT_MASK(irq), - EVENT_MASK(irq)); - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_clear); - -int cpcap_irq_mask(struct cpcap_device *cpcap, - enum cpcap_irqs irq) -{ - struct cpcap_irqdata *data = cpcap->irqdata; - int retval = -EINVAL; - - if ((irq < CPCAP_IRQ__NUM) && (irq != CPCAP_IRQ_SECMAC)) { - data->irq_info[irq].enabled = 0; - retval = cpcap_regacc_write(cpcap, - get_mask_reg(irq), - EVENT_MASK(irq), - EVENT_MASK(irq)); - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_mask); - -int cpcap_irq_unmask(struct cpcap_device *cpcap, - enum cpcap_irqs irq) -{ - struct cpcap_irqdata *data = cpcap->irqdata; - int retval = -EINVAL; - - if ((irq < CPCAP_IRQ__NUM) && (irq != CPCAP_IRQ_SECMAC)) { - data->irq_info[irq].enabled = 1; - retval = cpcap_regacc_write(cpcap, - get_mask_reg(irq), - 0, - EVENT_MASK(irq)); - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_unmask); - -int cpcap_irq_mask_get(struct cpcap_device *cpcap, - enum cpcap_irqs irq) -{ - struct cpcap_irqdata *data = cpcap->irqdata; - int retval = -EINVAL; - - if ((irq < CPCAP_IRQ__NUM) && (irq != CPCAP_IRQ_SECMAC)) - return data->irq_info[irq].enabled; - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_irq_mask_get); - -int cpcap_irq_sense(struct cpcap_device *cpcap, - enum cpcap_irqs irq, - unsigned char clear) -{ - unsigned short val; - int retval; - - if (irq >= CPCAP_IRQ__NUM) - return -EINVAL; - - retval = cpcap_regacc_read(cpcap, get_sense_reg(irq), &val); - if (retval) - return retval; - - if (clear) - retval = cpcap_irq_clear(cpcap, irq); - if (retval) - return retval; - - return ((val & EVENT_MASK(irq)) != 0) ? 1 : 0; -} -EXPORT_SYMBOL_GPL(cpcap_irq_sense); - -#ifdef CONFIG_PM -int cpcap_irq_suspend(struct cpcap_device *cpcap) -{ - struct spi_device *spi = cpcap->spi; - struct cpcap_irqdata *data = cpcap->irqdata; - - disable_irq(spi->irq); - flush_work(&data->work); - return 0; -} - -int cpcap_irq_resume(struct cpcap_device *cpcap) -{ - struct spi_device *spi = cpcap->spi; - - enable_irq(spi->irq); - return 0; -} -#endif diff --git a/drivers/mfd/cpcap-key.c b/drivers/mfd/cpcap-key.c deleted file mode 100644 index 783dd0193b49..000000000000 --- a/drivers/mfd/cpcap-key.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - - - -struct cpcap_key_data { - struct input_dev *input_dev; - struct cpcap_device *cpcap; -}; - -static int cpcap_key_probe(struct platform_device *pdev) -{ - int err; - struct cpcap_key_data *key; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - key = kzalloc(sizeof(*key), GFP_KERNEL); - if (!key) - return -ENOMEM; - - key->cpcap = pdev->dev.platform_data; - - key->input_dev = input_allocate_device(); - if (key->input_dev == NULL) { - dev_err(&pdev->dev, "can't allocate input device\n"); - err = -ENOMEM; - goto err0; - } - - set_bit(EV_KEY, key->input_dev->evbit); - set_bit(KEY_MEDIA, key->input_dev->keybit); - set_bit(KEY_END, key->input_dev->keybit); - - key->input_dev->name = "cpcap-key"; - - err = input_register_device(key->input_dev); - if (err < 0) { - dev_err(&pdev->dev, "could not register input device.\n"); - goto err1; - } - - platform_set_drvdata(pdev, key); - cpcap_set_keydata(key->cpcap, key); - - dev_info(&pdev->dev, "CPCAP key device probed\n"); - - return 0; - -err1: - input_free_device(key->input_dev); -err0: - kfree(key); - return err; -} - -static int __exit cpcap_key_remove(struct platform_device *pdev) -{ - struct cpcap_key_data *key = platform_get_drvdata(pdev); - - input_unregister_device(key->input_dev); - input_free_device(key->input_dev); - kfree(key); - - return 0; -} - -void cpcap_broadcast_key_event(struct cpcap_device *cpcap, - unsigned int code, int value) -{ - struct cpcap_key_data *key = cpcap_get_keydata(cpcap); - - if (key && key->input_dev) - input_report_key(key->input_dev, code, value); -} -EXPORT_SYMBOL(cpcap_broadcast_key_event); - -static struct platform_driver cpcap_key_driver = { - .probe = cpcap_key_probe, - .remove = __exit_p(cpcap_key_remove), - .driver = { - .name = "cpcap_key", - .owner = THIS_MODULE, - }, -}; - -static int __init cpcap_key_init(void) -{ - return platform_driver_register(&cpcap_key_driver); -} -module_init(cpcap_key_init); - -static void __exit cpcap_key_exit(void) -{ - platform_driver_unregister(&cpcap_key_driver); -} -module_exit(cpcap_key_exit); - -MODULE_ALIAS("platform:cpcap_key"); -MODULE_DESCRIPTION("CPCAP KEY driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/cpcap-regacc.c b/drivers/mfd/cpcap-regacc.c deleted file mode 100644 index 3d5252e44536..000000000000 --- a/drivers/mfd/cpcap-regacc.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (C) 2007-2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include - -#define IS_CPCAP(reg) ((reg) >= CPCAP_REG_START && (reg) <= CPCAP_REG_END) - -static DEFINE_MUTEX(reg_access); - -/* - * This table contains information about a single register in the power IC. - * It is used during register access to information such as the register address - * and the modifiability of each bit in the register. Special notes for - * particular elements of this structure follows: - * - * constant_mask: A '1' in this mask indicates that the corresponding bit has a - * 'constant' modifiability, and therefore must never be changed by any register - * access. - * - * It is important to note that any bits that are 'constant' must have - * synchronized read/write values. That is to say, when a 'constant' bit is - * read the value read must be identical to the value that must be written to - * that bit in order for that bit to be read with the same value. - * - * rbw_mask: A '1' in this mask indicates that the corresponding bit (when not - * being changed) should be written with the current value of that bit. A '0' - * in this mask indicates that the corresponding bit (when not being changed) - * should be written with a value of '0'. - */ -static const struct { - unsigned short address; /* Address of the register */ - unsigned short constant_mask; /* Constant modifiability mask */ - unsigned short rbw_mask; /* Read-before-write mask */ -} register_info_tbl[CPCAP_NUM_REG_CPCAP] = { - [CPCAP_REG_INT1] = {0, 0x0004, 0x0000}, - [CPCAP_REG_INT2] = {1, 0x0000, 0x0000}, - [CPCAP_REG_INT3] = {2, 0x0000, 0x0000}, - [CPCAP_REG_INT4] = {3, 0xFC00, 0x0000}, - [CPCAP_REG_INTM1] = {4, 0x0004, 0xFFFF}, - [CPCAP_REG_INTM2] = {5, 0x0000, 0xFFFF}, - [CPCAP_REG_INTM3] = {6, 0x0000, 0xFFFF}, - [CPCAP_REG_INTM4] = {7, 0xFC00, 0xFFFF}, - [CPCAP_REG_INTS1] = {8, 0xFFFF, 0xFFFF}, - [CPCAP_REG_INTS2] = {9, 0xFFFF, 0xFFFF}, - [CPCAP_REG_INTS3] = {10, 0xFFFF, 0xFFFF}, - [CPCAP_REG_INTS4] = {11, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ASSIGN1] = {12, 0x80F8, 0xFFFF}, - [CPCAP_REG_ASSIGN2] = {13, 0x0000, 0xFFFF}, - [CPCAP_REG_ASSIGN3] = {14, 0x0004, 0xFFFF}, - [CPCAP_REG_ASSIGN4] = {15, 0x0068, 0xFFFF}, - [CPCAP_REG_ASSIGN5] = {16, 0x0000, 0xFFFF}, - [CPCAP_REG_ASSIGN6] = {17, 0xFC00, 0xFFFF}, - [CPCAP_REG_VERSC1] = {18, 0xFFFF, 0xFFFF}, - [CPCAP_REG_VERSC2] = {19, 0xFFFF, 0xFFFF}, - [CPCAP_REG_MI1] = {128, 0x0000, 0x0000}, - [CPCAP_REG_MIM1] = {129, 0x0000, 0xFFFF}, - [CPCAP_REG_MI2] = {130, 0x0000, 0xFFFF}, - [CPCAP_REG_MIM2] = {131, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UCC1] = {132, 0xF000, 0xFFFF}, - [CPCAP_REG_UCC2] = {133, 0xFC00, 0xFFFF}, - [CPCAP_REG_PC1] = {135, 0xFC00, 0xFFFF}, - [CPCAP_REG_PC2] = {136, 0xFC00, 0xFFFF}, - [CPCAP_REG_BPEOL] = {137, 0xFE00, 0xFFFF}, - [CPCAP_REG_PGC] = {138, 0xFE00, 0xFFFF}, - [CPCAP_REG_MT1] = {139, 0x0000, 0x0000}, - [CPCAP_REG_MT2] = {140, 0x0000, 0x0000}, - [CPCAP_REG_MT3] = {141, 0x0000, 0x0000}, - [CPCAP_REG_PF] = {142, 0x0000, 0xFFFF}, - [CPCAP_REG_SCC] = {256, 0xFF00, 0xFFFF}, - [CPCAP_REG_SW1] = {257, 0xFFFF, 0xFFFF}, - [CPCAP_REG_SW2] = {258, 0xFC7F, 0xFFFF}, - [CPCAP_REG_UCTM] = {259, 0xFFFE, 0xFFFF}, - [CPCAP_REG_TOD1] = {260, 0xFF00, 0xFFFF}, - [CPCAP_REG_TOD2] = {261, 0xFE00, 0xFFFF}, - [CPCAP_REG_TODA1] = {262, 0xFF00, 0xFFFF}, - [CPCAP_REG_TODA2] = {263, 0xFE00, 0xFFFF}, - [CPCAP_REG_DAY] = {264, 0x8000, 0xFFFF}, - [CPCAP_REG_DAYA] = {265, 0x8000, 0xFFFF}, - [CPCAP_REG_VAL1] = {266, 0x0000, 0xFFFF}, - [CPCAP_REG_VAL2] = {267, 0x0000, 0xFFFF}, - [CPCAP_REG_SDVSPLL] = {384, 0x2488, 0xFFFF}, - [CPCAP_REG_SI2CC1] = {385, 0x8000, 0xFFFF}, - [CPCAP_REG_Si2CC2] = {386, 0xFF00, 0xFFFF}, - [CPCAP_REG_S1C1] = {387, 0x9080, 0xFFFF}, - [CPCAP_REG_S1C2] = {388, 0x8080, 0xFFFF}, - [CPCAP_REG_S2C1] = {389, 0x9080, 0xFFFF}, - [CPCAP_REG_S2C2] = {390, 0x8080, 0xFFFF}, - [CPCAP_REG_S3C] = {391, 0xFA84, 0xFFFF}, - [CPCAP_REG_S4C1] = {392, 0x9080, 0xFFFF}, - [CPCAP_REG_S4C2] = {393, 0x8080, 0xFFFF}, - [CPCAP_REG_S5C] = {394, 0xFFD5, 0xFFFF}, - [CPCAP_REG_S6C] = {395, 0xFFF4, 0xFFFF}, - [CPCAP_REG_VCAMC] = {396, 0xFF48, 0xFFFF}, - [CPCAP_REG_VCSIC] = {397, 0xFFA8, 0xFFFF}, - [CPCAP_REG_VDACC] = {398, 0xFF48, 0xFFFF}, - [CPCAP_REG_VDIGC] = {399, 0xFF48, 0xFFFF}, - [CPCAP_REG_VFUSEC] = {400, 0xFF50, 0xFFFF}, - [CPCAP_REG_VHVIOC] = {401, 0xFFE8, 0xFFFF}, - [CPCAP_REG_VSDIOC] = {402, 0xFF40, 0xFFFF}, - [CPCAP_REG_VPLLC] = {403, 0xFFA4, 0xFFFF}, - [CPCAP_REG_VRF1C] = {404, 0xFF50, 0xFFFF}, - [CPCAP_REG_VRF2C] = {405, 0xFFD4, 0xFFFF}, - [CPCAP_REG_VRFREFC] = {406, 0xFFD4, 0xFFFF}, - [CPCAP_REG_VWLAN1C] = {407, 0xFFA8, 0xFFFF}, - [CPCAP_REG_VWLAN2C] = {408, 0xFD32, 0xFFFF}, - [CPCAP_REG_VSIMC] = {409, 0xE154, 0xFFFF}, - [CPCAP_REG_VVIBC] = {410, 0xFFF2, 0xFFFF}, - [CPCAP_REG_VUSBC] = {411, 0xFEA2, 0xFFFF}, - [CPCAP_REG_VUSBINT1C] = {412, 0xFFD4, 0xFFFF}, - [CPCAP_REG_VUSBINT2C] = {413, 0xFFD4, 0xFFFF}, - [CPCAP_REG_URT] = {414, 0xFFFE, 0xFFFF}, - [CPCAP_REG_URM1] = {415, 0x0000, 0xFFFF}, - [CPCAP_REG_URM2] = {416, 0xFC00, 0xFFFF}, - [CPCAP_REG_VAUDIOC] = {512, 0xFF88, 0xFFFF}, - [CPCAP_REG_CC] = {513, 0x0000, 0xFEDF}, - [CPCAP_REG_CDI] = {514, 0x4000, 0xFFFF}, - [CPCAP_REG_SDAC] = {515, 0xF000, 0xFCFF}, - [CPCAP_REG_SDACDI] = {516, 0xC000, 0xFFFF}, - [CPCAP_REG_TXI] = {517, 0x0000, 0xFFFF}, - [CPCAP_REG_TXMP] = {518, 0xF000, 0xFFFF}, - [CPCAP_REG_RXOA] = {519, 0xF800, 0xFFFF}, - [CPCAP_REG_RXVC] = {520, 0x00C3, 0xFFFF}, - [CPCAP_REG_RXCOA] = {521, 0xF800, 0xFFFF}, - [CPCAP_REG_RXSDOA] = {522, 0xE000, 0xFFFF}, - [CPCAP_REG_RXEPOA] = {523, 0x8000, 0xFFFF}, - [CPCAP_REG_RXLL] = {524, 0x0000, 0xFFFF}, - [CPCAP_REG_A2LA] = {525, 0xFF00, 0xFFFF}, - [CPCAP_REG_MIPIS1] = {526, 0x0000, 0xFFFF}, - [CPCAP_REG_MIPIS2] = {527, 0xFF00, 0xFFFF}, - [CPCAP_REG_MIPIS3] = {528, 0xFFFC, 0xFFFF}, - [CPCAP_REG_LVAB] = {529, 0xFFFC, 0xFFFF}, - [CPCAP_REG_CCC1] = {640, 0xFFF0, 0xFFFF}, - [CPCAP_REG_CRM] = {641, 0xC000, 0xFFFF}, - [CPCAP_REG_CCCC2] = {642, 0xFFC0, 0xFFFF}, - [CPCAP_REG_CCS1] = {643, 0x0000, 0xFFFF}, - [CPCAP_REG_CCS2] = {644, 0xFF00, 0xFFFF}, - [CPCAP_REG_CCA1] = {645, 0x0000, 0xFFFF}, - [CPCAP_REG_CCA2] = {646, 0x0000, 0xFFFF}, - [CPCAP_REG_CCM] = {647, 0xFC00, 0xFFFF}, - [CPCAP_REG_CCO] = {648, 0xFC00, 0xFFFF}, - [CPCAP_REG_CCI] = {649, 0xC000, 0xFFFF}, - [CPCAP_REG_ADCC1] = {768, 0x0000, 0xFFFF}, - [CPCAP_REG_ADCC2] = {769, 0x0080, 0xFFFF}, - [CPCAP_REG_ADCD0] = {770, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD1] = {771, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD2] = {772, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD3] = {773, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD4] = {774, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD5] = {775, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD6] = {776, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCD7] = {777, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCAL1] = {778, 0xFFFF, 0xFFFF}, - [CPCAP_REG_ADCAL2] = {779, 0xFFFF, 0xFFFF}, - [CPCAP_REG_USBC1] = {896, 0x0000, 0xFFFF}, - [CPCAP_REG_USBC2] = {897, 0x0000, 0xFFFF}, - [CPCAP_REG_USBC3] = {898, 0x8200, 0xFFFF}, - [CPCAP_REG_UVIDL] = {899, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UVIDH] = {900, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UPIDL] = {901, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UPIDH] = {902, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UFC1] = {903, 0xFF80, 0xFFFF}, - [CPCAP_REG_UFC2] = {904, 0xFF80, 0xFFFF}, - [CPCAP_REG_UFC3] = {905, 0xFF80, 0xFFFF}, - [CPCAP_REG_UIC1] = {906, 0xFF64, 0xFFFF}, - [CPCAP_REG_UIC2] = {907, 0xFF64, 0xFFFF}, - [CPCAP_REG_UIC3] = {908, 0xFF64, 0xFFFF}, - [CPCAP_REG_USBOTG1] = {909, 0xFFC0, 0xFFFF}, - [CPCAP_REG_USBOTG2] = {910, 0xFFC0, 0xFFFF}, - [CPCAP_REG_USBOTG3] = {911, 0xFFC0, 0xFFFF}, - [CPCAP_REG_UIER1] = {912, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIER2] = {913, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIER3] = {914, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIEF1] = {915, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIEF2] = {916, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIEF3] = {917, 0xFFE0, 0xFFFF}, - [CPCAP_REG_UIS] = {918, 0xFFFF, 0xFFFF}, - [CPCAP_REG_UIL] = {919, 0xFFFF, 0xFFFF}, - [CPCAP_REG_USBD] = {920, 0xFFFF, 0xFFFF}, - [CPCAP_REG_SCR1] = {921, 0xFF00, 0xFFFF}, - [CPCAP_REG_SCR2] = {922, 0xFF00, 0xFFFF}, - [CPCAP_REG_SCR3] = {923, 0xFF00, 0xFFFF}, - [CPCAP_REG_VMC] = {939, 0xFFFE, 0xFFFF}, - [CPCAP_REG_OWDC] = {940, 0xFFFC, 0xFFFF}, - [CPCAP_REG_GPIO0] = {941, 0x0D11, 0x3FFF}, - [CPCAP_REG_GPIO1] = {943, 0x0D11, 0x3FFF}, - [CPCAP_REG_GPIO2] = {945, 0x0D11, 0x3FFF}, - [CPCAP_REG_GPIO3] = {947, 0x0D11, 0x3FFF}, - [CPCAP_REG_GPIO4] = {949, 0x0D11, 0x3FFF}, - [CPCAP_REG_GPIO5] = {951, 0x0C11, 0x3FFF}, - [CPCAP_REG_GPIO6] = {953, 0x0C11, 0x3FFF}, - [CPCAP_REG_MDLC] = {1024, 0x0000, 0xFFFF}, - [CPCAP_REG_KLC] = {1025, 0x8000, 0xFFFF}, - [CPCAP_REG_ADLC] = {1026, 0x8000, 0xFFFF}, - [CPCAP_REG_REDC] = {1027, 0xFC00, 0xFFFF}, - [CPCAP_REG_GREENC] = {1028, 0xFC00, 0xFFFF}, - [CPCAP_REG_BLUEC] = {1029, 0xFC00, 0xFFFF}, - [CPCAP_REG_CFC] = {1030, 0xF000, 0xFFFF}, - [CPCAP_REG_ABC] = {1031, 0xFFC3, 0xFFFF}, - [CPCAP_REG_BLEDC] = {1032, 0xFC00, 0xFFFF}, - [CPCAP_REG_CLEDC] = {1033, 0xFC00, 0xFFFF}, - [CPCAP_REG_OW1C] = {1152, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW1D] = {1153, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW1I] = {1154, 0xFFFF, 0xFFFF}, - [CPCAP_REG_OW1IE] = {1155, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW1] = {1157, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW2C] = {1160, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW2D] = {1161, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW2I] = {1162, 0xFFFF, 0xFFFF}, - [CPCAP_REG_OW2IE] = {1163, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW2] = {1165, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW3C] = {1168, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW3D] = {1169, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW3I] = {1170, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW3IE] = {1171, 0xFF00, 0xFFFF}, - [CPCAP_REG_OW3] = {1173, 0xFF00, 0xFFFF}, - [CPCAP_REG_GCAIC] = {1174, 0xFF00, 0xFFFF}, - [CPCAP_REG_GCAIM] = {1175, 0xFF00, 0xFFFF}, - [CPCAP_REG_LGDIR] = {1176, 0xFFE0, 0xFFFF}, - [CPCAP_REG_LGPU] = {1177, 0xFFE0, 0xFFFF}, - [CPCAP_REG_LGPIN] = {1178, 0xFF00, 0xFFFF}, - [CPCAP_REG_LGMASK] = {1179, 0xFFE0, 0xFFFF}, - [CPCAP_REG_LDEB] = {1180, 0xFF00, 0xFFFF}, - [CPCAP_REG_LGDET] = {1181, 0xFF00, 0xFFFF}, - [CPCAP_REG_LMISC] = {1182, 0xFF07, 0xFFFF}, - [CPCAP_REG_LMACE] = {1183, 0xFFF8, 0xFFFF}, - [CPCAP_REG_TEST] = {7936, 0x0000, 0xFFFF}, - [CPCAP_REG_ST_TEST1] = {8002, 0x0000, 0xFFFF}, -}; - -static int cpcap_spi_access(struct spi_device *spi, u8 *buf, - size_t len) -{ - struct spi_message m; - struct spi_transfer t = { - .tx_buf = buf, - .len = len, - .rx_buf = buf, - .bits_per_word = 32, - }; - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - return spi_sync(spi, &m); -} - -static int cpcap_config_for_read(struct spi_device *spi, unsigned short reg, - unsigned short *data) -{ - int status = -ENOTTY; - u32 buf32; /* force buf to be 32bit aligned */ - u8 *buf = (u8 *) &buf32; - - if (spi != NULL) { - buf[3] = (reg >> 6) & 0x000000FF; - buf[2] = (reg << 2) & 0x000000FF; - buf[1] = 0; - buf[0] = 0; - - status = cpcap_spi_access(spi, buf, 4); - - if (status == 0) - *data = buf[0] | (buf[1] << 8); - } - - return status; -} - -static int cpcap_config_for_write(struct spi_device *spi, unsigned short reg, - unsigned short data) -{ - int status = -ENOTTY; - u32 buf32; /* force buf to be 32bit aligned */ - u8 *buf = (u8 *) &buf32; - - if (spi != NULL) { - buf[3] = ((reg >> 6) & 0x000000FF) | 0x80; - buf[2] = (reg << 2) & 0x000000FF; - buf[1] = (data >> 8) & 0x000000FF; - buf[0] = data & 0x000000FF; - - status = cpcap_spi_access(spi, buf, 4); - } - - return status; -} - -int cpcap_regacc_read(struct cpcap_device *cpcap, enum cpcap_reg reg, - unsigned short *value_ptr) -{ - int retval = -EINVAL; - struct spi_device *spi = cpcap->spi; - - if (IS_CPCAP(reg) && (value_ptr != 0)) { - mutex_lock(®_access); - - retval = cpcap_config_for_read(spi, register_info_tbl - [reg].address, value_ptr); - - mutex_unlock(®_access); - } - - return retval; -} - -int cpcap_regacc_write(struct cpcap_device *cpcap, - enum cpcap_reg reg, - unsigned short value, - unsigned short mask) -{ - int retval = -EINVAL; - unsigned short old_value = 0; - struct cpcap_platform_data *data; - struct spi_device *spi = cpcap->spi; - - data = (struct cpcap_platform_data *)spi->controller_data; - - if (IS_CPCAP(reg) && - (mask & register_info_tbl[reg].constant_mask) == 0) { - mutex_lock(®_access); - - value &= mask; - - if ((register_info_tbl[reg].rbw_mask) != 0) { - retval = cpcap_config_for_read(spi, register_info_tbl - [reg].address, - &old_value); - if (retval != 0) - goto error; - } - - old_value &= register_info_tbl[reg].rbw_mask; - old_value &= ~mask; - value |= old_value; - retval = cpcap_config_for_write(spi, - register_info_tbl[reg].address, - value); -error: - mutex_unlock(®_access); - } - - return retval; -} - -int cpcap_regacc_init(struct cpcap_device *cpcap) -{ - unsigned short i; - unsigned short mask; - int retval = 0; - struct cpcap_platform_data *data; - struct spi_device *spi = cpcap->spi; - - data = (struct cpcap_platform_data *)spi->controller_data; - - for (i = 0; i < data->init_len; i++) { - mask = 0xFFFF; - mask &= ~(register_info_tbl[data->init[i].reg].constant_mask); - - retval = cpcap_regacc_write(cpcap, data->init[i].reg, - data->init[i].data, - mask); - if (retval) - break; - } - - return retval; -} diff --git a/drivers/mfd/cpcap-uc.c b/drivers/mfd/cpcap-uc.c deleted file mode 100644 index 7d1113045506..000000000000 --- a/drivers/mfd/cpcap-uc.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright (C) 2008-2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#define ERROR_MACRO_TIMEOUT 0x81 -#define ERROR_MACRO_WRITE 0x82 -#define ERROR_MACRO_READ 0x83 - -#define RAM_START_TI 0x9000 -#define RAM_END_TI 0x9FA0 -#define RAM_START_ST 0x0000 -#define RAM_END_ST 0x0FFF - -#define HWCFG_ADDR_ST 0x0122 - -enum { - READ_STATE_1, /* Send size and location of RAM read. */ - READ_STATE_2, /*!< Read MT registers. */ - READ_STATE_3, /*!< Read data from uC. */ - READ_STATE_4, /*!< Check for error. */ -}; - -enum { - WRITE_STATE_1, /* Send size and location of RAM write. */ - WRITE_STATE_2, /* Check for error. */ - WRITE_STATE_3, /* Write data to uC. */ - WRITE_STATE_4 /* Check for error. */ -}; - -struct cpcap_uc_data { - struct cpcap_device *cpcap; - unsigned char is_supported; - unsigned char is_ready; - struct completion completion; - int cb_status; - struct mutex lock; - unsigned char uc_reset; - unsigned char state; - unsigned short state_cntr; - struct { - unsigned short address; - unsigned short *data; - unsigned short num_words; - } req; -}; - -static struct cpcap_uc_data *cpcap_uc_info; - -static int fops_open(struct inode *inode, struct file *file); -static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static ssize_t fops_write(struct file *file, const char *buf, - size_t count, loff_t *ppos); -static ssize_t fops_read(struct file *file, char *buf, - size_t count, loff_t *ppos); - - -static const struct file_operations fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = fops_ioctl, - .open = fops_open, - .read = fops_read, - .write = fops_write, -}; - -static struct miscdevice uc_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "cpcap_uc", - .fops = &fops, -}; - -static int is_valid_address(struct cpcap_device *cpcap, unsigned short address, - unsigned short num_words) -{ - int vld = 0; - - if (cpcap->vendor == CPCAP_VENDOR_TI) { - vld = (address >= RAM_START_TI) && - ((address + num_words) <= RAM_END_TI); - } else if (cpcap->vendor == CPCAP_VENDOR_ST) { - vld = ((address + num_words) <= RAM_END_ST); - } - - return vld; -} - -static void ram_read_state_machine(enum cpcap_irqs irq, void *data) -{ - struct cpcap_uc_data *uc_data = data; - unsigned short temp; - - if (irq != CPCAP_IRQ_UC_PRIRAMR) - return; - - switch (uc_data->state) { - case READ_STATE_1: - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1, - uc_data->req.address, 0xFFFF); - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2, - uc_data->req.num_words, 0xFFFF); - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0, 0xFFFF); - - if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST) - uc_data->state = READ_STATE_2; - else - uc_data->state = READ_STATE_3; - - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - break; - - case READ_STATE_2: - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &temp); - - if (temp == ERROR_MACRO_READ) { - uc_data->state = READ_STATE_1; - uc_data->state_cntr = 0; - - cpcap_irq_mask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - - uc_data->cb_status = -EIO; - - complete(&uc_data->completion); - } else { - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2, &temp); - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3, &temp); - - uc_data->state = READ_STATE_3; - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - } - break; - - case READ_STATE_3: - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, - uc_data->req.data + uc_data->state_cntr); - - uc_data->state_cntr += 1; - - if (uc_data->state_cntr == uc_data->req.num_words) - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2, &temp); - else { - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2, - uc_data->req.data + - uc_data->state_cntr); - - uc_data->state_cntr += 1; - } - - if (uc_data->state_cntr == uc_data->req.num_words) - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3, &temp); - else { - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3, - uc_data->req.data + - uc_data->state_cntr); - - uc_data->state_cntr += 1; - } - - if (uc_data->state_cntr == uc_data->req.num_words) - uc_data->state = READ_STATE_4; - - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - break; - - case READ_STATE_4: - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &temp); - - if (temp != ERROR_MACRO_READ) - uc_data->cb_status = 0; - else - uc_data->cb_status = -EIO; - - complete(&uc_data->completion); - - uc_data->state = READ_STATE_1; - uc_data->state_cntr = 0; - break; - - default: - uc_data->state = READ_STATE_1; - uc_data->state_cntr = 0; - break; - } -} - -static void ram_write_state_machine(enum cpcap_irqs irq, void *data) -{ - struct cpcap_uc_data *uc_data = data; - unsigned short error_check; - - if (irq != CPCAP_IRQ_UC_PRIRAMW) - return; - - switch (uc_data->state) { - case WRITE_STATE_1: - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1, - uc_data->req.address, 0xFFFF); - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2, - uc_data->req.num_words, 0xFFFF); - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0, 0xFFFF); - - uc_data->state = WRITE_STATE_2; - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW); - break; - - case WRITE_STATE_2: - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &error_check); - - if (error_check == ERROR_MACRO_WRITE) { - uc_data->state = WRITE_STATE_1; - uc_data->state_cntr = 0; - - cpcap_irq_mask(uc_data->cpcap, - CPCAP_IRQ_UC_PRIRAMW); - - uc_data->cb_status = -EIO; - complete(&uc_data->completion); - break; - } else - uc_data->state = WRITE_STATE_3; - - /* No error has occured, fall through */ - - case WRITE_STATE_3: - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1, - *(uc_data->req.data + uc_data->state_cntr), - 0xFFFF); - uc_data->state_cntr += 1; - - if (uc_data->state_cntr == uc_data->req.num_words) - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2, 0, - 0xFFFF); - else { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2, - *(uc_data->req.data + - uc_data->state_cntr), 0xFFFF); - - uc_data->state_cntr += 1; - } - - if (uc_data->state_cntr == uc_data->req.num_words) - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0, - 0xFFFF); - else { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, - *(uc_data->req.data + - uc_data->state_cntr), 0xFFFF); - - uc_data->state_cntr += 1; - } - - if (uc_data->state_cntr == uc_data->req.num_words) - uc_data->state = WRITE_STATE_4; - - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW); - break; - - case WRITE_STATE_4: - cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &error_check); - - if (error_check != ERROR_MACRO_WRITE) - uc_data->cb_status = 0; - else - uc_data->cb_status = -EIO; - - complete(&uc_data->completion); - - uc_data->state = WRITE_STATE_1; - uc_data->state_cntr = 0; - break; - - default: - uc_data->state = WRITE_STATE_1; - uc_data->state_cntr = 0; - break; - } -} - -static void reset_handler(enum cpcap_irqs irq, void *data) -{ - int i; - unsigned short regval; - struct cpcap_uc_data *uc_data = data; - - if (irq != CPCAP_IRQ_UCRESET) - return; - - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCC1, - CPCAP_BIT_PRIHALT, CPCAP_BIT_PRIHALT); - - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_PGC, - CPCAP_BIT_PRI_UC_SUSPEND, CPCAP_BIT_PRI_UC_SUSPEND); - - uc_data->uc_reset = 1; - uc_data->cb_status = -EIO; - complete(&uc_data->completion); - - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2, 0, 0xFFFF); - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MIM1, 0xFFFF, 0xFFFF); - cpcap_irq_mask(uc_data->cpcap, CPCAP_IRQ_PRIMAC); - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UCRESET); - - for (i = 0; i <= CPCAP_REG_END; i++) { - cpcap_regacc_read(uc_data->cpcap, i, ®val); - dev_err(&uc_data->cpcap->spi->dev, - "cpcap reg %d = 0x%04X\n", i, regval); - } - - BUG(); -} - -static void primac_handler(enum cpcap_irqs irq, void *data) -{ - struct cpcap_uc_data *uc_data = data; - - if (irq == CPCAP_IRQ_PRIMAC) - cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_PRIMAC); -} - -static int ram_write(struct cpcap_uc_data *uc_data, unsigned short address, - unsigned short num_words, unsigned short *data) -{ - int retval = -EFAULT; - - mutex_lock(&uc_data->lock); - - if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) && - (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM, - CPCAP_BIT_UCTM, CPCAP_BIT_UCTM); - } - - if (uc_data->is_supported && (num_words > 0) && - (data != NULL) && - is_valid_address(uc_data->cpcap, address, num_words) && - !uc_data->uc_reset) { - uc_data->req.address = address; - uc_data->req.data = data; - uc_data->req.num_words = num_words; - uc_data->state = WRITE_STATE_1; - uc_data->state_cntr = 0; - INIT_COMPLETION(uc_data->completion); - - retval = cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2, - CPCAP_BIT_PRIRAMW, - CPCAP_BIT_PRIRAMW); - if (retval) - goto err; - - /* Cannot call cpcap_irq_register() here because unregister - * cannot be called from the state machine. Doing so causes - * a deadlock. */ - retval = cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW); - if (retval) - goto err; - - wait_for_completion(&uc_data->completion); - retval = uc_data->cb_status; - } - -err: - if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) && - (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM, - 0, CPCAP_BIT_UCTM); - } - - mutex_unlock(&uc_data->lock); - return retval; -} - -static int ram_read(struct cpcap_uc_data *uc_data, unsigned short address, - unsigned short num_words, unsigned short *data) -{ - int retval = -EFAULT; - - mutex_lock(&uc_data->lock); - - if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) && - (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM, - CPCAP_BIT_UCTM, CPCAP_BIT_UCTM); - } - - if (uc_data->is_supported && (num_words > 0) && - is_valid_address(uc_data->cpcap, address, num_words) && - !uc_data->uc_reset) { - uc_data->req.address = address; - uc_data->req.data = data; - uc_data->req.num_words = num_words; - uc_data->state = READ_STATE_1; - uc_data->state_cntr = 0; - INIT_COMPLETION(uc_data->completion); - - retval = cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2, - CPCAP_BIT_PRIRAMR, - CPCAP_BIT_PRIRAMR); - if (retval) - goto err; - - /* Cannot call cpcap_irq_register() here because unregister - * cannot be called from the state machine. Doing so causes - * a deadlock. */ - retval = cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - if (retval) - goto err; - - wait_for_completion(&uc_data->completion); - retval = uc_data->cb_status; - } - -err: - if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) && - (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) { - cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM, - 0, CPCAP_BIT_UCTM); - } - - mutex_unlock(&uc_data->lock); - return retval; -} - -static int ram_load(struct cpcap_uc_data *uc_data, unsigned int num_words, - unsigned short *data) -{ - int retval = -EINVAL; - - if ((data != NULL) && (num_words > 0)) - retval = ram_write(uc_data, data[0], (num_words - 1), - (data + 1)); - - return retval; -} - -static ssize_t fops_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - ssize_t retval = -EINVAL; - unsigned short address; - unsigned short num_words; - unsigned short *data; - struct cpcap_uc_data *uc_data = file->private_data; - - if ((buf != NULL) && (ppos != NULL) && (count >= 2)) { - data = kzalloc(count, GFP_KERNEL); - - if (data != NULL) { - num_words = (unsigned short) (count >> 1); - - /* If the position (uC RAM address) is zero then the - * data contains the address */ - if (*ppos == 0) { - if (copy_from_user((void *) data, (void *) buf, - count) == 0) - retval = ram_load(uc_data, num_words, - data); - else - retval = -EFAULT; - } - /* If the position (uC RAM address) is not zero then the - * position holds the address to load the data */ - else { - address = (unsigned short) (*ppos); - - if (copy_from_user((void *) data, (void *) buf, - count) == 0) - retval = ram_write(uc_data, address, - num_words, data); - else - retval = -EFAULT; - } - - kfree(data); - } else { - retval = -ENOMEM; - } - } - - if (retval == 0) - retval = num_words; - - return retval; -} - -static ssize_t fops_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - ssize_t retval = -EFAULT; - unsigned short address; - unsigned short num_words; - unsigned short *data; - struct cpcap_uc_data *uc_data = file->private_data; - - if ((buf != NULL) && (ppos != NULL) && (count >= 2)) { - data = kzalloc(count, GFP_KERNEL); - - if (data != NULL) { - address = (unsigned short) (*ppos); - num_words = (unsigned short) (count >> 1); - - retval = ram_read(uc_data, address, num_words, data); - if (retval) - goto err; - - if (copy_to_user((void *)buf, (void *)data, count) == 0) - retval = count; - else - retval = -EFAULT; - -err: - kfree(data); - } else { - retval = -ENOMEM; - } - } - - return retval; -} - -static long fops_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int retval = -ENOTTY; - struct cpcap_uc_data *data = file->private_data; - - switch (cmd) { - case CPCAP_IOCTL_UC_MACRO_START: - /* User space will only attempt to start the init macro if - * the ram load requests complete successfully. This is used - * as an indication that kernel requests to start macros can - * be allowed. - */ - data->is_ready = 1; - - retval = cpcap_uc_start(data->cpcap, (enum cpcap_macro)arg); - - break; - - case CPCAP_IOCTL_UC_MACRO_STOP: - retval = cpcap_uc_stop(data->cpcap, (enum cpcap_macro)arg); - break; - - case CPCAP_IOCTL_UC_GET_VENDOR: - retval = copy_to_user((enum cpcap_vendor *)arg, - &(data->cpcap->vendor), - sizeof(enum cpcap_vendor)); - break; - - case CPCAP_IOCTL_UC_SET_TURBO_MODE: - if (arg != 0) - arg = 1; - retval = cpcap_regacc_write(data->cpcap, CPCAP_REG_UCTM, - (unsigned short)arg, - CPCAP_BIT_UCTM); - break; - - default: - break; - } - - return retval; -} - -static int fops_open(struct inode *inode, struct file *file) -{ - int retval = -ENOTTY; - - if (cpcap_uc_info->is_supported) - retval = 0; - - file->private_data = cpcap_uc_info; - dev_info(&cpcap_uc_info->cpcap->spi->dev, "CPCAP uC: open status:%d\n", - retval); - - return retval; -} - -int cpcap_uc_start(struct cpcap_device *cpcap, enum cpcap_macro macro) -{ - int retval = -EFAULT; - struct cpcap_uc_data *data = cpcap->ucdata; - - if ((data->is_ready) && - (macro > CPCAP_MACRO_USEROFF) && (macro < CPCAP_MACRO__END) && - (data->uc_reset == 0)) { - if ((macro == CPCAP_MACRO_4) || - ((cpcap->vendor == CPCAP_VENDOR_ST) && - ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) || - (macro == CPCAP_MACRO_15)))) { - retval = cpcap_regacc_write(cpcap, CPCAP_REG_MI2, - (1 << macro), - (1 << macro)); - } else { - retval = cpcap_regacc_write(cpcap, CPCAP_REG_MIM1, - 0, (1 << macro)); - } - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_uc_start); - -int cpcap_uc_stop(struct cpcap_device *cpcap, enum cpcap_macro macro) -{ - int retval = -EFAULT; - - if ((macro > CPCAP_MACRO_4) && - (macro < CPCAP_MACRO__END)) { - if ((cpcap->vendor == CPCAP_VENDOR_ST) && - ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) || - (macro == CPCAP_MACRO_15))) { - retval = cpcap_regacc_write(cpcap, CPCAP_REG_MI2, - 0, (1 << macro)); - } else { - retval = cpcap_regacc_write(cpcap, CPCAP_REG_MIM1, - (1 << macro), (1 << macro)); - } - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_uc_stop); - -unsigned char cpcap_uc_status(struct cpcap_device *cpcap, - enum cpcap_macro macro) -{ - unsigned char retval = 0; - unsigned short regval; - - if (macro < CPCAP_MACRO__END) { - if ((macro <= CPCAP_MACRO_4) || - ((cpcap->vendor == CPCAP_VENDOR_ST) && - ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) || - (macro == CPCAP_MACRO_15)))) { - cpcap_regacc_read(cpcap, CPCAP_REG_MI2, ®val); - - if (regval & (1 << macro)) - retval = 1; - } else { - cpcap_regacc_read(cpcap, CPCAP_REG_MIM1, ®val); - - if (!(regval & (1 << macro))) - retval = 1; - } - } - - return retval; -} -EXPORT_SYMBOL_GPL(cpcap_uc_status); - -static int fw_load(struct cpcap_uc_data *uc_data, struct device *dev) -{ - int err; - const struct ihex_binrec *rec; - const struct firmware *fw; - unsigned short *buf; - int i; - unsigned short num_bytes; - unsigned short num_words; - unsigned char odd_bytes; - struct cpcap_platform_data *data; - - data = uc_data->cpcap->spi->controller_data; - - if (!uc_data || !dev) - return -EINVAL; - - if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST) - err = request_ihex_firmware(&fw, "cpcap/firmware_0_2x.fw", dev); - else - err = request_ihex_firmware(&fw, "cpcap/firmware_1_2x.fw", dev); - - if (err) { - dev_err(dev, "Failed to load \"cpcap/firmware_%d_2x.fw\": %d\n", - uc_data->cpcap->vendor, err); - goto err; - } - - for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { - odd_bytes = 0; - num_bytes = be16_to_cpu(rec->len); - - /* Since loader requires words, need even number of bytes. */ - if (be16_to_cpu(rec->len) % 2) { - num_bytes++; - odd_bytes = 1; - } - - num_words = num_bytes >> 1; - dev_info(dev, "Loading %d word(s) at 0x%04x\n", - num_words, be32_to_cpu(rec->addr)); - - buf = kzalloc(num_bytes, GFP_KERNEL); - if (buf) { - for (i = 0; i < num_words; i++) { - if (odd_bytes && (i == (num_words - 1))) - buf[i] = rec->data[i * 2]; - else - buf[i] = ((uint16_t *)rec->data)[i]; - - buf[i] = be16_to_cpu(buf[i]); - } - - err = ram_write(uc_data, be32_to_cpu(rec->addr), - num_words, buf); - kfree(buf); - - if (err) { - dev_err(dev, "RAM write failed: %d\n", err); - break; - } - } else { - err = -ENOMEM; - dev_err(dev, "RAM write failed: %d\n", err); - break; - } - } - - release_firmware(fw); - - if (!err) { - uc_data->is_ready = 1; - - if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST) { - err = ram_write(uc_data, HWCFG_ADDR_ST, CPCAP_HWCFG_NUM, - data->hwcfg); - dev_info(dev, "Loaded HWCFG data: %d\n", err); - } - - err = cpcap_uc_start(uc_data->cpcap, CPCAP_MACRO_4); - dev_info(dev, "Started macro 4: %d\n", err); - } - -err: - return err; -} - -static int cpcap_uc_probe(struct platform_device *pdev) -{ - int retval = 0; - struct cpcap_uc_data *data; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->cpcap = pdev->dev.platform_data; - data->uc_reset = 0; - data->is_supported = 0; - data->req.address = 0; - data->req.data = NULL; - data->req.num_words = 0; - - init_completion(&data->completion); - mutex_init(&data->lock); - platform_set_drvdata(pdev, data); - cpcap_uc_info = data; - data->cpcap->ucdata = data; - - if (((data->cpcap->vendor == CPCAP_VENDOR_TI) && - (data->cpcap->revision >= CPCAP_REVISION_2_0)) || - (data->cpcap->vendor == CPCAP_VENDOR_ST)) { - retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_PRIMAC, - primac_handler, data); - if (retval) - goto err_free; - - cpcap_irq_clear(data->cpcap, CPCAP_IRQ_UCRESET); - retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_UCRESET, - reset_handler, data); - if (retval) - goto err_primac; - - retval = cpcap_irq_register(data->cpcap, - CPCAP_IRQ_UC_PRIRAMR, - ram_read_state_machine, data); - if (retval) - goto err_ucreset; - - retval = cpcap_irq_register(data->cpcap, - CPCAP_IRQ_UC_PRIRAMW, - ram_write_state_machine, data); - if (retval) - goto err_priramr; - - retval = misc_register(&uc_dev); - if (retval) - goto err_priramw; - - data->is_supported = 1; - - cpcap_regacc_write(data->cpcap, CPCAP_REG_MIM1, 0xFFFF, - 0xFFFF); - - retval = fw_load(data, &pdev->dev); - if (retval) - goto err_fw; - } else - retval = -ENODEV; - - return retval; - -err_fw: - misc_deregister(&uc_dev); -err_priramw: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMW); -err_priramr: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMR); -err_ucreset: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UCRESET); -err_primac: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_PRIMAC); -err_free: - kfree(data); - - return retval; -} - -static int __exit cpcap_uc_remove(struct platform_device *pdev) -{ - struct cpcap_uc_data *data = platform_get_drvdata(pdev); - - misc_deregister(&uc_dev); - - cpcap_irq_free(data->cpcap, CPCAP_IRQ_PRIMAC); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMW); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMR); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_UCRESET); - - kfree(data); - return 0; -} - - -static struct platform_driver cpcap_uc_driver = { - .probe = cpcap_uc_probe, - .remove = __exit_p(cpcap_uc_remove), - .driver = { - .name = "cpcap_uc", - .owner = THIS_MODULE, - }, -}; - -static int __init cpcap_uc_init(void) -{ - return platform_driver_register(&cpcap_uc_driver); -} -subsys_initcall(cpcap_uc_init); - -static void __exit cpcap_uc_exit(void) -{ - platform_driver_unregister(&cpcap_uc_driver); -} -module_exit(cpcap_uc_exit); - -MODULE_ALIAS("platform:cpcap_uc"); -MODULE_DESCRIPTION("CPCAP uC driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("cpcap/firmware_0_2x.fw"); -MODULE_FIRMWARE("cpcap/firmware_1_2x.fw"); diff --git a/drivers/mfd/cpcap-whisper.c b/drivers/mfd/cpcap-whisper.c deleted file mode 100644 index f2c428e86559..000000000000 --- a/drivers/mfd/cpcap-whisper.c +++ /dev/null @@ -1,826 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -void tegra_cpcap_audio_dock_state(bool connected); - -#define SENSE_USB_CLIENT (CPCAP_BIT_ID_FLOAT_S | \ - CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S) - -#define SENSE_USB_FLASH (CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S) - -#define SENSE_USB_HOST (CPCAP_BIT_ID_GROUND_S) -#define SENSE_USB_HOST_MASK (~CPCAP_BIT_SE1_S) - -#define SENSE_FACTORY (CPCAP_BIT_ID_FLOAT_S | \ - CPCAP_BIT_ID_GROUND_S | \ - CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S) - -#define SENSE_WHISPER_SPD (CPCAP_BIT_SE1_S) - -#define SENSE_WHISPER_PPD (0) - -#define SENSE_WHISPER_SMART (CPCAP_BIT_ID_GROUND_S | \ - CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S) - -#define SENSE_CHARGER_FLOAT (CPCAP_BIT_ID_FLOAT_S | \ - CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S | \ - CPCAP_BIT_SE1_S) - -#define SENSE_CHARGER (CPCAP_BIT_VBUSVLD_S | \ - CPCAP_BIT_SESSVLD_S | \ - CPCAP_BIT_SE1_S) - -/* TODO: Update with appropriate value. */ -#define ADC_AUDIO_THRES 0x12C - -enum cpcap_det_state { - CONFIG, - SAMPLE_1, - SAMPLE_2, - IDENTIFY, - IDENTIFY_WHISPER, - USB, - USB_POWER, - WHISPER, - WHISPER_SMART, -}; - -enum cpcap_accy { - CPCAP_ACCY_USB, - CPCAP_ACCY_USB_HOST, - CPCAP_ACCY_WHISPER, - CPCAP_ACCY_WHISPER_SMART, - CPCAP_ACCY_CHARGER, - CPCAP_ACCY_NONE, - - /* Used while debouncing the accessory. */ - CPCAP_ACCY_UNKNOWN, -}; - -enum { - NO_DOCK, - DESK_DOCK, - CAR_DOCK, - LE_DOCK, - HE_DOCK, -}; - -struct cpcap_whisper_data { - struct cpcap_device *cpcap; - struct cpcap_whisper_pdata *pdata; - struct delayed_work work; - struct workqueue_struct *wq; - unsigned short sense; - unsigned short prev_sense; - enum cpcap_det_state state; - struct regulator *regulator; - struct wake_lock wake_lock; - unsigned char is_vusb_enabled; - struct switch_dev wsdev; /* Whisper switch */ - struct switch_dev dsdev; /* Dock switch */ - struct switch_dev asdev; /* Audio switch */ - struct switch_dev csdev; /* Invalid charger switch */ - char dock_id[CPCAP_WHISPER_ID_SIZE]; - char dock_prop[CPCAP_WHISPER_PROP_SIZE]; - struct otg_transceiver *otg; -}; - -static struct cpcap_whisper_data *whisper_di; - -static int whisper_debug; -module_param(whisper_debug, int, S_IRUGO | S_IWUSR | S_IWGRP); - -static ssize_t print_name(struct switch_dev *dsdev, char *buf) -{ - switch (switch_get_state(dsdev)) { - case NO_DOCK: - return sprintf(buf, "None\n"); - case DESK_DOCK: - return sprintf(buf, "DESK\n"); - case CAR_DOCK: - return sprintf(buf, "CAR\n"); - case LE_DOCK: - return sprintf(buf, "LE\n"); - case HE_DOCK: - return sprintf(buf, "HE\n"); - } - - return -EINVAL; -} - -static ssize_t dock_id_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *dsdev = dev_get_drvdata(dev); - struct cpcap_whisper_data *data = - container_of(dsdev, struct cpcap_whisper_data, dsdev); - - return snprintf(buf, PAGE_SIZE, "%s\n", data->dock_id); -} -static DEVICE_ATTR(dock_addr, S_IRUGO | S_IWUSR, dock_id_show, NULL); - -static ssize_t dock_prop_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *dsdev = dev_get_drvdata(dev); - struct cpcap_whisper_data *data = - container_of(dsdev, struct cpcap_whisper_data, dsdev); - - return snprintf(buf, PAGE_SIZE, "%s\n", data->dock_prop); -} -static DEVICE_ATTR(dock_prop, S_IRUGO | S_IWUSR, dock_prop_show, NULL); - -static void vusb_enable(struct cpcap_whisper_data *data) -{ - if (!data->is_vusb_enabled) { - regulator_enable(data->regulator); - data->is_vusb_enabled = 1; - } -} - -static void vusb_disable(struct cpcap_whisper_data *data) -{ - if (data->is_vusb_enabled) { - regulator_disable(data->regulator); - data->is_vusb_enabled = 0; - } -} - -static int get_sense(struct cpcap_whisper_data *data) -{ - int retval = -EFAULT; - unsigned short value; - struct cpcap_device *cpcap; - - if (!data) - return -EFAULT; - cpcap = data->cpcap; - - retval = cpcap_regacc_read(cpcap, CPCAP_REG_INTS1, &value); - if (retval) - return retval; - - /* Clear ASAP after read. */ - retval = cpcap_regacc_write(cpcap, CPCAP_REG_INT1, - (CPCAP_BIT_CHRG_DET_I | - CPCAP_BIT_ID_FLOAT_I | - CPCAP_BIT_ID_GROUND_I), - (CPCAP_BIT_CHRG_DET_I | - CPCAP_BIT_ID_FLOAT_I | - CPCAP_BIT_ID_GROUND_I)); - if (retval) - return retval; - - data->sense = value & (CPCAP_BIT_ID_FLOAT_S | - CPCAP_BIT_ID_GROUND_S); - - retval = cpcap_regacc_read(cpcap, CPCAP_REG_INTS2, &value); - if (retval) - return retval; - - /* Clear ASAP after read. */ - retval = cpcap_regacc_write(cpcap, CPCAP_REG_INT2, - (CPCAP_BIT_VBUSVLD_I | - CPCAP_BIT_SESSVLD_I | - CPCAP_BIT_SE1_I), - (CPCAP_BIT_VBUSVLD_I | - CPCAP_BIT_SESSVLD_I | - CPCAP_BIT_SE1_I)); - if (retval) - return retval; - - data->sense |= value & (CPCAP_BIT_VBUSVLD_S | - CPCAP_BIT_SESSVLD_S | - CPCAP_BIT_SE1_S); - return 0; -} - -static int configure_hardware(struct cpcap_whisper_data *data, - enum cpcap_accy accy) -{ - int retval; - - retval = cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, - CPCAP_BIT_DP150KPU, - (CPCAP_BIT_DP150KPU | CPCAP_BIT_DP1K5PU | - CPCAP_BIT_DM1K5PU | CPCAP_BIT_DPPD | - CPCAP_BIT_DMPD)); - - switch (accy) { - case CPCAP_ACCY_USB: - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, 0, - CPCAP_BIT_VBUSPD); - gpio_set_value(data->pdata->data_gpio, 1); - if (data->otg) - blocking_notifier_call_chain(&data->otg->notifier, - USB_EVENT_VBUS, NULL); - break; - - case CPCAP_ACCY_USB_HOST: - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, 0, - CPCAP_BIT_VBUSPD); - gpio_set_value(data->pdata->data_gpio, 1); - if (data->otg) - blocking_notifier_call_chain(&data->otg->notifier, - USB_EVENT_ID, NULL); - break; - - case CPCAP_ACCY_WHISPER: - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, 0, - CPCAP_BIT_VBUSPD); - break; - - case CPCAP_ACCY_WHISPER_SMART: - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, 0, - CPCAP_BIT_VBUSPD); - gpio_set_value(data->pdata->data_gpio, 1); - if (data->otg) - blocking_notifier_call_chain(&data->otg->notifier, - USB_EVENT_ID, NULL); - break; - - case CPCAP_ACCY_UNKNOWN: - gpio_set_value(data->pdata->pwr_gpio, 0); - gpio_set_value(data->pdata->data_gpio, 0); - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, 0, - (CPCAP_BIT_VBUSPD | - CPCAP_BIT_ID100KPU)); - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC2, 0, - (CPCAP_BIT_EMUMODE2 | - CPCAP_BIT_EMUMODE1 | - CPCAP_BIT_EMUMODE0)); - break; - - case CPCAP_ACCY_CHARGER: - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, - CPCAP_BIT_VBUSPD, - CPCAP_BIT_VBUSPD); - break; - - case CPCAP_ACCY_NONE: - default: - gpio_set_value(data->pdata->pwr_gpio, 0); - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC1, - CPCAP_BIT_VBUSPD, - CPCAP_BIT_VBUSPD); - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC2, 0, - CPCAP_BIT_USBXCVREN); - vusb_disable(data); - if (data->otg) - blocking_notifier_call_chain(&data->otg->notifier, - USB_EVENT_NONE, NULL); - break; - } - - if (retval != 0) - retval = -EFAULT; - - return retval; -} - -static const char *accy_names[6] = {"USB", "USB host", "whisper", - "whisper_smart", "charger", "none"}; - -static void whisper_notify(struct cpcap_whisper_data *di, enum cpcap_accy accy) -{ - pr_info("%s: accy=%s\n", __func__, accy_names[accy]); - - configure_hardware(di, accy); - - if (accy == CPCAP_ACCY_WHISPER) - switch_set_state(&di->wsdev, 1); - else if (accy == CPCAP_ACCY_CHARGER) - switch_set_state(&di->csdev, 1); - else { - switch_set_state(&di->wsdev, 0); - switch_set_state(&di->dsdev, NO_DOCK); - switch_set_state(&di->asdev, 0); - switch_set_state(&di->csdev, 0); - memset(di->dock_id, 0, CPCAP_WHISPER_ID_SIZE); - memset(di->dock_prop, 0, CPCAP_WHISPER_PROP_SIZE); - tegra_cpcap_audio_dock_state(false); - } - - wake_lock_timeout(&di->wake_lock, HZ / 2); -} - -static void whisper_audio_check(struct cpcap_whisper_data *di) -{ - struct cpcap_adc_request req; - int ret; - unsigned short value; - int audio; - - if (!switch_get_state(&di->dsdev)) - return; - - cpcap_regacc_read(di->cpcap, CPCAP_REG_USBC1, &value); - value &= CPCAP_BIT_ID100KPU; - - cpcap_regacc_write(di->cpcap, CPCAP_REG_USBC1, CPCAP_BIT_IDPUCNTRL, - (CPCAP_BIT_ID100KPU | CPCAP_BIT_IDPUCNTRL)); - - msleep(200); - - req.format = CPCAP_ADC_FORMAT_RAW; - req.timing = CPCAP_ADC_TIMING_IMM; - req.type = CPCAP_ADC_TYPE_BANK_0; - - ret = cpcap_adc_sync_read(di->cpcap, &req); - - cpcap_regacc_write(di->cpcap, CPCAP_REG_USBC1, value, - (CPCAP_BIT_ID100KPU | CPCAP_BIT_IDPUCNTRL)); - - if (whisper_debug) - pr_info("%s: ADC result=0x%X (ret=%d, status=%d)\n", __func__, - req.result[CPCAP_ADC_USB_ID], ret, req.status); - - audio = (req.result[CPCAP_ADC_USB_ID] > ADC_AUDIO_THRES) ? 1 : 0; - switch_set_state(&di->asdev, audio); - tegra_cpcap_audio_dock_state(!!audio); - - pr_info("%s: Audio cable %s present\n", __func__, - (audio ? "is" : "not")); -} - -static void whisper_det_work(struct work_struct *work) -{ - struct cpcap_whisper_data *data = - container_of(work, struct cpcap_whisper_data, work.work); - - switch (data->state) { - case CONFIG: - wake_lock(&data->wake_lock); - vusb_enable(data); - cpcap_irq_mask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_mask(data->cpcap, CPCAP_IRQ_IDFLOAT); - cpcap_irq_mask(data->cpcap, CPCAP_IRQ_IDGND); - - configure_hardware(data, CPCAP_ACCY_UNKNOWN); - - data->state = SAMPLE_1; - queue_delayed_work(data->wq, &data->work, msecs_to_jiffies(11)); - break; - - case SAMPLE_1: - get_sense(data); - data->state = SAMPLE_2; - queue_delayed_work(data->wq, &data->work, - msecs_to_jiffies(100)); - break; - - case SAMPLE_2: - data->prev_sense = data->sense; - get_sense(data); - - if (data->prev_sense != data->sense) { - /* Stay in this state */ - data->state = SAMPLE_2; - } else - data->state = IDENTIFY; - - queue_delayed_work(data->wq, &data->work, - msecs_to_jiffies(100)); - break; - - case IDENTIFY: - get_sense(data); - data->state = CONFIG; - - if (whisper_debug) - pr_info("%s: sense=0x%04x\n", __func__, data->sense); - - if ((data->sense == SENSE_USB_CLIENT) || - (data->sense == SENSE_USB_FLASH) || - (data->sense == SENSE_FACTORY)) { - whisper_notify(data, CPCAP_ACCY_USB); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDGND); - - /* Special handling of USB undetect. */ - data->state = USB; - } else if ((data->sense & SENSE_USB_HOST_MASK) == - SENSE_USB_HOST) { - whisper_notify(data, CPCAP_ACCY_USB_HOST); - - data->state = USB_POWER; - queue_delayed_work(data->wq, &data->work, - msecs_to_jiffies(200)); - } else if ((data->sense == SENSE_WHISPER_SPD) || - (data->sense == SENSE_WHISPER_PPD)) { - gpio_set_value(data->pdata->pwr_gpio, 1); - - /* Extra identification step for Whisper. */ - data->state = IDENTIFY_WHISPER; - queue_delayed_work(data->wq, &data->work, - msecs_to_jiffies(47)); - } else if (data->sense == SENSE_WHISPER_SMART) { - whisper_notify(data, CPCAP_ACCY_WHISPER_SMART); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDGND); - - /* Special handling of Whisper Smart accessories. */ - data->state = WHISPER_SMART; - } else if ((data->sense == SENSE_CHARGER_FLOAT) || - (data->sense == SENSE_CHARGER)) { - whisper_notify(data, CPCAP_ACCY_CHARGER); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - } else { - whisper_notify(data, CPCAP_ACCY_NONE); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDFLOAT); - } - break; - - case IDENTIFY_WHISPER: - get_sense(data); - data->state = CONFIG; - - if (whisper_debug) - pr_info("%s: sense=0x%04x\n", __func__, data->sense); - - if (data->sense & CPCAP_BIT_SE1_S) { - whisper_notify(data, CPCAP_ACCY_WHISPER); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDFLOAT); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDGND); - - /* Special handling of Whisper undetect. */ - data->state = WHISPER; - } else { - whisper_notify(data, CPCAP_ACCY_NONE); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDFLOAT); - } - break; - - case USB: - get_sense(data); - - /* Check if Smart Whisper accessory fully inserted. */ - if (data->sense == SENSE_WHISPER_SMART) { - data->state = WHISPER_SMART; - - whisper_notify(data, CPCAP_ACCY_NONE); - whisper_notify(data, CPCAP_ACCY_WHISPER_SMART); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDGND); - } else { - data->state = CONFIG; - queue_delayed_work(data->wq, &data->work, 0); - } - - break; - - case USB_POWER: - gpio_set_value(data->pdata->pwr_gpio, 1); - data->state = CONFIG; - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDFLOAT); - break; - - case WHISPER: - get_sense(data); - - /* The removal of a Whisper accessory can only be detected - * if ID is floating. - */ - if (data->sense & CPCAP_BIT_ID_FLOAT_S) { - data->state = CONFIG; - queue_delayed_work(data->wq, &data->work, 0); - } else { - if (!(data->sense & CPCAP_BIT_ID_GROUND_S)) - whisper_audio_check(data); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDFLOAT); - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_IDGND); - } - break; - - case WHISPER_SMART: - get_sense(data); - - /* The removal of a Whisper Smart accessory can only be detected - * when VBUS disappears. - */ - if (!(data->sense & CPCAP_BIT_VBUSVLD_S)) { - data->state = CONFIG; - queue_delayed_work(data->wq, &data->work, 0); - } else { - if (!(data->sense & CPCAP_BIT_ID_GROUND_S)) - pr_info("%s: ID no longer ground\n", __func__); - - cpcap_irq_unmask(data->cpcap, CPCAP_IRQ_CHRG_DET); - } - break; - - default: - /* This shouldn't happen. Need to reset state machine. */ - vusb_disable(data); - data->state = CONFIG; - queue_delayed_work(data->wq, &data->work, 0); - break; - } -} - -static void whisper_int_handler(enum cpcap_irqs int_event, void *data) -{ - struct cpcap_whisper_data *di = data; - - if (whisper_debug) - pr_info("%s: irq=%d\n", __func__, int_event); - - queue_delayed_work(di->wq, &(di->work), 0); -} - -int cpcap_accy_whisper(struct cpcap_device *cpcap, - struct cpcap_whisper_request *req) -{ - struct cpcap_whisper_data *di = cpcap->accydata; - int retval = -EAGAIN; - unsigned short value = 0; - int dock; - - if (!di) - return -ENODEV; - - /* Can only change settings if not debouncing and whisper device - * is present. */ - if (di->state == WHISPER) { - if (req->cmd & CPCAP_WHISPER_ENABLE_UART) - value = CPCAP_BIT_EMUMODE0; - retval = cpcap_regacc_write(cpcap, CPCAP_REG_USBC2, value, - (CPCAP_BIT_EMUMODE2 | - CPCAP_BIT_EMUMODE1 | - CPCAP_BIT_EMUMODE0)); - - value = (req->cmd & CPCAP_WHISPER_MODE_PU) ? - CPCAP_BIT_ID100KPU : 0; - retval |= cpcap_regacc_write(cpcap, CPCAP_REG_USBC1, - value, CPCAP_BIT_ID100KPU); - if (value) { - retval |= cpcap_regacc_write(cpcap, CPCAP_REG_USBC2, - (CPCAP_BIT_EMUMODE2 | - CPCAP_BIT_EMUMODE0), - (CPCAP_BIT_EMUMODE2 | - CPCAP_BIT_EMUMODE1 | - CPCAP_BIT_EMUMODE0)); - } - - /* Report dock type to system. */ - dock = (req->cmd & CPCAP_WHISPER_ACCY_MASK) >> - CPCAP_WHISPER_ACCY_SHFT; - if (dock && (strlen(req->dock_id) < CPCAP_WHISPER_ID_SIZE)) - strncpy(di->dock_id, req->dock_id, - CPCAP_WHISPER_ID_SIZE); - if (dock && (strlen(req->dock_prop) < CPCAP_WHISPER_PROP_SIZE)) - strncpy(di->dock_prop, req->dock_prop, - CPCAP_WHISPER_PROP_SIZE); - switch_set_state(&di->dsdev, dock); - - whisper_audio_check(di); - } else if (di->state == WHISPER_SMART) { - /* Report dock type to system. */ - dock = (req->cmd & CPCAP_WHISPER_ACCY_MASK) >> - CPCAP_WHISPER_ACCY_SHFT; - if (dock && (strlen(req->dock_id) < CPCAP_WHISPER_ID_SIZE)) - strncpy(di->dock_id, req->dock_id, - CPCAP_WHISPER_ID_SIZE); - if (dock && (strlen(req->dock_prop) < CPCAP_WHISPER_PROP_SIZE)) - strncpy(di->dock_prop, req->dock_prop, - CPCAP_WHISPER_PROP_SIZE); - switch_set_state(&di->dsdev, dock); - retval = 0; - } - - return retval; -} - -void cpcap_accy_whisper_spdif_set_state(int state) -{ - if (!whisper_di) - return; - - if (!switch_get_state(&whisper_di->dsdev)) - return; - - state = ((state > 0) ? 2 : 0); - switch_set_state(&whisper_di->asdev, state); - - pr_info("%s: Audio cable %s present\n", __func__, - (state ? "is" : "not")); -} - -static int cpcap_whisper_probe(struct platform_device *pdev) -{ - int retval; - struct cpcap_whisper_data *data; - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform_data\n"); - return -EINVAL; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->pdata = pdev->dev.platform_data; - data->cpcap = platform_get_drvdata(pdev); - data->state = CONFIG; - data->wq = create_singlethread_workqueue("cpcap_whisper"); - INIT_DELAYED_WORK(&data->work, whisper_det_work); - wake_lock_init(&data->wake_lock, WAKE_LOCK_SUSPEND, "whisper"); - - data->wsdev.name = "whisper"; - switch_dev_register(&data->wsdev); - - data->asdev.name = "usb_audio"; - switch_dev_register(&data->asdev); - - data->csdev.name = "invalid_charger"; - switch_dev_register(&data->csdev); - - data->dsdev.name = "dock"; - data->dsdev.print_name = print_name; - switch_dev_register(&data->dsdev); - retval = device_create_file(data->dsdev.dev, &dev_attr_dock_addr); - if (retval < 0) { - dev_err(&pdev->dev, "Failed to create dock_addr file\n"); - goto free_mem; - } - retval = device_create_file(data->dsdev.dev, &dev_attr_dock_prop); - if (retval < 0) { - dev_err(&pdev->dev, "Failed to create dock_prop file\n"); - goto free_dock_id; - } - - platform_set_drvdata(pdev, data); - - data->regulator = regulator_get(&pdev->dev, "vusb"); - if (IS_ERR(data->regulator)) { - dev_err(&pdev->dev, - "Could not get regulator for cpcap_whisper\n"); - retval = PTR_ERR(data->regulator); - goto free_dock_prop; - } - regulator_set_voltage(data->regulator, 3300000, 3300000); - - retval = cpcap_irq_clear(data->cpcap, CPCAP_IRQ_CHRG_DET); - retval |= cpcap_irq_clear(data->cpcap, CPCAP_IRQ_IDFLOAT); - retval |= cpcap_irq_clear(data->cpcap, CPCAP_IRQ_IDGND); - - retval |= cpcap_irq_register(data->cpcap, CPCAP_IRQ_CHRG_DET, - whisper_int_handler, data); - retval |= cpcap_irq_register(data->cpcap, CPCAP_IRQ_IDFLOAT, - whisper_int_handler, data); - retval |= cpcap_irq_register(data->cpcap, CPCAP_IRQ_IDGND, - whisper_int_handler, data); - - retval |= cpcap_regacc_write(data->cpcap, CPCAP_REG_USBC2, - (data->pdata->uartmux << 8), - (CPCAP_BIT_UARTMUX1 | CPCAP_BIT_UARTMUX0)); - - if (retval != 0) { - dev_err(&pdev->dev, "Initialization Error\n"); - retval = -ENODEV; - goto free_irqs; - } - -#ifdef CONFIG_USB_CPCAP_OTG - data->otg = otg_get_transceiver(); -#endif - - data->cpcap->accydata = data; - whisper_di = data; - dev_info(&pdev->dev, "CPCAP Whisper detection probed\n"); - - /* Perform initial detection */ - whisper_det_work(&(data->work.work)); - - return 0; - -free_irqs: - cpcap_irq_free(data->cpcap, CPCAP_IRQ_IDGND); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_IDFLOAT); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_CHRG_DET); - regulator_put(data->regulator); -free_dock_prop: - device_remove_file(data->dsdev.dev, &dev_attr_dock_prop); -free_dock_id: - device_remove_file(data->dsdev.dev, &dev_attr_dock_addr); -free_mem: - switch_dev_unregister(&data->wsdev); - switch_dev_unregister(&data->dsdev); - switch_dev_unregister(&data->asdev); - switch_dev_unregister(&data->csdev); - wake_lock_destroy(&data->wake_lock); - kfree(data); - - return retval; -} - -static int __exit cpcap_whisper_remove(struct platform_device *pdev) -{ - struct cpcap_whisper_data *data = platform_get_drvdata(pdev); - - cpcap_irq_free(data->cpcap, CPCAP_IRQ_CHRG_DET); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_IDFLOAT); - cpcap_irq_free(data->cpcap, CPCAP_IRQ_IDGND); - - configure_hardware(data, CPCAP_ACCY_NONE); - cancel_delayed_work_sync(&data->work); - destroy_workqueue(data->wq); - - device_remove_file(data->dsdev.dev, &dev_attr_dock_prop); - device_remove_file(data->dsdev.dev, &dev_attr_dock_addr); - switch_dev_unregister(&data->wsdev); - switch_dev_unregister(&data->dsdev); - switch_dev_unregister(&data->asdev); - switch_dev_unregister(&data->csdev); - - gpio_set_value(data->pdata->data_gpio, 1); - - vusb_disable(data); - regulator_put(data->regulator); - -#ifdef CONFIG_USB_CPCAP_OTG - if (data->otg) - otg_put_transceiver(data->otg); -#endif - - wake_lock_destroy(&data->wake_lock); - - data->cpcap->accydata = NULL; - kfree(data); - - return 0; -} - -static struct platform_driver cpcap_whisper_driver = { - .probe = cpcap_whisper_probe, - .remove = __exit_p(cpcap_whisper_remove), - .driver = { - .name = "cpcap_whisper", - .owner = THIS_MODULE, - }, -}; - -static int __init cpcap_whisper_init(void) -{ - return cpcap_driver_register(&cpcap_whisper_driver); -} -late_initcall(cpcap_whisper_init); - -static void __exit cpcap_whisper_exit(void) -{ - cpcap_driver_unregister(&cpcap_whisper_driver); -} -module_exit(cpcap_whisper_exit); - -MODULE_ALIAS("platform:cpcap_whisper"); -MODULE_DESCRIPTION("CPCAP Whisper detection driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/tegra-cpcap-audio.c b/drivers/mfd/tegra-cpcap-audio.c deleted file mode 100644 index 02a8e5559d29..000000000000 --- a/drivers/mfd/tegra-cpcap-audio.c +++ /dev/null @@ -1,595 +0,0 @@ -/* drivers/mfd/cpcap-audio.c - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Iliyan Malchev - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static struct cpcap_device *cpcap; -static struct cpcap_audio_platform_data *pdata; -static struct cpcap_audio_stream current_output = { - .id = CPCAP_AUDIO_OUT_SPEAKER, -}; -static struct cpcap_audio_stream current_input = { - .id = CPCAP_AUDIO_IN_MIC1, -}; -static int codec_rate; -static int stdac_rate; -static bool dock_connected; -static bool bluetooth_byp; - -static int cpcap_audio_ctl_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int cpcap_audio_ctl_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static DEFINE_MUTEX(cpcap_lock); - -static void tegra_setup_audio_output_off(void) -{ - /* turn off the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 0); - - pdata->state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE; - pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_OFF; - - pdata->state->stdac_primary_speaker = CPCAP_AUDIO_OUT_NONE; - pdata->state->stdac_secondary_speaker = CPCAP_AUDIO_OUT_NONE; - cpcap_audio_set_audio_state(pdata->state); -} - -static void tegra_setup_audio_out_speaker_on(void) -{ - /* turn off the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 0); - - pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON; - /* Using an external amp, lineout is the loudspeaker. */ - pdata->state->stdac_primary_speaker = CPCAP_AUDIO_OUT_LINEOUT; - pdata->state->stdac_secondary_speaker = CPCAP_AUDIO_OUT_NONE; - cpcap_audio_set_audio_state(pdata->state); - - /* turn on the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 1); - gpio_direction_output(pdata->headset_gpio, 0); -} - -static void tegra_setup_audio_out_headset_on(void) -{ - /* turn off the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 0); - - pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON; - pdata->state->stdac_primary_speaker = CPCAP_AUDIO_OUT_STEREO_HEADSET; - pdata->state->stdac_secondary_speaker = CPCAP_AUDIO_OUT_NONE; - cpcap_audio_set_audio_state(pdata->state); - - /* turn on the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 1); -} - -static void tegra_setup_audio_out_headset_and_speaker_on(void) -{ - /* turn off the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 0); - - pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON; - pdata->state->stdac_primary_speaker = CPCAP_AUDIO_OUT_STEREO_HEADSET; - pdata->state->stdac_secondary_speaker = CPCAP_AUDIO_OUT_LINEOUT; - cpcap_audio_set_audio_state(pdata->state); - - /* turn on the amplifier */ - gpio_direction_output(pdata->speaker_gpio, 1); - gpio_direction_output(pdata->headset_gpio, 1); -} - -static void tegra_setup_audio_out_dock_headset_on(void) -{ - pdata->state->stdac_mode = CPCAP_AUDIO_STDAC_ON; - pdata->state->stdac_primary_speaker = CPCAP_AUDIO_OUT_EMU_STEREO; - pdata->state->stdac_secondary_speaker = CPCAP_AUDIO_OUT_EMU_STEREO; - cpcap_audio_set_audio_state(pdata->state); - - /* turn off the headset and speaker amplifiers */ - gpio_direction_output(pdata->speaker_gpio, 0); - gpio_direction_output(pdata->headset_gpio, 0); -} - -static void tegra_setup_audio_in_mute(void) -{ - pdata->state->codec_mute = CPCAP_AUDIO_CODEC_MUTE; - pdata->state->codec_mode = CPCAP_AUDIO_CODEC_OFF; - - pdata->state->microphone = CPCAP_AUDIO_IN_NONE; - - cpcap_audio_set_audio_state(pdata->state); -} - -static void tegra_setup_audio_in_handset_on(void) -{ - pdata->state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE; - pdata->state->codec_mode = CPCAP_AUDIO_CODEC_ON; - - pdata->state->microphone = CPCAP_AUDIO_IN_HANDSET; - cpcap_audio_set_audio_state(pdata->state); -} - -static void tegra_setup_audio_in_headset_on(void) -{ - pdata->state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE; - pdata->state->codec_mode = CPCAP_AUDIO_CODEC_ON; - - pdata->state->microphone = CPCAP_AUDIO_IN_HEADSET; - cpcap_audio_set_audio_state(pdata->state); -} - -static int rate_to_cpcap_codec_rate(int rate) -{ - return - rate == 8000 ? CPCAP_AUDIO_CODEC_RATE_8000_HZ : - rate == 11025 ? CPCAP_AUDIO_CODEC_RATE_11025_HZ : - rate == 12000 ? CPCAP_AUDIO_CODEC_RATE_12000_HZ : - rate == 16000 ? CPCAP_AUDIO_CODEC_RATE_16000_HZ : - rate == 22050 ? CPCAP_AUDIO_CODEC_RATE_22050_HZ : - rate == 24000 ? CPCAP_AUDIO_CODEC_RATE_24000_HZ : - rate == 32000 ? CPCAP_AUDIO_CODEC_RATE_32000_HZ : - rate == 44100 ? CPCAP_AUDIO_CODEC_RATE_44100_HZ : - rate == 48000 ? CPCAP_AUDIO_CODEC_RATE_48000_HZ : - /*default*/ CPCAP_AUDIO_CODEC_RATE_8000_HZ; -} - -static int rate_to_cpcap_stdac_rate(int rate) -{ - return - rate == 8000 ? CPCAP_AUDIO_STDAC_RATE_8000_HZ : - rate == 11025 ? CPCAP_AUDIO_STDAC_RATE_11025_HZ : - rate == 12000 ? CPCAP_AUDIO_STDAC_RATE_12000_HZ : - rate == 16000 ? CPCAP_AUDIO_STDAC_RATE_16000_HZ : - rate == 22050 ? CPCAP_AUDIO_STDAC_RATE_22050_HZ : - rate == 24000 ? CPCAP_AUDIO_STDAC_RATE_24000_HZ : - rate == 32000 ? CPCAP_AUDIO_STDAC_RATE_32000_HZ : - rate == 44100 ? CPCAP_AUDIO_STDAC_RATE_44100_HZ : - rate == 48000 ? CPCAP_AUDIO_STDAC_RATE_48000_HZ : - /*default*/ CPCAP_AUDIO_STDAC_RATE_44100_HZ; -} - -static void tegra_setup_audio_out_rate(int rate) -{ - pdata->state->stdac_rate = rate_to_cpcap_stdac_rate(rate); - stdac_rate = rate; - cpcap_audio_set_audio_state(pdata->state); -} - -static void tegra_setup_audio_in_rate(int rate) -{ - pdata->state->codec_rate = rate_to_cpcap_codec_rate(rate); - codec_rate = rate; - cpcap_audio_set_audio_state(pdata->state); -} - -static long cpcap_audio_ctl_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int rc = 0; - struct cpcap_audio_stream in, out; - int rate; - mutex_lock(&cpcap_lock); - - switch (cmd) { - case CPCAP_AUDIO_OUT_SET_OUTPUT: - if (copy_from_user(&out, (const void __user *)arg, - sizeof(out))) { - rc = -EFAULT; - goto done; - } - if (out.id > CPCAP_AUDIO_OUT_MAX) { - pr_err("%s: invalid audio-output selector %d\n", - __func__, out.id); - rc = -EINVAL; - goto done; - } - - switch (out.id) { - case CPCAP_AUDIO_OUT_SPEAKER: - pr_debug("%s: setting output path to speaker\n", - __func__); - if (out.on) - tegra_setup_audio_out_speaker_on(); - else - tegra_setup_audio_output_off(); - current_output = out; - break; - case CPCAP_AUDIO_OUT_HEADSET: - pr_debug("%s: setting output path to headset\n", - __func__); - if (out.on) - tegra_setup_audio_out_headset_on(); - else - tegra_setup_audio_output_off(); - current_output = out; - break; - case CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER: - pr_debug("%s: setting output path to " - "headset + speaker\n", __func__); - if (out.on) - tegra_setup_audio_out_headset_and_speaker_on(); - else - tegra_setup_audio_output_off(); - - current_output = out; - break; - case CPCAP_AUDIO_OUT_ANLG_DOCK_HEADSET: - pr_err("%s: setting output path to basic dock\n", - __func__); - if (out.on) - tegra_setup_audio_out_dock_headset_on(); - else - tegra_setup_audio_output_off(); - current_output = out; - break; - case CPCAP_AUDIO_OUT_STANDBY: - current_output.on = !out.on; - if (out.on) { - pr_debug("%s: standby mode\n", __func__); - tegra_setup_audio_output_off(); - break; - } - - switch (current_output.id) { - case CPCAP_AUDIO_OUT_SPEAKER: - pr_debug("%s: standby off (speaker)", __func__); - tegra_setup_audio_out_speaker_on(); - break; - case CPCAP_AUDIO_OUT_HEADSET: - pr_debug("%s: standby off (headset)", __func__); - tegra_setup_audio_out_headset_on(); - break; - case CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER: - pr_debug("%s: standby off (speaker + headset)", - __func__); - tegra_setup_audio_out_headset_and_speaker_on(); - break; - case CPCAP_AUDIO_OUT_ANLG_DOCK_HEADSET: - pr_err("%s: standby off (dock headset)", - __func__); - tegra_setup_audio_out_dock_headset_on(); - break; - } - break; - } - break; - case CPCAP_AUDIO_OUT_GET_OUTPUT: - if (copy_to_user((void __user *)arg, ¤t_output, - sizeof(current_output))) - rc = -EFAULT; - break; - case CPCAP_AUDIO_IN_SET_INPUT: - if (copy_from_user(&in, (const void __user *)arg, - sizeof(in))) { - rc = -EFAULT; - goto done; - } - if (in.id > CPCAP_AUDIO_IN_MAX) { - pr_err("%s: invalid audio input selector %d\n", - __func__, in.id); - rc = -EINVAL; - goto done; - } - switch (in.id) { - case CPCAP_AUDIO_IN_MIC1: - if (in.on) { - pr_debug("%s: setting input path to on-board mic\n", - __func__); - tegra_setup_audio_in_handset_on(); - } else { - pr_debug("%s: mute on-board mic\n", __func__); - tegra_setup_audio_in_mute(); - } - - current_input = in; - break; - case CPCAP_AUDIO_IN_MIC2: - if (in.on) { - pr_debug("%s: setting input path to headset mic\n", - __func__); - tegra_setup_audio_in_headset_on(); - } else { - pr_debug("%s: mute headset mic\n", __func__); - tegra_setup_audio_in_mute(); - } - - current_input = in; - break; - case CPCAP_AUDIO_IN_STANDBY: - current_input.on = !in.on; - if (in.on) { - pr_debug("%s: microphone in standby mode\n", - __func__); - tegra_setup_audio_in_mute(); - break; - } - switch (current_input.id) { - case CPCAP_AUDIO_IN_MIC1: - tegra_setup_audio_in_handset_on(); - break; - case CPCAP_AUDIO_IN_MIC2: - tegra_setup_audio_in_headset_on(); - break; - } - break; - } - break; - case CPCAP_AUDIO_IN_GET_INPUT: - if (copy_to_user((void __user *)arg, ¤t_input, - sizeof(current_input))) - rc = -EFAULT; - break; - case CPCAP_AUDIO_OUT_SET_VOLUME: - if (arg > CPCAP_AUDIO_OUT_VOL_MAX) { - pr_err("%s: invalid audio volume %ld\n", - __func__, arg); - rc = -EINVAL; - goto done; - } - pdata->state->output_gain = arg; - cpcap_audio_set_audio_state(pdata->state); - break; - case CPCAP_AUDIO_IN_SET_VOLUME: - if (arg > CPCAP_AUDIO_IN_VOL_MAX) { - pr_err("%s: invalid audio-input volume %ld\n", - __func__, arg); - rc = -EINVAL; - goto done; - } - pdata->state->input_gain = (unsigned)arg; - cpcap_audio_set_audio_state(pdata->state); - break; - case CPCAP_AUDIO_OUT_GET_VOLUME: - if (copy_to_user((void __user *)arg, &pdata->state->output_gain, - sizeof(unsigned int))) { - rc = -EFAULT; - goto done; - } - break; - case CPCAP_AUDIO_IN_GET_VOLUME: - if (copy_to_user((void __user *)arg, &pdata->state->input_gain, - sizeof(unsigned int))) { - rc = -EFAULT; - goto done; - } - break; - case CPCAP_AUDIO_OUT_GET_RATE: - if (copy_to_user((void __user *)arg, &stdac_rate, - sizeof(int))) { - rc = -EFAULT; - goto done; - } - break; - case CPCAP_AUDIO_OUT_SET_RATE: - rate = (int)arg; - if (rate < 8000 || rate > 48000) { - pr_err("%s: invalid rate %d\n", __func__, rate); - rc = -EFAULT; - goto done; - } - pr_debug("%s: setting output rate to %dHz\n", __func__, rate); - tegra_setup_audio_out_rate(rate); - break; - case CPCAP_AUDIO_IN_GET_RATE: - if (copy_to_user((void __user *)arg, &codec_rate, - sizeof(int))) { - rc = -EFAULT; - goto done; - } - break; - case CPCAP_AUDIO_IN_SET_RATE: - rate = (int)arg; - if (rate < 8000 || rate > 48000) { - pr_err("%s: invalid in rate %d\n", __func__, rate); - rc = -EFAULT; - goto done; - } - pr_debug("%s: setting input rate to %dHz\n", __func__, rate); - tegra_setup_audio_in_rate(rate); - break; - case CPCAP_AUDIO_SET_BLUETOOTH_BYPASS: - bluetooth_byp = (bool)arg; - if (pdata->bluetooth_bypass) - pdata->bluetooth_bypass(bluetooth_byp); - else - pr_err("%s: no bluetooth bypass handler\n", __func__); - break; - } - -done: - mutex_unlock(&cpcap_lock); - return rc; -} - -static const struct file_operations cpcap_audio_ctl_fops = { - .open = cpcap_audio_ctl_open, - .release = cpcap_audio_ctl_release, - .unlocked_ioctl = cpcap_audio_ctl_ioctl, -}; - -static struct miscdevice cpcap_audio_ctl = { - .name = "audio_ctl", - .minor = MISC_DYNAMIC_MINOR, - .fops = &cpcap_audio_ctl_fops, -}; - -/* Couple the CPCAP and Dock audio state, to avoid pops */ -void tegra_cpcap_audio_dock_state(bool connected) -{ - pr_debug("%s: %s", __func__, connected ? "connected" : "disconnected"); - - mutex_lock(&cpcap_lock); - dock_connected = connected; - /* Borrow (unused) "ext output" to keep dock speaker amplifier on. */ - pdata->state->ext_primary_speaker = dock_connected ? - CPCAP_AUDIO_OUT_EMU_STEREO : CPCAP_AUDIO_OUT_NONE; - cpcap_audio_set_audio_state(pdata->state); - mutex_unlock(&cpcap_lock); -} -EXPORT_SYMBOL(tegra_cpcap_audio_dock_state); - -static void cpcap_audio_callback(int status) -{ - mutex_lock(&cpcap_lock); - if (status == 1 || status == 2) { - if (pdata->state->stdac_primary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET) - tegra_setup_audio_out_headset_on(); - if (pdata->state->microphone == - CPCAP_AUDIO_IN_HEADSET) - tegra_setup_audio_in_headset_on(); - } - if (status == 0) { - if (pdata->state->stdac_primary_speaker == - CPCAP_AUDIO_OUT_STEREO_HEADSET) - tegra_setup_audio_output_off(); - if (pdata->state->microphone == - CPCAP_AUDIO_IN_HEADSET) - tegra_setup_audio_in_mute(); - } - - mutex_unlock(&cpcap_lock); -} - -static int cpcap_audio_probe(struct platform_device *pdev) -{ - int rc; - - pr_debug("%s\n", __func__); - - cpcap = platform_get_drvdata(pdev); - BUG_ON(!cpcap); - - pdata = pdev->dev.platform_data; - BUG_ON(!pdata); - - if (pdata->speaker_gpio >= 0) { - tegra_gpio_enable(pdata->speaker_gpio); - rc = gpio_request(pdata->speaker_gpio, "speaker"); - if (rc) { - pr_err("%s: could not get speaker GPIO %d: %d\n", - __func__, pdata->speaker_gpio, rc); - goto fail1; - } - } - - if (pdata->headset_gpio >= 0) { - tegra_gpio_enable(pdata->headset_gpio); - rc = gpio_request(pdata->headset_gpio, "headset"); - if (rc) { - pr_err("%s: could not get headset GPIO %d: %d\n", - __func__, pdata->headset_gpio, rc); - goto fail2; - } - } - - pdata->state->cpcap = cpcap; - if (cpcap_audio_init(pdata->state, pdata->regulator)) - goto fail3; - - cpcap->h2w_new_state = &cpcap_audio_callback; - - rc = misc_register(&cpcap_audio_ctl); - if (rc < 0) { - pr_err("%s: failed to register misc device: %d\n", __func__, - rc); - goto fail3; - } - - return rc; - -fail3: - if (pdata->headset_gpio >= 0) - gpio_free(pdata->headset_gpio); -fail2: - if (pdata->headset_gpio >= 0) - tegra_gpio_disable(pdata->headset_gpio); - if (pdata->speaker_gpio >= 0) - gpio_free(pdata->speaker_gpio); -fail1: - if (pdata->speaker_gpio >= 0) - tegra_gpio_disable(pdata->speaker_gpio); - return rc; -} - -#ifdef CONFIG_PM -static int tegra_audio_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - dev_dbg(&pdev->dev, "%s\n", __func__); - return 0; -} - -static int tegra_audio_resume(struct platform_device *pdev) -{ - dev_dbg(&pdev->dev, "%s\n", __func__); - /* initialize DAC/DAP connections */ - if (pdata->bluetooth_bypass) - pdata->bluetooth_bypass(bluetooth_byp); - else - pr_warn("No function for setting up DAC/DAP."); - return 0; -} -#endif - -static struct platform_driver cpcap_audio_driver = { - .probe = cpcap_audio_probe, - .driver = { - .name = "cpcap_audio", - .owner = THIS_MODULE, - }, -#ifdef CONFIG_PM - .suspend = tegra_audio_suspend, - .resume = tegra_audio_resume, -#endif -}; - -static int __init tegra_cpcap_audio_init(void) -{ - return cpcap_driver_register(&cpcap_audio_driver); -} - -module_init(tegra_cpcap_audio_init); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index ab667f296897..4cde31e6a252 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -15,8 +15,6 @@ * published by the Free Software Foundation. */ -#include -#include #include #include #include @@ -31,62 +29,9 @@ #define TPS6586X_GPIOSET1 0x5d #define TPS6586X_GPIOSET2 0x5e -/* interrupt control registers */ -#define TPS6586X_INT_ACK1 0xb5 -#define TPS6586X_INT_ACK2 0xb6 -#define TPS6586X_INT_ACK3 0xb7 -#define TPS6586X_INT_ACK4 0xb8 - -/* interrupt mask registers */ -#define TPS6586X_INT_MASK1 0xb0 -#define TPS6586X_INT_MASK2 0xb1 -#define TPS6586X_INT_MASK3 0xb2 -#define TPS6586X_INT_MASK4 0xb3 -#define TPS6586X_INT_MASK5 0xb4 - /* device id */ #define TPS6586X_VERSIONCRC 0xcd - -struct tps6586x_irq_data { - u8 mask_reg; - u8 mask_mask; -}; - -#define TPS6586X_IRQ(_reg, _mask) \ - { \ - .mask_reg = (_reg) - TPS6586X_INT_MASK1, \ - .mask_mask = (_mask), \ - } - -static const struct tps6586x_irq_data tps6586x_irqs[] = { - [TPS6586X_INT_PLDO_0] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 0), - [TPS6586X_INT_PLDO_1] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 1), - [TPS6586X_INT_PLDO_2] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 2), - [TPS6586X_INT_PLDO_3] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 3), - [TPS6586X_INT_PLDO_4] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 4), - [TPS6586X_INT_PLDO_5] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 5), - [TPS6586X_INT_PLDO_6] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 6), - [TPS6586X_INT_PLDO_7] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 7), - [TPS6586X_INT_COMP_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 0), - [TPS6586X_INT_ADC] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 1), - [TPS6586X_INT_PLDO_8] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 2), - [TPS6586X_INT_PLDO_9] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 3), - [TPS6586X_INT_PSM_0] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 4), - [TPS6586X_INT_PSM_1] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 5), - [TPS6586X_INT_PSM_2] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 6), - [TPS6586X_INT_PSM_3] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 7), - [TPS6586X_INT_RTC_ALM1] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 4), - [TPS6586X_INT_ACUSB_OVP] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 0x03), - [TPS6586X_INT_USB_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 2), - [TPS6586X_INT_AC_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 3), - [TPS6586X_INT_BAT_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 1 << 0), - [TPS6586X_INT_CHG_STAT] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 0xfc), - [TPS6586X_INT_CHG_TEMP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0x06), - [TPS6586X_INT_PP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0xf0), - [TPS6586X_INT_RESUME] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 5), - [TPS6586X_INT_LOW_SYS] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 6), - [TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1), -}; +#define TPS658621A_VERSIONCRC 0x15 struct tps6586x { struct mutex lock; @@ -94,12 +39,6 @@ struct tps6586x { struct i2c_client *client; struct gpio_chip gpio; - struct irq_chip irq_chip; - struct mutex irq_lock; - int irq_base; - u32 irq_en; - u8 mask_cache[5]; - u8 mask_reg[5]; }; static inline int __tps6586x_read(struct i2c_client *client, @@ -323,129 +262,6 @@ static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); } -static void tps6586x_irq_lock(unsigned int irq) -{ - struct tps6586x *tps6586x = get_irq_chip_data(irq); - - mutex_lock(&tps6586x->irq_lock); -} - -static void tps6586x_irq_enable(unsigned int irq) -{ - struct tps6586x *tps6586x = get_irq_chip_data(irq); - unsigned int __irq = irq - tps6586x->irq_base; - const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; - - tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; - tps6586x->irq_en |= (1 << __irq); -} - -static void tps6586x_irq_disable(unsigned int irq) -{ - struct tps6586x *tps6586x = get_irq_chip_data(irq); - - unsigned int __irq = irq - tps6586x->irq_base; - const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; - - tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; - tps6586x->irq_en &= ~(1 << __irq); -} - -static void tps6586x_irq_sync_unlock(unsigned int irq) -{ - struct tps6586x *tps6586x = get_irq_chip_data(irq); - int i; - - for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { - if (tps6586x->mask_reg[i] != tps6586x->mask_cache[i]) { - if (!WARN_ON(tps6586x_write(tps6586x->dev, - TPS6586X_INT_MASK1 + i, - tps6586x->mask_reg[i]))) - tps6586x->mask_cache[i] = tps6586x->mask_reg[i]; - } - } - - mutex_unlock(&tps6586x->irq_lock); -} - -static irqreturn_t tps6586x_irq(int irq, void *data) -{ - struct tps6586x *tps6586x = data; - u32 acks; - int ret = 0; - - ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, - sizeof(acks), (uint8_t *)&acks); - - if (ret < 0) { - dev_err(tps6586x->dev, "failed to read interrupt status\n"); - return IRQ_NONE; - } - - acks = le32_to_cpu(acks); - - while (acks) { - int i = __ffs(acks); - - if (tps6586x->irq_en & (1 << i)) - handle_nested_irq(tps6586x->irq_base + i); - - acks &= ~(1 << i); - } - - return IRQ_HANDLED; -} - -static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, - int irq_base) -{ - int i, ret; - u8 tmp[4]; - - if (!irq_base) { - dev_warn(tps6586x->dev, "No interrupt support on IRQ base\n"); - return -EINVAL; - } - - mutex_init(&tps6586x->irq_lock); - for (i = 0; i < 5; i++) { - tps6586x->mask_cache[i] = 0xff; - tps6586x->mask_reg[i] = 0xff; - tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff); - } - - tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp); - - tps6586x->irq_base = irq_base; - - tps6586x->irq_chip.name = "tps6586x"; - tps6586x->irq_chip.enable = tps6586x_irq_enable; - tps6586x->irq_chip.disable = tps6586x_irq_disable; - tps6586x->irq_chip.bus_lock = tps6586x_irq_lock; - tps6586x->irq_chip.bus_sync_unlock = tps6586x_irq_sync_unlock; - - for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { - int __irq = i + tps6586x->irq_base; - set_irq_chip_data(__irq, tps6586x); - set_irq_chip_and_handler(__irq, &tps6586x->irq_chip, - handle_simple_irq); - set_irq_nested_thread(__irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(__irq, IRQF_VALID); -#endif - } - - ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT, - "tps6586x", tps6586x); - - if (!ret) { - device_init_wakeup(tps6586x->dev, 1); - enable_irq_wake(irq); - } - - return ret; -} - static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, struct tps6586x_platform_data *pdata) { @@ -490,7 +306,10 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, return -EIO; } - dev_info(&client->dev, "VERSIONCRC is %02x\n", ret); + if (ret != TPS658621A_VERSIONCRC) { + dev_err(&client->dev, "Unsupported chip ID: %x\n", ret); + return -ENODEV; + } tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); if (tps6586x == NULL) @@ -502,15 +321,6 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, mutex_init(&tps6586x->lock); - if (client->irq) { - ret = tps6586x_irq_init(tps6586x, client->irq, - pdata->irq_base); - if (ret) { - dev_err(&client->dev, "IRQ init failed: %d\n", ret); - goto err_irq_init; - } - } - ret = tps6586x_add_subdevs(tps6586x, pdata); if (ret) { dev_err(&client->dev, "add devices failed: %d\n", ret); @@ -522,20 +332,12 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, return 0; err_add_devs: - if (client->irq) - free_irq(client->irq, tps6586x); -err_irq_init: kfree(tps6586x); return ret; } static int __devexit tps6586x_i2c_remove(struct i2c_client *client) { - struct tps6586x *tps6586x = i2c_get_clientdata(client); - - if (client->irq) - free_irq(client->irq, tps6586x); - return 0; } diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index b5347167aa72..1e7aaaf6cc6f 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1464,11 +1464,7 @@ static 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; } - switch (ret) { - case 0x6204: - case 0x6246: - break; - default: + if (ret != 0x6204) { dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); ret = -EINVAL; goto err; @@ -1621,7 +1617,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8321: ret = mfd_add_devices(wm831x->dev, -1, wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, wm831x->irq_base); + NULL, 0); break; default: diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 9c4ef5015d6e..b74331260744 100755 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -53,10 +53,6 @@ config AD525X_DPOT_SPI To compile this driver as a module, choose M here: the module will be called ad525x_dpot-spi. -config ANDROID_PMEM - bool "Android pmem allocator" - default y - config ATMEL_PWM tristate "Atmel AT32/AT91 PWM support" depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 @@ -203,13 +199,6 @@ config ENCLOSURE_SERVICES driver (SCSI/ATA) which supports enclosures or a SCSI enclosure device (SES) to use these services. -config KERNEL_DEBUGGER_CORE - bool "Kernel Debugger Core" - default n - ---help--- - Generic kernel debugging command processor used by low level - (interrupt context) platform-specific debuggers. - config SGI_XP tristate "Support communication between SGI SSIs" depends on NET @@ -332,62 +321,6 @@ config HMC6352 This driver provides support for the Honeywell HMC6352 compass, providing configuration and heading data via sysfs. -config SENSORS_AK8975 - tristate "AK8975 compass support" - default n - depends on I2C - help - If you say yes here you get support for Asahi Kasei's - orientation sensor AK8975. - -config SENSORS_CAP_PROX - tristate "Motorola Capacitive Proximity Sensor" - default n - depends on I2C - help - Say yes here if you wish to include the Motorola - Capacitive Proximity Sensor driver. - -config SENSORS_KXTF9 - tristate "KXTF9 Accelerometer" - default n - depends on I2C - help - Say yes here if you wish to include the Kionix - KXTF9 accelerometer driver. - -config SENSORS_L3G4200D - tristate "ST Micro Gyroscope" - default n - depends on I2C - help - Say yes here if you wish to include the ST Micro - L3G4200D gyroscope driver. - -config SENSORS_MAX9635 - tristate "Maxim Ambient Light Sensor" - default n - depends on I2C - help - Say yes here if you wish to include the Maxim - MAX9635 ambient light sensor driver. - -config SENSORS_NCT1008 - tristate "ON Semiconductor Temperature Sensor" - default n - depends on I2C - help - Say yes here if you wish to include the ON Semiconductor - NCT1008 Temperature sensor. - -config SENSORS_MOTO_BMP085 - tristate "BMP085 Barometer (moto driver)" - default n - depends on I2C - help - Say yes here if you wish to include the Bosch - BMP085 barometer driver. - config EP93XX_PWM tristate "EP93xx PWM support" depends on ARCH_EP93XX @@ -421,10 +354,6 @@ config TI_DAC7512 This driver can also be built as a module. If so, the module will be calles ti_dac7512. -config UID_STAT - bool "UID based statistics tracking exported to /proc/uid_stat" - default n - config VMWARE_BALLOON tristate "VMware Balloon Driver" depends on X86 @@ -461,46 +390,9 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. -config WL127X_RFKILL - tristate "Bluetooth power control driver for TI wl127x" - depends on RFKILL - default n - ---help--- - Creates an rfkill entry in sysfs for power control of Bluetooth - TI wl127x chips. - -config APANIC - bool "Android kernel panic diagnostics driver" - default n - ---help--- - Driver which handles kernel panics and attempts to write - critical debugging data to flash. - -config APANIC_PLABEL - string "Android panic dump flash partition label" - depends on APANIC - default "kpanic" - ---help--- - If your platform uses a different flash partition label for storing - crashdumps, enter it here. - -config GPS_GPIO_BRCM4750 - bool "Enable gpio controller for GPS brcm 4750" - default y - ---help--- - Adds GPIO controller driver for GPS Broadcom 4750 chipset - -config TEGRA_CRYPTO_DEV - bool "Device node to access tegra aes hardware" - ---help--- - Dev node /dev/tegra-crypto in order to get access to tegra aes - hardware from user space - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" -source "drivers/misc/ts27010mux/Kconfig" source "drivers/misc/iwmc3200top/Kconfig" -source "drivers/misc/radio_ctrl/Kconfig" endif # MISC_DEVICES diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c7c058e406cf..42eab95cde2a 100755 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -16,10 +16,8 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o -obj-$(CONFIG_ANDROID_PMEM) += pmem.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o -obj-$(CONFIG_KERNEL_DEBUGGER_CORE) += kernel_debugger.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ @@ -30,7 +28,6 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o -obj-$(CONFIG_UID_STAT) += uid_stat.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o @@ -38,16 +35,3 @@ obj-y += eeprom/ obj-y += cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o -obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o -obj-$(CONFIG_APANIC) += apanic.o -obj-$(CONFIG_SENSORS_AK8975) += akm8975.o -obj-$(CONFIG_SENSORS_KXTF9) += kxtf9.o -obj-$(CONFIG_SENSORS_CAP_PROX) += cap_prox.o -obj-$(CONFIG_SENSORS_MAX9635) += max9635.o -obj-$(CONFIG_SENSORS_NCT1008) += nct1008.o -obj-$(CONFIG_SENSORS_L3G4200D) += l3g4200d.o -obj-$(CONFIG_GPS_GPIO_BRCM4750) += gps-gpio-brcm4750.o -obj-y += radio_ctrl/ -obj-$(CONFIG_SENSORS_MOTO_BMP085) += moto_bmp085.o -obj-$(CONFIG_TEGRA_CRYPTO_DEV) += tegra-cryptodev.o -obj-$(CONFIG_TS27010MUX) += ts27010mux/ diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 6cfcb636577a..b8c6df9c8437 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -53,13 +53,13 @@ static int write8(void *client, u8 val) static int write16(void *client, u8 reg, u8 val) { u8 data[2] = {reg, val}; - return spi_write(client, data, 2); + return spi_write(client, data, 1); } static int write24(void *client, u8 reg, u16 val) { u8 data[3] = {reg, val >> 8, val}; - return spi_write(client, data, 3); + return spi_write(client, data, 1); } static int read8(void *client) diff --git a/drivers/misc/akm8975.c b/drivers/misc/akm8975.c deleted file mode 100644 index eb935f672d98..000000000000 --- a/drivers/misc/akm8975.c +++ /dev/null @@ -1,638 +0,0 @@ -/* drivers/misc/akm8975.c - akm8975 compass driver - * - * Copyright (C) 2007-2008 HTC Corporation. - * Author: Hou-Kun Chen - * - * 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. - * - */ - -/* - * Revised by AKM 2009/04/02 - * Revised by Motorola 2010/08/16 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AK8975DRV_CALL_DBG 0 -#if AK8975DRV_CALL_DBG -#define FUNCDBG(msg) pr_info("%s:%s\n", __func__, msg); -#else -#define FUNCDBG(msg) -#endif - -#define AK8975DRV_DATA_DBG 0 -#define MAX_FAILURE_COUNT 10 - -struct akm8975_data { - struct i2c_client *this_client; - struct input_dev *input_dev; - struct work_struct work; - struct mutex flags_lock; - struct regulator *regulator; -}; - -/* -* Because misc devices can not carry a pointer from driver register to -* open, we keep this global. This limits the driver to a single instance. -*/ -struct akm8975_data *akmd_data; - -static DECLARE_WAIT_QUEUE_HEAD(open_wq); - -static atomic_t open_flag; - -static short m_flag; -static short mv_flag; - -static short akmd_delay; - -static ssize_t akm8975_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%u\n", i2c_smbus_read_byte_data(client, - AK8975_REG_CNTL)); -} -static ssize_t akm8975_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - strict_strtoul(buf, 10, &val); - if (val > 0xff) - return -EINVAL; - i2c_smbus_write_byte_data(client, AK8975_REG_CNTL, val); - return count; -} -static DEVICE_ATTR(akm_ms1, S_IWUSR | S_IRUGO, akm8975_show, akm8975_store); - -static int akm8975_i2c_rxdata(struct akm8975_data *akm, char *buf, int length) -{ - struct i2c_msg msgs[] = { - { - .addr = akm->this_client->addr, - .flags = 0, - .len = 1, - .buf = buf, - }, - { - .addr = akm->this_client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = buf, - }, - }; - - FUNCDBG("called"); - - if (i2c_transfer(akm->this_client->adapter, msgs, 2) < 0) { - pr_err("akm8975_i2c_rxdata: transfer error\n"); - return EIO; - } else - return 0; -} - -static int akm8975_i2c_txdata(struct akm8975_data *akm, char *buf, int length) -{ - struct i2c_msg msgs[] = { - { - .addr = akm->this_client->addr, - .flags = 0, - .len = length, - .buf = buf, - }, - }; - - FUNCDBG("called"); - - if (i2c_transfer(akm->this_client->adapter, msgs, 1) < 0) { - pr_err("akm8975_i2c_txdata: transfer error\n"); - return -EIO; - } else - return 0; -} - -static void akm8975_ecs_report_value(struct akm8975_data *akm, short *rbuf) -{ - struct akm8975_data *data = i2c_get_clientdata(akm->this_client); - - FUNCDBG("called"); - -#if AK8975DRV_DATA_DBG - pr_info("akm8975_ecs_report_value: yaw = %d, pitch = %d, roll = %d\n", - rbuf[0], rbuf[1], rbuf[2]); - pr_info("tmp = %d, m_stat= %d, g_stat=%d\n", rbuf[3], rbuf[4], rbuf[5]); - pr_info("Acceleration: x = %d LSB, y = %d LSB, z = %d LSB\n", - rbuf[6], rbuf[7], rbuf[8]); - pr_info("Magnetic: x = %d LSB, y = %d LSB, z = %d LSB\n\n", - rbuf[9], rbuf[10], rbuf[11]); -#endif - mutex_lock(&akm->flags_lock); - /* Report magnetic sensor information */ - if (m_flag) { - input_report_rel(data->input_dev, REL_RX, rbuf[0]); - input_report_rel(data->input_dev, REL_RY, rbuf[1]); - input_report_rel(data->input_dev, REL_RZ, rbuf[2]); - input_report_rel(data->input_dev, REL_HWHEEL, rbuf[4]); - } - - if (mv_flag) { - input_report_rel(data->input_dev, REL_DIAL, rbuf[9]); - input_report_rel(data->input_dev, REL_WHEEL, rbuf[10]); - input_report_rel(data->input_dev, REL_MISC, rbuf[11]); - } - mutex_unlock(&akm->flags_lock); - - input_sync(data->input_dev); -} - -static void akm8975_ecs_close_done(struct akm8975_data *akm) -{ - FUNCDBG("called"); - mutex_lock(&akm->flags_lock); - m_flag = 0; - mv_flag = 0; - mutex_unlock(&akm->flags_lock); -} - -static int akm_aot_open(struct inode *inode, struct file *file) -{ - int ret = -1; - - FUNCDBG("called"); - if (atomic_cmpxchg(&open_flag, 0, 1) == 0) { - wake_up(&open_wq); - ret = 0; - } - - ret = nonseekable_open(inode, file); - if (ret) - return ret; - - file->private_data = akmd_data; - - return ret; -} - -static int akm_aot_release(struct inode *inode, struct file *file) -{ - FUNCDBG("called"); - atomic_set(&open_flag, 0); - wake_up(&open_wq); - return 0; -} - -static long akm_aot_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *) arg; - short flag; - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - case ECS_IOCTL_APP_SET_MVFLAG: - if (copy_from_user(&flag, argp, sizeof(flag))) - return -EFAULT; - if (flag < 0 || flag > 1) - return -EINVAL; - break; - case ECS_IOCTL_APP_SET_DELAY: - if (copy_from_user(&flag, argp, sizeof(flag))) - return -EFAULT; - break; - default: - break; - } - - mutex_lock(&akm->flags_lock); - switch (cmd) { - case ECS_IOCTL_APP_SET_MFLAG: - m_flag = flag; - break; - case ECS_IOCTL_APP_GET_MFLAG: - flag = m_flag; - break; - case ECS_IOCTL_APP_SET_MVFLAG: - mv_flag = flag; - break; - case ECS_IOCTL_APP_GET_MVFLAG: - flag = mv_flag; - break; - case ECS_IOCTL_APP_SET_DELAY: - akmd_delay = flag; - break; - case ECS_IOCTL_APP_GET_DELAY: - flag = akmd_delay; - break; - default: - mutex_unlock(&akm->flags_lock); - return -ENOTTY; - } - mutex_unlock(&akm->flags_lock); - - switch (cmd) { - case ECS_IOCTL_APP_GET_MFLAG: - case ECS_IOCTL_APP_GET_MVFLAG: - case ECS_IOCTL_APP_GET_DELAY: - if (copy_to_user(argp, &flag, sizeof(flag))) - return -EFAULT; - break; - default: - break; - } - - return 0; -} - -static int akmd_open(struct inode *inode, struct file *file) -{ - int err = 0; - - FUNCDBG("called"); - err = nonseekable_open(inode, file); - if (err) - return err; - - file->private_data = akmd_data; - return 0; -} - -static int akmd_release(struct inode *inode, struct file *file) -{ - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - akm8975_ecs_close_done(akm); - return 0; -} - -static long akmd_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *) arg; - - char rwbuf[16]; - int ret = -1; - int status; - short value[12]; - short delay; - struct akm8975_data *akm = file->private_data; - - FUNCDBG("called"); - - switch (cmd) { - case ECS_IOCTL_READ: - case ECS_IOCTL_WRITE: - if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) - return -EFAULT; - break; - - case ECS_IOCTL_SET_YPR: - if (copy_from_user(&value, argp, sizeof(value))) - return -EFAULT; - break; - - default: - break; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (rwbuf[0] < 1) - return -EINVAL; - - ret = akm8975_i2c_rxdata(akm, &rwbuf[1], rwbuf[0]); - if (ret < 0) - return ret; - break; - - case ECS_IOCTL_WRITE: - if (rwbuf[0] < 2) - return -EINVAL; - - ret = akm8975_i2c_txdata(akm, &rwbuf[1], rwbuf[0]); - if (ret < 0) - return ret; - break; - case ECS_IOCTL_SET_YPR: - akm8975_ecs_report_value(akm, value); - break; - - case ECS_IOCTL_GET_OPEN_STATUS: - wait_event_interruptible(open_wq, - (atomic_read(&open_flag) != 0)); - status = atomic_read(&open_flag); - break; - case ECS_IOCTL_GET_CLOSE_STATUS: - wait_event_interruptible(open_wq, - (atomic_read(&open_flag) == 0)); - status = atomic_read(&open_flag); - break; - - case ECS_IOCTL_GET_DELAY: - delay = akmd_delay; - break; - - default: - FUNCDBG("Unknown cmd\n"); - return -ENOTTY; - } - - switch (cmd) { - case ECS_IOCTL_READ: - if (copy_to_user(argp, &rwbuf, sizeof(rwbuf))) - return -EFAULT; - break; - case ECS_IOCTL_GET_OPEN_STATUS: - case ECS_IOCTL_GET_CLOSE_STATUS: - if (copy_to_user(argp, &status, sizeof(status))) - return -EFAULT; - break; - case ECS_IOCTL_GET_DELAY: - if (copy_to_user(argp, &delay, sizeof(delay))) - return -EFAULT; - break; - default: - break; - } - - return 0; -} - -/* needed to clear the int. pin */ -static void akm_work_func(struct work_struct *work) -{ - struct akm8975_data *akm = - container_of(work, struct akm8975_data, work); - - FUNCDBG("called"); - enable_irq(akm->this_client->irq); -} - -static irqreturn_t akm8975_interrupt(int irq, void *dev_id) -{ - struct akm8975_data *akm = dev_id; - FUNCDBG("called"); - - disable_irq_nosync(akm->this_client->irq); - schedule_work(&akm->work); - return IRQ_HANDLED; -} - -static int akm8975_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - int ret = 0; - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - /* TO DO: might need more work after power mgmt - is enabled */ - if (akm->regulator) - ret = regulator_disable(akm->regulator); - return ret; -} - -static int akm8975_resume(struct i2c_client *client) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - int ret = 0; - -#if AK8975DRV_CALL_DBG - pr_info("%s\n", __func__); -#endif - /* TO DO: might need more work after power mgmt - is enabled */ - if (akm->regulator) - ret = regulator_enable(akm->regulator); - return ret; -} - -static int akm8975_init_client(struct i2c_client *client) -{ - struct akm8975_data *data; - int ret; - - data = i2c_get_clientdata(client); - - ret = request_irq(client->irq, akm8975_interrupt, IRQF_TRIGGER_RISING, - "akm8975", data); - - if (ret < 0) { - pr_err("akm8975_init_client: request irq failed\n"); - goto err; - } - - init_waitqueue_head(&open_wq); - - mutex_lock(&data->flags_lock); - m_flag = 0; - mv_flag = 0; - mutex_unlock(&data->flags_lock); - - return 0; -err: - return ret; -} - -static const struct file_operations akmd_fops = { - .owner = THIS_MODULE, - .open = akmd_open, - .release = akmd_release, - .unlocked_ioctl = akmd_ioctl, -}; - -static const struct file_operations akm_aot_fops = { - .owner = THIS_MODULE, - .open = akm_aot_open, - .release = akm_aot_release, - .unlocked_ioctl = akm_aot_ioctl, -}; - -static struct miscdevice akm_aot_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8975_aot", - .fops = &akm_aot_fops, -}; - -static struct miscdevice akmd_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "akm8975_dev", - .fops = &akmd_fops, -}; - -int akm8975_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct akm8975_data *akm; - int err; - FUNCDBG("called"); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "platform data is NULL. exiting.\n"); - err = -ENODEV; - goto exit_check_functionality_failed; - } - - akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); - if (!akm) { - dev_err(&client->dev, - "failed to allocate memory for module data\n"); - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - mutex_init(&akm->flags_lock); - INIT_WORK(&akm->work, akm_work_func); - i2c_set_clientdata(client, akm); - - akm->regulator = regulator_get(&client->dev, "vcc"); - if (IS_ERR_OR_NULL(akm->regulator)) { - dev_err(&client->dev, "unable to get regulator %s\n", - dev_name(&client->dev)); - akm->regulator = NULL; - } else { - regulator_enable(akm->regulator); - } - - akm8975_init_client(client); - akm->this_client = client; - akmd_data = akm; - - akm->input_dev = input_allocate_device(); - if (!akm->input_dev) { - err = -ENOMEM; - dev_err(&akm->this_client->dev, - "input device allocate failed\n"); - goto exit_input_dev_alloc_failed; - } - - /* orientation: yaw */ - input_set_capability(akm->input_dev, EV_REL, REL_RX); - /* orientation: pitch */ - input_set_capability(akm->input_dev, EV_REL, REL_RY); - /* orientation: roll */ - input_set_capability(akm->input_dev, EV_REL, REL_RZ); - - /* status of orientation sensor */ - input_set_capability(akm->input_dev, EV_REL, REL_HWHEEL); - - /* x-axis of raw magnetic vector */ - input_set_capability(akm->input_dev, EV_REL, REL_DIAL); - /* y-axis of raw magnetic vector */ - input_set_capability(akm->input_dev, EV_REL, REL_WHEEL); - /* z-axis of raw magnetic vector */ - input_set_capability(akm->input_dev, EV_REL, REL_MISC); - - akm->input_dev->name = "compass"; - - err = input_register_device(akm->input_dev); - if (err) { - pr_err("akm8975_probe: Unable to register input device: %s\n", - akm->input_dev->name); - goto exit_input_register_device_failed; - } - - err = misc_register(&akmd_device); - if (err) { - pr_err("akm8975_probe: akmd_device register failed\n"); - goto exit_misc_device_register_failed; - } - - err = misc_register(&akm_aot_device); - if (err) { - pr_err("akm8975_probe: akm_aot_device register failed\n"); - goto exit_misc_device_register_failed; - } - - err = device_create_file(&client->dev, &dev_attr_akm_ms1); - return 0; - -exit_misc_device_register_failed: -exit_input_register_device_failed: - input_free_device(akm->input_dev); -exit_input_dev_alloc_failed: - if (akm->regulator) - regulator_put(akm->regulator); - kfree(akm); -exit_alloc_data_failed: -exit_check_functionality_failed: - return err; -} - -static int __devexit akm8975_remove(struct i2c_client *client) -{ - struct akm8975_data *akm = i2c_get_clientdata(client); - FUNCDBG("called"); - free_irq(client->irq, NULL); - input_unregister_device(akm->input_dev); - misc_deregister(&akmd_device); - misc_deregister(&akm_aot_device); - if (akm->regulator) { - regulator_disable(akm->regulator); - regulator_put(akm->regulator); - } - kfree(akm); - return 0; -} - -static const struct i2c_device_id akm8975_id[] = { - { "akm8975", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, akm8975_id); - -static struct i2c_driver akm8975_driver = { - .probe = akm8975_probe, - .remove = akm8975_remove, - .resume = akm8975_resume, - .suspend = akm8975_suspend, - .id_table = akm8975_id, - .driver = { - .name = "akm8975", - }, -}; - -static int __init akm8975_init(void) -{ - pr_info("AK8975 compass driver: init\n"); - return i2c_add_driver(&akm8975_driver); -} - -static void __exit akm8975_exit(void) -{ - i2c_del_driver(&akm8975_driver); -} - -module_init(akm8975_init); -module_exit(akm8975_exit); - -MODULE_AUTHOR("Hou-Kun Chen "); -MODULE_DESCRIPTION("AK8975 compass driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/apanic.c b/drivers/misc/apanic.c deleted file mode 100644 index ca875f89da7a..000000000000 --- a/drivers/misc/apanic.c +++ /dev/null @@ -1,606 +0,0 @@ -/* drivers/misc/apanic.c - * - * Copyright (C) 2009 Google, Inc. - * Author: San Mehat - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void ram_console_enable_console(int); - -struct panic_header { - u32 magic; -#define PANIC_MAGIC 0xdeadf00d - - u32 version; -#define PHDR_VERSION 0x01 - - u32 console_offset; - u32 console_length; - - u32 threads_offset; - u32 threads_length; -}; - -struct apanic_data { - struct mtd_info *mtd; - struct panic_header curr; - void *bounce; - struct proc_dir_entry *apanic_console; - struct proc_dir_entry *apanic_threads; -}; - -static struct apanic_data drv_ctx; -static struct work_struct proc_removal_work; -static DEFINE_MUTEX(drv_mutex); - -static unsigned int *apanic_bbt; -static unsigned int apanic_erase_blocks; -static unsigned int apanic_good_blocks; - -static void set_bb(unsigned int block, unsigned int *bbt) -{ - unsigned int flag = 1; - - BUG_ON(block >= apanic_erase_blocks); - - flag = flag << (block%32); - apanic_bbt[block/32] |= flag; - apanic_good_blocks--; -} - -static unsigned int get_bb(unsigned int block, unsigned int *bbt) -{ - unsigned int flag; - - BUG_ON(block >= apanic_erase_blocks); - - flag = 1 << (block%32); - return apanic_bbt[block/32] & flag; -} - -static void alloc_bbt(struct mtd_info *mtd, unsigned int *bbt) -{ - int bbt_size; - apanic_erase_blocks = (mtd->size)>>(mtd->erasesize_shift); - bbt_size = (apanic_erase_blocks+32)/32; - - apanic_bbt = kmalloc(bbt_size*4, GFP_KERNEL); - memset(apanic_bbt, 0, bbt_size*4); - apanic_good_blocks = apanic_erase_blocks; -} -static void scan_bbt(struct mtd_info *mtd, unsigned int *bbt) -{ - int i; - - for (i = 0; i < apanic_erase_blocks; i++) { - if (mtd->block_isbad(mtd, i*mtd->erasesize)) - set_bb(i, apanic_bbt); - } -} - -#define APANIC_INVALID_OFFSET 0xFFFFFFFF - -static unsigned int phy_offset(struct mtd_info *mtd, unsigned int offset) -{ - unsigned int logic_block = offset>>(mtd->erasesize_shift); - unsigned int phy_block; - unsigned good_block = 0; - - for (phy_block = 0; phy_block < apanic_erase_blocks; phy_block++) { - if (!get_bb(phy_block, apanic_bbt)) - good_block++; - if (good_block == (logic_block + 1)) - break; - } - - if (good_block != (logic_block + 1)) - return APANIC_INVALID_OFFSET; - - return offset + ((phy_block-logic_block)<erasesize_shift); -} - -static void apanic_erase_callback(struct erase_info *done) -{ - wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; - wake_up(wait_q); -} - -static int apanic_proc_read(char *buffer, char **start, off_t offset, - int count, int *peof, void *dat) -{ - struct apanic_data *ctx = &drv_ctx; - size_t file_length; - off_t file_offset; - unsigned int page_no; - off_t page_offset; - int rc; - size_t len; - - if (!count) - return 0; - - mutex_lock(&drv_mutex); - - switch ((int) dat) { - case 1: /* apanic_console */ - file_length = ctx->curr.console_length; - file_offset = ctx->curr.console_offset; - break; - case 2: /* apanic_threads */ - file_length = ctx->curr.threads_length; - file_offset = ctx->curr.threads_offset; - break; - default: - pr_err("Bad dat (%d)\n", (int) dat); - mutex_unlock(&drv_mutex); - return -EINVAL; - } - - if ((offset + count) > file_length) { - mutex_unlock(&drv_mutex); - return 0; - } - - /* We only support reading a maximum of a flash page */ - if (count > ctx->mtd->writesize) - count = ctx->mtd->writesize; - - page_no = (file_offset + offset) / ctx->mtd->writesize; - page_offset = (file_offset + offset) % ctx->mtd->writesize; - - - if (phy_offset(ctx->mtd, (page_no * ctx->mtd->writesize)) - == APANIC_INVALID_OFFSET) { - pr_err("apanic: reading an invalid address\n"); - mutex_unlock(&drv_mutex); - return -EINVAL; - } - rc = ctx->mtd->read(ctx->mtd, - phy_offset(ctx->mtd, (page_no * ctx->mtd->writesize)), - ctx->mtd->writesize, - &len, ctx->bounce); - - if (page_offset) - count -= page_offset; - memcpy(buffer, ctx->bounce + page_offset, count); - - *start = count; - - if ((offset + count) == file_length) - *peof = 1; - - mutex_unlock(&drv_mutex); - return count; -} - -static void mtd_panic_erase(void) -{ - struct apanic_data *ctx = &drv_ctx; - struct erase_info erase; - DECLARE_WAITQUEUE(wait, current); - wait_queue_head_t wait_q; - int rc, i; - - init_waitqueue_head(&wait_q); - erase.mtd = ctx->mtd; - erase.callback = apanic_erase_callback; - erase.len = ctx->mtd->erasesize; - erase.priv = (u_long)&wait_q; - for (i = 0; i < ctx->mtd->size; i += ctx->mtd->erasesize) { - erase.addr = i; - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&wait_q, &wait); - - if (get_bb(erase.addr>>ctx->mtd->erasesize_shift, apanic_bbt)) { - printk(KERN_WARNING - "apanic: Skipping erase of bad " - "block @%llx\n", erase.addr); - set_current_state(TASK_RUNNING); - remove_wait_queue(&wait_q, &wait); - continue; - } - - rc = ctx->mtd->erase(ctx->mtd, &erase); - if (rc) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&wait_q, &wait); - printk(KERN_ERR - "apanic: Erase of 0x%llx, 0x%llx failed\n", - (unsigned long long) erase.addr, - (unsigned long long) erase.len); - if (rc == -EIO) { - if (ctx->mtd->block_markbad(ctx->mtd, - erase.addr)) { - printk(KERN_ERR - "apanic: Err marking blk bad\n"); - goto out; - } - printk(KERN_INFO - "apanic: Marked a bad block" - " @%llx\n", erase.addr); - set_bb(erase.addr>>ctx->mtd->erasesize_shift, - apanic_bbt); - continue; - } - goto out; - } - schedule(); - remove_wait_queue(&wait_q, &wait); - } - printk(KERN_DEBUG "apanic: %s partition erased\n", - CONFIG_APANIC_PLABEL); -out: - return; -} - -static void apanic_remove_proc_work(struct work_struct *work) -{ - struct apanic_data *ctx = &drv_ctx; - - mutex_lock(&drv_mutex); - mtd_panic_erase(); - memset(&ctx->curr, 0, sizeof(struct panic_header)); - if (ctx->apanic_console) { - remove_proc_entry("apanic_console", NULL); - ctx->apanic_console = NULL; - } - if (ctx->apanic_threads) { - remove_proc_entry("apanic_threads", NULL); - ctx->apanic_threads = NULL; - } - mutex_unlock(&drv_mutex); -} - -static int apanic_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - schedule_work(&proc_removal_work); - return count; -} - -static void mtd_panic_notify_add(struct mtd_info *mtd) -{ - struct apanic_data *ctx = &drv_ctx; - struct panic_header *hdr = ctx->bounce; - size_t len; - int rc; - int proc_entry_created = 0; - - if (strcmp(mtd->name, CONFIG_APANIC_PLABEL)) - return; - - ctx->mtd = mtd; - - alloc_bbt(mtd, apanic_bbt); - scan_bbt(mtd, apanic_bbt); - - if (apanic_good_blocks == 0) { - printk(KERN_ERR "apanic: no any good blocks?!\n"); - goto out_err; - } - - rc = mtd->read(mtd, phy_offset(mtd, 0), mtd->writesize, - &len, ctx->bounce); - if (rc && rc == -EBADMSG) { - printk(KERN_WARNING - "apanic: Bad ECC on block 0 (ignored)\n"); - } else if (rc && rc != -EUCLEAN) { - printk(KERN_ERR "apanic: Error reading block 0 (%d)\n", rc); - goto out_err; - } - - if (len != mtd->writesize) { - printk(KERN_ERR "apanic: Bad read size (%d)\n", rc); - goto out_err; - } - - printk(KERN_INFO "apanic: Bound to mtd partition '%s'\n", mtd->name); - - if (hdr->magic != PANIC_MAGIC) { - printk(KERN_INFO "apanic: No panic data available\n"); - mtd_panic_erase(); - return; - } - - if (hdr->version != PHDR_VERSION) { - printk(KERN_INFO "apanic: Version mismatch (%d != %d)\n", - hdr->version, PHDR_VERSION); - mtd_panic_erase(); - return; - } - - memcpy(&ctx->curr, hdr, sizeof(struct panic_header)); - - printk(KERN_INFO "apanic: c(%u, %u) t(%u, %u)\n", - hdr->console_offset, hdr->console_length, - hdr->threads_offset, hdr->threads_length); - - if (hdr->console_length) { - ctx->apanic_console = create_proc_entry("apanic_console", - S_IFREG | S_IRUGO, NULL); - if (!ctx->apanic_console) - printk(KERN_ERR "%s: failed creating procfile\n", - __func__); - else { - ctx->apanic_console->read_proc = apanic_proc_read; - ctx->apanic_console->write_proc = apanic_proc_write; - ctx->apanic_console->size = hdr->console_length; - ctx->apanic_console->data = (void *) 1; - proc_entry_created = 1; - } - } - - if (hdr->threads_length) { - ctx->apanic_threads = create_proc_entry("apanic_threads", - S_IFREG | S_IRUGO, NULL); - if (!ctx->apanic_threads) - printk(KERN_ERR "%s: failed creating procfile\n", - __func__); - else { - ctx->apanic_threads->read_proc = apanic_proc_read; - ctx->apanic_threads->write_proc = apanic_proc_write; - ctx->apanic_threads->size = hdr->threads_length; - ctx->apanic_threads->data = (void *) 2; - proc_entry_created = 1; - } - } - - if (!proc_entry_created) - mtd_panic_erase(); - - return; -out_err: - ctx->mtd = NULL; -} - -static void mtd_panic_notify_remove(struct mtd_info *mtd) -{ - struct apanic_data *ctx = &drv_ctx; - if (mtd == ctx->mtd) { - ctx->mtd = NULL; - printk(KERN_INFO "apanic: Unbound from %s\n", mtd->name); - } -} - -static struct mtd_notifier mtd_panic_notifier = { - .add = mtd_panic_notify_add, - .remove = mtd_panic_notify_remove, -}; - -static int in_panic = 0; - -static int apanic_writeflashpage(struct mtd_info *mtd, loff_t to, - const u_char *buf) -{ - int rc; - size_t wlen; - int panic = in_interrupt() | in_atomic(); - - if (panic && !mtd->panic_write) { - printk(KERN_EMERG "%s: No panic_write available\n", __func__); - return 0; - } else if (!panic && !mtd->write) { - printk(KERN_EMERG "%s: No write available\n", __func__); - return 0; - } - - to = phy_offset(mtd, to); - if (to == APANIC_INVALID_OFFSET) { - printk(KERN_EMERG "apanic: write to invalid address\n"); - return 0; - } - - if (panic) - rc = mtd->panic_write(mtd, to, mtd->writesize, &wlen, buf); - else - rc = mtd->write(mtd, to, mtd->writesize, &wlen, buf); - - if (rc) { - printk(KERN_EMERG - "%s: Error writing data to flash (%d)\n", - __func__, rc); - return rc; - } - - return wlen; -} - -extern int log_buf_copy(char *dest, int idx, int len); -extern void log_buf_clear(void); - -/* - * Writes the contents of the console to the specified offset in flash. - * Returns number of bytes written - */ -static int apanic_write_console(struct mtd_info *mtd, unsigned int off) -{ - struct apanic_data *ctx = &drv_ctx; - int saved_oip; - int idx = 0; - int rc, rc2; - unsigned int last_chunk = 0; - - while (!last_chunk) { - saved_oip = oops_in_progress; - oops_in_progress = 1; - rc = log_buf_copy(ctx->bounce, idx, mtd->writesize); - if (rc < 0) - break; - - if (rc != mtd->writesize) - last_chunk = rc; - - oops_in_progress = saved_oip; - if (rc <= 0) - break; - if (rc != mtd->writesize) - memset(ctx->bounce + rc, 0, mtd->writesize - rc); - - rc2 = apanic_writeflashpage(mtd, off, ctx->bounce); - if (rc2 <= 0) { - printk(KERN_EMERG - "apanic: Flash write failed (%d)\n", rc2); - return idx; - } - if (!last_chunk) - idx += rc2; - else - idx += last_chunk; - off += rc2; - } - return idx; -} - -static int apanic(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct apanic_data *ctx = &drv_ctx; - struct panic_header *hdr = (struct panic_header *) ctx->bounce; - int console_offset = 0; - int console_len = 0; - int threads_offset = 0; - int threads_len = 0; - int rc; - - if (in_panic) - return NOTIFY_DONE; - in_panic = 1; -#ifdef CONFIG_PREEMPT - /* Ensure that cond_resched() won't try to preempt anybody */ - add_preempt_count(PREEMPT_ACTIVE); -#endif - touch_softlockup_watchdog(); - - if (!ctx->mtd) - goto out; - - if (ctx->curr.magic) { - printk(KERN_EMERG "Crash partition in use!\n"); - goto out; - } - console_offset = ctx->mtd->writesize; - - /* - * Write out the console - */ - console_len = apanic_write_console(ctx->mtd, console_offset); - if (console_len < 0) { - printk(KERN_EMERG "Error writing console to panic log! (%d)\n", - console_len); - console_len = 0; - } - - /* - * Write out all threads - */ - threads_offset = ALIGN(console_offset + console_len, - ctx->mtd->writesize); - if (!threads_offset) - threads_offset = ctx->mtd->writesize; - - ram_console_enable_console(0); - - log_buf_clear(); - show_state_filter(0); - threads_len = apanic_write_console(ctx->mtd, threads_offset); - if (threads_len < 0) { - printk(KERN_EMERG "Error writing threads to panic log! (%d)\n", - threads_len); - threads_len = 0; - } - - /* - * Finally write the panic header - */ - memset(ctx->bounce, 0, PAGE_SIZE); - hdr->magic = PANIC_MAGIC; - hdr->version = PHDR_VERSION; - - hdr->console_offset = console_offset; - hdr->console_length = console_len; - - hdr->threads_offset = threads_offset; - hdr->threads_length = threads_len; - - rc = apanic_writeflashpage(ctx->mtd, 0, ctx->bounce); - if (rc <= 0) { - printk(KERN_EMERG "apanic: Header write failed (%d)\n", - rc); - goto out; - } - - printk(KERN_EMERG "apanic: Panic dump sucessfully written to flash\n"); - - out: -#ifdef CONFIG_PREEMPT - sub_preempt_count(PREEMPT_ACTIVE); -#endif - in_panic = 0; - return NOTIFY_DONE; -} - -static struct notifier_block panic_blk = { - .notifier_call = apanic, -}; - -static int panic_dbg_get(void *data, u64 *val) -{ - apanic(NULL, 0, NULL); - return 0; -} - -static int panic_dbg_set(void *data, u64 val) -{ - BUG(); - return -1; -} - -DEFINE_SIMPLE_ATTRIBUTE(panic_dbg_fops, panic_dbg_get, panic_dbg_set, "%llu\n"); - -int __init apanic_init(void) -{ - register_mtd_user(&mtd_panic_notifier); - atomic_notifier_chain_register(&panic_notifier_list, &panic_blk); - debugfs_create_file("apanic", 0644, NULL, NULL, &panic_dbg_fops); - memset(&drv_ctx, 0, sizeof(drv_ctx)); - drv_ctx.bounce = (void *) __get_free_page(GFP_KERNEL); - INIT_WORK(&proc_removal_work, apanic_remove_proc_work); - printk(KERN_INFO "Android kernel panic handler initialized (bind=%s)\n", - CONFIG_APANIC_PLABEL); - return 0; -} - -module_init(apanic_init); diff --git a/drivers/misc/cap_prox.c b/drivers/misc/cap_prox.c deleted file mode 100755 index 5fdb6324d0e9..000000000000 --- a/drivers/misc/cap_prox.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define CAP_PROX_NAME "cap-prox" -#define CP_STATUS_NUM_KEYS_ENABLED 0x20 - -#define CP_STATUS_KEY3_IN_DETECT 0x24 -#define CP_STATUS_KEY1_IN_DETECT 0x21 -#define CP_STATUS_KEY1_KEY3_IN_DETECT 0x25 -#define CP_STATUS_KEY1_KEY3_EN_FORCE_DETECT 0x75 - -struct cap_prox_msg { - uint8_t status; - uint16_t ref_key1; - uint16_t ref_key3; - uint8_t chip_id; - uint8_t sw_ver; - uint8_t reserved8; - uint16_t signal1; - uint16_t signal2; - uint16_t signal3; - uint16_t signal4; - uint16_t save_ref1; - uint16_t save_ref2; - uint16_t save_ref3; - uint16_t save_ref4; -} __attribute__ ((packed)); - -struct cap_prox_data { - struct i2c_client *client; - struct input_dev *input_dev; - struct delayed_work input_work; - struct work_struct irq_work; - struct cap_prox_platform_data *pdata; - - atomic_t enabled; - spinlock_t irq_lock; - int irq_state; -}; - -static uint32_t cp_dbg; -module_param_named(cp_debug, cp_dbg, uint, 0664); - -struct cap_prox_data *cap_prox_misc_data; -struct workqueue_struct *cp_irq_wq; - -static void cap_prox_irq_enable(struct cap_prox_data *cp, int enable) -{ - unsigned long flags; - - spin_lock_irqsave(&cp->irq_lock, flags); - if (cp->irq_state != enable) { - if (enable) - enable_irq(cp->client->irq); - else - disable_irq_nosync(cp->client->irq); - cp->irq_state = enable; - } - spin_unlock_irqrestore(&cp->irq_lock, flags); -} - -static irqreturn_t cap_prox_irq_handler(int irq, void *dev_id) -{ - struct cap_prox_data *cp = dev_id; - - cap_prox_irq_enable(cp, 0); - queue_work(cp_irq_wq, &cp->irq_work); - - return IRQ_HANDLED; -} - -static int cap_prox_write(struct cap_prox_data *cp, void *buf, int buf_sz) -{ - int retries = 10; - int ret; - - do { - ret = i2c_master_send(cp->client, (char *)buf, buf_sz); - } while ((ret < buf_sz) && (--retries > 0)); - - if (ret < 0) - pr_info("%s: Error while trying to write %d bytes\n", __func__, - buf_sz); - else if (ret != buf_sz) { - pr_info("%s: Write %d bytes, expected %d\n", __func__, - ret, buf_sz); - ret = -EIO; - } - return ret; -} - -static int cap_prox_read(struct cap_prox_data *cp, void *buf, int buf_sz) -{ - int retries = 10; - int ret; - - do { - memset(buf, 0, buf_sz); - ret = i2c_master_recv(cp->client, (char *)buf, buf_sz); - } while ((ret < 0) && (--retries > 0)); - - if (ret < 0) - pr_info("%s: Error while trying to read %d bytes\n", __func__, - buf_sz); - else if (ret != buf_sz) { - pr_info("%s: Read %d bytes, expected %d\n", __func__, - ret, buf_sz); - ret = -EIO; - } - - return ret >= 0 ? 0 : ret; -} - -static void cap_prox_calibrate(struct cap_prox_data *cp) { - cap_prox_write(cp, &cp->pdata->plat_cap_prox_cfg.calibrate,1); - if (cp_dbg) - pr_info("%s: Send Calibrate 0x%x\n", __func__, - cp->pdata->plat_cap_prox_cfg.calibrate); -} - -static int cap_prox_read_data(struct cap_prox_data *cp) -{ - struct cap_prox_msg *msg; - uint8_t status; - int ret = -1; - int key1_ref_drift = 0; - int key3_ref_drift = 0; - int ref_drift_diff = 0; - int key1_save_drift = 0; - int key3_save_drift = 0; - int save_drift_diff = 0; - int key1_key2_signal_drift = 0; - int key3_key4_signal_drift = 0; - uint8_t mesg_buf[sizeof(struct cap_prox_msg)]; - - - ret = cap_prox_read(cp, mesg_buf, sizeof(struct cap_prox_msg)); - if (ret) { - status = CP_STATUS_NUM_KEYS_ENABLED; - pr_info("%s: read failed \n", __func__); - goto read_fail_ret; - } - msg = (struct cap_prox_msg *)mesg_buf; - - if (cp_dbg & 0x02) { - pr_info("%s: Cap-Prox data \n", __func__); - pr_info(" msg->status 0x%2x \n", msg->status); - pr_info(" msg->ref_key1 %d \n", msg->ref_key1); - pr_info(" msg->ref_key3 %d \n", msg->ref_key3); - pr_info(" msg->chip_id 0x%2x \n", msg->chip_id); - pr_info(" msg->sw_ver 0x%2x \n", msg->sw_ver); - pr_info(" msg->signal1 %d \n", msg->signal1); - pr_info(" msg->signal2 %d \n", msg->signal2); - pr_info(" msg->signal3 %d \n", msg->signal3); - pr_info(" msg->signal4 %d \n", msg->signal4); - pr_info(" msg->save_ref1 %d \n", msg->save_ref1); - pr_info(" msg->save_ref2 %d \n", msg->save_ref2); - pr_info(" msg->save_ref3 %d \n", msg->save_ref3); - pr_info(" msg->save_ref4 %d \n\n", msg->save_ref4); - } - - key1_ref_drift = abs(msg->ref_key1 - msg->signal1); - key3_ref_drift = abs(msg->ref_key3 - msg->signal3); - ref_drift_diff = abs(key3_ref_drift - key1_ref_drift); - key1_save_drift = abs(msg->save_ref1 - msg->signal1); - key3_save_drift = abs(msg->save_ref3 - msg->signal3); - save_drift_diff = abs(key3_save_drift - key1_save_drift); - key1_key2_signal_drift = abs(msg->signal1 - msg->signal2); - key3_key4_signal_drift = abs(msg->signal3 - msg->signal4); - - if (cp_dbg) { - pr_info("%s: Key1 ref drift %d \n", __func__, key1_ref_drift); - pr_info("%s: key3 ref drift %d \n", __func__, key3_ref_drift); - pr_info("%s: Key1 Key3 ref drift diff %d \n\n", - __func__, ref_drift_diff); - pr_info("%s: Key1 save drift %d \n", __func__, key1_save_drift); - pr_info("%s: key3 save drift %d \n", __func__, key3_save_drift); - pr_info("%s: Key1 Key3 saved drift diff %d \n\n", - __func__, save_drift_diff); - pr_info("%s: Key1 Key2 signal/sheild drift diff %d \n\n", - __func__, key1_key2_signal_drift); - pr_info("%s: Key3 Key4 signal/sheild drift diff %d \n\n", - __func__, key3_key4_signal_drift); - } - - switch (msg->status) { - - case CP_STATUS_KEY1_IN_DETECT: - if (key1_ref_drift < cp->pdata->key1_ref_drift_thres_l) - cap_prox_calibrate(cp); - break; - case CP_STATUS_KEY3_IN_DETECT: - if (key3_ref_drift < cp->pdata->key3_ref_drift_thres_l) - cap_prox_calibrate(cp); - break; - case CP_STATUS_KEY1_KEY3_EN_FORCE_DETECT: - /* Key1 sensor has failed, keep in force detect */ - if ((key1_key2_signal_drift > - cp->pdata->key1_failsafe_thres) && - (msg->signal2 > cp->pdata->key2_signal_thres)) { - msg->status = CP_STATUS_NUM_KEYS_ENABLED; - break; - } - - /* Key3 sensor has failed, keep in force detect */ - if ((key3_key4_signal_drift > - cp->pdata->key3_failsafe_thres) && - (msg->signal4 > cp->pdata->key4_signal_thres)) { - msg->status = CP_STATUS_NUM_KEYS_ENABLED; - break; - } - - status = msg->status & 0xF0; - cap_prox_write(cp,&status,1); - break; - case CP_STATUS_KEY1_KEY3_IN_DETECT: - if ((key3_ref_drift < cp->pdata->key1_ref_drift_thres_h) && - (key1_ref_drift < cp->pdata->key3_ref_drift_thres_h) && - (ref_drift_diff < cp->pdata->ref_drift_diff_thres)) - cap_prox_calibrate(cp); - break; - default: - if (cp_dbg) { - pr_info("%s: Cap-prox message 0x%x\n", __func__, - msg->status); - } - msg->status = CP_STATUS_NUM_KEYS_ENABLED; - break; - } - status = msg->status; - -read_fail_ret: - return status; -} - -static int cap_prox_hw_init(struct cap_prox_data *cp) -{ - pr_info("%s: HW init\n", __func__); - cap_prox_calibrate(cp); - cap_prox_write(cp,&cp->pdata->plat_cap_prox_cfg.thres_key1,1); - cap_prox_write(cp,&cp->pdata->plat_cap_prox_cfg.thres_key2,1); - msleep(200); - - return 0; -} - -static void cap_prox_irq_work_func(struct work_struct *work) -{ - int ret; - u8 buf[2]; - struct cap_prox_data *cp = - container_of(work, struct cap_prox_data, irq_work); - - cancel_delayed_work_sync(&cp->input_work); - ret = cap_prox_read(cp, buf, 2); - - if (cp_dbg) - pr_info("%s: Cap-Prox Status: [0x%x][0x%x] \n", - __func__, buf[0], buf[1]); - - if (buf[0] != CP_STATUS_NUM_KEYS_ENABLED) - schedule_delayed_work(&cp->input_work, - msecs_to_jiffies(cp->pdata->poll_interval)); - - cap_prox_irq_enable(cp, 1); - -} - -static struct miscdevice cap_prox_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = CAP_PROX_NAME, -}; - -static void cap_prox_input_work_func(struct work_struct *work) -{ - int ret = 0; - struct cap_prox_data *cp = container_of((struct delayed_work *)work, - struct cap_prox_data, input_work); - ret = cap_prox_read_data(cp); - - if (ret != CP_STATUS_NUM_KEYS_ENABLED) - schedule_delayed_work(&cp->input_work, - msecs_to_jiffies(cp->pdata->poll_interval)); -} - -static int cap_prox_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct cap_prox_platform_data *pdata = client->dev.platform_data; - struct cap_prox_data *cp; - struct cap_prox_msg *msg; - uint8_t mesg_buf[sizeof(struct cap_prox_msg)]; - int err = -1; - - if (pdata == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - } else if (!client->irq) { - pr_err("%s: polling mode currently not supported\n", __func__); - return -ENODEV; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s: need I2C_FUNC_I2C\n", __func__); - return -ENODEV; - } - - cp = kzalloc(sizeof(struct cap_prox_data), GFP_KERNEL); - if (cp == NULL) { - err = -ENOMEM; - goto err_out1; - } - - cp->pdata = pdata; - cp->client = client; - i2c_set_clientdata(client, cp); - spin_lock_init(&cp->irq_lock); - cp->irq_state = 1; - - INIT_WORK(&cp->irq_work, cap_prox_irq_work_func); - INIT_DELAYED_WORK(&cp->input_work, cap_prox_input_work_func); - - err = cap_prox_hw_init(cp); - if (err < 0) - goto err_out2; - - err = misc_register(&cap_prox_misc_device); - if (err < 0) { - dev_err(&client->dev, "misc register failed: %d\n", err); - goto err_out2; - } - - err = cap_prox_read(cp, mesg_buf, sizeof(struct cap_prox_msg)); - if (err) - goto err_out3; - msg = (struct cap_prox_msg *)mesg_buf; - pr_info("%s: msg->status 0x%2x \n", __func__, msg->status); - - /* Could be booted with body proximity, so force detect */ - cap_prox_write(cp,&cp->pdata->plat_cap_prox_cfg.force_detect,1); - - err = request_irq(cp->client->irq, cap_prox_irq_handler, - IRQF_TRIGGER_FALLING, "cap_prox_irq", cp); - if (err < 0) { - dev_err(&client->dev, "request irq failed: %d\n", err); - goto err_out3; - } - - pr_info("%s: Request IRQ = %d\n", __func__, cp->client->irq); - - cap_prox_write(cp, &cp->pdata->plat_cap_prox_cfg.address_ptr, 1); - - dev_info(&client->dev, "cap-prox probed\n"); - - return 0; - -err_out3: - misc_deregister(&cap_prox_misc_device); -err_out2: - kfree(cp); -err_out1: - return err; -} - -static int __devexit cap_prox_remove(struct i2c_client *client) -{ - struct cap_prox_data *cp = i2c_get_clientdata(client); - - free_irq(cp->client->irq, cp); - misc_deregister(&cap_prox_misc_device); - i2c_set_clientdata(client, NULL); - kfree(cp); - - return 0; -} - -static int cap_prox_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct cap_prox_data *cp = i2c_get_clientdata(client); - - if (cp_dbg & 0x4) - pr_info("%s: Suspending\n", __func__); - - cap_prox_irq_enable(cp, 0); - cancel_delayed_work_sync(&cp->input_work); - - return 0; -} - -static int cap_prox_resume(struct i2c_client *client) -{ - struct cap_prox_data *cp = i2c_get_clientdata(client); - - if (cp_dbg & 0x4) - pr_info("%s: Resuming\n", __func__); - - schedule_delayed_work(&cp->input_work, - msecs_to_jiffies(cp->pdata->min_poll_interval)); - cap_prox_irq_enable(cp, 1); - - return 0; -} - -static const struct i2c_device_id cap_prox_id[] = { - { CAP_PROX_NAME, 0 }, - { } -}; - -static struct i2c_driver cap_prox_driver = { - .probe = cap_prox_probe, - .remove = cap_prox_remove, - .suspend = cap_prox_suspend, - .resume = cap_prox_resume, - .id_table = cap_prox_id, - .driver = { - .name = CAP_PROX_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __devinit cap_prox_init(void) -{ - cp_irq_wq = create_singlethread_workqueue("cp_irq_wq"); - if (cp_irq_wq == NULL) { - pr_err("%s: No memory for cp_irq_wq\n", __func__); - return -ENOMEM; - } - return i2c_add_driver(&cap_prox_driver); -} - -static void __exit cap_prox_exit(void) -{ - i2c_del_driver(&cap_prox_driver); - if (cp_irq_wq) - destroy_workqueue(cp_irq_wq); -} - -module_init(cap_prox_init); -module_exit(cap_prox_exit); - -MODULE_AUTHOR("Motorola"); -MODULE_DESCRIPTION("Capacitive Proximity Sensor Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/gps-gpio-brcm4750.c b/drivers/misc/gps-gpio-brcm4750.c deleted file mode 100755 index ad05d709cf60..000000000000 --- a/drivers/misc/gps-gpio-brcm4750.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct gps_gpio_brcm4750_platform_data *gps_gpio_data; -/* Wakeup timer state definition */ - -enum timer_state { - /* Timer is inactive */ - TIMER_INACTIVE = 0, - /* Timer is active, waitting for timeout */ - TIMER_ACTIVE, - /* Timer has timeout, has wokenup process, waiting for next poll */ - TIMER_EXPIRED, - /* Timer is unused. */ - TIMER_INVALID -}; - -static int gps_start_wakeup_timer( struct file *filp, unsigned long timer_val_msecs) -{ - ktime_t low_interval = ktime_set(timer_val_msecs/MSEC_PER_SEC, - (timer_val_msecs%MSEC_PER_SEC)*NSEC_PER_MSEC); - /* set the alarm expiry window to 500 msecs */ - ktime_t slack = ktime_set(0, 500*NSEC_PER_MSEC); - ktime_t next = ktime_add(alarm_get_elapsed_realtime(), low_interval); - /* set filp structure if it is first time timer is scheduled */ - if (filp->private_data == NULL) - { - filp->private_data = (void *)gps_gpio_data; - } - alarm_cancel(&gps_gpio_data->alarm); - gps_gpio_data->timer_status = TIMER_ACTIVE; - alarm_start_range(&gps_gpio_data->alarm, next, ktime_add(next, slack)); - return 0; -} - -static int gps_stop_wakeup_timer( struct file *filp) -{ - if (filp->private_data == NULL) - return 0; - - alarm_cancel(&gps_gpio_data->alarm); - gps_gpio_data->timer_status = TIMER_INACTIVE; - return 0; -} - -static void gps_brcm4750_alarm(struct alarm* alarm) -{ - - struct gps_gpio_brcm4750_platform_data *gps_gpio_data = - container_of(alarm, struct gps_gpio_brcm4750_platform_data, alarm); - gps_gpio_data->timer_status = TIMER_EXPIRED; - - wake_lock_timeout(&gps_gpio_data->gps_brcm4750_wake, 5* HZ); - /* trigger poll wait */ - wake_up_interruptible(&(gps_gpio_data->gps_brcm4750_wq)); -} - - -static unsigned int gps_brcm_4750_poll(struct file *filp, poll_table *wait) -{ - unsigned int ret = 0; - struct gps_gpio_brcm4750_platform_data *gps_gpio_data; - /* If the timer is not present, do not permit this operation */ - if (filp->private_data == NULL) - { - return -EPERM; - } - - gps_gpio_data = (struct gps_gpio_brcm4750_platform_data *)filp->private_data; - if (gps_gpio_data->timer_status == TIMER_INVALID || - gps_gpio_data->timer_status == TIMER_INACTIVE) - { - return -EPERM; - } - - /* Check whether the timer has already expired */ - if (gps_gpio_data->timer_status == TIMER_EXPIRED) { - gps_gpio_data->timer_status = TIMER_INACTIVE; - return POLLIN; - } - /* release wake lock before poll wait */ - - wake_unlock(&gps_gpio_data->gps_brcm4750_wake); - poll_wait(filp, &(gps_gpio_data->gps_brcm4750_wq), wait); - - if (gps_gpio_data->timer_status == TIMER_EXPIRED) { - gps_gpio_data->timer_status = TIMER_INACTIVE; - ret = POLLIN; - } - return ret; -} -static long gps_brcm4750_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - unsigned int gpio_val; - - if (cmd <= 0) - return -EINVAL; - - switch (cmd) { - case IOC_GPS_GPIO_RESET: - if (copy_from_user((void *) &gpio_val, (void *) arg, - sizeof(int))) - return -EFAULT; - if (!(gpio_val == 0 || gpio_val == 1)) - return -EINVAL; - pr_info("%s: Setting gps gpio reset pin: %d\n", - __func__, gpio_val); - if (gps_gpio_data->set_reset_gpio) - gps_gpio_data->set_reset_gpio(gpio_val); - break; - case IOC_GPS_GPIO_STANDBY: - if (copy_from_user((void *) &gpio_val, (void *) arg, - sizeof(int))) - return -EFAULT; - if (!(gpio_val == 0 || gpio_val == 1)) - return -EINVAL; - pr_info("%s: Setting gps gpio standby pin to: %d\n", - __func__, gpio_val); - if (gps_gpio_data->set_standby_gpio) - gps_gpio_data->set_standby_gpio(gpio_val); - break; - case IOC_GPS_START_TIMER: - gps_start_wakeup_timer(filp, (unsigned long)arg); - break; - case IOC_GPS_STOP_TIMER: - gps_stop_wakeup_timer(filp); - break; - default: - pr_info("%s: Invalid GPS GPIO IOCTL command\n", __func__); - return -EINVAL; - } - - return 0; -} - -static const struct file_operations gps_brcm4750_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = gps_brcm4750_ioctl, - .poll = gps_brcm_4750_poll, -}; - -static struct miscdevice gps_gpio_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = GPS_GPIO_DRIVER_NAME, - .fops = &gps_brcm4750_fops, -}; - -static int gps_gpio_brcm4750_probe(struct platform_device *pdev) -{ - gps_gpio_data = pdev->dev.platform_data; - wake_lock_init(&gps_gpio_data->gps_brcm4750_wake, WAKE_LOCK_SUSPEND, - "gps-brcm4750"); - alarm_init(&gps_gpio_data->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, - gps_brcm4750_alarm); - init_waitqueue_head(&(gps_gpio_data->gps_brcm4750_wq)); - gps_gpio_data->timer_status = TIMER_INVALID; - if (misc_register(&gps_gpio_miscdev)) { - pr_info("%s: gps_brcm4750 misc_register failed\n", __func__); - return -1; - } - return 0; -} - -static int gps_gpio_brcm4750_remove(struct platform_device *pdev) -{ - if (gps_gpio_data->free_gpio) - gps_gpio_data->free_gpio(); - return 0; -} - -static struct platform_driver gps_gpio_brcm4750_driver = { - .probe = gps_gpio_brcm4750_probe, - .remove = gps_gpio_brcm4750_remove, - .driver = { - .name = GPS_GPIO_DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init gps_gpio_brcm4750_init(void) -{ - return platform_driver_register(&gps_gpio_brcm4750_driver); -} - -static void __exit gps_gpio_brcm4750_exit(void) -{ - platform_driver_unregister(&gps_gpio_brcm4750_driver); -} - -module_init(gps_gpio_brcm4750_init); -module_exit(gps_gpio_brcm4750_exit); - -MODULE_AUTHOR("Motorola"); -MODULE_DESCRIPTION("GPS GPIO Controller and wake up timer for BRCM 4750"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/kernel_debugger.c b/drivers/misc/kernel_debugger.c deleted file mode 100644 index 4a9fef6244ed..000000000000 --- a/drivers/misc/kernel_debugger.c +++ /dev/null @@ -1,89 +0,0 @@ -/* drivers/android/kernel_debugger.c - * - * Guts of the kernel debugger. - * Needs something to actually push commands to it. - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#define dprintf(fmt...) (ctxt->printf(ctxt->cookie, fmt)) - -static void do_ps(struct kdbg_ctxt *ctxt) -{ - struct task_struct *g, *p; - unsigned state; - static const char stat_nam[] = "RSDTtZX"; - - dprintf("pid ppid prio task pc\n"); - read_lock(&tasklist_lock); - do_each_thread(g, p) { - state = p->state ? __ffs(p->state) + 1 : 0; - dprintf("%5d %5d %4d ", p->pid, p->parent->pid, p->prio); - dprintf("%-13.13s %c", p->comm, - state >= sizeof(stat_nam) ? '?' : stat_nam[state]); - if (state == TASK_RUNNING) - dprintf(" running\n"); - else - dprintf(" %08lx\n", thread_saved_pc(p)); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); -} - -int log_buf_copy(char *dest, int idx, int len); -extern int do_syslog(int type, char __user *bug, int count); -static void do_sysrq(struct kdbg_ctxt *ctxt, char rq) -{ - char buf[128]; - int ret; - int idx = 0; - do_syslog(5 /* clear */, NULL, 0); - handle_sysrq(rq); - while (1) { - ret = log_buf_copy(buf, idx, sizeof(buf) - 1); - if (ret <= 0) - break; - buf[ret] = 0; - dprintf("%s", buf); - idx += ret; - } -} - -static void do_help(struct kdbg_ctxt *ctxt) -{ - dprintf("Kernel Debugger commands:\n"); - dprintf(" ps Process list\n"); - dprintf(" sysrq sysrq options\n"); - dprintf(" sysrq Execute sysrq with \n"); -} - -int kernel_debugger(struct kdbg_ctxt *ctxt, char *cmd) -{ - if (!strcmp(cmd, "ps")) - do_ps(ctxt); - if (!strcmp(cmd, "sysrq")) - do_sysrq(ctxt, 'h'); - if (!strncmp(cmd, "sysrq ", 6)) - do_sysrq(ctxt, cmd[6]); - if (!strcmp(cmd, "help")) - do_help(ctxt); - - return 0; -} - diff --git a/drivers/misc/max9635.c b/drivers/misc/max9635.c deleted file mode 100644 index bcafebedd51d..000000000000 --- a/drivers/misc/max9635.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG 1 - -#define MAX9635_ALLOWED_R_BYTES 1 -#define MAX9635_ALLOWED_W_BYTES 2 -#define MAX9635_MAX_RW_RETRIES 5 -#define MAX9635_I2C_RETRY_DELAY 10 -#define AUTO_INCREMENT 0x0 - -#define MAX9635_INT_STATUS 0x00 -#define MAX9635_INT_EN 0x01 -#define MAX9635_CONFIGURE 0x02 -#define MAX9635_ALS_DATA_H 0x03 -#define MAX9635_ALS_DATA_L 0x04 -#define MAX9635_ALS_THRESH_H 0x05 -#define MAX9635_ALS_THRESH_L 0x06 -#define MAX9635_THRESH_TIMER 0x07 - -struct max9635_zone_conv { - int lower_threshold; - int upper_threshold; -}; - -struct max9635_data { - struct input_dev *idev; - struct i2c_client *client; - struct delayed_work working_queue; - struct max9635_platform_data *als_pdata; - struct max9635_zone_conv max9635_zone_info[255]; - atomic_t enabled; - spinlock_t irq_lock; - int cur_irq_state; - struct regulator *regulator; -}; - -struct max9635_data *max9635_misc_data; - -#ifdef DEBUG -struct max9635_reg { - const char *name; - uint8_t reg; -} max9635_regs[] = { - {"INT_STATUS", MAX9635_INT_STATUS}, - {"INT_ENABLE", MAX9635_INT_EN}, - {"CONFIG", MAX9635_CONFIGURE}, - {"ALS_DATA_HIGH", MAX9635_ALS_DATA_H}, - {"ALS_DATA_LOW", MAX9635_ALS_DATA_L}, - {"ALS_THRESH_H", MAX9635_ALS_THRESH_H}, - {"ALS_THRESH_L", MAX9635_ALS_THRESH_L}, - {"ALS_THRESH_TIMER", MAX9635_THRESH_TIMER}, -}; -#endif - -static uint32_t max9635_debug = 0x00; -module_param_named(als_debug, max9635_debug, uint, 0664); - -static int max9635_read_reg(struct max9635_data *als_data, u8 * buf, int len) -{ - int err; - int tries = 0; - struct i2c_msg msgs[] = { - { - .addr = als_data->client->addr, - .flags = als_data->client->flags & I2C_M_TEN, - .len = 1, - .buf = buf, - }, - { - .addr = als_data->client->addr, - .flags = (als_data->client->flags & I2C_M_TEN) | I2C_M_RD, - .len = len, - .buf = buf, - }, - }; - - do { - err = i2c_transfer(als_data->client->adapter, msgs, 2); - if (err != 2) - msleep_interruptible(MAX9635_I2C_RETRY_DELAY); - } while ((err != 2) && (++tries < MAX9635_MAX_RW_RETRIES)); - - if (err != 2) { - pr_err("%s:read transfer error\n", __func__); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int max9635_write_reg(struct max9635_data *als_data, u8 * buf, int len) -{ - int err; - int tries = 0; - struct i2c_msg msgs[] = { - { - .addr = als_data->client->addr, - .flags = als_data->client->flags & I2C_M_TEN, - .len = len + 1, - .buf = buf, - }, - }; - - do { - err = i2c_transfer(als_data->client->adapter, msgs, 1); - if (err != 1) - msleep_interruptible(MAX9635_I2C_RETRY_DELAY); - } while ((err != 1) && (++tries < MAX9635_MAX_RW_RETRIES)); - - if (err != 1) { - pr_err("%s:write transfer error\n", __func__); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int max9635_init_registers(struct max9635_data *als_data) -{ - u8 buf[2]; - - buf[0] = (AUTO_INCREMENT | MAX9635_CONFIGURE); - buf[1] = als_data->als_pdata->configure; - if (max9635_write_reg(als_data, buf, 1)) - goto init_failed; - - buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_H); - buf[1] = als_data->als_pdata->def_high_threshold; - if (max9635_write_reg(als_data, buf, 1)) - goto init_failed; - - buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_L); - buf[1] = als_data->als_pdata->def_low_threshold; - if (max9635_write_reg(als_data, buf, 1)) - goto init_failed; - - buf[0] = (AUTO_INCREMENT | MAX9635_THRESH_TIMER); - buf[1] = als_data->als_pdata->threshold_timer; - if (max9635_write_reg(als_data, buf, 1)) - goto init_failed; - - return 0; - -init_failed: - pr_err("%s:Register 0x%d initialization failed\n", __func__, buf[0]); - return -EINVAL; -} - -static void max9635_irq_enable(struct max9635_data *als_data, int enable) -{ - unsigned long flags; - - spin_lock_irqsave(&als_data->irq_lock, flags); - if (als_data->cur_irq_state != enable) { - if (enable) - enable_irq(als_data->client->irq); - else - disable_irq_nosync(als_data->client->irq); - als_data->cur_irq_state = enable; - } - spin_unlock_irqrestore(&als_data->irq_lock, flags); -} - -static irqreturn_t max9635_irq_handler(int irq, void *dev) -{ - struct max9635_data *als_data = dev; - - max9635_irq_enable(als_data, 0); - schedule_delayed_work(&als_data->working_queue, 0); - - return IRQ_HANDLED; -} - -static int max9635_read_adj_als(struct max9635_data *als_data) -{ - int ret; - int lux = 0; - u8 low_buf = MAX9635_ALS_DATA_L; - u8 high_buf = MAX9635_ALS_DATA_H; - u8 exponent; - u16 mantissa; - - ret = max9635_read_reg(als_data, &high_buf, 1); - if (ret != 0) { - pr_err("%s: Unable to read lux high byte register: %d\n", - __func__, ret); - return -1; - } - ret = max9635_read_reg(als_data, &low_buf, 1); - if (ret != 0) { - pr_err("%s: Unable to read lux low byte register: %d\n", - __func__, ret); - return -1; - } - - exponent = (high_buf & 0xf0) >> 4; - mantissa = ((high_buf & 0x0f) << 4) | (low_buf & 0x0f); - - lux = ((0001 << exponent) * mantissa) / 20; - if (max9635_debug & 1) - pr_info("exp = 0x%X, mant = 0x%X, lux = %d\n", - exponent, mantissa, lux); - - lux = lux * (exponent + als_data->als_pdata->lens_coeff); - - if (max9635_debug & 1) - pr_info("%s:Reporting LUX %d\n", __func__, lux); - return lux; -} - -static int max9635_report_input(struct max9635_data *als_data) -{ - int ret = 0; - int lux_val; - u8 buf[2] = { MAX9635_INT_STATUS, 0x00 }; - - lux_val = max9635_read_adj_als(als_data); - if (lux_val >= 0) { - input_event(als_data->idev, EV_MSC, MSC_RAW, lux_val); - input_sync(als_data->idev); - } - - /* Clear the interrupt status register */ - ret = max9635_read_reg(als_data, buf, 1); - if (ret != 0) { - pr_err("%s:Unable to read interrupt register: %d\n", - __func__, ret); - return -1; - } - max9635_irq_enable(als_data, 1); - return ret; -} - -static int max9635_device_power(struct max9635_data *als_data, u8 state) -{ - int err; - u8 buf[2] = { (AUTO_INCREMENT | MAX9635_INT_EN) }; - - buf[1] = state; - err = max9635_write_reg(als_data, buf, 1); - if (err) - pr_err("%s:Unable to turn off prox: %d\n", __func__, err); - - return err; -} - -static int max9635_enable(struct max9635_data *als_data) -{ - int err; - - if (!atomic_cmpxchg(&als_data->enabled, 0, 1)) { - if (!IS_ERR_OR_NULL(als_data->regulator)) - regulator_enable(als_data->regulator); - err = max9635_device_power(als_data, 0x01); - if (err) { - atomic_set(&als_data->enabled, 0); - return err; - } - } - return 0; -} - -static int max9635_disable(struct max9635_data *als_data) -{ - if (atomic_cmpxchg(&als_data->enabled, 1, 0)) { - if (!IS_ERR_OR_NULL(als_data->regulator)) - regulator_disable(als_data->regulator); - max9635_device_power(als_data, 0x00); - } - cancel_delayed_work_sync(&als_data->working_queue); - - return 0; -} - -static int max9635_misc_open(struct inode *inode, struct file *file) -{ - int err; - err = nonseekable_open(inode, file); - if (err < 0) - return err; - - file->private_data = max9635_misc_data; - - return 0; -} - -static long max9635_misc_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - u8 enable; - struct max9635_data *als_data = file->private_data; - - switch (cmd) { - case MAX9635_IOCTL_SET_ENABLE: - if (copy_from_user(&enable, argp, 1)) - return -EFAULT; - if (enable > 1) - return -EINVAL; - - if (enable != 0) - max9635_enable(als_data); - else - max9635_disable(als_data); - - break; - - case MAX9635_IOCTL_GET_ENABLE: - enable = atomic_read(&als_data->enabled); - if (copy_to_user(argp, &enable, 1)) - return -EINVAL; - - break; - - default: - return -EINVAL; - } - - return 0; -} - -static const struct file_operations max9635_misc_fops = { - .owner = THIS_MODULE, - .open = max9635_misc_open, - .unlocked_ioctl = max9635_misc_ioctl, -}; - -static struct miscdevice max9635_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = MAX9635_NAME, - .fops = &max9635_misc_fops, -}; -#ifdef DEBUG -static ssize_t max9635_registers_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, - dev); - struct max9635_data *als_data = i2c_get_clientdata(client); - unsigned i, n, reg_count; - u8 als_reg[2]; - - reg_count = sizeof(max9635_regs) / sizeof(max9635_regs[0]); - for (i = 0, n = 0; i < reg_count; i++) { - als_reg[0] = (AUTO_INCREMENT | max9635_regs[i].reg); - max9635_read_reg(als_data, als_reg, 1); - n += scnprintf(buf + n, PAGE_SIZE - n, - "%-20s = 0x%02X\n", - max9635_regs[i].name, als_reg[0]); - } - - return n; -} - -static ssize_t max9635_registers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, - dev); - struct max9635_data *als_data = i2c_get_clientdata(client); - unsigned i, reg_count, value; - int error; - u8 als_reg[2]; - char name[30]; - - if (count >= 30) { - pr_err("%s:input too long\n", __func__); - return -1; - } - - if (sscanf(buf, "%s %x", name, &value) != 2) { - pr_err("%s:unable to parse input\n", __func__); - return -1; - } - - reg_count = sizeof(max9635_regs) / sizeof(max9635_regs[0]); - for (i = 0; i < reg_count; i++) { - if (!strcmp(name, max9635_regs[i].name)) { - als_reg[0] = (AUTO_INCREMENT | max9635_regs[i].reg); - als_reg[1] = value; - error = max9635_write_reg(als_data, als_reg, 1); - if (error) { - pr_err("%s:Failed to write register %s\n", - __func__, name); - return -1; - } - return count; - } - } - if (!strcmp("Go", name)) { - max9635_enable(als_data); - return 0; - } - if (!strcmp("Stop", name)) { - max9635_disable(als_data); - return 0; - } - pr_err("%s:no such register %s\n", __func__, name); - return -1; -} - -static DEVICE_ATTR(registers, 0644, max9635_registers_show, - max9635_registers_store); -#endif - -static void max9635_work_queue(struct work_struct *work) -{ - struct max9635_data *als_data = - container_of((struct delayed_work *)work, struct max9635_data, - working_queue); - - max9635_report_input(als_data); -} - -static int max9635_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct max9635_platform_data *pdata = client->dev.platform_data; - struct max9635_data *als_data; - int error = 0; - - if (pdata == NULL) { - pr_err("%s: platform data required\n", __func__); - return -ENODEV; - } else if (!client->irq) { - pr_err("%s: polling mode currently not supported\n", __func__); - return -ENODEV; - } - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s:I2C_FUNC_I2C not supported\n", __func__); - return -ENODEV; - } - - als_data = kzalloc(sizeof(struct max9635_data), GFP_KERNEL); - if (als_data == NULL) { - error = -ENOMEM; - goto err_alloc_data_failed; - } - - als_data->client = client; - als_data->als_pdata = pdata; - max9635_misc_data = als_data; - - als_data->idev = input_allocate_device(); - if (!als_data->idev) { - error = -ENOMEM; - pr_err("%s: input device allocate failed: %d\n", __func__, - error); - goto error_input_allocate_failed; - } - - als_data->idev->name = "max9635_als"; - input_set_capability(als_data->idev, EV_MSC, MSC_RAW); - - error = misc_register(&max9635_misc_device); - if (error < 0) { - pr_err("%s: max9635 register failed\n", __func__); - goto error_misc_register_failed; - } - - atomic_set(&als_data->enabled, 0); - - INIT_DELAYED_WORK(&als_data->working_queue, max9635_work_queue); - - error = input_register_device(als_data->idev); - if (error) { - pr_err("%s: input device register failed:%d\n", __func__, - error); - goto error_input_register_failed; - } - - error = max9635_init_registers(als_data); - if (error < 0) { - pr_err("%s: Register Initialization failed: %d\n", - __func__, error); - error = -ENODEV; - goto err_reg_init_failed; - } - - spin_lock_init(&als_data->irq_lock); - als_data->cur_irq_state = 1; - - error = request_irq(als_data->client->irq, max9635_irq_handler, - IRQF_TRIGGER_FALLING, MAX9635_NAME, als_data); - if (error != 0) { - pr_err("%s: irq request failed: %d\n", __func__, error); - error = -ENODEV; - goto err_req_irq_failed; - } - - i2c_set_clientdata(client, als_data); - - als_data->regulator = regulator_get(&client->dev, "vio"); - -#ifdef DEBUG - error = device_create_file(&als_data->client->dev, &dev_attr_registers); - if (error < 0) { - pr_err("%s:File device creation failed: %d\n", __func__, error); - error = -ENODEV; - goto err_create_registers_file_failed; - } -#endif - - return 0; - -#ifdef DEBUG -err_create_registers_file_failed: - free_irq(als_data->client->irq, als_data); -#endif -err_req_irq_failed: -err_reg_init_failed: - input_unregister_device(als_data->idev); -error_input_register_failed: - misc_deregister(&max9635_misc_device); -error_misc_register_failed: - input_free_device(als_data->idev); -error_input_allocate_failed: - kfree(als_data); -err_alloc_data_failed: - return error; -} - -static int max9635_remove(struct i2c_client *client) -{ - struct max9635_data *als_data = i2c_get_clientdata(client); -#ifdef DEBUG - device_remove_file(&als_data->client->dev, &dev_attr_registers); -#endif - if (!IS_ERR_OR_NULL(als_data->regulator)) - regulator_put(als_data->regulator); - free_irq(als_data->client->irq, als_data); - input_unregister_device(als_data->idev); - input_free_device(als_data->idev); - misc_deregister(&max9635_misc_device); - kfree(als_data); - return 0; -} - -static int max9635_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct max9635_data *als_data = i2c_get_clientdata(client); - - if (max9635_debug) - pr_info("%s: Suspending\n", __func__); - - max9635_irq_enable(als_data, 0); - cancel_delayed_work_sync(&als_data->working_queue); - - return 0; -} - -static int max9635_resume(struct i2c_client *client) -{ - struct max9635_data *als_data = i2c_get_clientdata(client); - - if (max9635_debug) - pr_info("%s: Resuming\n", __func__); - - max9635_irq_enable(als_data, 1); - - return 0; -} - -static const struct i2c_device_id max9635_id[] = { - {MAX9635_NAME, 0}, - {} -}; - -static struct i2c_driver max9635_i2c_driver = { - .probe = max9635_probe, - .remove = max9635_remove, - .suspend = max9635_suspend, - .resume = max9635_resume, - .id_table = max9635_id, - .driver = { - .name = MAX9635_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init max9635_init(void) -{ - return i2c_add_driver(&max9635_i2c_driver); -} - -static void __exit max9635_exit(void) -{ - i2c_del_driver(&max9635_i2c_driver); -} - -module_init(max9635_init); -module_exit(max9635_exit); - -MODULE_DESCRIPTION("ALS driver for Maxim 9635"); -MODULE_AUTHOR("Dan Murphy "); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/moto_bmp085.c b/drivers/misc/moto_bmp085.c deleted file mode 100644 index 4973a32593e2..000000000000 --- a/drivers/misc/moto_bmp085.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DEBUG - -#define NO_CYCLE 0 -#define TEMP_CYCLE 1 -#define PRESSURE_CYCLE 2 - -/* Register definitions */ -#define BMP085_TAKE_MEAS_REG 0xf4 -#define BMP085_READ_MEAS_REG_U 0xf6 -#define BMP085_READ_MEAS_REG_L 0xf7 -#define BMP085_READ_MEAS_REG_XL 0xf8 - -/* Bytes defined by the spec to take measurements -Temperature will take 4.5ms before EOC */ -#define BMP085_MEAS_TEMP 0x2e -/* 4.5ms wait for measurement */ -#define BMP085_MEAS_PRESS_OVERSAMP_0 0x34 -/* 7.5ms wait for measurement */ -#define BMP085_MEAS_PRESS_OVERSAMP_1 0x74 -/* 13.5ms wait for measurement */ -#define BMP085_MEAS_PRESS_OVERSAMP_2 0xb4 -/* 25.5ms wait for measurement */ -#define BMP085_MEAS_PRESS_OVERSAMP_3 0xf4 - - -/* EEPROM registers each is a two byte value so there is -an upper byte and a lower byte */ -#define BMP085_EEPROM_AC1_U 0xaa -#define BMP085_EEPROM_AC1_L 0xab -#define BMP085_EEPROM_AC2_U 0xac -#define BMP085_EEPROM_AC2_L 0xad -#define BMP085_EEPROM_AC3_U 0xae -#define BMP085_EEPROM_AC3_L 0xaf -#define BMP085_EEPROM_AC4_U 0xb0 -#define BMP085_EEPROM_AC4_L 0xb1 -#define BMP085_EEPROM_AC5_U 0xb2 -#define BMP085_EEPROM_AC5_L 0xb3 -#define BMP085_EEPROM_AC6_U 0xb4 -#define BMP085_EEPROM_AC6_L 0xb5 -#define BMP085_EEPROM_B1_U 0xb6 -#define BMP085_EEPROM_B1_L 0xb7 -#define BMP085_EEPROM_B2_U 0xb8 -#define BMP085_EEPROM_B2_L 0xb9 -#define BMP085_EEPROM_MB_U 0xba -#define BMP085_EEPROM_MB_L 0xbb -#define BMP085_EEPROM_MC_U 0xbc -#define BMP085_EEPROM_MC_L 0xbd -#define BMP085_EEPROM_MD_U 0xbe -#define BMP085_EEPROM_MD_L 0xbf - -#ifdef DEBUG -struct bmp085_reg { - const char *name; - uint8_t reg; -} bmp085_regs[] = { - {"MEASURE_REG", BMP085_TAKE_MEAS_REG}, - {"CNTRL_1", BMP085_READ_MEAS_REG_U}, - {"CNTRL_2", BMP085_READ_MEAS_REG_L}, - {"CNTRL_3", BMP085_READ_MEAS_REG_XL}, - {"EE_AC1_U", BMP085_EEPROM_AC1_U}, - {"EE_AC1_U", BMP085_EEPROM_AC1_L}, - {"EE_AC2_U", BMP085_EEPROM_AC2_U}, - {"EE_AC2_L", BMP085_EEPROM_AC2_L}, - {"EE_AC3_U", BMP085_EEPROM_AC3_U}, - {"EE_AC3_L", BMP085_EEPROM_AC3_L}, - {"EE_AC4_U", BMP085_EEPROM_AC4_U}, - {"EE_AC4_L", BMP085_EEPROM_AC4_L}, - {"EE_AC5_U", BMP085_EEPROM_AC5_U}, - {"EE_AC5_L", BMP085_EEPROM_AC5_L}, - {"EE_AC6_U", BMP085_EEPROM_AC6_U}, - {"EE_AC6_L", BMP085_EEPROM_AC6_L}, - {"EE_B1_U", BMP085_EEPROM_B1_U}, - {"EE_B1_L", BMP085_EEPROM_B1_L}, - {"EE_B2_U", BMP085_EEPROM_B2_U}, - {"EE_B2_L", BMP085_EEPROM_B2_L}, - {"EE_MB_U", BMP085_EEPROM_MB_U}, - {"EE_MB_L", BMP085_EEPROM_MB_L}, - {"EE_MC_U", BMP085_EEPROM_MC_U}, - {"EE_MC_L", BMP085_EEPROM_MC_L}, - {"EE_MD_U", BMP085_EEPROM_MD_U}, - {"EE_MD_L", BMP085_EEPROM_MD_L}, -}; -#endif -static uint32_t bmp085_debug = 0x00; -module_param_named(baro_debug, bmp085_debug, uint, 0664); - -#define I2C_RETRY_DELAY 5 -#define I2C_RETRIES 5 -#define AUTO_INCREMENT 0x80 - -static struct workqueue_struct *barom_wq; - -struct bmp085_eeprom_data { - s16 AC1, AC2, AC3; - u16 AC4, AC5, AC6; - s16 B1, B2; - s16 MB, MC, MD; -}; - -struct bmp085_data { - struct i2c_client *client; - struct bmp085_platform_data *pdata; - struct mutex lock; - struct delayed_work input_work; - struct work_struct wq; - struct workqueue_struct *working_queue; - struct input_dev *input_dev; - - u8 oversampling_rate; - u8 measurement_cycle; - - int uncalib_temperature; - int uncalib_pressure; - int calib_temperature; - long calib_pressure; - long b5; /* Needed for pressure calculation */ - - struct bmp085_eeprom_data bmp085_eeprom_vals; - - atomic_t enabled; - int on_before_suspend; - struct regulator *regulator; - struct regulator *io_regulator; - u8 resume_state[5]; -}; - -/* - * Because misc devices can not carry a pointer from driver register to - * open, we keep this global. This limits the driver to a single instance. - */ -struct bmp085_data *bmp085_misc_data; - -static int bmp085_i2c_read(struct bmp085_data *barom, u8 * buf, int len) -{ - int err; - int tries = 0; - struct i2c_msg msgs[] = { - { - .addr = barom->client->addr, - .flags = barom->client->flags & I2C_M_TEN, - .len = 1, - .buf = buf, - }, - { - .addr = barom->client->addr, - .flags = (barom->client->flags & I2C_M_TEN) | I2C_M_RD, - .len = len, - .buf = buf, - }, - }; - - do { - err = i2c_transfer(barom->client->adapter, msgs, 2); - if (err != 2) - msleep_interruptible(I2C_RETRY_DELAY); - } while ((err != 2) && (++tries < I2C_RETRIES)); - - if (err != 2) { - pr_err("%s:read transfer error\n", __func__); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int bmp085_i2c_write(struct bmp085_data *barom, u8 * buf, int len) -{ - int err; - int tries = 0; - struct i2c_msg msgs[] = { - { - .addr = barom->client->addr, - .flags = barom->client->flags & I2C_M_TEN, - .len = len + 1, - .buf = buf, - }, - }; - - do { - err = i2c_transfer(barom->client->adapter, msgs, 1); - if (err != 1) - msleep_interruptible(I2C_RETRY_DELAY); - } while ((err != 1) && (++tries < I2C_RETRIES)); - - if (err != 1) { - pr_err("%s:write transfer error\n", __func__); - err = -EIO; - } else { - err = 0; - } - - return err; -} - -static int bmp085_update_measurement_accuracy(struct bmp085_data *barom, - int accuracy) -{ - if (accuracy > 3) - accuracy = 3; - barom->oversampling_rate = accuracy; - - return 0; -} - -static void bmp085_schedule_work(struct bmp085_data *barom) -{ - schedule_delayed_work(&barom->input_work, - msecs_to_jiffies(barom->pdata->poll_interval)); -} - -static int bmp085_enable(struct bmp085_data *barom) -{ - int err = 0; - - if (!atomic_cmpxchg(&barom->enabled, 0, 1)) { - if (barom->regulator) - err = regulator_enable(barom->regulator); - err = regulator_enable(barom->io_regulator); - if (err < 0) { - atomic_set(&barom->enabled, 0); - return err; - } - schedule_delayed_work(&barom->input_work, - msecs_to_jiffies(barom->pdata-> - poll_interval)); - } - - return 0; -} - -static int bmp085_disable(struct bmp085_data *barom) -{ - if (atomic_cmpxchg(&barom->enabled, 1, 0)) { - cancel_delayed_work_sync(&barom->input_work); - if (barom->regulator) - regulator_disable(barom->regulator); - regulator_disable(barom->io_regulator); - } - barom->measurement_cycle = NO_CYCLE; - - return 0; -} - -static int bmp085_misc_open(struct inode *inode, struct file *file) -{ - int err; - err = nonseekable_open(inode, file); - if (err < 0) - return err; - - file->private_data = bmp085_misc_data; - - return 0; -} - -static long bmp085_misc_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - u8 buf[4]; - int err; - int interval; - struct bmp085_data *barom = file->private_data; - - switch (cmd) { - case BMP085_IOCTL_GET_DELAY: - interval = barom->pdata->poll_interval; - if (copy_to_user(argp, &interval, sizeof(interval))) - return -EFAULT; - break; - - case BMP085_IOCTL_SET_DELAY: - if (copy_from_user(&interval, argp, sizeof(interval))) - return -EFAULT; - if (interval < 0 || interval > 200) - return -EINVAL; - - barom->pdata->poll_interval = - max(interval, barom->pdata->min_interval); - break; - - case BMP085_IOCTL_SET_ENABLE: - if (copy_from_user(&interval, argp, sizeof(interval))) - return -EFAULT; - if (interval > 1) - return -EINVAL; - - if (interval) - bmp085_enable(barom); - else - bmp085_disable(barom); - - break; - - case BMP085_IOCTL_GET_ENABLE: - interval = atomic_read(&barom->enabled); - if (copy_to_user(argp, &interval, sizeof(interval))) - return -EINVAL; - - break; - - case BMP085_IOCTL_ACCURACY: - if (copy_from_user(&buf, argp, 1)) - return -EFAULT; - err = bmp085_update_measurement_accuracy(barom, arg); - if (err < 0) - return err; - - break; - - default: - return -EINVAL; - } - - return 0; -} - -static const struct file_operations bmp085_misc_fops = { - .owner = THIS_MODULE, - .open = bmp085_misc_open, - .unlocked_ioctl = bmp085_misc_ioctl, -}; - -static struct miscdevice bmp085_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = BMP085_NAME, - .fops = &bmp085_misc_fops, -}; - -#ifdef BMP085_OPEN_ENABLE -int bmp085_input_open(struct input_dev *input) -{ - struct bmp085_data *barom = input_get_drvdata(input); - - return bmp085_enable(barom); -} - -void bmp085_input_close(struct input_dev *dev) -{ - struct bmp085_data *barom = input_get_drvdata(dev); - - bmp085_disable(barom); -} -#endif -#ifdef DEBUG -static ssize_t bmp085_registers_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, - dev); - struct bmp085_data *barom_data = i2c_get_clientdata(client); - u8 barom_reg[2]; - unsigned i, n, reg_count; - - reg_count = sizeof(bmp085_regs) / sizeof(bmp085_regs[0]); - for (i = 0, n = 0; i < reg_count; i++) { - barom_reg[0] = (AUTO_INCREMENT | bmp085_regs[i].reg); - bmp085_i2c_read(barom_data, barom_reg, 1); - n += scnprintf(buf + n, PAGE_SIZE - n, - "%-20s = 0x%02X\n", - bmp085_regs[i].name, barom_reg[0]); - } - return n; -} - -static ssize_t bmp085_registers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, - dev); - struct bmp085_data *barom_data = i2c_get_clientdata(client); - unsigned i, reg_count, value; - int error; - u8 barom_reg[2]; - char name[30]; - - if (count >= 30) { - pr_err("%s:input too long\n", __func__); - return -1; - } - - if (sscanf(buf, "%s %x", name, &value) != 2) { - pr_err("%s:unable to parse input\n", __func__); - return -1; - } - - reg_count = sizeof(bmp085_regs) / sizeof(bmp085_regs[0]); - for (i = 0; i < reg_count; i++) { - if (!strcmp(name, bmp085_regs[i].name)) { - barom_reg[0] = (AUTO_INCREMENT | bmp085_regs[i].reg); - barom_reg[1] = value; - error = bmp085_i2c_write(barom_data, barom_reg, 2); - if (error) { - pr_err("%s:Failed to write register %s\n", - __func__, name); - return -1; - } - return count; - } - } - if (!strcmp("Go", name)) { - if (value > 0) - bmp085_enable(barom_data); - else - bmp085_disable(barom_data); - - return 0; - } - if (!strcmp("acc", name)) { - barom_data->oversampling_rate = value; - return 0; - } - - pr_err("%s:no such register %s\n", __func__, name); - return -1; -} - -static DEVICE_ATTR(registers, 0644, bmp085_registers_show, - bmp085_registers_store); -#endif -static int bmp085_get_temperature_data(struct bmp085_data *barom) -{ - int err = -1; - u8 buf[2] = { BMP085_READ_MEAS_REG_U, 0 }; - int x1; - unsigned int x2; - - err = bmp085_i2c_read(barom, buf, 2); - if (err) { - pr_err("%s:Cannot read pressure measurement\n", __func__); - return err; - } - if (bmp085_debug & 2) - pr_err("%s:Read Temp 0x%X 0x%X\n", __func__, buf[0], buf[1]); - - barom->uncalib_temperature = (buf[0] << 8) + buf[1]; - - /* The math is derived from the data sheet. */ - x1 = ((barom->uncalib_temperature - barom->bmp085_eeprom_vals.AC6) * - barom->bmp085_eeprom_vals.AC5) >> 15; - x2 = (barom->bmp085_eeprom_vals.MC << 11) / - (x1 + barom->bmp085_eeprom_vals.MD); - barom->b5 = x1 + x2; - barom->calib_temperature = (barom->b5 + 8) >> 4; - if (bmp085_debug & 1) - pr_err("%s:Calibrated Temp %d\n", - __func__, barom->calib_temperature); - - return err; -} - -static int bmp085_get_barometer_data(struct bmp085_data *barom) -{ - int err = -1; - long x1, x2, x3, b3, b6; - unsigned long b4, b7; - long p; - u8 buf[3] = { BMP085_READ_MEAS_REG_U, 0, 0 }; - - err = bmp085_i2c_read(barom, buf, 3); - if (err) { - pr_err("%s:Cannot read pressure measurement\n", __func__); - return err; - } - - /* Raw data to uncalibrate pressure. Conversion compliments of the - data sheet */ - barom->uncalib_pressure = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) >> - (8 - barom->oversampling_rate); - if (bmp085_debug & 2) - pr_err("%s:Uncalibrated pressure %d\n", __func__, - barom->uncalib_pressure); - - /* Complicated math compliments of the data sheet */ - b6 = (barom->b5 - 4000); - x1 = (barom->bmp085_eeprom_vals.B2 * ((b6 * b6) >> 12)) >> 11; - x2 = (barom->bmp085_eeprom_vals.AC2 * b6) >> 11; - x3 = x1 + x2; - b3 = (((((long)barom->bmp085_eeprom_vals.AC1) * 4 + - x3) << barom->oversampling_rate) + 2) >> 2; - x1 = (barom->bmp085_eeprom_vals.AC3 * b6) >> 13; - x2 = (barom->bmp085_eeprom_vals.B1 * (b6 * b6 >> 12)) >> 16; - x3 = ((x1 + x2) + 2) >> 2; - b4 = (barom->bmp085_eeprom_vals.AC4 * - (unsigned long)(x3 + 32768)) >> 15; - b7 = ((unsigned long)barom->uncalib_pressure - - b3) * (50000 >> barom->oversampling_rate); - if (b7 < 0x80000000) - p = (b7 * 2) / b4; - else - p = (b7 / b4) * 2; - x1 = (p >> 8) * (p >> 8); - x1 = (x1 * 3038) >> 16; - x2 = (-7357 * p) >> 16; - barom->calib_pressure = p + ((x1 + x2 + 3791) >> 4); - if (bmp085_debug & 1) - pr_info("%s:Calibrated Pressure is %li\n", - __func__, barom->calib_pressure); - - return err; -} - -static void bmp085_input_work_func(struct work_struct *work) -{ - struct bmp085_data *barom = container_of((struct delayed_work *)work, - struct bmp085_data, - input_work); - int err; - u8 buf[2]; - - buf[0] = (AUTO_INCREMENT | BMP085_TAKE_MEAS_REG); - buf[1] = BMP085_MEAS_TEMP; - - if ((barom->measurement_cycle == TEMP_CYCLE) || - (barom->measurement_cycle == PRESSURE_CYCLE)) { - /* One of the measurements took to long so - reset the state machine */ - barom->measurement_cycle = NO_CYCLE; - } else { - barom->measurement_cycle = TEMP_CYCLE; - err = bmp085_i2c_write(barom, buf, 2); - if (err) { - pr_err("%s:Cannot start temp measurement\n", __func__); - barom->measurement_cycle = NO_CYCLE; - return; - } - } - bmp085_schedule_work(barom); - return; -} - -void bmp085_work_queue(struct work_struct *work) -{ - int err = 0; - struct bmp085_data *barom_data = - container_of(work, struct bmp085_data, wq); - u8 buf[2]; - - if (barom_data->measurement_cycle == NO_CYCLE) { - pr_err("%s:No cycle defined\n", __func__); - } else if (barom_data->measurement_cycle == TEMP_CYCLE) { - - if (bmp085_debug & 1) - pr_err("%s:Temp cycle\n", __func__); - - err = bmp085_get_temperature_data(barom_data); - if (err) { - pr_err("%s:Cannot read temp measurement\n", __func__); - return; - } - /* Setup for a pressure measurement */ - buf[0] = (AUTO_INCREMENT | BMP085_TAKE_MEAS_REG); - buf[1] = BMP085_MEAS_PRESS_OVERSAMP_0 | - (barom_data->oversampling_rate << 6); - - barom_data->measurement_cycle = PRESSURE_CYCLE; - - err = bmp085_i2c_write(barom_data, buf, 2); - if (err) { - pr_err("%s:Cannot start temp measurement\n", __func__); - barom_data->measurement_cycle = NO_CYCLE; - return; - } - } else { - /* Get and report the pressure */ - if (bmp085_debug & 1) - pr_err("%s:Pressure cycle\n", __func__); - - err = bmp085_get_barometer_data(barom_data); - if (err) { - pr_err("%s:Pressure measurement failed\n", __func__); - return; - } - - input_report_abs(barom_data->input_dev, ABS_PRESSURE, - barom_data->calib_pressure); - input_sync(barom_data->input_dev); - - barom_data->measurement_cycle = NO_CYCLE; - } - enable_irq(barom_data->client->irq); - return; -} - -irqreturn_t bmp085_irq_handler(int irq, void *dev) -{ - struct bmp085_data *barom_data = dev; - disable_irq_nosync(barom_data->client->irq); - queue_work(barom_wq, &barom_data->wq); - - return IRQ_HANDLED; -} - -static int bmp085_validate_pdata(struct bmp085_data *barom) -{ - barom->pdata->poll_interval = max(barom->pdata->poll_interval, - barom->pdata->min_interval); - - /* Enforce minimum polling interval */ - if (barom->pdata->poll_interval < barom->pdata->min_interval) { - pr_err("%s:minimum poll interval violated\n", __func__); - return -EINVAL; - } - - return 0; -} - -static int bmp085_input_init(struct bmp085_data *barom) -{ - int err; - - INIT_DELAYED_WORK(&barom->input_work, bmp085_input_work_func); - - barom->input_dev = input_allocate_device(); - if (!barom->input_dev) { - err = -ENOMEM; - dev_err(&barom->client->dev, "input device allocate failed\n"); - goto err0; - } -#ifdef BMP085_OPEN_ENABLE - barom->input_dev->open = bmp085_input_open; - barom->input_dev->close = bmp085_input_close; -#endif - - input_set_drvdata(barom->input_dev, barom); - - set_bit(EV_ABS, barom->input_dev->evbit); - - /* Need to define the correct min and max */ - input_set_abs_params(barom->input_dev, ABS_PRESSURE, - barom->pdata->min_p, barom->pdata->max_p, - barom->pdata->fuzz, barom->pdata->flat); - - barom->input_dev->name = "barometer"; - - err = input_register_device(barom->input_dev); - if (err) { - dev_err(&barom->client->dev, - "unable to register input polled device %s\n", - barom->input_dev->name); - goto err1; - } - - return 0; - -err1: - input_free_device(barom->input_dev); -err0: - return err; -} - -static void bmp085_input_cleanup(struct bmp085_data *barom) -{ - input_unregister_device(barom->input_dev); - input_free_device(barom->input_dev); -} - -static int bmp085_read_store_eeprom_val(struct bmp085_data *barom) -{ - int err = 0; - u8 buf[22]; - - buf[0] = BMP085_EEPROM_AC1_U; - err = bmp085_i2c_read(barom, buf, 22); - if (err) { - pr_err("%s:Cannot read EEPROM values\n", __func__); - return err; - } - - barom->bmp085_eeprom_vals.AC1 = (buf[0] << 8) | buf[1]; - barom->bmp085_eeprom_vals.AC2 = (buf[2] << 8) | buf[3]; - barom->bmp085_eeprom_vals.AC3 = (buf[4] << 8) | buf[5]; - barom->bmp085_eeprom_vals.AC4 = (buf[6] << 8) | buf[7]; - barom->bmp085_eeprom_vals.AC5 = (buf[8] << 8) | buf[9]; - barom->bmp085_eeprom_vals.AC6 = (buf[10] << 8) | buf[11]; - barom->bmp085_eeprom_vals.B1 = (buf[12] << 8) | buf[13]; - barom->bmp085_eeprom_vals.B2 = (buf[14] << 8) | buf[15]; - barom->bmp085_eeprom_vals.MB = (buf[16] << 8) | buf[17]; - barom->bmp085_eeprom_vals.MC = (buf[18] << 8) | buf[19]; - barom->bmp085_eeprom_vals.MD = (buf[20] << 8) | buf[21]; - - return 0; -} - -static int bmp085_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct bmp085_data *barom; - int err = -1; - - if (client->dev.platform_data == NULL) { - pr_err("%s:platform data is NULL. exiting.\n", __func__); - err = -ENODEV; - goto err0; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s:client not i2c capable\n", __func__); - err = -ENODEV; - goto err0; - } - - barom = kzalloc(sizeof(*barom), GFP_KERNEL); - if (barom == NULL) { - pr_err("%s:failed to allocate memory for module data\n", - __func__); - err = -ENOMEM; - goto err0; - } - mutex_init(&barom->lock); - mutex_lock(&barom->lock); - barom->client = client; - barom->oversampling_rate = 0; - barom->b5 = 0; - - barom->pdata = kzalloc(sizeof(*barom->pdata), GFP_KERNEL); - if (barom->pdata == NULL) - goto err1; - - memcpy(barom->pdata, client->dev.platform_data, sizeof(*barom->pdata)); - - err = bmp085_validate_pdata(barom); - if (err < 0) { - pr_err("%s:failed to validate platform data\n", __func__); - goto err1_1; - } - - i2c_set_clientdata(client, barom); - - err = bmp085_read_store_eeprom_val(barom); - if (err) { - pr_err("%s: Reading the EEPROM failed\n", __func__); - err = -ENODEV; - goto err_req_irq_failed; - } - - INIT_WORK(&barom->wq, bmp085_work_queue); - - err = request_irq(barom->client->irq, bmp085_irq_handler, - IRQF_TRIGGER_RISING, BMP085_NAME, barom); - if (err != 0) { - pr_err("%s: irq request failed: %d\n", __func__, err); - err = -ENODEV; - goto err_req_irq_failed; - } - - barom->regulator = regulator_get(&client->dev, "vcc"); - if (IS_ERR_OR_NULL(barom->regulator)) { - dev_err(&client->dev, "unable to get regulator\n"); - barom->regulator = NULL; - } - barom->io_regulator = regulator_get(&client->dev, "vio"); - if (IS_ERR(barom->io_regulator)) - barom->io_regulator = NULL; - - err = bmp085_input_init(barom); - if (err < 0) - goto err3; - - bmp085_misc_data = barom; - - err = misc_register(&bmp085_misc_device); - if (err < 0) { - dev_err(&client->dev, "barom_device register failed\n"); - goto err4; - } -#ifdef DEBUG - err = device_create_file(&client->dev, &dev_attr_registers); - if (err < 0) - pr_err("%s:File device creation failed: %d\n", __func__, err); -#endif - - /* As default, do not report information */ - atomic_set(&barom->enabled, 0); - - mutex_unlock(&barom->lock); - - return 0; - -err4: - bmp085_input_cleanup(barom); -err3: - if (barom->regulator) - regulator_put(barom->regulator); - if (barom->io_regulator) - regulator_put(barom->io_regulator); -err_req_irq_failed: -err1_1: - mutex_unlock(&barom->lock); - kfree(barom->pdata); -err1: - kfree(barom); -err0: - return err; -} - -static int __devexit bmp085_remove(struct i2c_client *client) -{ - /* TO DO: revisit ordering here once _probe order is finalized */ - struct bmp085_data *barom = i2c_get_clientdata(client); - - misc_deregister(&bmp085_misc_device); - bmp085_input_cleanup(barom); - bmp085_disable(barom); - if (barom->regulator) - regulator_put(barom->regulator); - if (barom->io_regulator) - regulator_put(barom->io_regulator); -#ifdef DEBUG - device_remove_file(&client->dev, &dev_attr_registers); -#endif - destroy_workqueue(barom_wq); - - kfree(barom->pdata); - kfree(barom); - - return 0; -} - -static int bmp085_resume(struct i2c_client *client) -{ - struct bmp085_data *barom = i2c_get_clientdata(client); - - if (barom->on_before_suspend) - return bmp085_enable(barom); - return 0; -} - -static int bmp085_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct bmp085_data *barom = i2c_get_clientdata(client); - - barom->on_before_suspend = atomic_read(&barom->enabled); - return bmp085_disable(barom); -} - -static const struct i2c_device_id bmp085_id[] = { - {BMP085_NAME, 0}, - {}, -}; - -MODULE_DEVICE_TABLE(i2c, bmp085_id); - -static struct i2c_driver bmp085_driver = { - .driver = { - .name = BMP085_NAME, - }, - .probe = bmp085_probe, - .remove = __devexit_p(bmp085_remove), - .resume = bmp085_resume, - .suspend = bmp085_suspend, - .id_table = bmp085_id, -}; - -static int __init bmp085_init(void) -{ - barom_wq = create_singlethread_workqueue("barometer_wq"); - if (!barom_wq) { - pr_err("%s: Cannot create work queue\n", __func__); - return -ENOMEM; - } - pr_info("BMP085 barometer driver\n"); - return i2c_add_driver(&bmp085_driver); -} - -static void __exit bmp085_exit(void) -{ - i2c_del_driver(&bmp085_driver); - return; -} - -module_init(bmp085_init); -module_exit(bmp085_exit); - -MODULE_DESCRIPTION("bmp085 barometer driver"); -MODULE_AUTHOR("Dan Murphy D.Murphy@Motorola.com"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/nct1008.c b/drivers/misc/nct1008.c deleted file mode 100755 index 4ae48e4003aa..000000000000 --- a/drivers/misc/nct1008.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * drivers/misc/nct1008.c - * - * Driver for NCT1008, temperature monitoring device from ON Semiconductors - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DRIVER_NAME "nct1008" - -/* Register Addresses */ -#define LOCAL_TEMP_RD 0x00 -#define STATUS_RD 0x02 -#define CONFIG_RD 0x03 - -#define CONFIG_WR 0x09 -#define CONV_RATE_WR 0x0A -#define LOCAL_TEMP_HI_LIMIT_WR 0x0B -#define EXT_TEMP_HI_LIMIT_HI_BYTE 0x0D -#define OFFSET_WR 0x11 -#define EXT_THERM_LIMIT_WR 0x19 -#define LOCAL_THERM_LIMIT_WR 0x20 -#define THERM_HYSTERESIS_WR 0x21 - -/* Configuration Register Bits */ -#define EXTENDED_RANGE_BIT (0x1 << 2) -#define THERM2_BIT (0x1 << 5) -#define STANDBY_BIT (0x1 << 6) - -/* Max Temperature Measurements */ -#define EXTENDED_RANGE_OFFSET 64U -#define STANDARD_RANGE_MAX 127U -#define EXTENDED_RANGE_MAX (150U + EXTENDED_RANGE_OFFSET) - -struct nct1008_data { - struct work_struct work; - struct i2c_client *client; - struct mutex mutex; - u8 config; - void (*alarm_fn)(bool raised); -}; - -static void nct1008_enable(struct i2c_client *client) -{ - struct nct1008_data *data = i2c_get_clientdata(client); - - i2c_smbus_write_byte_data(client, CONFIG_WR, - data->config & ~STANDBY_BIT); -} - -static void nct1008_disable(struct i2c_client *client) -{ - struct nct1008_data *data = i2c_get_clientdata(client); - - i2c_smbus_write_byte_data(client, CONFIG_WR, - data->config | STANDBY_BIT); -} - - -static void nct1008_work_func(struct work_struct *work) -{ - struct nct1008_data *data = container_of(work, struct nct1008_data, work); - int irq = data->client->irq; - - mutex_lock(&data->mutex); - - if (data->alarm_fn) { - /* Therm2 line is active low */ - data->alarm_fn(!gpio_get_value(irq_to_gpio(irq))); - } - - mutex_unlock(&data->mutex); -} - -static irqreturn_t nct1008_irq(int irq, void *dev_id) -{ - struct nct1008_data *data = dev_id; - schedule_work(&data->work); - - return IRQ_HANDLED; -} - -static inline u8 value_to_temperature(bool extended, u8 value) -{ - return (extended ? (u8)(value - EXTENDED_RANGE_OFFSET) : value); -} - -static inline u8 temperature_to_value(bool extended, u8 temp) -{ - return (extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : temp); -} - -static int __devinit nct1008_configure_sensor(struct nct1008_data* data) -{ - struct i2c_client *client = data->client; - struct nct1008_platform_data *pdata = client->dev.platform_data; - u8 value; - int err; - - if (!pdata || !pdata->supported_hwrev) - return -ENODEV; - - /* - * Initial Configuration - device is placed in standby and - * ALERT/THERM2 pin is configured as THERM2 - */ - data->config = value = pdata->ext_range ? - (STANDBY_BIT | THERM2_BIT | EXTENDED_RANGE_BIT) : - (STANDBY_BIT | THERM2_BIT); - - err = i2c_smbus_write_byte_data(client, CONFIG_WR, value); - if (err < 0) - goto error; - - /* Temperature conversion rate */ - err = i2c_smbus_write_byte_data(client, CONV_RATE_WR, pdata->conv_rate); - if (err < 0) - goto error; - - /* External temperature h/w shutdown limit */ - value = temperature_to_value(pdata->ext_range, pdata->shutdown_ext_limit); - err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value); - if (err < 0) - goto error; - - /* Local temperature h/w shutdown limit */ - value = temperature_to_value(pdata->ext_range, pdata->shutdown_local_limit); - err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value); - if (err < 0) - goto error; - - /* External Temperature Throttling limit */ - value = temperature_to_value(pdata->ext_range, pdata->throttling_ext_limit); - err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE, value); - if (err < 0) - goto error; - - /* Local Temperature Throttling limit */ - value = pdata->ext_range ? EXTENDED_RANGE_MAX : STANDARD_RANGE_MAX; - err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR, value); - if (err < 0) - goto error; - - /* Remote channel offset */ - err = i2c_smbus_write_byte_data(client, OFFSET_WR, pdata->offset); - if (err < 0) - goto error; - - /* THERM hysteresis */ - err = i2c_smbus_write_byte_data(client, THERM_HYSTERESIS_WR, pdata->hysteresis); - if (err < 0) - goto error; - - data->alarm_fn = pdata->alarm_fn; - return 0; -error: - return err; -} - -static int __devinit nct1008_configure_irq(struct nct1008_data *data) -{ - INIT_WORK(&data->work, nct1008_work_func); - - return request_irq(data->client->irq, nct1008_irq, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, DRIVER_NAME, data); -} - -static int __devinit nct1008_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct nct1008_data *data; - int err; - - data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL); - - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->mutex); - - err = nct1008_configure_sensor(data); /* sensor is in standby */ - if (err < 0) - goto error; - - err = nct1008_configure_irq(data); - if (err < 0) - goto error; - - nct1008_enable(client); /* sensor is running */ - - schedule_work(&data->work); /* check initial state */ - - return 0; - -error: - kfree(data); - return err; -} - -static int __devexit nct1008_remove(struct i2c_client *client) -{ - struct nct1008_data *data = i2c_get_clientdata(client); - - free_irq(data->client->irq, data); - cancel_work_sync(&data->work); - kfree(data); - - return 0; -} - -#ifdef CONFIG_PM -static int nct1008_suspend(struct i2c_client *client, pm_message_t state) -{ - disable_irq(client->irq); - nct1008_disable(client); - - return 0; -} - -static int nct1008_resume(struct i2c_client *client) -{ - struct nct1008_data *data = i2c_get_clientdata(client); - - nct1008_enable(client); - enable_irq(client->irq); - schedule_work(&data->work); - - return 0; -} -#endif - -static const struct i2c_device_id nct1008_id[] = { - { DRIVER_NAME, 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, nct1008_id); - -static struct i2c_driver nct1008_driver = { - .driver = { - .name = DRIVER_NAME, - }, - .probe = nct1008_probe, - .remove = __devexit_p(nct1008_remove), - .id_table = nct1008_id, -#ifdef CONFIG_PM - .suspend = nct1008_suspend, - .resume = nct1008_resume, -#endif -}; - -static int __init nct1008_init(void) -{ - return i2c_add_driver(&nct1008_driver); -} - -static void __exit nct1008_exit(void) -{ - i2c_del_driver(&nct1008_driver); -} - -MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008"); -MODULE_LICENSE("GPL"); - -module_init (nct1008_init); -module_exit (nct1008_exit); diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c deleted file mode 100644 index 890831e2deb7..000000000000 --- a/drivers/misc/pmem.c +++ /dev/null @@ -1,1344 +0,0 @@ -/* drivers/android/pmem.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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PMEM_MAX_DEVICES 10 -#define PMEM_MAX_ORDER 128 -#define PMEM_MIN_ALLOC PAGE_SIZE - -#define PMEM_DEBUG 1 - -/* indicates that a refernce to this file has been taken via get_pmem_file, - * the file should not be released until put_pmem_file is called */ -#define PMEM_FLAGS_BUSY 0x1 -/* indicates that this is a suballocation of a larger master range */ -#define PMEM_FLAGS_CONNECTED 0x1 << 1 -/* indicates this is a master and not a sub allocation and that it is mmaped */ -#define PMEM_FLAGS_MASTERMAP 0x1 << 2 -/* submap and unsubmap flags indicate: - * 00: subregion has never been mmaped - * 10: subregion has been mmaped, reference to the mm was taken - * 11: subretion has ben released, refernece to the mm still held - * 01: subretion has been released, reference to the mm has been released - */ -#define PMEM_FLAGS_SUBMAP 0x1 << 3 -#define PMEM_FLAGS_UNSUBMAP 0x1 << 4 - - -struct pmem_data { - /* in alloc mode: an index into the bitmap - * in no_alloc mode: the size of the allocation */ - int index; - /* see flags above for descriptions */ - unsigned int flags; - /* protects this data field, if the mm_mmap sem will be held at the - * same time as this sem, the mm sem must be taken first (as this is - * the order for vma_open and vma_close ops */ - struct rw_semaphore sem; - /* info about the mmaping process */ - struct vm_area_struct *vma; - /* task struct of the mapping process */ - struct task_struct *task; - /* process id of teh mapping process */ - pid_t pid; - /* file descriptor of the master */ - int master_fd; - /* file struct of the master */ - struct file *master_file; - /* a list of currently available regions if this is a suballocation */ - struct list_head region_list; - /* a linked list of data so we can access them for debugging */ - struct list_head list; -#if PMEM_DEBUG - int ref; -#endif -}; - -struct pmem_bits { - unsigned allocated:1; /* 1 if allocated, 0 if free */ - unsigned order:7; /* size of the region in pmem space */ -}; - -struct pmem_region_node { - struct pmem_region region; - struct list_head list; -}; - -#define PMEM_DEBUG_MSGS 0 -#if PMEM_DEBUG_MSGS -#define DLOG(fmt,args...) \ - do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ - ##args); } \ - while (0) -#else -#define DLOG(x...) do {} while (0) -#endif - -struct pmem_info { - struct miscdevice dev; - /* physical start address of the remaped pmem space */ - unsigned long base; - /* vitual start address of the remaped pmem space */ - unsigned char __iomem *vbase; - /* total size of the pmem space */ - unsigned long size; - /* number of entries in the pmem space */ - unsigned long num_entries; - /* pfn of the garbage page in memory */ - unsigned long garbage_pfn; - /* index of the garbage page in the pmem space */ - int garbage_index; - /* the bitmap for the region indicating which entries are allocated - * and which are free */ - struct pmem_bits *bitmap; - /* indicates the region should not be managed with an allocator */ - unsigned no_allocator; - /* indicates maps of this region should be cached, if a mix of - * cached and uncached is desired, set this and open the device with - * O_SYNC to get an uncached region */ - unsigned cached; - unsigned buffered; - /* in no_allocator mode the first mapper gets the whole space and sets - * this flag */ - unsigned allocated; - /* for debugging, creates a list of pmem file structs, the - * data_list_sem should be taken before pmem_data->sem if both are - * needed */ - struct semaphore data_list_sem; - struct list_head data_list; - /* pmem_sem protects the bitmap array - * a write lock should be held when modifying entries in bitmap - * a read lock should be held when reading data from bits or - * dereferencing a pointer into bitmap - * - * pmem_data->sem protects the pmem data of a particular file - * Many of the function that require the pmem_data->sem have a non- - * locking version for when the caller is already holding that sem. - * - * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER: - * down(pmem_data->sem) => down(bitmap_sem) - */ - struct rw_semaphore bitmap_sem; - - long (*ioctl)(struct file *, unsigned int, unsigned long); - int (*release)(struct inode *, struct file *); -}; - -static struct pmem_info pmem[PMEM_MAX_DEVICES]; -static int id_count; - -#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated) -#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order -#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) -#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) -#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC) -#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base) -#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC) -#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \ - PMEM_LEN(id, index)) -#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase) -#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \ - PMEM_LEN(id, index)) -#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED) -#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK))) -#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \ - (!(data->flags & PMEM_FLAGS_UNSUBMAP))) - -static int pmem_release(struct inode *, struct file *); -static int pmem_mmap(struct file *, struct vm_area_struct *); -static int pmem_open(struct inode *, struct file *); -static long pmem_ioctl(struct file *, unsigned int, unsigned long); - -struct file_operations pmem_fops = { - .release = pmem_release, - .mmap = pmem_mmap, - .open = pmem_open, - .unlocked_ioctl = pmem_ioctl, -}; - -static int get_id(struct file *file) -{ - return MINOR(file->f_dentry->d_inode->i_rdev); -} - -int is_pmem_file(struct file *file) -{ - int id; - - if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode)) - return 0; - id = get_id(file); - if (unlikely(id >= PMEM_MAX_DEVICES)) - return 0; - if (unlikely(file->f_dentry->d_inode->i_rdev != - MKDEV(MISC_MAJOR, pmem[id].dev.minor))) - return 0; - return 1; -} - -static int has_allocation(struct file *file) -{ - struct pmem_data *data; - /* check is_pmem_file first if not accessed via pmem_file_ops */ - - if (unlikely(!file->private_data)) - return 0; - data = (struct pmem_data *)file->private_data; - if (unlikely(data->index < 0)) - return 0; - return 1; -} - -static int is_master_owner(struct file *file) -{ - struct file *master_file; - struct pmem_data *data; - int put_needed, ret = 0; - - if (!is_pmem_file(file) || !has_allocation(file)) - return 0; - data = (struct pmem_data *)file->private_data; - if (PMEM_FLAGS_MASTERMAP & data->flags) - return 1; - master_file = fget_light(data->master_fd, &put_needed); - if (master_file && data->master_file == master_file) - ret = 1; - fput_light(master_file, put_needed); - return ret; -} - -static int pmem_free(int id, int index) -{ - /* caller should hold the write lock on pmem_sem! */ - int buddy, curr = index; - DLOG("index %d\n", index); - - if (pmem[id].no_allocator) { - pmem[id].allocated = 0; - return 0; - } - /* clean up the bitmap, merging any buddies */ - pmem[id].bitmap[curr].allocated = 0; - /* find a slots buddy Buddy# = Slot# ^ (1 << order) - * if the buddy is also free merge them - * repeat until the buddy is not free or end of the bitmap is reached - */ - do { - buddy = PMEM_BUDDY_INDEX(id, curr); - if (PMEM_IS_FREE(id, buddy) && - PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) { - PMEM_ORDER(id, buddy)++; - PMEM_ORDER(id, curr)++; - curr = min(buddy, curr); - } else { - break; - } - } while (curr < pmem[id].num_entries); - - return 0; -} - -static void pmem_revoke(struct file *file, struct pmem_data *data); - -static int pmem_release(struct inode *inode, struct file *file) -{ - struct pmem_data *data = (struct pmem_data *)file->private_data; - struct pmem_region_node *region_node; - struct list_head *elt, *elt2; - int id = get_id(file), ret = 0; - - - down(&pmem[id].data_list_sem); - /* if this file is a master, revoke all the memory in the connected - * files */ - if (PMEM_FLAGS_MASTERMAP & data->flags) { - struct pmem_data *sub_data; - list_for_each(elt, &pmem[id].data_list) { - sub_data = list_entry(elt, struct pmem_data, list); - down_read(&sub_data->sem); - if (PMEM_IS_SUBMAP(sub_data) && - file == sub_data->master_file) { - up_read(&sub_data->sem); - pmem_revoke(file, sub_data); - } else - up_read(&sub_data->sem); - } - } - list_del(&data->list); - up(&pmem[id].data_list_sem); - - - down_write(&data->sem); - - /* if its not a conencted file and it has an allocation, free it */ - if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) { - down_write(&pmem[id].bitmap_sem); - ret = pmem_free(id, data->index); - up_write(&pmem[id].bitmap_sem); - } - - /* if this file is a submap (mapped, connected file), downref the - * task struct */ - if (PMEM_FLAGS_SUBMAP & data->flags) - if (data->task) { - put_task_struct(data->task); - data->task = NULL; - } - - file->private_data = NULL; - - list_for_each_safe(elt, elt2, &data->region_list) { - region_node = list_entry(elt, struct pmem_region_node, list); - list_del(elt); - kfree(region_node); - } - BUG_ON(!list_empty(&data->region_list)); - - up_write(&data->sem); - kfree(data); - if (pmem[id].release) - ret = pmem[id].release(inode, file); - - return ret; -} - -static int pmem_open(struct inode *inode, struct file *file) -{ - struct pmem_data *data; - int id = get_id(file); - int ret = 0; - - DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file)); - /* setup file->private_data to indicate its unmapped */ - /* you can only open a pmem device one time */ - if (file->private_data != NULL) - return -1; - data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL); - if (!data) { - printk("pmem: unable to allocate memory for pmem metadata."); - return -1; - } - data->flags = 0; - data->index = -1; - data->task = NULL; - data->vma = NULL; - data->pid = 0; - data->master_file = NULL; -#if PMEM_DEBUG - data->ref = 0; -#endif - INIT_LIST_HEAD(&data->region_list); - init_rwsem(&data->sem); - - file->private_data = data; - INIT_LIST_HEAD(&data->list); - - down(&pmem[id].data_list_sem); - list_add(&data->list, &pmem[id].data_list); - up(&pmem[id].data_list_sem); - return ret; -} - -static unsigned long pmem_order(unsigned long len) -{ - int i; - - len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC; - len--; - for (i = 0; i < sizeof(len)*8; i++) - if (len >> i == 0) - break; - return i; -} - -static int pmem_allocate(int id, unsigned long len) -{ - /* caller should hold the write lock on pmem_sem! */ - /* return the corresponding pdata[] entry */ - int curr = 0; - int end = pmem[id].num_entries; - int best_fit = -1; - unsigned long order = pmem_order(len); - - if (pmem[id].no_allocator) { - DLOG("no allocator"); - if ((len > pmem[id].size) || pmem[id].allocated) - return -1; - pmem[id].allocated = 1; - return len; - } - - if (order > PMEM_MAX_ORDER) - return -1; - DLOG("order %lx\n", order); - - /* look through the bitmap: - * if you find a free slot of the correct order use it - * otherwise, use the best fit (smallest with size > order) slot - */ - while (curr < end) { - if (PMEM_IS_FREE(id, curr)) { - if (PMEM_ORDER(id, curr) == (unsigned char)order) { - /* set the not free bit and clear others */ - best_fit = curr; - break; - } - if (PMEM_ORDER(id, curr) > (unsigned char)order && - (best_fit < 0 || - PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit))) - best_fit = curr; - } - curr = PMEM_NEXT_INDEX(id, curr); - } - - /* if best_fit < 0, there are no suitable slots, - * return an error - */ - if (best_fit < 0) { - printk("pmem: no space left to allocate!\n"); - return -1; - } - - /* now partition the best fit: - * split the slot into 2 buddies of order - 1 - * repeat until the slot is of the correct order - */ - while (PMEM_ORDER(id, best_fit) > (unsigned char)order) { - int buddy; - PMEM_ORDER(id, best_fit) -= 1; - buddy = PMEM_BUDDY_INDEX(id, best_fit); - PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit); - } - pmem[id].bitmap[best_fit].allocated = 1; - return best_fit; -} - -static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot) -{ - int id = get_id(file); -#ifdef pgprot_noncached - if (pmem[id].cached == 0 || file->f_flags & O_SYNC) - return pgprot_noncached(vma_prot); -#endif -#ifdef pgprot_ext_buffered - else if (pmem[id].buffered) - return pgprot_ext_buffered(vma_prot); -#endif - return vma_prot; -} - -static unsigned long pmem_start_addr(int id, struct pmem_data *data) -{ - if (pmem[id].no_allocator) - return PMEM_START_ADDR(id, 0); - else - return PMEM_START_ADDR(id, data->index); - -} - -static void *pmem_start_vaddr(int id, struct pmem_data *data) -{ - return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase; -} - -static unsigned long pmem_len(int id, struct pmem_data *data) -{ - if (pmem[id].no_allocator) - return data->index; - else - return PMEM_LEN(id, data->index); -} - -static int pmem_map_garbage(int id, struct vm_area_struct *vma, - struct pmem_data *data, unsigned long offset, - unsigned long len) -{ - int i, garbage_pages = len >> PAGE_SHIFT; - - vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE; - for (i = 0; i < garbage_pages; i++) { - if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE), - pmem[id].garbage_pfn)) - return -EAGAIN; - } - return 0; -} - -static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma, - struct pmem_data *data, unsigned long offset, - unsigned long len) -{ - int garbage_pages; - DLOG("unmap offset %lx len %lx\n", offset, len); - - BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); - - garbage_pages = len >> PAGE_SHIFT; - zap_page_range(vma, vma->vm_start + offset, len, NULL); - pmem_map_garbage(id, vma, data, offset, len); - return 0; -} - -static int pmem_map_pfn_range(int id, struct vm_area_struct *vma, - struct pmem_data *data, unsigned long offset, - unsigned long len) -{ - DLOG("map offset %lx len %lx\n", offset, len); - BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start)); - BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end)); - BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); - BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset)); - - if (io_remap_pfn_range(vma, vma->vm_start + offset, - (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT, - len, vma->vm_page_prot)) { - return -EAGAIN; - } - return 0; -} - -static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma, - struct pmem_data *data, unsigned long offset, - unsigned long len) -{ - /* hold the mm semp for the vma you are modifying when you call this */ - BUG_ON(!vma); - zap_page_range(vma, vma->vm_start + offset, len, NULL); - return pmem_map_pfn_range(id, vma, data, offset, len); -} - -static void pmem_vma_open(struct vm_area_struct *vma) -{ - struct file *file = vma->vm_file; - struct pmem_data *data = file->private_data; - int id = get_id(file); - /* this should never be called as we don't support copying pmem - * ranges via fork */ - BUG_ON(!has_allocation(file)); - down_write(&data->sem); - /* remap the garbage pages, forkers don't get access to the data */ - pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end); - up_write(&data->sem); -} - -static void pmem_vma_close(struct vm_area_struct *vma) -{ - struct file *file = vma->vm_file; - struct pmem_data *data = file->private_data; - - DLOG("current %u ppid %u file %p count %d\n", current->pid, - current->parent->pid, file, file_count(file)); - if (unlikely(!is_pmem_file(file) || !has_allocation(file))) { - printk(KERN_WARNING "pmem: something is very wrong, you are " - "closing a vm backing an allocation that doesn't " - "exist!\n"); - return; - } - down_write(&data->sem); - if (data->vma == vma) { - data->vma = NULL; - if ((data->flags & PMEM_FLAGS_CONNECTED) && - (data->flags & PMEM_FLAGS_SUBMAP)) - data->flags |= PMEM_FLAGS_UNSUBMAP; - } - /* the kernel is going to free this vma now anyway */ - up_write(&data->sem); -} - -static struct vm_operations_struct vm_ops = { - .open = pmem_vma_open, - .close = pmem_vma_close, -}; - -static int pmem_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct pmem_data *data; - int index; - unsigned long vma_size = vma->vm_end - vma->vm_start; - int ret = 0, id = get_id(file); - - if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) { -#if PMEM_DEBUG - printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned" - " and a multiple of pages_size.\n"); -#endif - return -EINVAL; - } - - data = (struct pmem_data *)file->private_data; - down_write(&data->sem); - /* check this file isn't already mmaped, for submaps check this file - * has never been mmaped */ - if ((data->flags & PMEM_FLAGS_SUBMAP) || - (data->flags & PMEM_FLAGS_UNSUBMAP)) { -#if PMEM_DEBUG - printk(KERN_ERR "pmem: you can only mmap a pmem file once, " - "this file is already mmaped. %x\n", data->flags); -#endif - ret = -EINVAL; - goto error; - } - /* if file->private_data == unalloced, alloc*/ - if (data && data->index == -1) { - down_write(&pmem[id].bitmap_sem); - index = pmem_allocate(id, vma->vm_end - vma->vm_start); - up_write(&pmem[id].bitmap_sem); - data->index = index; - } - /* either no space was available or an error occured */ - if (!has_allocation(file)) { - ret = -EINVAL; - printk("pmem: could not find allocation for map.\n"); - goto error; - } - - if (pmem_len(id, data) < vma_size) { -#if PMEM_DEBUG - printk(KERN_WARNING "pmem: mmap size [%lu] does not match" - "size of backing region [%lu].\n", vma_size, - pmem_len(id, data)); -#endif - ret = -EINVAL; - goto error; - } - - vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT; - vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot); - - if (data->flags & PMEM_FLAGS_CONNECTED) { - struct pmem_region_node *region_node; - struct list_head *elt; - if (pmem_map_garbage(id, vma, data, 0, vma_size)) { - printk("pmem: mmap failed in kernel!\n"); - ret = -EAGAIN; - goto error; - } - list_for_each(elt, &data->region_list) { - region_node = list_entry(elt, struct pmem_region_node, - list); - DLOG("remapping file: %p %lx %lx\n", file, - region_node->region.offset, - region_node->region.len); - if (pmem_remap_pfn_range(id, vma, data, - region_node->region.offset, - region_node->region.len)) { - ret = -EAGAIN; - goto error; - } - } - data->flags |= PMEM_FLAGS_SUBMAP; - get_task_struct(current->group_leader); - data->task = current->group_leader; - data->vma = vma; -#if PMEM_DEBUG - data->pid = current->pid; -#endif - DLOG("submmapped file %p vma %p pid %u\n", file, vma, - current->pid); - } else { - if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) { - printk(KERN_INFO "pmem: mmap failed in kernel!\n"); - ret = -EAGAIN; - goto error; - } - data->flags |= PMEM_FLAGS_MASTERMAP; - data->pid = current->pid; - } - vma->vm_ops = &vm_ops; -error: - up_write(&data->sem); - return ret; -} - -/* the following are the api for accessing pmem regions by other drivers - * from inside the kernel */ -int get_pmem_user_addr(struct file *file, unsigned long *start, - unsigned long *len) -{ - struct pmem_data *data; - if (!is_pmem_file(file) || !has_allocation(file)) { -#if PMEM_DEBUG - printk(KERN_INFO "pmem: requested pmem data from invalid" - "file.\n"); -#endif - return -1; - } - data = (struct pmem_data *)file->private_data; - down_read(&data->sem); - if (data->vma) { - *start = data->vma->vm_start; - *len = data->vma->vm_end - data->vma->vm_start; - } else { - *start = 0; - *len = 0; - } - up_read(&data->sem); - return 0; -} - -int get_pmem_addr(struct file *file, unsigned long *start, - unsigned long *vstart, unsigned long *len) -{ - struct pmem_data *data; - int id; - - if (!is_pmem_file(file) || !has_allocation(file)) { - return -1; - } - - data = (struct pmem_data *)file->private_data; - if (data->index == -1) { -#if PMEM_DEBUG - printk(KERN_INFO "pmem: requested pmem data from file with no " - "allocation.\n"); - return -1; -#endif - } - id = get_id(file); - - down_read(&data->sem); - *start = pmem_start_addr(id, data); - *len = pmem_len(id, data); - *vstart = (unsigned long)pmem_start_vaddr(id, data); - up_read(&data->sem); -#if PMEM_DEBUG - down_write(&data->sem); - data->ref++; - up_write(&data->sem); -#endif - return 0; -} - -int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, - unsigned long *len, struct file **filp) -{ - struct file *file; - - file = fget(fd); - if (unlikely(file == NULL)) { - printk(KERN_INFO "pmem: requested data from file descriptor " - "that doesn't exist."); - return -1; - } - - if (get_pmem_addr(file, start, vstart, len)) - goto end; - - if (filp) - *filp = file; - return 0; -end: - fput(file); - return -1; -} - -void put_pmem_file(struct file *file) -{ - struct pmem_data *data; - int id; - - if (!is_pmem_file(file)) - return; - id = get_id(file); - data = (struct pmem_data *)file->private_data; -#if PMEM_DEBUG - down_write(&data->sem); - if (data->ref == 0) { - printk("pmem: pmem_put > pmem_get %s (pid %d)\n", - pmem[id].dev.name, data->pid); - BUG(); - } - data->ref--; - up_write(&data->sem); -#endif - fput(file); -} - -void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len) -{ - struct pmem_data *data; - int id; - void *vaddr; - struct pmem_region_node *region_node; - struct list_head *elt; - void *flush_start, *flush_end; - - if (!is_pmem_file(file) || !has_allocation(file)) { - return; - } - - id = get_id(file); - data = (struct pmem_data *)file->private_data; - if (!pmem[id].cached || file->f_flags & O_SYNC) - return; - - down_read(&data->sem); - vaddr = pmem_start_vaddr(id, data); - /* if this isn't a submmapped file, flush the whole thing */ - if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) { - dmac_flush_range(vaddr, vaddr + pmem_len(id, data)); - goto end; - } - /* otherwise, flush the region of the file we are drawing */ - list_for_each(elt, &data->region_list) { - region_node = list_entry(elt, struct pmem_region_node, list); - if ((offset >= region_node->region.offset) && - ((offset + len) <= (region_node->region.offset + - region_node->region.len))) { - flush_start = vaddr + region_node->region.offset; - flush_end = flush_start + region_node->region.len; - dmac_flush_range(flush_start, flush_end); - break; - } - } -end: - up_read(&data->sem); -} - -static int pmem_connect(unsigned long connect, struct file *file) -{ - struct pmem_data *data = (struct pmem_data *)file->private_data; - struct pmem_data *src_data; - struct file *src_file; - int ret = 0, put_needed; - - down_write(&data->sem); - /* retrieve the src file and check it is a pmem file with an alloc */ - src_file = fget_light(connect, &put_needed); - DLOG("connect %p to %p\n", file, src_file); - if (!src_file) { - printk("pmem: src file not found!\n"); - ret = -EINVAL; - goto err_no_file; - } - if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) { - printk(KERN_INFO "pmem: src file is not a pmem file or has no " - "alloc!\n"); - ret = -EINVAL; - goto err_bad_file; - } - src_data = (struct pmem_data *)src_file->private_data; - - if (has_allocation(file) && (data->index != src_data->index)) { - printk("pmem: file is already mapped but doesn't match this" - " src_file!\n"); - ret = -EINVAL; - goto err_bad_file; - } - data->index = src_data->index; - data->flags |= PMEM_FLAGS_CONNECTED; - data->master_fd = connect; - data->master_file = src_file; - -err_bad_file: - fput_light(src_file, put_needed); -err_no_file: - up_write(&data->sem); - return ret; -} - -static void pmem_unlock_data_and_mm(struct pmem_data *data, - struct mm_struct *mm) -{ - up_write(&data->sem); - if (mm != NULL) { - up_write(&mm->mmap_sem); - mmput(mm); - } -} - -static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data, - struct mm_struct **locked_mm) -{ - int ret = 0; - struct mm_struct *mm = NULL; - *locked_mm = NULL; -lock_mm: - down_read(&data->sem); - if (PMEM_IS_SUBMAP(data)) { - mm = get_task_mm(data->task); - if (!mm) { -#if PMEM_DEBUG - printk("pmem: can't remap task is gone!\n"); -#endif - up_read(&data->sem); - return -1; - } - } - up_read(&data->sem); - - if (mm) - down_write(&mm->mmap_sem); - - down_write(&data->sem); - /* check that the file didn't get mmaped before we could take the - * data sem, this should be safe b/c you can only submap each file - * once */ - if (PMEM_IS_SUBMAP(data) && !mm) { - pmem_unlock_data_and_mm(data, mm); - up_write(&data->sem); - goto lock_mm; - } - /* now check that vma.mm is still there, it could have been - * deleted by vma_close before we could get the data->sem */ - if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) { - /* might as well release this */ - if (data->flags & PMEM_FLAGS_SUBMAP) { - put_task_struct(data->task); - data->task = NULL; - /* lower the submap flag to show the mm is gone */ - data->flags &= ~(PMEM_FLAGS_SUBMAP); - } - pmem_unlock_data_and_mm(data, mm); - return -1; - } - *locked_mm = mm; - return ret; -} - -int pmem_remap(struct pmem_region *region, struct file *file, - unsigned operation) -{ - int ret; - struct pmem_region_node *region_node; - struct mm_struct *mm = NULL; - struct list_head *elt, *elt2; - int id = get_id(file); - struct pmem_data *data = (struct pmem_data *)file->private_data; - - /* pmem region must be aligned on a page boundry */ - if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || - !PMEM_IS_PAGE_ALIGNED(region->len))) { -#if PMEM_DEBUG - printk("pmem: request for unaligned pmem suballocation " - "%lx %lx\n", region->offset, region->len); -#endif - return -EINVAL; - } - - /* if userspace requests a region of len 0, there's nothing to do */ - if (region->len == 0) - return 0; - - /* lock the mm and data */ - ret = pmem_lock_data_and_mm(file, data, &mm); - if (ret) - return 0; - - /* only the owner of the master file can remap the client fds - * that back in it */ - if (!is_master_owner(file)) { -#if PMEM_DEBUG - printk("pmem: remap requested from non-master process\n"); -#endif - ret = -EINVAL; - goto err; - } - - /* check that the requested range is within the src allocation */ - if (unlikely((region->offset > pmem_len(id, data)) || - (region->len > pmem_len(id, data)) || - (region->offset + region->len > pmem_len(id, data)))) { -#if PMEM_DEBUG - printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n"); -#endif - ret = -EINVAL; - goto err; - } - - if (operation == PMEM_MAP) { - region_node = kmalloc(sizeof(struct pmem_region_node), - GFP_KERNEL); - if (!region_node) { - ret = -ENOMEM; -#if PMEM_DEBUG - printk(KERN_INFO "No space to allocate metadata!"); -#endif - goto err; - } - region_node->region = *region; - list_add(®ion_node->list, &data->region_list); - } else if (operation == PMEM_UNMAP) { - int found = 0; - list_for_each_safe(elt, elt2, &data->region_list) { - region_node = list_entry(elt, struct pmem_region_node, - list); - if (region->len == 0 || - (region_node->region.offset == region->offset && - region_node->region.len == region->len)) { - list_del(elt); - kfree(region_node); - found = 1; - } - } - if (!found) { -#if PMEM_DEBUG - printk("pmem: Unmap region does not map any mapped " - "region!"); -#endif - ret = -EINVAL; - goto err; - } - } - - if (data->vma && PMEM_IS_SUBMAP(data)) { - if (operation == PMEM_MAP) - ret = pmem_remap_pfn_range(id, data->vma, data, - region->offset, region->len); - else if (operation == PMEM_UNMAP) - ret = pmem_unmap_pfn_range(id, data->vma, data, - region->offset, region->len); - } - -err: - pmem_unlock_data_and_mm(data, mm); - return ret; -} - -static void pmem_revoke(struct file *file, struct pmem_data *data) -{ - struct pmem_region_node *region_node; - struct list_head *elt, *elt2; - struct mm_struct *mm = NULL; - int id = get_id(file); - int ret = 0; - - data->master_file = NULL; - ret = pmem_lock_data_and_mm(file, data, &mm); - /* if lock_data_and_mm fails either the task that mapped the fd, or - * the vma that mapped it have already gone away, nothing more - * needs to be done */ - if (ret) - return; - /* unmap everything */ - /* delete the regions and region list nothing is mapped any more */ - if (data->vma) - list_for_each_safe(elt, elt2, &data->region_list) { - region_node = list_entry(elt, struct pmem_region_node, - list); - pmem_unmap_pfn_range(id, data->vma, data, - region_node->region.offset, - region_node->region.len); - list_del(elt); - kfree(region_node); - } - /* delete the master file */ - pmem_unlock_data_and_mm(data, mm); -} - -static void pmem_get_size(struct pmem_region *region, struct file *file) -{ - struct pmem_data *data = (struct pmem_data *)file->private_data; - int id = get_id(file); - - if (!has_allocation(file)) { - region->offset = 0; - region->len = 0; - return; - } else { - region->offset = pmem_start_addr(id, data); - region->len = pmem_len(id, data); - } - DLOG("offset %lx len %lx\n", region->offset, region->len); -} - - -static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct pmem_data *data; - int id = get_id(file); - - switch (cmd) { - case PMEM_GET_PHYS: - { - struct pmem_region region; - DLOG("get_phys\n"); - if (!has_allocation(file)) { - region.offset = 0; - region.len = 0; - } else { - data = (struct pmem_data *)file->private_data; - region.offset = pmem_start_addr(id, data); - region.len = pmem_len(id, data); - } - printk(KERN_INFO "pmem: request for physical address of pmem region " - "from process %d.\n", current->pid); - if (copy_to_user((void __user *)arg, ®ion, - sizeof(struct pmem_region))) - return -EFAULT; - break; - } - case PMEM_MAP: - { - struct pmem_region region; - if (copy_from_user(®ion, (void __user *)arg, - sizeof(struct pmem_region))) - return -EFAULT; - data = (struct pmem_data *)file->private_data; - return pmem_remap(®ion, file, PMEM_MAP); - } - break; - case PMEM_UNMAP: - { - struct pmem_region region; - if (copy_from_user(®ion, (void __user *)arg, - sizeof(struct pmem_region))) - return -EFAULT; - data = (struct pmem_data *)file->private_data; - return pmem_remap(®ion, file, PMEM_UNMAP); - break; - } - case PMEM_GET_SIZE: - { - struct pmem_region region; - DLOG("get_size\n"); - pmem_get_size(®ion, file); - if (copy_to_user((void __user *)arg, ®ion, - sizeof(struct pmem_region))) - return -EFAULT; - break; - } - case PMEM_GET_TOTAL_SIZE: - { - struct pmem_region region; - DLOG("get total size\n"); - region.offset = 0; - get_id(file); - region.len = pmem[id].size; - if (copy_to_user((void __user *)arg, ®ion, - sizeof(struct pmem_region))) - return -EFAULT; - break; - } - case PMEM_ALLOCATE: - { - if (has_allocation(file)) - return -EINVAL; - data = (struct pmem_data *)file->private_data; - data->index = pmem_allocate(id, arg); - break; - } - case PMEM_CONNECT: - DLOG("connect\n"); - return pmem_connect(arg, file); - break; - case PMEM_CACHE_FLUSH: - { - struct pmem_region region; - DLOG("flush\n"); - if (copy_from_user(®ion, (void __user *)arg, - sizeof(struct pmem_region))) - return -EFAULT; - flush_pmem_file(file, region.offset, region.len); - break; - } - default: - if (pmem[id].ioctl) - return pmem[id].ioctl(file, cmd, arg); - return -EINVAL; - } - return 0; -} - -#if PMEM_DEBUG -static ssize_t debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t debug_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - struct list_head *elt, *elt2; - struct pmem_data *data; - struct pmem_region_node *region_node; - int id = (int)file->private_data; - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - - DLOG("debug open\n"); - n = scnprintf(buffer, debug_bufmax, - "pid #: mapped regions (offset, len) (offset,len)...\n"); - - down(&pmem[id].data_list_sem); - list_for_each(elt, &pmem[id].data_list) { - data = list_entry(elt, struct pmem_data, list); - down_read(&data->sem); - n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:", - data->pid); - list_for_each(elt2, &data->region_list) { - region_node = list_entry(elt2, struct pmem_region_node, - list); - n += scnprintf(buffer + n, debug_bufmax - n, - "(%lx,%lx) ", - region_node->region.offset, - region_node->region.len); - } - n += scnprintf(buffer + n, debug_bufmax - n, "\n"); - up_read(&data->sem); - } - up(&pmem[id].data_list_sem); - - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static struct file_operations debug_fops = { - .read = debug_read, - .open = debug_open, -}; -#endif - -#if 0 -static struct miscdevice pmem_dev = { - .name = "pmem", - .fops = &pmem_fops, -}; -#endif - -int pmem_setup(struct android_pmem_platform_data *pdata, - long (*ioctl)(struct file *, unsigned int, unsigned long), - int (*release)(struct inode *, struct file *)) -{ - int err = 0; - int i, index = 0; - int id = id_count; - id_count++; - - pmem[id].no_allocator = pdata->no_allocator; - pmem[id].cached = pdata->cached; - pmem[id].buffered = pdata->buffered; - pmem[id].base = pdata->start; - pmem[id].size = pdata->size; - pmem[id].ioctl = ioctl; - pmem[id].release = release; - init_rwsem(&pmem[id].bitmap_sem); - init_MUTEX(&pmem[id].data_list_sem); - INIT_LIST_HEAD(&pmem[id].data_list); - pmem[id].dev.name = pdata->name; - pmem[id].dev.minor = id; - pmem[id].dev.fops = &pmem_fops; - printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached); - - err = misc_register(&pmem[id].dev); - if (err) { - printk(KERN_ALERT "Unable to register pmem driver!\n"); - goto err_cant_register_device; - } - pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC; - - pmem[id].bitmap = kmalloc(pmem[id].num_entries * - sizeof(struct pmem_bits), GFP_KERNEL); - if (!pmem[id].bitmap) - goto err_no_mem_for_metadata; - - memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) * - pmem[id].num_entries); - - for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) { - if ((pmem[id].num_entries) & 1<name, S_IFREG | S_IRUGO, NULL, (void *)id, - &debug_fops); -#endif - return 0; -error_cant_remap: - kfree(pmem[id].bitmap); -err_no_mem_for_metadata: - misc_deregister(&pmem[id].dev); -err_cant_register_device: - return -1; -} - -static int pmem_probe(struct platform_device *pdev) -{ - struct android_pmem_platform_data *pdata; - - if (!pdev || !pdev->dev.platform_data) { - printk(KERN_ALERT "Unable to probe pmem!\n"); - return -1; - } - pdata = pdev->dev.platform_data; - return pmem_setup(pdata, NULL, NULL); -} - - -static int pmem_remove(struct platform_device *pdev) -{ - int id = pdev->id; - __free_page(pfn_to_page(pmem[id].garbage_pfn)); - misc_deregister(&pmem[id].dev); - return 0; -} - -static struct platform_driver pmem_driver = { - .probe = pmem_probe, - .remove = pmem_remove, - .driver = { .name = "android_pmem" } -}; - - -static int __init pmem_init(void) -{ - return platform_driver_register(&pmem_driver); -} - -static void __exit pmem_exit(void) -{ - platform_driver_unregister(&pmem_driver); -} - -module_init(pmem_init); -module_exit(pmem_exit); - diff --git a/drivers/misc/radio_ctrl/Kconfig b/drivers/misc/radio_ctrl/Kconfig deleted file mode 100644 index c2f64b70745f..000000000000 --- a/drivers/misc/radio_ctrl/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -config RADIO_CTRL_CLASS - bool "Radio Modem Controller Class" - default n - -config MDM6600_CTRL - bool "Motorola MDM6X00 Modem Controller" - default n - select RADIO_CTRL_CLASS - ---help--- - Enables the device driver to control and interface with - the modem co-processor. This module is needed to monitor - modem panics, interact with the modem during factory resets, - and allow modem power up/down support. - - If unsure, say N. - -config WRIGLEY_CTRL - bool "Motorola Wrigley Modem Controller" - default n - select RADIO_CTRL_CLASS - ---help--- - Enables the device driver to control and interface with - the Wrigley modem co-processor. This module is needed to monitor - modem panics, interact with the modem during factory resets, - and allow modem power up/down support. - - If unsure, say N. diff --git a/drivers/misc/radio_ctrl/Makefile b/drivers/misc/radio_ctrl/Makefile deleted file mode 100644 index b8f863f3559d..000000000000 --- a/drivers/misc/radio_ctrl/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for modem (radio) control drivers -# - -obj-$(CONFIG_RADIO_CTRL_CLASS) += radio_class.o -obj-$(CONFIG_MDM6600_CTRL) += mdm6600_ctrl.o -obj-$(CONFIG_WRIGLEY_CTRL) += wrigley_ctrl.o diff --git a/drivers/misc/radio_ctrl/mdm6600_ctrl.c b/drivers/misc/radio_ctrl/mdm6600_ctrl.c deleted file mode 100644 index dd0ac242533d..000000000000 --- a/drivers/misc/radio_ctrl/mdm6600_ctrl.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - Copyright (C) 2010 Motorola, 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AP_STATUS_BP_PANIC_ACK 0x00 -#define AP_STATUS_DATA_ONLY_BYPASS 0x01 -#define AP_STATUS_FULL_BYPASS 0x02 -#define AP_STATUS_NO_BYPASS 0x03 -#define AP_STATUS_BP_SHUTDOWN_REQ 0x04 -#define AP_STATUS_UNDEFINED 0x07 - -#define BP_STATUS_PANIC 0x00 -#define BP_STATUS_PANIC_BUSY_WAIT 0x01 -#define BP_STATUS_QC_DLOAD 0x02 -#define BP_STATUS_RAM_DOWNLOADER 0x03 -#define BP_STATUS_PHONE_CODE_AWAKE 0x04 -#define BP_STATUS_PHONE_CODE_ASLEEP 0x05 -#define BP_STATUS_SHUTDOWN_ACK 0x06 -#define BP_STATUS_UNDEFINED 0x07 - - -#define LOOP_DELAY_TIME_MS 500 - -static const char *mdmctrl = "mdm6600_ctrl"; - -static const char *bp_status[8] = { - [BP_STATUS_PANIC] = "panic", - [BP_STATUS_PANIC_BUSY_WAIT] = "panic busy wait", - [BP_STATUS_QC_DLOAD] = "qc dload", - [BP_STATUS_RAM_DOWNLOADER] = "ram downloader", - [BP_STATUS_PHONE_CODE_AWAKE] = "awake", - [BP_STATUS_PHONE_CODE_ASLEEP] = "asleep", - [BP_STATUS_SHUTDOWN_ACK] = "shutdown ack", - [BP_STATUS_UNDEFINED] = "undefined", -}; - -static const char *bp_power_state[2] = { - "off", - "on", -}; - -#define BP_STATUS_MAX_LENGTH 32 -#define BP_COMMAND_MAX_LENGTH 32 - -/* structure to keep track of gpio, irq, and irq enabled info */ -struct gpio_info { - int irq; - struct work_struct work; -}; - -struct mdm_ctrl_info { - struct mdm_ctrl_platform_data *pdata; - struct gpio_info gpios[MDM_CTRL_NUM_GPIOS]; -}; - -static struct mdm_ctrl_info mdm_ctrl; - -static DEFINE_MUTEX(mdm_ctrl_info_lock); - -struct workqueue_struct *working_queue = NULL; - -struct class *radio_cls = NULL; -static struct radio_dev radio_cdev; - -static unsigned int bp_status_idx = BP_STATUS_UNDEFINED; -static unsigned int bp_power_idx = 0; - -static void __devexit mdm_ctrl_shutdown(struct platform_device *pdev); -static void mdm_ctrl_powerup(void); -static void mdm_ctrl_set_bootmode(int mode); -static void mdm_ctrl_dump_log(void); - -static const char *bp_status_string(unsigned int stat) -{ - if (stat < ARRAY_SIZE(bp_status)) - return bp_status[stat]; - else - return "status out of range"; -} - -static const char *bp_power_state_string(unsigned int stat) -{ - if (stat < ARRAY_SIZE(bp_power_state)) - return bp_power_state[stat]; - else - return "status out of range"; -} - -static ssize_t mdm_status_show(struct radio_dev *dev, char *buff) -{ - ssize_t status = 0; - status = snprintf(buff, BP_STATUS_MAX_LENGTH, "%s\n", - bp_status_string(bp_status_idx)); - - return status; -} - -static ssize_t mdm_power_show(struct radio_dev *rdev, char *buff) -{ - ssize_t status = 0; - status = snprintf(buff, BP_STATUS_MAX_LENGTH, "%s\n", - bp_power_state_string(bp_power_idx)); - - return status; -} - -static ssize_t mdm_user_command(struct radio_dev *rdev, char *post_strip) -{ - - pr_info("%s: user command = %s\n", mdmctrl, post_strip); - - if (strcmp(post_strip,"shutdown") == 0) { - mdm_ctrl_shutdown(NULL); - } else if (strcmp(post_strip,"powerup") == 0) { - mdm_ctrl_powerup(); - } else if (strcmp(post_strip,"bootmode_normal") == 0) { - mdm_ctrl_set_bootmode(0); - } else if (strcmp(post_strip,"bootmode_flash") == 0) { - mdm_ctrl_set_bootmode(1); - } else if (strcmp(post_strip,"dump_log") == 0) { - mdm_ctrl_dump_log(); - } else { - return -EINVAL; - } - - return 0; -} - -static unsigned int mdm_gpio_get_value(struct mdm_ctrl_gpio gpio) -{ - return gpio_get_value(gpio.number); -} - -static void mdm_gpio_set_value(struct mdm_ctrl_gpio gpio, - unsigned int value) -{ - gpio_set_value(gpio.number, value); -} - -static void mdm_gpio_free(struct mdm_ctrl_gpio *gpio) -{ - if (gpio->allocated) - gpio_free(gpio->number); - gpio->allocated = 0; -} - -static int mdm_gpio_setup(struct mdm_ctrl_gpio *gpio) -{ - if (gpio_request(gpio->number, gpio->name)) { - printk(KERN_ERR "failed to aquire gpio %s", gpio->name); - return -1; - } - gpio->allocated = 1; - gpio_export(gpio->number, false); - if (gpio->direction == MDM_GPIO_DIRECTION_IN) - gpio_direction_input(gpio->number); - else if (gpio->direction == MDM_GPIO_DIRECTION_OUT) - gpio_direction_output(gpio->number, gpio->default_value); - return 0; -} - -static unsigned int get_bp_status(void) -{ - unsigned int status = BP_STATUS_UNDEFINED; - unsigned int bp_status[3] = {0}; - - mutex_lock(&mdm_ctrl_info_lock); - if (mdm_ctrl.pdata) { - bp_status[0] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_STATUS_0]); - bp_status[1] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_STATUS_1]); - bp_status[2] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_STATUS_2]); - } - mutex_unlock(&mdm_ctrl_info_lock); - - status = ((bp_status[2] & 0x1) << 2) | - ((bp_status[1] & 0x1) << 1) | - (bp_status[0] & 0x1); - - return status; -} - -static unsigned int get_bp_power_status(void) -{ - unsigned int status = 0; - - mutex_lock(&mdm_ctrl_info_lock); - if (mdm_ctrl.pdata) { - status = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_RESOUT]); - } - - mutex_unlock(&mdm_ctrl_info_lock); - - return status & 0x1; -} - -static unsigned int get_ap_status(void) -{ - unsigned int status = AP_STATUS_UNDEFINED; - unsigned int ap_status[3] = {0}; - - mutex_lock(&mdm_ctrl_info_lock); - if (mdm_ctrl.pdata) { - ap_status[0] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_0]); - ap_status[1] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_1]); - ap_status[2] = mdm_gpio_get_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_2]); - } - mutex_unlock(&mdm_ctrl_info_lock); - - status = ((ap_status[2] & 0x1) << 2) | - ((ap_status[1] & 0x1) << 1) | - (ap_status[0] & 0x1); - - return status; -} - -static void set_ap_status(unsigned int status) -{ - mutex_lock(&mdm_ctrl_info_lock); - if (mdm_ctrl.pdata) { - mdm_gpio_set_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_0], - (status & 0x1)); - mdm_gpio_set_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_1], - (status >> 1) & 0x1); - mdm_gpio_set_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_AP_STATUS_2], - (status >> 2) & 0x1); - } - mutex_unlock(&mdm_ctrl_info_lock); -} - -static void set_bp_pwron(int on) -{ - mutex_lock(&mdm_ctrl_info_lock); - if ((mdm_ctrl.pdata) && ((on == 1) || (on == 0))) { - mdm_gpio_set_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_PWRON], - on); - } - mutex_unlock(&mdm_ctrl_info_lock); -} - -static void set_bp_resin(int on) -{ - mutex_lock(&mdm_ctrl_info_lock); - if ((mdm_ctrl.pdata) && ((on == 1) || (on == 0))) { - mdm_gpio_set_value( - mdm_ctrl.pdata->gpios[MDM_CTRL_GPIO_BP_RESIN], - on); - } - mutex_unlock(&mdm_ctrl_info_lock); -} - -static void update_bp_status(void) { - - static int bp_status_prev_idx = BP_STATUS_UNDEFINED; - - bp_status_prev_idx = bp_status_idx; - bp_status_idx = get_bp_status(); - bp_power_idx = get_bp_power_status(); - - pr_info("%s: modem status: %s -> %s [power %s]", mdmctrl, - bp_status_string(bp_status_prev_idx), - bp_status_string(bp_status_idx), - bp_power_state_string(bp_power_idx)); - - kobject_uevent(&radio_cdev.dev->kobj, KOBJ_CHANGE); -} - -static void mdm_ctrl_powerup(void) -{ - unsigned int bp_status; - - pr_info("%s: Starting up modem.", mdmctrl); - - bp_status = get_bp_status(); - pr_info("%s: Initial Modem status %s [0x%x]", - mdmctrl, bp_status_string(bp_status), bp_status); - - set_ap_status(AP_STATUS_NO_BYPASS); - pr_info("%s: ap_status set to %d", mdmctrl, get_ap_status()); - msleep(100); - set_bp_resin(0); - msleep(100); - /* Toggle the power, delaying to allow modem to respond */ - set_bp_pwron(1); - msleep(100); - set_bp_pwron(0); - - /* now let user handles bp status change through uevent */ -} - -static void mdm_ctrl_set_bootmode(int mode) -{ - mutex_lock(&mdm_ctrl_info_lock); - if (mdm_ctrl.pdata && ((mode == 0) || (mode == 1))) { - gpio_request(mdm_ctrl.pdata->cmd_gpios.cmd1, - "BP Command 1"); - gpio_direction_output(mdm_ctrl.pdata->cmd_gpios.cmd1, - mode); - gpio_request(mdm_ctrl.pdata->cmd_gpios.cmd2, - "BP Command 2"); - gpio_direction_output(mdm_ctrl.pdata->cmd_gpios.cmd2, - mode); - - } - mutex_unlock(&mdm_ctrl_info_lock); -} - -static void irq_worker(struct work_struct *work) -{ - struct gpio_info *gpio = container_of(work, struct gpio_info, work); - update_bp_status(); - enable_irq(gpio->irq); -} - -static irqreturn_t irq_handler(int irq, void *data) -{ - struct gpio_info *gpio = (struct gpio_info *) data; - - disable_irq_nosync(irq); - queue_work(working_queue, &gpio->work); - - return IRQ_HANDLED; -} - -static int mdm_gpio_setup_internal(struct mdm_ctrl_platform_data *pdata) -{ - int i; - int rv = 0; - struct gpio_info *gpio_data = NULL; - - mutex_lock(&mdm_ctrl_info_lock); - memset(&mdm_ctrl, 0, sizeof (mdm_ctrl)); - - mdm_ctrl.pdata = pdata; - - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) { - gpio_data = &mdm_ctrl.gpios[i]; - if (pdata->gpios[i].direction == MDM_GPIO_DIRECTION_IN) { - INIT_WORK(&gpio_data->work, irq_worker); - gpio_data->irq = gpio_to_irq(pdata->gpios[i].number); - rv = request_irq(gpio_data->irq, irq_handler, - IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING, - pdata->gpios[i].name, gpio_data); - if (rv < 0) { - pr_err("%s: Cannot request IRQ (%d) from kernel!", - mdmctrl, gpio_data->irq); - } else { - enable_irq_wake(gpio_data->irq); - } - } - } - - mutex_unlock(&mdm_ctrl_info_lock); - return rv; -} - -static void mdm_gpio_cleanup_internal(void) -{ - int i; - struct gpio_info *gpio_data = NULL; - - mutex_lock(&mdm_ctrl_info_lock); - - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) { - gpio_data = &mdm_ctrl.gpios[i]; - - if (gpio_data->irq) { - disable_irq_wake(gpio_data->irq); - free_irq(gpio_data->irq, gpio_data); - } - } - memset(&mdm_ctrl, 0, sizeof (mdm_ctrl)); - mutex_unlock(&mdm_ctrl_info_lock); -} - -static struct radio_dev radio_cdev = { - .name = "mdm6600", - .power_status = mdm_power_show, - .status = mdm_status_show, - .command = mdm_user_command, -}; - -static int __devinit mdm_ctrl_probe(struct platform_device *pdev) -{ - int i; - struct mdm_ctrl_platform_data *pdata = pdev->dev.platform_data; - - dev_info(&pdev->dev, "mdm_ctrl_probe"); - - pr_debug("%s: radio_cdev = %p\n", __func__, &radio_cdev); - - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) { - if (mdm_gpio_setup(&pdata->gpios[i])) { - dev_err(&pdev->dev, "failed to aquire gpio %d\n", - pdata->gpios[i].number); - goto probe_cleanup; - } - } - - working_queue = create_singlethread_workqueue("mdm_ctrl_wq"); - if (!working_queue) { - dev_err(&pdev->dev, "Cannot create work queue."); - goto probe_err; - } - - if (mdm_gpio_setup_internal(pdata) < 0) { - dev_err(&pdev->dev, "Failed to setup bp status irq"); - goto err_setup; - } - - if (radio_dev_register(&radio_cdev)) { - pr_err("%s: failed to register mdm_ctr device\n", __func__); - goto err_setup; - } - - update_bp_status(); - - return 0; - -err_setup: - mdm_gpio_cleanup_internal(); - -probe_err: - destroy_workqueue(working_queue); - -probe_cleanup: - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) - mdm_gpio_free(&pdata->gpios[i]); - - return -1; -} - -static int __devexit mdm_ctrl_remove(struct platform_device *pdev) -{ - int i; - struct mdm_ctrl_platform_data *pdata = pdev->dev.platform_data; - - dev_info(&pdev->dev, "cleanup\n"); - - radio_dev_unregister(&radio_cdev); - - mdm_gpio_cleanup_internal(); - - if (working_queue) - destroy_workqueue(working_queue); - - for (i = 0; i < MDM_CTRL_NUM_GPIOS; i++) - mdm_gpio_free(&pdata->gpios[i]); - - return 0; -} - -static unsigned int __devexit bp_shutdown_wait(unsigned int delay_sec) -{ - unsigned int i, loop_count; - unsigned int bp_status; - unsigned int gpio_value; - unsigned int pd_failure = 1; - - loop_count = (delay_sec * 1000) / LOOP_DELAY_TIME_MS; - - for (i = 0; i < loop_count; i++) { - msleep(LOOP_DELAY_TIME_MS); - bp_status = get_bp_status(); - if (bp_status == BP_STATUS_SHUTDOWN_ACK) { - pr_info("%s: Modem powered off (with ack).", mdmctrl); - pd_failure = 0; - break; - } - - gpio_value = get_bp_power_status(); - - if (gpio_value == 0) { - pr_info("%s: Modem powered off.", mdmctrl); - pd_failure = 0; - break; - } - } - return pd_failure; -} - -static void __devexit mdm_ctrl_shutdown(struct platform_device *pdev) -{ - unsigned int pd_failure; - unsigned int bp_status; - - pr_info("%s: Shutting down modem.", mdmctrl); - - bp_status = get_bp_status(); - pr_info("%s: Initial Modem status %s [0x%x]", - mdmctrl, bp_status_string(bp_status), bp_status); - - set_ap_status(AP_STATUS_BP_SHUTDOWN_REQ); - - /* Allow modem to process status */ - msleep(100); - pr_info("%s: ap_status set to %d", mdmctrl, get_ap_status()); - - /* Assert PWRON to tell modem to shutdown and leave pin asserted */ - /* until acknowledged or wait times out */ - set_bp_pwron(1); - msleep(100); - - /* This should be enough to power down the modem */ - /* if this doesn't work, reset the modem and try */ - /* one more time, ultimately the modem will be */ - /* hard powered off */ - pd_failure = bp_shutdown_wait(5); - set_bp_pwron(0); - if (pd_failure) { - pr_info("%s: Resetting unresponsive modem.", mdmctrl); - set_bp_resin(1); - pd_failure = bp_shutdown_wait(5); - } - - if (pd_failure) - pr_err("%s: Modem failed to power down.", mdmctrl); -} - -static void mdm_ctrl_dump_log(void) -{ - pr_info("%s: Dumping modem log", mdmctrl); - - /* To implement the dump, the BP expects BP_PWRON to be asserted - * while the AP status pins remain normal. - */ - set_bp_pwron(1); - msleep(100); - set_bp_pwron(0); - - /* Allow enough time for the log to dump fully to EFS on the BP, - * so that users of this don't have to wait themselves. - */ - msleep(500); -} - -static struct platform_driver mdm6x00_ctrl_driver = { - .probe = mdm_ctrl_probe, - .remove = __devexit_p(mdm_ctrl_remove), - .shutdown = __devexit_p(mdm_ctrl_shutdown), - .driver = { - .name = MDM_CTRL_MODULE_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init mdm6600_ctrl_init(void) -{ - printk(KERN_DEBUG "mdm6600_ctrl_init\n"); - return platform_driver_register(&mdm6x00_ctrl_driver); -} - -static void __exit mdm6600_ctrl_exit(void) -{ - printk(KERN_DEBUG "mdm6600_ctrl_exit\n"); - platform_driver_unregister(&mdm6x00_ctrl_driver); -} - -module_init(mdm6600_ctrl_init); -module_exit(mdm6600_ctrl_exit); - -MODULE_AUTHOR("Motorola"); -MODULE_DESCRIPTION("MDM6X00 Control Driver"); -MODULE_VERSION("1.1.4"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/radio_ctrl/radio_class.c b/drivers/misc/radio_ctrl/radio_class.c deleted file mode 100644 index 33a9adac8236..000000000000 --- a/drivers/misc/radio_ctrl/radio_class.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2011 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -static struct class *radio_cls; - -/* show the device status */ -static ssize_t radio_status_show(struct device *dev, - struct device_attribute *attr, char *buff) -{ - struct radio_dev *rdev = dev_get_drvdata(dev); - - if (!rdev || !rdev->status) { - pr_err("%s: supporting function not found\n", __func__); - return -ENODEV; - } - - return rdev->status(rdev, buff); -} - -/* show the device power state */ -static ssize_t radio_power_show(struct device *dev, - struct device_attribute *attr, char *buff) -{ - struct radio_dev *rdev = dev_get_drvdata(dev); - - if (!rdev || !rdev->power_status) { - pr_err("%s: supporting function not found\n", __func__); - return -ENODEV; - } - return rdev->power_status(rdev, buff); -} - -/* control the radio device */ -static ssize_t radio_command(struct device *dev, - struct device_attribute *attr, const char *buff, size_t size) -{ - struct radio_dev *rdev = dev_get_drvdata(dev); - char tmp[RADIO_COMMAND_MAX_LENGTH]; - char *post_strip = NULL; - ssize_t ret; - - if (!rdev || !rdev->command) { - pr_err("%s: supporting function not found\n", __func__); - return -ENODEV; - } - pr_debug("%s: rdev.name = %s\n", __func__, rdev->name); - - if (size > RADIO_COMMAND_MAX_LENGTH - 1) { - pr_err("%s: command too long\n", __func__); - return -EINVAL; - } - - /* strip whitespaces if any */ - memcpy(tmp, buff, size); - tmp[size] = '\0'; - post_strip = strim(tmp); - - pr_debug("%s: command = %s size = %d\n", __func__, post_strip, size); - - ret = rdev->command(rdev, post_strip); - return ret >= 0 ? size : ret; -} - -static DEVICE_ATTR(status, S_IRUGO, radio_status_show, NULL); -static DEVICE_ATTR(power_status, S_IRUGO, radio_power_show, NULL); -static DEVICE_ATTR(command, S_IWUSR, NULL, radio_command); - -int radio_dev_register(struct radio_dev *rdev) -{ - int err = -1; - - rdev->dev = device_create(radio_cls, NULL, 0, rdev, - "%s", rdev->name); - if (IS_ERR(rdev->dev)) - return PTR_ERR(rdev->dev); - - pr_info("%s: register %s\n", __func__, rdev->name); - pr_debug("%s: dev = %p\n", __func__, rdev->dev); - - /* /sys/class/radio//status */ - if (rdev->status) { - err = device_create_file(rdev->dev, &dev_attr_status); - if (err < 0) { - pr_err("%s: status file create failed for %s\n", - __func__, rdev->name); - goto err_status; - } - } - - /* /sys/class/radio//power_status */ - if (rdev->power_status) { - err = device_create_file(rdev->dev, &dev_attr_power_status); - if (err < 0) { - pr_err("%s: power_status file create failed for %s\n", - __func__, rdev->name); - goto err_pwr_status; - } - } - - /* /sys/class/radio//command */ - if (rdev->command) { - err = device_create_file(rdev->dev, &dev_attr_command); - if (err < 0) { - pr_err("%s: command file create failed for %s\n", - __func__, rdev->name); - goto err_command; - } - } - - return 0; - -err_command: - device_remove_file(rdev->dev, &dev_attr_power_status); -err_pwr_status: - device_remove_file(rdev->dev, &dev_attr_status); -err_status: - put_device(rdev->dev); - device_unregister(rdev->dev); - dev_set_drvdata(rdev->dev, NULL); - - return err; -} -EXPORT_SYMBOL(radio_dev_register); - -void radio_dev_unregister(struct radio_dev *rdev) -{ - if (rdev) { - if (rdev->command) - device_remove_file(rdev->dev, &dev_attr_command); - if (rdev->power_status) - device_remove_file(rdev->dev, &dev_attr_power_status); - if (rdev->status) - device_remove_file(rdev->dev, &dev_attr_status); - - put_device(rdev->dev); - device_unregister(rdev->dev); - dev_set_drvdata(rdev->dev, NULL); - } -} -EXPORT_SYMBOL(radio_dev_unregister); - -static int __init radio_class_init(void) -{ - pr_info("%s: initialized radio_class\n", __func__); - - /* /sys/class/radio */ - radio_cls = class_create(THIS_MODULE, "radio"); - if (IS_ERR(radio_cls)) { - pr_err("%s: failed to initialize radio class\n", __func__); - return PTR_ERR(radio_cls); - } - - return 0; -} - -static void __exit radio_class_exit(void) -{ - pr_info("%s: destroy radio_class\n", __func__); - class_destroy(radio_cls); -} - -module_init(radio_class_init); -module_exit(radio_class_exit); - -MODULE_AUTHOR("Jim Wylder "); -MODULE_DESCRIPTION("Radio Control Class"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/radio_ctrl/wrigley_ctrl.c b/drivers/misc/radio_ctrl/wrigley_ctrl.c deleted file mode 100644 index 1887432a31f5..000000000000 --- a/drivers/misc/radio_ctrl/wrigley_ctrl.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2011 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GPIO_MAX_NAME 30 - -enum wrigley_status { - WRIGLEY_STATUS_NORMAL, - WRIGLEY_STATUS_FLASH, - WRIGLEY_STATUS_RESETTING, - WRIGLEY_STATUS_OFF, - WRIGLEY_STATUS_UNDEFINED, -}; - -static const char *wrigley_status_str[] = { - [WRIGLEY_STATUS_NORMAL] = "normal", - [WRIGLEY_STATUS_FLASH] = "flash", - [WRIGLEY_STATUS_RESETTING] = "resetting", - [WRIGLEY_STATUS_OFF] = "off", - [WRIGLEY_STATUS_UNDEFINED] = "undefined", -}; - -struct wrigley_info { - unsigned int disable_gpio; - char disable_name[GPIO_MAX_NAME]; - - unsigned int flash_gpio; - char flash_name[GPIO_MAX_NAME]; - - unsigned int reset_gpio; - char reset_name[GPIO_MAX_NAME]; - - bool boot_flash; - enum wrigley_status status; - - struct radio_dev rdev; -}; - -static ssize_t wrigley_status_show(struct radio_dev *rdev, char *buff) -{ - struct wrigley_info *info = - container_of(rdev, struct wrigley_info, rdev); - - pr_debug("%s: wrigley_status = %d\n", __func__, info->status); - if (info->status > WRIGLEY_STATUS_UNDEFINED) - info->status = WRIGLEY_STATUS_UNDEFINED; - - return snprintf(buff, RADIO_STATUS_MAX_LENGTH, "%s\n", - wrigley_status_str[info->status]); -} - -static ssize_t wrigley_do_powerdown(struct wrigley_info *info) -{ - int i, value, err = -1; - - pr_info("%s: powering down\n", __func__); - gpio_direction_output(info->disable_gpio, 0); - - for (i = 0; i < 10; i++) { - value = gpio_get_value(info->reset_gpio); - pr_debug("%s: reset value = %d\n", __func__, value); - if (!value) { - err = 0; - info->status = WRIGLEY_STATUS_OFF; - break; - } - msleep(100); - } - - return err; -} - -/* hard reset of Wrigley data card - * recipe is: - * 1) set force_flash high - * 2) configure reset as output and drive low for 10ms - * 3) configure reset as input - * 4) set force flash low - * 5) verify data card reset by sampling reset - */ -static ssize_t wrigley_do_reset(struct wrigley_info *info) -{ - int i; - int value; - int err = -1; - - gpio_direction_output(info->flash_gpio, 1); - - gpio_direction_output(info->reset_gpio, 0); - msleep(10); - gpio_set_value(info->reset_gpio, 1); - - gpio_direction_input(info->reset_gpio); - gpio_set_value(info->flash_gpio, 0); - for (i = 0; i < 10; i++) { - value = gpio_get_value(info->reset_gpio); - pr_info("%s: reset value = %d\n", __func__, value); - if (!value) { - err = 0; - info->status = WRIGLEY_STATUS_OFF; - break; - } - msleep(100); - } - - return err; -} - -static ssize_t wrigley_do_powerup(struct wrigley_info *info) -{ - int i, value, err = -1; - - pr_debug("%s: enter\n", __func__); - - /* power on in normal or flash mode */ - if (info->boot_flash) - gpio_direction_output(info->flash_gpio, 1); - else - gpio_direction_output(info->flash_gpio, 0); - - /* set disable high to actually power on the card */ - pr_debug("%s: set disable high\n", __func__); - gpio_direction_output(info->disable_gpio, 1); - info->status = WRIGLEY_STATUS_RESETTING; - - /* verify power up by sampling reset */ - for (i = 0; i < 10; i++) { - value = gpio_get_value(info->reset_gpio); - pr_debug("%s: reset value = %d\n", __func__, value); - if (value) { - err = 0; - break; - } - msleep(100); - } - - if (!err) { - if (info->boot_flash) { - pr_debug("%s: started wrigley in flash mode\n", - __func__); - info->status = WRIGLEY_STATUS_FLASH; - } else { - pr_debug("%s: started wrigley in normal mode\n", - __func__); - info->status = WRIGLEY_STATUS_NORMAL; - } - } else { - pr_err("%s: failed to start wrigley\n", __func__); - info->status = WRIGLEY_STATUS_UNDEFINED; - } - - return err; -} - -static ssize_t wrigley_set_flash_mode(struct wrigley_info *info, bool enable) -{ - pr_debug("%s: set boot state to %d\n", __func__, enable); - info->boot_flash = enable; - return 0; -} - -static ssize_t wrigley_command(struct radio_dev *rdev, char *cmd) -{ - struct wrigley_info *info = - container_of(rdev, struct wrigley_info, rdev); - - pr_info("%s: user command = %s\n", __func__, cmd); - - if (strcmp(cmd, "shutdown") == 0) - return wrigley_do_powerdown(info); - else if (strcmp(cmd, "reset") == 0) - return wrigley_do_reset(info); - else if (strcmp(cmd, "powerup") == 0) - return wrigley_do_powerup(info); - else if (strcmp(cmd, "bootmode_normal") == 0) - return wrigley_set_flash_mode(info, 0); - else if (strcmp(cmd, "bootmode_flash") == 0) - return wrigley_set_flash_mode(info, 1); - - pr_err("%s: command %s not supported\n", __func__, cmd); - return -EINVAL; -} - -static irqreturn_t wrigley_reset_fn(int irq, void *data) -{ - struct wrigley_info *info = (struct wrigley_info *) data; - pr_debug("%s: reset irq (%d) fired\n", __func__, irq); - if (info->rdev.dev) - kobject_uevent(&info->rdev.dev->kobj, KOBJ_CHANGE); - return IRQ_HANDLED; -} - -static irqreturn_t wrigley_reset_isr(int irq, void *data) -{ - struct wrigley_info *info = (struct wrigley_info *) data; - pr_debug("%s: reset irq (%d) fired\n", __func__, irq); - info->status = WRIGLEY_STATUS_RESETTING; - return IRQ_WAKE_THREAD; -} - -static int __devinit wrigley_probe(struct platform_device *pdev) -{ - struct wrigley_ctrl_platform_data *pdata = pdev->dev.platform_data; - struct wrigley_info *info; - int reset_irq, err = 0; - - pr_info("%s: %s\n", __func__, dev_name(&pdev->dev)); - - info = kzalloc(sizeof(struct wrigley_info), GFP_KERNEL); - if (!info) { - err = -ENOMEM; - goto err_exit; - } - - platform_set_drvdata(pdev, info); - - /* setup radio_class device */ - info->rdev.name = dev_name(&pdev->dev); - info->rdev.status = wrigley_status_show; - info->rdev.command = wrigley_command; - - /* disable */ - pr_debug("%s: setup wrigley_disable\n", __func__); - info->disable_gpio = pdata->gpio_disable; - snprintf(info->disable_name, GPIO_MAX_NAME, "%s-%s", - dev_name(&pdev->dev), "disable"); - err = gpio_request(info->disable_gpio, info->disable_name); - if (err) { - pr_err("%s: err_disable\n", __func__); - goto err_disable; - } - gpio_export(info->disable_gpio, false); - - /* reset */ - pr_debug("%s: setup wrigley_reset\n", __func__); - info->reset_gpio = pdata->gpio_reset; - snprintf(info->reset_name, GPIO_MAX_NAME, "%s-%s", - dev_name(&pdev->dev), "reset"); - err = gpio_request(info->reset_gpio, info->reset_name); - if (err) { - pr_err("%s: err requesting reset gpio\n", __func__); - goto err_reset; - } - gpio_direction_input(info->reset_gpio); - reset_irq = gpio_to_irq(info->reset_gpio); - err = request_threaded_irq(reset_irq, wrigley_reset_isr, - wrigley_reset_fn, IRQ_TYPE_EDGE_FALLING, info->reset_name, - info); - if (err) { - pr_err("%s: request irq (%d) %s failed\n", - __func__, reset_irq, info->reset_name); - gpio_free(info->reset_gpio); - goto err_reset; - } - gpio_export(info->reset_gpio, false); - - /* force_flash */ - pr_debug("%s: setup wrigley_force_flash\n", __func__); - info->flash_gpio = pdata->gpio_force_flash; - snprintf(info->flash_name, GPIO_MAX_NAME, "%s-%s", - dev_name(&pdev->dev), "flash"); - err = gpio_request(info->flash_gpio, info->flash_name); - if (err) { - pr_err("%s: error requesting flash gpio\n", __func__); - goto err_flash; - } - gpio_export(info->flash_gpio, false); - - /* try to determine the boot up mode of the device */ - info->boot_flash = !!gpio_get_value(info->flash_gpio); - if (gpio_get_value(info->reset_gpio)) { - if (info->boot_flash) - info->status = WRIGLEY_STATUS_FLASH; - else - info->status = WRIGLEY_STATUS_NORMAL; - } else - info->status = WRIGLEY_STATUS_OFF; - - pr_debug("%s: initial status = %s\n", __func__, - wrigley_status_str[info->status]); - - err = radio_dev_register(&info->rdev); - if (err) { - pr_err("%s: failed to register radio device\n", __func__); - goto err_dev_register; - } - - return 0; - -err_dev_register: - gpio_free(info->flash_gpio); -err_flash: - free_irq(reset_irq, info); - gpio_free(info->reset_gpio); -err_reset: - gpio_free(info->disable_gpio); -err_disable: - platform_set_drvdata(pdev, NULL); - kfree(info); -err_exit: - return err; -} - -static void __devexit wrigley_shutdown(struct platform_device *pdev) -{ - struct wrigley_info *info = platform_get_drvdata(pdev); - pr_info("%s: %s\n", __func__, dev_name(&pdev->dev)); - (void) wrigley_do_powerdown(info); -} - -static int __devexit wrigley_remove(struct platform_device *pdev) -{ - struct wrigley_info *info = platform_get_drvdata(pdev); - - pr_info("%s: %s\n", __func__, dev_name(&pdev->dev)); - - radio_dev_unregister(&info->rdev); - - /* flash */ - gpio_free(info->flash_gpio); - - /* reset */ - free_irq(gpio_to_irq(info->reset_gpio), info); - gpio_free(info->reset_gpio); - - /* disable */ - gpio_free(info->disable_gpio); - - platform_set_drvdata(pdev, NULL); - kfree(info); - - return 0; -} - -static struct platform_driver wrigley_driver = { - .probe = wrigley_probe, - .remove = __devexit_p(wrigley_remove), - .shutdown = __devexit_p(wrigley_shutdown), - .driver = { - .name = "wrigley", - .owner = THIS_MODULE, - }, -}; - -static int __init wrigley_init(void) -{ - - pr_info("%s: initializing %s\n", __func__, wrigley_driver.driver.name); - - return platform_driver_register(&wrigley_driver); -} - -static void __exit wrigley_exit(void) -{ - pr_info("%s: exiting %s\n", __func__, wrigley_driver.driver.name); - return platform_driver_unregister(&wrigley_driver); -} - -module_init(wrigley_init); -module_exit(wrigley_exit); - -MODULE_AUTHOR("Jim Wylder "); -MODULE_DESCRIPTION("Wrigley Modem Control"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 6956f7e7d439..d551f09ccb79 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -439,23 +439,18 @@ xpc_discovery(void) * nodes that can comprise an access protection grouping. The access * protection is in regards to memory, IOI and IPI. */ + max_regions = 64; region_size = xp_region_size; - if (is_uv()) - max_regions = 256; - else { - max_regions = 64; - - switch (region_size) { - case 128: - max_regions *= 2; - case 64: - max_regions *= 2; - case 32: - max_regions *= 2; - region_size = 16; - DBUG_ON(!is_shub2()); - } + switch (region_size) { + case 128: + max_regions *= 2; + case 64: + max_regions *= 2; + case 32: + max_regions *= 2; + region_size = 16; + DBUG_ON(!is_shub2()); } for (region = 0; region < max_regions; region++) { diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 17bbacb1b4b1..1f59ee2226ca 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -417,7 +417,6 @@ xpc_process_activate_IRQ_rcvd_uv(void) static void xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, struct xpc_activate_mq_msghdr_uv *msg_hdr, - int part_setup, int *wakeup_hb_checker) { unsigned long irq_flags; @@ -482,9 +481,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; - if (!part_setup) - break; - msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_closerequest_uv, hdr); @@ -501,9 +497,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { struct xpc_activate_mq_msg_chctl_closereply_uv *msg; - if (!part_setup) - break; - msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_closereply_uv, hdr); @@ -518,9 +511,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; - if (!part_setup) - break; - msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_openrequest_uv, hdr); @@ -538,9 +528,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { struct xpc_activate_mq_msg_chctl_openreply_uv *msg; - if (!part_setup) - break; - msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_openreply_uv, hdr); args = &part->remote_openclose_args[msg->ch_number]; @@ -558,9 +545,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; - if (!part_setup) - break; - msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); spin_lock_irqsave(&part->chctl_lock, irq_flags); @@ -637,7 +621,6 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) part_referenced = xpc_part_ref(part); xpc_handle_activate_mq_msg_uv(part, msg_hdr, - part_referenced, &wakeup_hb_checker); if (part_referenced) xpc_part_deref(part); diff --git a/drivers/misc/tegra-cryptodev.c b/drivers/misc/tegra-cryptodev.c deleted file mode 100644 index b5fb637fd309..000000000000 --- a/drivers/misc/tegra-cryptodev.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * drivers/misc/tegra-cryptodev.c - * - * crypto dev node for NVIDIA tegra aes hardware - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tegra-cryptodev.h" - -#define NBUFS 2 - -struct tegra_crypto_ctx { - struct crypto_ablkcipher *ecb_tfm; - struct crypto_ablkcipher *cbc_tfm; - struct crypto_rng *rng; - int use_ssk; -}; - -struct tegra_crypto_completion { - struct completion restart; - int req_err; -}; - -static int alloc_bufs(unsigned long *buf[NBUFS]) -{ - int i; - - for (i = 0; i < NBUFS; i++) { - buf[i] = (void *)__get_free_page(GFP_KERNEL); - if (!buf[i]) - goto err_free_buf; - } - - return 0; - -err_free_buf: - while (i-- > 0) - free_page((unsigned long)buf[i]); - - return -ENOMEM; -} - -static void free_bufs(unsigned long *buf[NBUFS]) -{ - int i; - - for (i = 0; i < NBUFS; i++) - free_page((unsigned long)buf[i]); -} - -static int tegra_crypto_dev_open(struct inode *inode, struct file *filp) -{ - struct tegra_crypto_ctx *ctx; - int ret = 0; - - ctx = kzalloc(sizeof(struct tegra_crypto_ctx), GFP_KERNEL); - if (!ctx) { - pr_err("no memory for context\n"); - return -ENOMEM; - } - - ctx->ecb_tfm = crypto_alloc_ablkcipher("ecb-aes-tegra", - CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0); - if (IS_ERR(ctx->ecb_tfm)) { - pr_err("Failed to load transform for ecb-aes-tegra: %ld\n", - PTR_ERR(ctx->ecb_tfm)); - ret = PTR_ERR(ctx->ecb_tfm); - goto fail_ecb; - } - - ctx->cbc_tfm = crypto_alloc_ablkcipher("cbc-aes-tegra", - CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0); - if (IS_ERR(ctx->cbc_tfm)) { - pr_err("Failed to load transform for cbc-aes-tegra: %ld\n", - PTR_ERR(ctx->cbc_tfm)); - ret = PTR_ERR(ctx->cbc_tfm); - goto fail_cbc; - } - - ctx->rng = crypto_alloc_rng("rng-aes-tegra", CRYPTO_ALG_TYPE_RNG, 0); - if (IS_ERR(ctx->rng)) { - pr_err("Failed to load transform for tegra rng: %ld\n", - PTR_ERR(ctx->rng)); - ret = PTR_ERR(ctx->rng); - goto fail_rng; - } - - filp->private_data = ctx; - return ret; - -fail_rng: - crypto_free_ablkcipher(ctx->cbc_tfm); - -fail_cbc: - crypto_free_ablkcipher(ctx->ecb_tfm); - -fail_ecb: - kfree(ctx); - return ret; -} - -static int tegra_crypto_dev_release(struct inode *inode, struct file *filp) -{ - struct tegra_crypto_ctx *ctx = filp->private_data; - - crypto_free_ablkcipher(ctx->ecb_tfm); - crypto_free_ablkcipher(ctx->cbc_tfm); - crypto_free_rng(ctx->rng); - kfree(ctx); - filp->private_data = NULL; - return 0; -} - -static void tegra_crypt_complete(struct crypto_async_request *req, int err) -{ - struct tegra_crypto_completion *done = req->data; - - if (err != -EINPROGRESS) { - done->req_err = err; - complete(&done->restart); - } -} - -static int process_crypt_req(struct tegra_crypto_ctx *ctx, struct tegra_crypt_req *crypt_req) -{ - struct crypto_ablkcipher *tfm; - struct ablkcipher_request *req = NULL; - struct scatterlist in_sg; - struct scatterlist out_sg; - unsigned long *xbuf[NBUFS]; - int ret = 0, size = 0; - unsigned long total = 0; - struct tegra_crypto_completion tcrypt_complete; - - if (crypt_req->op & TEGRA_CRYPTO_ECB) { - req = ablkcipher_request_alloc(ctx->ecb_tfm, GFP_KERNEL); - tfm = ctx->ecb_tfm; - } else { - req = ablkcipher_request_alloc(ctx->cbc_tfm, GFP_KERNEL); - tfm = ctx->cbc_tfm; - } - if (!req) { - pr_err("%s: Failed to allocate request\n", __func__); - return -ENOMEM; - } - - if ((crypt_req->keylen < 0) || (crypt_req->keylen > AES_MAX_KEY_SIZE)) - return -EINVAL; - - crypto_ablkcipher_clear_flags(tfm, ~0); - - if (!ctx->use_ssk) { - ret = crypto_ablkcipher_setkey(tfm, crypt_req->key, - crypt_req->keylen); - if (ret < 0) { - pr_err("setkey failed"); - goto process_req_out; - } - } - - ret = alloc_bufs(xbuf); - if (ret < 0) { - pr_err("alloc_bufs failed"); - goto process_req_out; - } - - init_completion(&tcrypt_complete.restart); - - ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - tegra_crypt_complete, &tcrypt_complete); - - total = crypt_req->plaintext_sz; - while (total > 0) { - size = min(total, PAGE_SIZE); - ret = copy_from_user(xbuf[0], - (void __user *)crypt_req->plaintext, size); - if (ret < 0) { - pr_debug("%s: copy_from_user failed (%d)\n", __func__, ret); - goto process_req_buf_out; - } - sg_init_one(&in_sg, xbuf[0], size); - sg_init_one(&out_sg, xbuf[1], size); - - ablkcipher_request_set_crypt(req, &in_sg, - &out_sg, size, crypt_req->iv); - - INIT_COMPLETION(tcrypt_complete.restart); - tcrypt_complete.req_err = 0; - ret = crypt_req->encrypt ? - crypto_ablkcipher_encrypt(req) : - crypto_ablkcipher_decrypt(req); - - if ((ret == -EINPROGRESS) || (ret == -EBUSY)) { - /* crypto driver is asynchronous */ - ret = wait_for_completion_interruptible(&tcrypt_complete.restart); - - if (ret < 0) - goto process_req_buf_out; - - if (tcrypt_complete.req_err < 0) { - ret = tcrypt_complete.req_err; - goto process_req_buf_out; - } - } else if (ret < 0) { - pr_debug("%scrypt failed (%d)\n", - crypt_req->encrypt ? "en" : "de", ret); - goto process_req_buf_out; - } - - ret = copy_to_user((void __user *)crypt_req->result, xbuf[1], - size); - if (ret < 0) - goto process_req_buf_out; - - total -= size; - crypt_req->result += size; - crypt_req->plaintext += size; - } - -process_req_buf_out: - free_bufs(xbuf); -process_req_out: - ablkcipher_request_free(req); - - return ret; -} - -static long tegra_crypto_dev_ioctl(struct file *filp, - unsigned int ioctl_num, unsigned long arg) -{ - struct tegra_crypto_ctx *ctx = filp->private_data; - struct tegra_crypt_req crypt_req; - struct tegra_rng_req rng_req; - char *rng; - int ret = 0; - - switch (ioctl_num) { - case TEGRA_CRYPTO_IOCTL_NEED_SSK: - ctx->use_ssk = (int)arg; - break; - case TEGRA_CRYPTO_IOCTL_PROCESS_REQ: - ret = copy_from_user(&crypt_req, (void __user *)arg, sizeof(crypt_req)); - if (ret < 0) { - pr_debug("%s: copy_from_user fail(%d)\n", __func__, ret); - break; - } - - ret = process_crypt_req(ctx, &crypt_req); - break; - - case TEGRA_CRYPTO_IOCTL_SET_SEED: - if (copy_from_user(&rng_req, (void __user *)arg, sizeof(rng_req))) - return -EFAULT; - - ret = crypto_rng_reset(ctx->rng, rng_req.seed, - crypto_rng_seedsize(ctx->rng)); - break; - case TEGRA_CRYPTO_IOCTL_GET_RANDOM: - if (copy_from_user(&rng_req, (void __user *)arg, sizeof(rng_req))) - return -EFAULT; - - rng = kzalloc(rng_req.nbytes, GFP_KERNEL); - if (!rng) { - pr_err("mem alloc for rng fail"); - ret = -ENODATA; - goto rng_out; - } - - ret = crypto_rng_get_bytes(ctx->rng, rng, rng_req.nbytes); - - if (ret != rng_req.nbytes) { - pr_debug("rng failed"); - ret = -ENODATA; - goto rng_out; - } - - ret = copy_to_user((void __user *)rng_req.rdata, - rng, rng_req.nbytes); - ret = (ret < 0) ? -ENODATA : 0; -rng_out: - if (rng) - kfree(rng); - - break; - - - default: - pr_debug("invalid ioctl code(%d)", ioctl_num); - ret = -EINVAL; - } - return ret; -} - -struct file_operations tegra_crypto_fops = { - .owner = THIS_MODULE, - .open = tegra_crypto_dev_open, - .release = tegra_crypto_dev_release, - .unlocked_ioctl = tegra_crypto_dev_ioctl, -}; - -struct miscdevice tegra_crypto_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "tegra-crypto", - .fops = &tegra_crypto_fops, -}; - -static int __init tegra_crypto_dev_init(void) -{ - return misc_register(&tegra_crypto_device); -} - -late_initcall(tegra_crypto_dev_init); - -MODULE_DESCRIPTION("Tegra AES hw device node."); -MODULE_AUTHOR("NVIDIA Corporation"); -MODULE_LICENSE("GPLv2"); diff --git a/drivers/misc/tegra-cryptodev.h b/drivers/misc/tegra-cryptodev.h deleted file mode 100644 index 973e3f28d008..000000000000 --- a/drivers/misc/tegra-cryptodev.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __TEGRA_CRYPTODEV_H -#define __TEGRA_CRYPTODEV_H - -#include - -#include - -/* ioctl arg = 1 if you want to use ssk. arg = 0 to use normal key */ -#define TEGRA_CRYPTO_IOCTL_NEED_SSK _IOWR(0x98, 100, int) -#define TEGRA_CRYPTO_IOCTL_PROCESS_REQ _IOWR(0x98, 101, int*) -#define TEGRA_CRYPTO_IOCTL_SET_SEED _IOWR(0x98, 102, int*) -#define TEGRA_CRYPTO_IOCTL_GET_RANDOM _IOWR(0x98, 103, int*) - -#define TEGRA_CRYPTO_MAX_KEY_SIZE AES_MAX_KEY_SIZE -#define TEGRA_CRYPTO_IV_SIZE AES_BLOCK_SIZE -#define DEFAULT_RNG_BLK_SZ 16 - -/* the seed consists of 16 bytes of key + 16 bytes of init vector */ -#define TEGRA_CRYPTO_RNG_SEED_SIZE AES_KEYSIZE_128 + DEFAULT_RNG_BLK_SZ - -/* encrypt/decrypt operations */ -#define TEGRA_CRYPTO_ECB BIT(0) -#define TEGRA_CRYPTO_CBC BIT(1) -#define TEGRA_CRYPTO_RNG BIT(2) - -/* a pointer to this struct needs to be passed to: - * TEGRA_CRYPTO_IOCTL_PROCESS_REQ - */ -struct tegra_crypt_req { - int op; /* e.g. TEGRA_CRYPTO_ECB */ - bool encrypt; - char key[TEGRA_CRYPTO_MAX_KEY_SIZE]; - int keylen; - char iv[TEGRA_CRYPTO_IV_SIZE]; - int ivlen; - u8 *plaintext; - int plaintext_sz; - u8 *result; -}; - -/* pointer to this struct should be passed to: - * TEGRA_CRYPTO_IOCTL_SET_SEED - * TEGRA_CRYPTO_IOCTL_GET_RANDOM - */ -struct tegra_rng_req { - u8 seed[TEGRA_CRYPTO_RNG_SEED_SIZE]; - u8 *rdata; /* random generated data */ - int nbytes; /* random data length */ -}; - -#endif diff --git a/drivers/misc/ts27010mux/Kconfig b/drivers/misc/ts27010mux/Kconfig deleted file mode 100644 index 4ccb475086d6..000000000000 --- a/drivers/misc/ts27010mux/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# -# TS 27.010 configuration -# - -menu "Motorola TS 27.010 Mux driver" - -config TS27010MUX - tristate "Motorola TS 27.010 Mux driver" - default n - -endmenu diff --git a/drivers/misc/ts27010mux/Makefile b/drivers/misc/ts27010mux/Makefile deleted file mode 100644 index e83cd3057e7b..000000000000 --- a/drivers/misc/ts27010mux/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the ts27010mux driver. -# -# -MODULE_NAME = ts27010mux - -obj-$(CONFIG_TS27010MUX) += $(MODULE_NAME).o - -$(MODULE_NAME)-objs := ts27010_mux.o \ - ts27010_tty.o \ - ts27010_ldisc.o diff --git a/drivers/misc/ts27010mux/ts0710.h b/drivers/misc/ts27010mux/ts0710.h deleted file mode 100644 index 663102bf553c..000000000000 --- a/drivers/misc/ts27010mux/ts0710.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * File: ts0710.h - * - * Portions derived from rfcomm.c, original header as follows: - * - * Copyright (C) 2000, 2001 Axis Communications AB - * Copyright (C) 2002, 2004, 2009 Motorola - * - * Author: Mats Friden - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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. - * - * Exceptionally, Axis Communications AB grants discretionary and - * conditional permissions for additional use of the text contained - * in the company's release of the AXIS OpenBT Stack under the - * provisions set forth hereunder. - * - * Provided that, if you use the AXIS OpenBT Stack with other files, - * that do not implement functionality as specified in the Bluetooth - * System specification, to produce an executable, this does not by - * itself cause the resulting executable to be covered by the GNU - * General Public License. Your use of that executable is in no way - * restricted on account of using the AXIS OpenBT Stack code with it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the provisions of the GNU - * General Public License. - * - */ - -#define TS0710_MAX_CHN 17 - -#define SET_PF(ctr) ((ctr) | (1 << 4)) -#define CLR_PF(ctr) ((ctr) & 0xef) -#define GET_PF(ctr) (((ctr) >> 4) & 0x1) - -#define SHORT_PAYLOAD_SIZE 127 - -#define EA 1 -#define FCS_SIZE 1 -#define FLAG_SIZE 2 - -#define TS0710_MAX_HDR_SIZE 5 -#define DEF_TS0710_MTU 1024 - -#define TS0710_BASIC_FLAG 0xF9 - -/* the control field */ -#define SABM 0x2f -#define SABM_SIZE 4 -#define UA 0x63 -#define UA_SIZE 4 -#define DM 0x0f -#define DISC 0x43 -#define UIH 0xef - -/* the type field in a multiplexer command packet */ -#define TEST 0x8 -#define FCON 0x28 -#define FCOFF 0x18 -#define MSC 0x38 -#define RPN 0x24 -#define RLS 0x14 -#define PN 0x20 -#define NSC 0x4 - -/* V.24 modem control signals */ -#define FC 0x2 -#define RTC 0x4 -#define RTR 0x8 -#define IC 0x40 -#define DV 0x80 - -#define CTRL_CHAN 0 /* The control channel is defined as DLCI 0 */ -#define MCC_CR 0x2 -#define MCC_CMD 1 /* Multiplexer command cr */ -#define MCC_RSP 0 /* Multiplexer response cr */ - -static inline int mcc_is_cmd(u8 type) -{ - return type & MCC_CR; -} - -static inline int mcc_is_rsp(u8 type) -{ - return !(type & MCC_CR); -} - - -#ifdef __LITTLE_ENDIAN_BITFIELD - -struct address_field { - u8 ea:1; - u8 cr:1; - u8 d:1; - u8 server_chn:5; -} __attribute__ ((packed)); - -static inline int ts0710_dlci(u8 addr) -{ - return (addr >> 2) & 0x3f; -} - - -struct short_length { - u8 ea:1; - u8 len:7; -} __attribute__ ((packed)); - -struct long_length { - u8 ea:1; - u8 l_len:7; - u8 h_len; -} __attribute__ ((packed)); - -struct short_frame_head { - struct address_field addr; - u8 control; - struct short_length length; -} __attribute__ ((packed)); - -struct short_frame { - struct short_frame_head h; - u8 data[0]; -} __attribute__ ((packed)); - -struct long_frame_head { - struct address_field addr; - u8 control; - struct long_length length; - u8 data[0]; -} __attribute__ ((packed)); - -struct long_frame { - struct long_frame_head h; - u8 data[0]; -} __attribute__ ((packed)); - -/* Typedefinitions for structures used for the multiplexer commands */ -struct mcc_type { - u8 ea:1; - u8 cr:1; - u8 type:6; -} __attribute__ ((packed)); - -struct mcc_short_frame_head { - struct mcc_type type; - struct short_length length; - u8 value[0]; -} __attribute__ ((packed)); - -struct mcc_short_frame { - struct mcc_short_frame_head h; - u8 value[0]; -} __attribute__ ((packed)); - -struct mcc_long_frame_head { - struct mcc_type type; - struct long_length length; - u8 value[0]; -} __attribute__ ((packed)); - -struct mcc_long_frame { - struct mcc_long_frame_head h; - u8 value[0]; -} __attribute__ ((packed)); - -/* MSC-command */ -struct v24_sigs { - u8 ea:1; - u8 fc:1; - u8 rtc:1; - u8 rtr:1; - u8 reserved:2; - u8 ic:1; - u8 dv:1; -} __attribute__ ((packed)); - -struct brk_sigs { - u8 ea:1; - u8 b1:1; - u8 b2:1; - u8 b3:1; - u8 len:4; -} __attribute__ ((packed)); - -struct msc_msg_data { - struct address_field dlci; - u8 v24_sigs; -} __attribute__ ((packed)); - -struct pn_msg_data { - u8 dlci:6; - u8 res1:2; - - u8 frame_type:4; - u8 credit_flow:4; - - u8 prior:6; - u8 res2:2; - - u8 ack_timer; - u8 frame_sizel; - u8 frame_sizeh; - u8 max_nbrof_retrans; - u8 credits; -} __attribute__ ((packed)); - -#else -#error Only littel-endianess supported now! -#endif - -#define TS0710_FRAME_SIZE(len) \ - ((len) > SHORT_PAYLOAD_SIZE ? \ - (len) + FLAG_SIZE + sizeof(struct long_frame) + FCS_SIZE : \ - (len) + FLAG_SIZE + sizeof(struct short_frame) + FCS_SIZE) - -#define TS0710_MCC_FRAME_SIZE(len) \ - TS0710_FRAME_SIZE((len) + sizeof(struct mcc_short_frame)) - - - -enum { - REJECTED = 0, - DISCONNECTED, - CONNECTING, - NEGOTIATING, - CONNECTED, - DISCONNECTING, - FLOW_STOPPED -}; - -enum ts0710_events { - CONNECT_IND, - CONNECT_CFM, - DISCONN_CFM -}; - -struct dlci_struct { - u8 state; - u8 flow_control; - u16 mtu; - int clients; - struct mutex lock; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; -}; - -struct chan_struct { - struct mutex write_lock; - u8 *buf; -}; - - -/* user space interfaces */ -struct ts0710_con { - u16 mtu; - - struct dlci_struct dlci[TS0710_MAX_CHN]; - struct chan_struct chan[NR_MUXS]; -}; diff --git a/drivers/misc/ts27010mux/ts27010_ldisc.c b/drivers/misc/ts27010mux/ts27010_ldisc.c deleted file mode 100644 index 2fc89b25a134..000000000000 --- a/drivers/misc/ts27010mux/ts27010_ldisc.c +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "ts27010_mux.h" -#include "ts27010_ringbuf.h" - -struct ts27010_ldisc_data { - struct ts27010_ringbuf *rbuf; - struct work_struct recv_work; - spinlock_t recv_lock; - - struct mutex send_lock; -}; - -static void ts27010_ldisc_recv_worker(struct work_struct *work) -{ - struct ts27010_ldisc_data *ts = - container_of(work, struct ts27010_ldisc_data, recv_work); - - /* TODO: should have a *mux to pass around */ - ts27010_mux_recv(ts->rbuf); -} - - -int ts27010_ldisc_send(struct tty_struct *tty, u8 *data, int len) -{ - struct ts27010_ldisc_data *ts = 0; - - if (tty->disc_data == NULL) { - pr_err("\n %s try to send mux command while \ - ttyS is closed.\n", __func__); - return len; - } else - ts = tty->disc_data; - - mutex_lock(&ts->send_lock); - if (tty->driver->ops->write_room(tty) < len) - pr_err("\n******** write overflow ********\n\n"); - len = tty->driver->ops->write(tty, data, len); - mutex_unlock(&ts->send_lock); - return len; -} - -/* - * Called when a tty is put into tx27010mux line discipline. Called in process - * context. - */ -static int ts27010_ldisc_open(struct tty_struct *tty) -{ - struct ts27010_ldisc_data *ts; - int err; - - ts = kzalloc(sizeof(*ts), GFP_KERNEL); - if (ts == NULL) { - err = -ENOMEM; - goto err0; - } - - ts->rbuf = ts27010_ringbuf_alloc(LDISC_BUFFER_SIZE); - if (ts->rbuf == NULL) { - err = ENOMEM; - goto err1; - } - INIT_WORK(&ts->recv_work, ts27010_ldisc_recv_worker); - - mutex_init(&ts->send_lock); - ts->recv_lock = __SPIN_LOCK_UNLOCKED(ts->recv_lock); - - tty->disc_data = ts; - - /* TODO: goes away with clean tty interface */ - ts27010mux_tty = tty; - - return 0; - -err1: - kfree(ts); -err0: - return err; -} - -/* - * Called when the tty is put into another line discipline - * or it hangs up. We have to wait for any cpu currently - * executing in any of the other ts27010_tty_* routines to - * finish before we can call tsmux27010_unregister_channel and free - * the tsmux27010 struct. This routine must be called from - * process context, not interrupt or softirq context. - */ -static void ts27010_ldisc_close(struct tty_struct *tty) -{ - struct ts27010_ldisc_data *ts = tty->disc_data; - - if (!ts) - return; - - tty->disc_data = NULL; - /* TODO: goes away with clean tty interface */ - ts27010mux_tty = NULL; - /* TODO: find some way of dealing with ts_data freeing safely */ - ts27010_ringbuf_free(ts->rbuf); - kfree(ts); -} - -/* - * Called on tty hangup in process context. - * - * Wait for I/O to driver to complete and unregister ts27010mux channel. - * This is already done by the close routine, so just call that. - */ -static int ts27010_ldisc_hangup(struct tty_struct *tty) -{ - ts27010_ldisc_close(tty); - return 0; -} -/* - * Read does nothing - no data is ever available this way. - */ -static ssize_t ts27010_ldisc_read(struct tty_struct *tty, struct file *file, - unsigned char __user *buf, size_t count) -{ - return -EAGAIN; -} - -/* - * Write on the tty does nothing. - */ -static ssize_t ts27010_ldisc_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) -{ - return -EAGAIN; -} - -/* - * Called in process context only. May be re-entered by multiple - * ioctl calling threads. - */ -static int ts27010_ldisc_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int err; - - switch (cmd) { - default: - /* Try the various mode ioctls */ - err = tty_mode_ioctl(tty, file, cmd, arg); - } - - return err; -} - -/* No kernel lock - fine */ -static unsigned int ts27010_ldisc_poll(struct tty_struct *tty, - struct file *file, - poll_table *wait) -{ - unsigned int mask = 0; - - poll_wait(file, &tty->read_wait, wait); - poll_wait(file, &tty->write_wait, wait); - if (tty_hung_up_p(file)) - mask |= POLLHUP; - if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0) - mask |= POLLOUT | POLLWRNORM; - - return mask; - - -} - -/* - * This can now be called from hard interrupt level as well - * as soft interrupt level or mainline. Because of this, - * we copy the data and schedule work so that we can assure - * the mux receive code is called in processes context. - */ -static void ts27010_ldisc_receive(struct tty_struct *tty, - const unsigned char *data, - char *cflags, int count) -{ - struct ts27010_ldisc_data *ts = tty->disc_data; - int n; - unsigned long flags; - - WARN_ON(count == 0); - - spin_lock_irqsave(&ts->recv_lock, flags); - n = ts27010_ringbuf_write(ts->rbuf, data, count); - spin_unlock_irqrestore(&ts->recv_lock, flags); - - if (n < count) - pr_err("ts27010_ldisc: buffer overrun. dropping data.\n"); - - schedule_work(&ts->recv_work); -} - -static void ts27010_ldisc_wakeup(struct tty_struct *tty) -{ - pr_info(" Enter into ts27010mux_tty_wakeup\n"); -} - - - -static struct tty_ldisc_ops ts27010_ldisc = { - .owner = THIS_MODULE, - .magic = TTY_LDISC_MAGIC, - .name = "n_ts27010", - .open = ts27010_ldisc_open, - .close = ts27010_ldisc_close, - .hangup = ts27010_ldisc_hangup, - .read = ts27010_ldisc_read, - .write = ts27010_ldisc_write, - .ioctl = ts27010_ldisc_ioctl, - .poll = ts27010_ldisc_poll, - .receive_buf = ts27010_ldisc_receive, - .write_wakeup = ts27010_ldisc_wakeup, -}; - -int ts27010_ldisc_init(void) -{ - int err; - - err = tty_register_ldisc(N_GSM0710, &ts27010_ldisc); - if (err < 0) - pr_err("ts27010: unable to register line discipline\n"); - - return err; -} - -void ts27010_ldisc_remove(void) -{ - tty_unregister_ldisc(N_GSM0710); -} diff --git a/drivers/misc/ts27010mux/ts27010_mux.c b/drivers/misc/ts27010mux/ts27010_mux.c deleted file mode 100644 index 982728d967cf..000000000000 --- a/drivers/misc/ts27010mux/ts27010_mux.c +++ /dev/null @@ -1,1394 +0,0 @@ -/* - * File: ts27010_mux.c - * - * Portions derived from rfcomm.c, original header as follows: - * - * Copyright (C) 2000, 2001 Axis Communications AB - * Copyright (C) 2002, 2004, 2009 Motorola, Inc.7 - * - * Author: Mats Friden - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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. - * - * Exceptionally, Axis Communications AB grants discretionary and - * conditional permissions for additional use of the text contained - * in the company's release of the AXIS OpenBT Stack under the - * provisions set forth hereunder. - * - * Provided that, if you use the AXIS OpenBT Stack with other files, - * that do not implement functionality as specified in the Bluetooth - * System specification, to produce an executable, this does not by - * itself cause the resulting executable to be covered by the GNU - * General Public License. Your use of that executable is in no way - * restricted on account of using the AXIS OpenBT Stack code with it. - * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the provisions of the GNU - * General Public License. - * - * TODO: - * * test command - * * flow control - * * support for non sholes - */ - -#define DEBUG - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ts27010_mux.h" -#include "ts27010_ringbuf.h" -#include "ts0710.h" - -#define TS0710MUX_MAJOR 245 -#define TS0710MUX_MINOR_START 0 - -/* 2500ms, for BP UART hardware flow control AP UART */ -#define TS0710MUX_TIME_OUT 250 - -#define CRC_VALID 0xcf - -#define TS0710MUX_IO_DLCI_FC_ON 0x54F2 -#define TS0710MUX_IO_DLCI_FC_OFF 0x54F3 -#define TS0710MUX_IO_FC_ON 0x54F4 -#define TS0710MUX_IO_FC_OFF 0x54F5 - - -#define TS0710MUX_SEND_BUF_SIZE (TS0710_FRAME_SIZE(DEF_TS0710_MTU)) - -#define TS0710MUX_SERIAL_BUF_SIZE 2048 - -#define CMDTAG 0x55 -#define DATATAG 0xAA - -static const u8 tty2dlci[NR_MUXS] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 -}; - -static const u8 iscmdtty[NR_MUXS] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -}; - -struct dlci_tty { - const u8 cmdtty; - const u8 datatty; -}; - -static const struct dlci_tty dlci2tty[] = { - {0, 0}, /* DLCI 0 */ - {0, 0}, /* DLCI 1 */ - {1, 1}, /* DLCI 2 */ - {2, 2}, /* DLCI 3 */ - {3, 3}, /* DLCI 4 */ - {4, 4}, /* DLCI 5 */ - {5, 5}, /* DLCI 6 */ - {6, 6}, /* DLCI 7 */ - {7, 7}, /* DLCI 8 */ - {8, 8}, /* DLCI 9 */ - {9, 9}, /* DLCI 10 */ - {10, 10}, /* DLCI 11 */ - {11, 11}, /* DLCI 12 */ - {12, 12}, /* DLCI 13 */ - {13, 13}, /* DLCI 14 */ - {14, 14}, /* DLCI 15 */ - {15, 15}, /* DLCI 16 */ -}; - -enum recv_state { - RECV_STATE_IDLE, - RECV_STATE_ADDR, - RECV_STATE_CONTROL, - RECV_STATE_LEN, - RECV_STATE_LEN2, - RECV_STATE_DATA, - RECV_STATE_END, -}; - -/* Bit number in flags of mux_send_struct */ -struct tty_struct *ts27010mux_tty; - -static u8 crctable[256]; -static struct ts0710_con ts0710_connection; - -#define DBG_DATA (1<<0) -#define DBG_CMD (1<<1) -#define DBG_VERBOSE (1<<2) - -#ifdef DEBUG - -static int debug; - -module_param_named(debug_level, debug, int, S_IRUGO | S_IWUSR); - -#define ts_debug(level, format, arg...) do { \ - if (debug & level) \ - pr_debug(format , ## arg); \ - } while (0) - -#define TS0710_DBG_BUF_SIZE 2048 -static unsigned char dbg_buf[TS0710_DBG_BUF_SIZE]; - -static void ts27010_debughex(int level, const char *header, - const u8 *buf, int len) -{ - int i; - int c; - - if (len <= 0) - return; - - c = 0; - for (i = 0; (i < len) && (c < (TS0710_DBG_BUF_SIZE - 3)); i++) { - sprintf(&dbg_buf[c], "%02x ", buf[i]); - c += 3; - } - dbg_buf[c] = 0; - - ts_debug(level, "%s%s\n", header, dbg_buf); -} - -static void ts27010_debugrbufhex(int level, const char *header, - struct ts27010_ringbuf *rbuf, - int idx, int len) -{ - int i; - int c; - - if (len <= 0) - return; - - c = 0; - for (i = 0; (i < len) && (c < (TS0710_DBG_BUF_SIZE - 3)); i++) { - sprintf(&dbg_buf[c], "%02x ", - ts27010_ringbuf_peek(rbuf, idx+i)); - c += 3; - } - dbg_buf[c] = 0; - - ts_debug(level, "%s%s\n", header, dbg_buf); -} - -static void ts27010_debugrbuf(int level, const char *header, - struct ts27010_ringbuf *rbuf, - int idx, int len) -{ - int i; - - len = min(TS0710_DBG_BUF_SIZE - 1, len); - - for (i = 0; i < len; i++) - dbg_buf[i] = ts27010_ringbuf_peek(rbuf, idx+i); - - if (dbg_buf[i-1] == '\n') - dbg_buf[i-1] = '\0'; - else - dbg_buf[i] = '\0'; - - ts_debug(level, "%s%s\n", header, dbg_buf); -} - -static void ts27010_debugstr(int level, const char *header, - const char *buf, int len) -{ - if (len <= 0) - return; - - len = min(TS0710_DBG_BUF_SIZE - 1, len); - - memcpy(dbg_buf, buf, len); - - if (dbg_buf[len-1] == '\n') - dbg_buf[len-1] = '\0'; - else - dbg_buf[len] = '\0'; - - ts_debug(level, "%s%s\n", header, dbg_buf); -} - -#else /* DEBUG */ - -static inline void ts0710_debughex(u8 *buf, int len) { } -static inline void ts27010_debugrbuf(struct ts27010_ringbuf *rbuf, - int idx, int len) { } -static void ts27010_debugstr(const char *buf, int len) { } -#define ts_debug(level, format, arg...) do { \ - } while (0) - -#endif /* DEBUG */ - - -static int ts0710_valid_dlci(u8 dlci) -{ - if ((dlci < TS0710_MAX_CHN) && (dlci > 0)) - return 1; - else - return 0; -} - -static void ts0710_crc_create_table(u8 table[]) -{ - int i, j; - - u8 data; - u8 code_word = 0xe0; - u8 sr = 0; - - for (j = 0; j < 256; j++) { - data = (u8) j; - - for (i = 0; i < 8; i++) { - if ((data & 0x1) ^ (sr & 0x1)) { - sr >>= 1; - sr ^= code_word; - } else { - sr >>= 1; - } - - data >>= 1; - sr &= 0xff; - } - - table[j] = sr; - sr = 0; - } -} - -static u8 ts0710_crc_start(void) -{ - return 0xff; -} - -static u8 ts0710_crc_calc(u8 fcs, u8 c) -{ - return crctable[fcs ^ c]; -} - -static u8 ts0710_crc_end(u8 fcs) -{ - return 0xff - fcs; -} - -static int ts0710_crc_check(u8 fcs) -{ - return fcs == CRC_VALID; -} - -static u8 ts0710_crc_data(u8 *data, int length) -{ - u8 fcs = ts0710_crc_start(); - - while (length--) - fcs = ts0710_crc_calc(fcs, *data++); - - return ts0710_crc_end(fcs); -} - -static void ts0710_pkt_set_header(u8 *data, int len, int addr_ea, - int addr_cr, int addr_dlci, - int control) -{ - struct short_frame *pkt = (struct short_frame *)(data + 1); - - pkt->h.addr.ea = addr_ea; - pkt->h.addr.cr = addr_cr; - pkt->h.addr.d = addr_dlci & 0x1; - pkt->h.addr.server_chn = addr_dlci >> 1; - pkt->h.control = control; - - if ((len) > SHORT_PAYLOAD_SIZE) { - struct long_frame *long_pkt = (struct long_frame *)(data + 1); - long_pkt->h.length.ea = 0; - long_pkt->h.length.l_len = len & 0x7F; - long_pkt->h.length.h_len = (len >> 7) & 0xFF; - } else { - pkt->h.length.ea = 1; - pkt->h.length.len = len; - } -} - -static void *ts0710_pkt_data(u8 *data) -{ - struct short_frame *pkt = (struct short_frame *)(data + 1); - if (pkt->h.length.ea == 1) - return pkt->data; - else - return pkt->data+1; -} - -static int ts0710_pkt_send(struct ts0710_con *ts0710, u8 *data) -{ - struct short_frame *pkt = (struct short_frame *)(data + 1); - u8 *d; - int len; - int header_len; - int res; - - if (pkt->h.length.ea == 1) { - len = pkt->h.length.len; - d = pkt->data; - header_len = sizeof(*pkt); - } else { - struct long_frame *long_pkt = (struct long_frame *)(data + 1); - len = (long_pkt->h.length.h_len << 7) | - long_pkt->h.length.l_len; - d = pkt->data+1; - header_len = sizeof(*long_pkt); - } - - data[0] = TS0710_BASIC_FLAG; - d[len] = ts0710_crc_data(data+1, header_len); - d[len+1] = TS0710_BASIC_FLAG; - - ts27010_debughex(DBG_VERBOSE, "ts27010: > ", - data, TS0710_FRAME_SIZE(len)); - - if (!ts27010mux_tty) { - pr_warning("ts27010: ldisc closed. discarding %d bytes\n", - TS0710_FRAME_SIZE(len)); - return -ENODEV; - } - - res = ts27010_ldisc_send(ts27010mux_tty, data, - TS0710_FRAME_SIZE(len)); - - if (res < 0) { - pr_err("ts27010: pkt write error %d\n", res); - return res; - } else if (res != TS0710_FRAME_SIZE(len)) { - pr_err("ts27010: short write %d < %d\n", res, - TS0710_FRAME_SIZE(len)); - return -EIO; - } - - return res; - -} - -/* TODO: look at this */ -static void ts0710_reset_dlci(u8 j) -{ - if (j >= TS0710_MAX_CHN) - return; - - ts0710_connection.dlci[j].state = DISCONNECTED; - ts0710_connection.dlci[j].flow_control = 0; - ts0710_connection.dlci[j].mtu = DEF_TS0710_MTU; - init_waitqueue_head(&ts0710_connection.dlci[j].open_wait); - init_waitqueue_head(&ts0710_connection.dlci[j].close_wait); -} - -/* TODO: look at this */ -static void ts0710_reset_con(void) -{ - int j; - - ts0710_connection.mtu = DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE; - - for (j = 0; j < TS0710_MAX_CHN; j++) - ts0710_reset_dlci(j); -} - -static void ts0710_init(void) -{ - ts0710_crc_create_table(crctable); - ts0710_reset_con(); -} - -/* TODO: look at this */ -static void ts0710_upon_disconnect(void) -{ - struct ts0710_con *ts0710 = &ts0710_connection; - int j; - - for (j = 0; j < TS0710_MAX_CHN; j++) { - ts0710->dlci[j].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[j].open_wait); - wake_up_interruptible(&ts0710->dlci[j].close_wait); - } - ts0710_reset_con(); -} - -static int ts27010_send_cmd(struct ts0710_con *ts0710, u8 dlci, u8 cmd) -{ - u8 frame[TS0710_FRAME_SIZE(0)]; - ts0710_pkt_set_header(frame, 0, 1, MCC_RSP, dlci, SET_PF(cmd)); - return ts0710_pkt_send(ts0710, frame); -} - - -static int ts27010_send_ua(struct ts0710_con *ts0710, u8 dlci) -{ - ts_debug(DBG_CMD, "ts27010: sending UA packet to DLCI %d\n", dlci); - return ts27010_send_cmd(ts0710, dlci, UA); -} - -static int ts27010_send_dm(struct ts0710_con *ts0710, u8 dlci) -{ - ts_debug(DBG_CMD, "ts27010: sending DM packet to DLCI %d\n", dlci); - return ts27010_send_cmd(ts0710, dlci, DM); -} - -static int ts27010_send_sabm(struct ts0710_con *ts0710, u8 dlci) -{ - ts_debug(DBG_CMD, "ts27010: sending SABM packet to DLCI %d\n", dlci); - return ts27010_send_cmd(ts0710, dlci, SABM); -} - -static int ts27010_send_disc(struct ts0710_con *ts0710, u8 dlci) -{ - ts_debug(DBG_CMD, "ts27010: sending DISC packet to DLCI %d\n", dlci); - return ts27010_send_cmd(ts0710, dlci, DISC); -} - -static int ts27010_send_uih(struct ts0710_con *ts0710, u8 dlci, - u8 *frame, u8 tag, const u8 *data, int len) -{ - ts_debug(DBG_CMD, - "ts27010: sending %d length UIH packet to DLCI %d\n", - len, dlci); - ts0710_pkt_set_header(frame, len+1, 1, MCC_CMD, dlci, CLR_PF(UIH)); - *(u8 *)ts0710_pkt_data(frame) = tag; - memcpy(ts0710_pkt_data(frame)+1, data, len); - return ts0710_pkt_send(ts0710, frame); -} - -static void ts27010_mcc_set_header(u8 *frame, int len, int cr, int cmd) -{ - struct mcc_short_frame *mcc_pkt; - ts0710_pkt_set_header(frame, sizeof(struct mcc_short_frame) + len, - 1, MCC_CMD, CTRL_CHAN, CLR_PF(UIH)); - - mcc_pkt = ts0710_pkt_data(frame); - mcc_pkt->h.type.ea = EA; - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = cmd; - mcc_pkt->h.length.ea = EA; - mcc_pkt->h.length.len = len; -} - -static void *ts27010_mcc_data(u8 *frame) -{ - return ((struct mcc_short_frame *)ts0710_pkt_data(frame))->value; -} - -static int ts27010_send_pn(struct ts0710_con *ts0710, u8 prior, int frame_size, - u8 credit_flow, u8 credits, u8 dlci, u8 cr) -{ - u8 frame[TS0710_MCC_FRAME_SIZE(sizeof(struct pn_msg_data))]; - struct pn_msg_data *pn; - - ts_debug(DBG_CMD, "ts27010: sending PN MCC\n"); - ts27010_mcc_set_header(frame, sizeof(struct pn_msg_data), cr, PN); - - pn = ts27010_mcc_data(frame); - pn->res1 = 0; - pn->res2 = 0; - pn->dlci = dlci; - pn->frame_type = 0; - pn->credit_flow = credit_flow; - pn->prior = prior; - pn->ack_timer = 0; - pn->frame_sizel = frame_size & 0xff; - pn->frame_sizeh = frame_size >> 8; - pn->credits = credits; - pn->max_nbrof_retrans = 0; - - return ts0710_pkt_send(ts0710, frame); -} - -static int ts27010_send_nsc(struct ts0710_con *ts0710, u8 type, int cr) -{ - u8 frame[TS0710_MCC_FRAME_SIZE(sizeof(struct mcc_type))]; - struct mcc_type *t; - - ts_debug(DBG_CMD, "ts27010: sending NSC MCC\n"); - ts27010_mcc_set_header(frame, sizeof(struct mcc_type), cr, NSC); - - t = ts27010_mcc_data(frame); - t->ea = 1; - t->cr = mcc_is_cmd(type); - t->type = type >> 2; - - return ts0710_pkt_send(ts0710, frame); -} - -static int ts27010_send_msc(struct ts0710_con *ts0710, - u8 value, int cr, u8 dlci) -{ - u8 frame[TS0710_MCC_FRAME_SIZE(sizeof(struct msc_msg_data))]; - struct msc_msg_data *msc; - - ts_debug(DBG_CMD, "ts27010: sending MSC MCC\n"); - ts27010_mcc_set_header(frame, sizeof(struct msc_msg_data), cr, MSC); - - msc = ts27010_mcc_data(frame); - - msc->dlci.ea = 1; - msc->dlci.cr = 1; - msc->dlci.d = dlci & 1; - msc->dlci.server_chn = (dlci >> 1) & 0x1f; - - msc->v24_sigs = value; - - return ts0710_pkt_send(ts0710, frame); -} - -static void ts27010_handle_msc(struct ts0710_con *ts0710, u8 type, - struct ts27010_ringbuf *rbuf, - int data_idx, int len) -{ - u8 dlci; - u8 v24_sigs; - - dlci = ts27010_ringbuf_peek(rbuf, data_idx) >> 2; - v24_sigs = ts27010_ringbuf_peek(rbuf, data_idx + 1); - - if ((ts0710->dlci[dlci].state != CONNECTED) - && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { - ts27010_send_dm(ts0710, dlci); - return; - } - - if (mcc_is_cmd(type)) { - ts_debug(DBG_VERBOSE, - "ts27010: received modem status command\n"); - if (v24_sigs & FC) { - if (ts0710->dlci[dlci].state == CONNECTED) { - ts_debug(DBG_CMD, - "ts27010: flow off on dlci%d\n", dlci); - ts0710->dlci[dlci].state = FLOW_STOPPED; - } - } else { - if (ts0710->dlci[dlci].state == FLOW_STOPPED) { - ts0710->dlci[dlci].state = CONNECTED; - ts_debug(DBG_CMD, - "ts27010: flow on on dlci%d\n", dlci); - /* TODO: flow control not supported */ - } - } - ts27010_send_msc(ts0710, v24_sigs, MCC_RSP, dlci); - } else { - ts_debug(DBG_VERBOSE, - "ts27010: received modem status response\n"); - - if (v24_sigs & FC) - ts_debug(DBG_CMD, "ts27010: flow stop accepted\n"); - } -} - -static void ts27010_handle_pn(struct ts0710_con *ts0710, u8 type, - struct ts27010_ringbuf *rbuf, - int data_idx, int len) -{ - u8 dlci; - u16 frame_size; - struct pn_msg_data pn; - int i; - - if (len != 8) { - pr_err("ts27010: reveived pn on length:%d != 8\n", len); - return; - } - - for (i = 0; i < 8; i++) - ((u8 *)&pn)[i] = ts27010_ringbuf_peek(rbuf, data_idx + i); - - dlci = pn.dlci; - frame_size = pn.frame_sizel | (pn.frame_sizeh << 8); - - if (mcc_is_cmd(type)) { - ts_debug(DBG_CMD, - "ts27010: received PN command with frame size %d\n", - frame_size); - - /* TODO: this looks like it will only ever shrink mtu */ - frame_size = min(frame_size, ts0710->dlci[dlci].mtu); - ts27010_send_pn(ts0710, pn.prior, frame_size, - 0, 0, dlci, MCC_RSP); - ts0710->dlci[dlci].mtu = frame_size; - - ts_debug(DBG_VERBOSE, - "ts27010: mtu set to %d on dlci%d\n", - frame_size, dlci); - } else { - ts_debug(DBG_CMD, - "ts27010: received PN response with frame size %d\n", - frame_size); - - frame_size = min(frame_size, ts0710->dlci[dlci].mtu); - ts0710->dlci[dlci].mtu = frame_size; - - ts_debug(DBG_VERBOSE, "ts27010: mtu set to %d on dlci%d\n", - frame_size, dlci); - - if (ts0710->dlci[dlci].state == NEGOTIATING) { - ts0710->dlci[dlci].state = CONNECTING; - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - } - } -} - - - -static void ts27010_handle_mcc(struct ts0710_con *ts0710, u8 control, - struct ts27010_ringbuf *rbuf, - int data_idx, int len) -{ - u8 type; - u8 mcc_len; - - type = ts27010_ringbuf_peek(rbuf, data_idx++); - len--; - mcc_len = ts27010_ringbuf_peek(rbuf, data_idx++); - len--; - - if (mcc_len != len) { - pr_warning("ts27010: handle_mcc: mcc_len:%d != len:%d\n", - mcc_len, len); - } - - switch (type >> 2) { - case TEST: - pr_warning("ts27010: test command unimplemented\n"); - break; - - case FCON: - ts_debug(DBG_CMD, - "ts27010: received all channels flow control on\n"); - pr_warning("ts27010: flow control unimplemented\n"); - break; - - case FCOFF: - ts_debug(DBG_CMD, - "ts27010: received all channels flow control off\n"); - pr_warning("ts27010: flow control unimplemented\n"); - break; - - case MSC: - ts27010_handle_msc(ts0710, type, rbuf, data_idx, len); - break; - - case PN: - ts27010_handle_pn(ts0710, type, rbuf, data_idx, len); - break; - - case NSC: - pr_warning("ts27010: received non supported cmd response\n"); - break; - - default: - pr_warning("ts27010: received a non supported command\n"); - ts27010_send_nsc(ts0710, type, MCC_RSP); - break; - } -} - -static void ts27010_handle_sabm(struct ts0710_con *ts0710, u8 control, int dlci) -{ - ts_debug(DBG_CMD, "ts27010: SABM received on dlci %d\n", dlci); - - if (ts0710_valid_dlci(dlci)) { - ts27010_send_ua(ts0710, dlci); - - ts0710->dlci[dlci].state = CONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - } else { - pr_warning("ts27010: invalid dlci %d. sending DM\n", dlci); - ts27010_send_dm(ts0710, dlci); - } -} - -static void ts27010_handle_ua(struct ts0710_con *ts0710, u8 control, int dlci) -{ - ts_debug(DBG_CMD, "ts27010: UA packet received on dlci %d\n", dlci); - - if (ts0710_valid_dlci(dlci)) { - if (ts0710->dlci[dlci].state == CONNECTING) { - ts0710->dlci[dlci].state = CONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci]. - open_wait); - } else if (ts0710->dlci[dlci].state == DISCONNECTING) { - if (dlci == 0) { - ts0710_upon_disconnect(); - } else { - ts0710->dlci[dlci].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci]. - open_wait); - wake_up_interruptible(&ts0710->dlci[dlci]. - close_wait); - ts0710_reset_dlci(dlci); - } - } else { - pr_warning("ts27010: invalid UA packet\n"); - } - } else { - pr_warning("ts27010: invalid dlci %d\n", dlci); - } -} - -static void ts27010_handle_dm(struct ts0710_con *ts0710, u8 control, int dlci) -{ - int oldstate; - - ts_debug(DBG_CMD, "ts27010: DM packet received on dlci %d\n", dlci); - - if (dlci == 0) { - oldstate = ts0710->dlci[0].state; - ts0710_upon_disconnect(); - if (oldstate == CONNECTING) - ts0710->dlci[0].state = REJECTED; - } else if (ts0710_valid_dlci(dlci)) { - if (ts0710->dlci[dlci].state == CONNECTING) - ts0710->dlci[dlci].state = REJECTED; - else - ts0710->dlci[dlci].state = DISCONNECTED; - - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - wake_up_interruptible(&ts0710->dlci[dlci].close_wait); - ts0710_reset_dlci(dlci); - } else { - pr_warning("ts27010: invalid dlci %d\n", dlci); - } -} - -static void ts27010_handle_disc(struct ts0710_con *ts0710, u8 control, int dlci) -{ - ts_debug(DBG_CMD, "ts27010: DISC packet received on dlci %d\n", dlci); - - if (!dlci) { - ts27010_send_ua(ts0710, dlci); - ts_debug(DBG_CMD, "ts27010: sending back UA\n"); - - ts0710_upon_disconnect(); - } else if (ts0710_valid_dlci(dlci)) { - ts27010_send_ua(ts0710, dlci); - ts_debug(DBG_CMD, "ts27010: sending back UA\n"); - - ts0710->dlci[dlci].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - wake_up_interruptible(&ts0710->dlci[dlci].close_wait); - ts0710_reset_dlci(dlci); - } else { - pr_warning("ts27010: invalid dlci %d\n", dlci); - } -} - -static void ts27010_handle_uih(struct ts0710_con *ts0710, u8 control, int dlci, - struct ts27010_ringbuf *rbuf, - int data_idx, int len) -{ - int tag; - int tty_idx; - - if ((dlci >= TS0710_MAX_CHN)) { - pr_warning("invalid dlci %d\n", dlci); - ts27010_send_dm(ts0710, dlci); - return; - } - - if (GET_PF(control)) { - pr_warning("ts27010: uih packet with P/F set, discarding.\n"); - return; - } - - if ((ts0710->dlci[dlci].state != CONNECTED) - && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { - pr_warning("ts27010: uih: dlci %d not connected, discarding.\n", - dlci); - ts27010_send_dm(ts0710, dlci); - return; - } - - if (dlci == 0) { - pr_info("ts27010: mcc on channel 0\n"); - ts27010_handle_mcc(ts0710, control, rbuf, data_idx, len); - return; - } - - ts_debug(DBG_CMD, "ts27010: uih on channel %d\n", dlci); - - if (len > ts0710->dlci[dlci].mtu) { - pr_warning("ts27010: dlci%d: uih_len:%d " - "is bigger than mtu:%d, discarding.\n", - dlci, len, ts0710->dlci[dlci].mtu); - return; - } - - tag = ts27010_ringbuf_peek(rbuf, data_idx); - len--; - data_idx++; - - if (len == 0) - return; - - switch (tag) { - case CMDTAG: - tty_idx = dlci2tty[dlci].cmdtty; - ts_debug(DBG_VERBOSE, - "ts27010: CMDTAG on DLCI %d, /dev/mux%d\n", - dlci, tty_idx); - ts27010_debugrbuf(DBG_DATA, "ts27010: dlci[dlci]; - int try; - int retval; - - ts_debug(DBG_CMD, "ts27010: closing dlci %d\n", dlci); - - mutex_lock(&d->lock); - - if (d->clients > 1) { - d->clients--; - mutex_unlock(&d->lock); - return 0; - } - - if (d->state == DISCONNECTED || - d->state == REJECTED || - d->state == DISCONNECTING) { - d->clients--; - mutex_unlock(&d->lock); - return 0; - } - - d->state = DISCONNECTING; - /* Reducing retry to improve recovery times on BP panic/powercycle */ - try = 1; - while (try--) { - retval = ts27010_send_disc(ts0710, dlci); - if (retval < 0) - break; - - mutex_unlock(&d->lock); - retval = wait_event_interruptible_timeout(d->close_wait, - d->state != - DISCONNECTING, - TS0710MUX_TIME_OUT); - mutex_lock(&d->lock); - - if (retval == 0) - continue; - - if (retval == -ERESTARTSYS) { - retval = -EAGAIN; - break; - } - - if (d->state != DISCONNECTED) { - retval = -EIO; - break; - } - - retval = 0; - break; - } - - if (try < 0) - retval = -EIO; - - /* TODO: unclear if this is the right thing to do */ - if (d->state != DISCONNECTED) { - if (dlci == 0) { - ts0710_upon_disconnect(); - } else { - d->state = DISCONNECTED; - wake_up_interruptible(&d->close_wait); - ts0710_reset_dlci(dlci); - } - } - - d->clients--; - - mutex_unlock(&d->lock); - - return retval; -} - -/* call with dlci locked held */ -int ts0710_wait_for_open(struct ts0710_con *ts0710, int dlci) -{ - int try = 8; - int ret; - struct dlci_struct *d = &ts0710->dlci[dlci]; - - while (try--) { - mutex_unlock(&d->lock); - ret = wait_event_interruptible_timeout(d->open_wait, - d->state != CONNECTING, - TS0710MUX_TIME_OUT); - /* - * It is possible that d->state could have changed back to - * to connecting between being woken up and aquiring the lock. - * The side effect is that this open() will return turn -ENODEV. - */ - - mutex_lock(&d->lock); - if (ret == 0) - continue; - - if (ret == -ERESTARTSYS) - return -EAGAIN; - - if (d->state == REJECTED) - return -EREJECTED; - - if (d->state != CONNECTED) - return -ENODEV; - - return 0; - } - - return -ENODEV; -} - - -int ts0710_open_channel(u8 dlci) -{ - struct ts0710_con *ts0710 = &ts0710_connection; - struct dlci_struct *d = &ts0710->dlci[dlci]; - int try; - int retval; - - mutex_lock(&d->lock); - if (d->clients > 0) { - if (d->state == CONNECTED) { - d->clients++; - mutex_unlock(&d->lock); - return 0; - } - - if (d->state != CONNECTING) { - mutex_unlock(&d->lock); - return -EREJECTED; - } - retval = ts0710_wait_for_open(ts0710, dlci); - d->clients++; - mutex_unlock(&d->lock); - return retval; - } - - if (d->state != DISCONNECTED && d->state != REJECTED) { - pr_err("ts27010: DLCI%d: state invalid on open\n", dlci); - mutex_unlock(&d->lock); - return -ENODEV; - } - - /* we are the first to try to open the dlci */ - d->state = CONNECTING; - /* userspace already has a retry mechanism, not needed here */ - try = dlci == 0 ? 10 : 1; - while (try--) { - ts27010_send_sabm(ts0710, dlci); - - mutex_unlock(&d->lock); - retval = wait_event_interruptible_timeout(d->open_wait, - d->state != - CONNECTING, - TS0710MUX_TIME_OUT); - mutex_lock(&d->lock); - - if (retval == 0) - continue; - - if (retval == -ERESTARTSYS) { - retval = -EAGAIN; - break; - } - - if (d->state == REJECTED) { - retval = -EREJECTED; - break; - } - - if (d->state != CONNECTED) { - retval = -ENODEV; - break; - } - - d->clients++; - - retval = 0; - break; - } - - if (try < 0) - retval = -ENODEV; - - if (d->state == CONNECTING) - d->state = DISCONNECTED; - - /* other ttys might be waiting on this dlci */ - wake_up_interruptible(&d->open_wait); - - mutex_unlock(&d->lock); - return retval; -} - -int ts27010_mux_active(void) -{ - return ts27010mux_tty != NULL; -} - - -int ts27010_mux_line_open(int line) -{ - int dlci; - - dlci = tty2dlci[line]; - - /* TODO: need to make sure channel 0 is open */ - - return ts0710_open_channel(dlci); -} - -void ts27010_mux_line_close(int line) -{ - int dlci; - - dlci = tty2dlci[line]; - ts0710_close_channel(dlci); - -} - -int ts27010_mux_line_write(int line, const unsigned char *buf, int count) -{ - /* TODO: this should come from somewhere good */ - struct ts0710_con *ts0710 = &ts0710_connection; - int dlci; - int err; - int c; - u8 tag; - - dlci = tty2dlci[line]; - if (ts0710->dlci[0].state == FLOW_STOPPED) { - /* TODO: this should block */ - pr_info("Flow stopped on all channels, " - "returning zero /dev/mux%d\n", - line); - return 0; - } else if (ts0710->dlci[dlci].state == FLOW_STOPPED) { - /* TODO: this should block */ - pr_info("Flow stopped, returning zero /dev/mux%d\n", line); - return 0; - } else if (ts0710->dlci[dlci].state == CONNECTED) { - mutex_lock(&ts0710->chan[line].write_lock); - - c = min(count, (ts0710->dlci[dlci].mtu - 1)); - if (c <= 0) { - err = 0; - goto err; - } - - ts_debug(DBG_VERBOSE, "ts27010: preparing to send %d bytes " - "from /dev/mux%d\n", c, line); - - if (iscmdtty[line]) { - ts27010_debugstr(DBG_DATA, "ts27010: >C ", buf, c); - ts_debug(DBG_VERBOSE, "CMDTAG\n"); - tag = CMDTAG; - } else { - ts27010_debughex(DBG_DATA, "ts27010: >D ", buf, c); - ts_debug(DBG_VERBOSE, "DATATAG\n"); - tag = DATATAG; - } - - ts27010_send_uih(ts0710, dlci, ts0710->chan[line].buf, - tag, buf, c); - - mutex_unlock(&ts0710->chan[line].write_lock); - - /* - * TODO: should check write notify flag and call back - * into the tty layer - */ - - return c; - } else { - pr_warning("ts27010: write on DLCI %d while not connected\n", - dlci); - return -EDISCONNECTED; - } - -err: - mutex_unlock(&ts0710->chan[line].write_lock); - return err; -} - -int ts27010_mux_line_chars_in_buffer(int line) -{ - struct ts0710_con *ts0710 = &ts0710_connection; - - if (mutex_is_locked(&ts0710->chan[line].write_lock)) - return TS0710MUX_SERIAL_BUF_SIZE; - else - return 0; -} - -int ts27010_mux_line_write_room(int line) -{ - struct ts0710_con *ts0710 = &ts0710_connection; - - if (mutex_is_locked(&ts0710->chan[line].write_lock)) - return 0; - else - return TS0710MUX_SERIAL_BUF_SIZE; -} - - -void ts27010_mux_recv(struct ts27010_ringbuf *rbuf) -{ - int count; - int i; - u8 c; - int state = RECV_STATE_IDLE; - int consume_idx = -1; - int data_idx = 0; - u8 addr = 0; - u8 control = 0; - int len = 0; - u8 fcs = 0; - - count = ts27010_ringbuf_level(rbuf); - - for (i = 0; i < count; i++) { - c = ts27010_ringbuf_peek(rbuf, i); - - switch (state) { - case RECV_STATE_IDLE: - if (c == TS0710_BASIC_FLAG) { - fcs = ts0710_crc_start(); - state = RECV_STATE_ADDR; - } else { - consume_idx = i; - } - break; - - case RECV_STATE_ADDR: - if (c != TS0710_BASIC_FLAG) { - fcs = ts0710_crc_calc(fcs, c); - addr = c; - state = RECV_STATE_CONTROL; - } else { - pr_warning( - "ts27010: RX wrong data. Drop msg.\n"); - consume_idx = i; - } - break; - - case RECV_STATE_CONTROL: - fcs = ts0710_crc_calc(fcs, c); - control = c; - state = RECV_STATE_LEN; - break; - - case RECV_STATE_LEN: - fcs = ts0710_crc_calc(fcs, c); - len = c>>1; - if (c & 0x1) { - data_idx = i+1; - state = RECV_STATE_DATA; - } else { - state = RECV_STATE_LEN2; - } - break; - - case RECV_STATE_LEN2: - fcs = ts0710_crc_calc(fcs, c); - len |= c<<7; - data_idx = i+1; - if (len + data_idx >= LDISC_BUFFER_SIZE) { - pr_warning( - "ts27010: wrong length, Drop msg.\n"); - state = RECV_STATE_IDLE; - consume_idx = i; - break; - } - state = RECV_STATE_DATA; - break; - - case RECV_STATE_DATA: - if (i == data_idx+len) { - /* FCS byte */ - fcs = ts0710_crc_calc(fcs, c); - state = RECV_STATE_END; - } - break; - - case RECV_STATE_END: - if (c == TS0710_BASIC_FLAG && ts0710_crc_check(fcs)) { - ts27010_handle_frame(rbuf, addr, control, - data_idx, len); - } else { - pr_warning("ts27010: lost synchronization\n"); - } - consume_idx = i; - state = RECV_STATE_IDLE; - break; - } - } - - ts27010_ringbuf_consume(rbuf, consume_idx+1); - -} - -static int __init mux_init(void) -{ - int err; - int j; - - ts0710_init(); - - for (j = 0; j < TS0710_MAX_CHN; j++) - mutex_init(&ts0710_connection.dlci[j].lock); - - for (j = 0; j < NR_MUXS; j++) { - ts0710_connection.chan[j].buf = - kmalloc(TS0710MUX_SEND_BUF_SIZE, GFP_KERNEL); - if (ts0710_connection.chan[j].buf == NULL) { - err = -ENOMEM; - goto err0; - } - - mutex_init(&ts0710_connection.chan[j].write_lock); - - } - - err = ts27010_ldisc_init(); - if (err != 0) { - pr_err("ts27010mux: error %d registering line disc.\n", err); - goto err0; - } - - err = ts27010_tty_init(); - if (err != 0) { - pr_err("ts27010mux: error %d registering tty.\n", err); - goto err1; - } - - pr_info("ts27010 mux registered\n"); - - return 0; - -err1: - ts27010_ldisc_remove(); - -err0: - for (j = 0; j < NR_MUXS; j++) - kfree(ts0710_connection.chan[j].buf); - - return err; -} - -static void __exit mux_exit(void) -{ - int j; - - for (j = 0; j < NR_MUXS; j++) - kfree(&ts0710_connection.chan[j].buf); - - ts27010_tty_remove(); - ts27010_ldisc_remove(); -} - -module_init(mux_init); -module_exit(mux_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("TS 07.10 Multiplexer"); diff --git a/drivers/misc/ts27010mux/ts27010_mux.h b/drivers/misc/ts27010mux/ts27010_mux.h deleted file mode 100644 index 3013dd725d88..000000000000 --- a/drivers/misc/ts27010mux/ts27010_mux.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ts27010_mux.h - * - * Copyright (C) 2002, 2004, 2009 Motorola, 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* -* This header file should be included by both MUX and other applications -* which access MUX device files. It gives the additional macro definitions -* shared between MUX and applications. -*/ - -#define NR_MUXS 16 - -#define NUM_MUX_CMD_FILES 16 -#define NUM_MUX_DATA_FILES 0 -#define NUM_MUX_FILES (NUM_MUX_CMD_FILES + NUM_MUX_DATA_FILES) - -#define LDISC_BUFFER_SIZE (4096 - sizeof(struct ts27010_ringbuf)) - -/* TODO: should use the IOCTLNUM macros */ -/* Special ioctl() upon a MUX device file for hanging up a call */ -#define TS0710MUX_IO_MSC_HANGUP 0x54F0 - -/* Special ioctl() upon a MUX device file for MUX loopback test */ -#define TS0710MUX_IO_TEST_CMD 0x54F1 - -/* TODO: get rid of these */ -/* Special Error code might be return from write() to a MUX device file */ -#define EDISCONNECTED 900 /* link is disconnected */ - -/* Special Error code might be return from open() to a MUX device file */ -#define EREJECTED 901 /* link connection request is rejected */ - -/* TODO: goes away with clean tty interface */ -extern struct tty_struct *ts27010mux_tty; - -struct ts27010_ringbuf; - -int ts27010_mux_active(void); -int ts27010_mux_line_open(int line); -void ts27010_mux_line_close(int line); -int ts27010_mux_line_write(int line, const unsigned char *buf, int count); -int ts27010_mux_line_chars_in_buffer(int line); -int ts27010_mux_line_write_room(int line); -void ts27010_mux_recv(struct ts27010_ringbuf *rbuf); - -int ts27010_ldisc_init(void); -void ts27010_ldisc_remove(void); -int ts27010_ldisc_send(struct tty_struct *tty, u8 *data, int len); - - -int ts27010_tty_init(void); -void ts27010_tty_remove(void); -int ts27010_tty_send(int line, u8 *data, int len); -int ts27010_tty_send_rbuf(int line, struct ts27010_ringbuf *rbuf, - int data_idx, int len); - - diff --git a/drivers/misc/ts27010mux/ts27010_ringbuf.h b/drivers/misc/ts27010mux/ts27010_ringbuf.h deleted file mode 100644 index 939143a86a11..000000000000 --- a/drivers/misc/ts27010mux/ts27010_ringbuf.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * simple ring buffer - * - * supports a concurrent reader and writer without locking - */ - - -struct ts27010_ringbuf { - int len; - int head; - int tail; - u8 buf[]; -}; - - -static inline struct ts27010_ringbuf *ts27010_ringbuf_alloc(int len) -{ - struct ts27010_ringbuf *rbuf; - - rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL); - if (rbuf == NULL) - return NULL; - - rbuf->len = len; - rbuf->head = 0; - rbuf->tail = 0; - - return rbuf; -} - -static inline void ts27010_ringbuf_free(struct ts27010_ringbuf *rbuf) -{ - kfree(rbuf); -} - -static inline int ts27010_ringbuf_level(struct ts27010_ringbuf *rbuf) -{ - int level = rbuf->head - rbuf->tail; - - if (level < 0) - level = rbuf->len + level; - - return level; -} - -static inline int ts27010_ringbuf_room(struct ts27010_ringbuf *rbuf) -{ - return rbuf->len - ts27010_ringbuf_level(rbuf) - 1; -} - -static inline u8 ts27010_ringbuf_peek(struct ts27010_ringbuf *rbuf, int i) -{ - return rbuf->buf[(rbuf->tail + i) % rbuf->len]; -} - -static inline int ts27010_ringbuf_consume(struct ts27010_ringbuf *rbuf, - int count) -{ - count = min(count, ts27010_ringbuf_level(rbuf)); - - rbuf->tail = (rbuf->tail + count) % rbuf->len; - - return count; -} - -static inline int ts27010_ringbuf_push(struct ts27010_ringbuf *rbuf, u8 datum) -{ - if (ts27010_ringbuf_room(rbuf) == 0) - return 0; - - rbuf->buf[rbuf->head] = datum; - rbuf->head = (rbuf->head + 1) % rbuf->len; - - return 1; -} - -static inline int ts27010_ringbuf_write(struct ts27010_ringbuf *rbuf, - const u8 *data, int len) -{ - int count = 0; - int i; - - for (i = 0; i < len; i++) - count += ts27010_ringbuf_push(rbuf, data[i]); - - return count; -} - - diff --git a/drivers/misc/ts27010mux/ts27010_tty.c b/drivers/misc/ts27010mux/ts27010_tty.c deleted file mode 100644 index 324954010493..000000000000 --- a/drivers/misc/ts27010mux/ts27010_tty.c +++ /dev/null @@ -1,254 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "ts27010_mux.h" -#include "ts27010_ringbuf.h" - -struct ts27010_tty_channel_data { - atomic_t ref_count; - struct tty_struct *tty; -}; - -struct ts27010_tty_data { - struct ts27010_tty_channel_data chan[NR_MUXS]; -}; - -/* TODO: find a good place to put this */ -struct tty_driver *driver; - -/* TODO: should request a major */ -#define TS0710MUX_MAJOR 245 -#define TS0710MUX_MINOR_START 0 - -int ts27010_tty_send(int line, u8 *data, int len) -{ - struct ts27010_tty_data *td = driver->driver_state; - struct tty_struct *tty = td->chan[line].tty; - - if (!tty) { - pr_info("ts27010: mux%d no open. discarding %d bytes\n", - line, len); - return 0; - } - - BUG_ON(tty_insert_flip_string(tty, data, len) != len); - tty_flip_buffer_push(tty); - return len; -} - -int ts27010_tty_send_rbuf(int line, struct ts27010_ringbuf *rbuf, - int data_idx, int len) -{ - struct ts27010_tty_data *td = driver->driver_state; - struct tty_struct *tty = td->chan[line].tty; - - if (!tty) { - pr_info("ts27010: mux%d no open. discarding %d bytes\n", - line, len); - return 0; - } - - while (len--) { - char c = ts27010_ringbuf_peek(rbuf, data_idx++); - tty_insert_flip_char(tty, c, TTY_NORMAL); - } - tty_flip_buffer_push(tty); - return len; -} - -static int ts27010_tty_open(struct tty_struct *tty, struct file *filp) -{ - struct ts27010_tty_data *td = tty->driver->driver_state; - int err; - int line; - - if (!ts27010_mux_active()) { - pr_err("ts27010: tty open when line discipline not active.\n"); - err = -ENODEV; - goto err; - } - - line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { - pr_err("ts27010: tty index out of range.\n"); - err = -ENODEV; - goto err; - } - - atomic_inc(&td->chan[line].ref_count); - - td->chan[line].tty = tty; - - err = ts27010_mux_line_open(line); - if (err < 0) - goto err; - - return 0; - -err: - return err; -} - - -static void ts27010_tty_close(struct tty_struct *tty, struct file *filp) -{ - struct ts27010_tty_data *td = tty->driver->driver_state; - - if (atomic_dec_and_test(&td->chan[tty->index].ref_count)) { - ts27010_mux_line_close(tty->index); - - td->chan[tty->index].tty = NULL; - - /* - * the old code did: - * wake_up_interruptible(&tty->read_wait); - * wake_up_interruptible(&tty->write_wait); - * - * I belive this is unecessary - */ - } -} - -static int ts27010_tty_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - return ts27010_mux_line_write(tty->index, buf, count); -} - - -static int ts27010_tty_write_room(struct tty_struct *tty) -{ - return ts27010_mux_line_write_room(tty->index); -} - -static void ts27010_tty_flush_buffer(struct tty_struct *tty) -{ - pr_warning("ts27010: flush_buffer not implemented on line %d\n", - tty->index); -} - -static int ts27010_tty_chars_in_buffer(struct tty_struct *tty) -{ - return ts27010_mux_line_chars_in_buffer(tty->index); -} - -static void ts27010_tty_throttle(struct tty_struct *tty) -{ - pr_warning("ts27010: throttle not implemented on line %d\n", - tty->index); -} - -static void ts27010_tty_unthrottle(struct tty_struct *tty) -{ - pr_warning("ts27010: unthrottle not implemented on line %d\n", - tty->index); -} - -static int ts27010_tty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int line; - - line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) - return -ENODEV; - - switch (cmd) { - case TS0710MUX_IO_MSC_HANGUP: - pr_warning("ts27010: ioctl msc_hangup not implemented\n"); - return 0; - - case TS0710MUX_IO_TEST_CMD: - pr_warning("ts27010: ioctl msc_hangup not implemented\n"); - return 0; - - default: - break; - } - - return -ENOIOCTLCMD; -} - -static const struct tty_operations ts27010_tty_ops = { - .open = ts27010_tty_open, - .close = ts27010_tty_close, - .write = ts27010_tty_write, - .write_room = ts27010_tty_write_room, - .flush_buffer = ts27010_tty_flush_buffer, - .chars_in_buffer = ts27010_tty_chars_in_buffer, - .throttle = ts27010_tty_throttle, - .unthrottle = ts27010_tty_unthrottle, - .ioctl = ts27010_tty_ioctl, -}; - -int ts27010_tty_init(void) -{ - struct ts27010_tty_data *td; - int err; - int i; - - driver = alloc_tty_driver(NR_MUXS); - if (driver == NULL) { - err = -ENOMEM; - goto err0; - } - - td = kzalloc(sizeof(*td), GFP_KERNEL); - if (td == NULL) { - err = -ENOMEM; - goto err1; - } - - for (i = 0; i < NR_MUXS; i++) - atomic_set(&td->chan[i].ref_count, 0); - - driver->driver_state = td; - - driver->driver_name = "ts0710mux"; - driver->name = "ts0710mux"; - driver->major = TS0710MUX_MAJOR; - driver->major = 234; - driver->minor_start = TS0710MUX_MINOR_START; - driver->type = TTY_DRIVER_TYPE_SERIAL; - driver->subtype = SERIAL_TYPE_NORMAL; - driver->init_termios = tty_std_termios; - driver->init_termios.c_iflag = 0; - driver->init_termios.c_oflag = 0; - driver->init_termios.c_cflag = B38400 | CS8 | CREAD; - driver->init_termios.c_lflag = 0; - driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; - - driver->other = NULL; - driver->owner = THIS_MODULE; - - tty_set_operations(driver, &ts27010_tty_ops); - - if (tty_register_driver(driver)) { - pr_err("ts27010: can't register tty driver\n"); - err = -EINVAL; - goto err2; - } - - return 0; - -err2: - kfree(td); -err1: - put_tty_driver(driver); -err0: - return err; -} - -void ts27010_tty_remove(void) -{ - struct ts27010_tty_data *td = driver->driver_state; - tty_unregister_driver(driver); - kfree(td); - put_tty_driver(driver); -} - diff --git a/drivers/misc/uid_stat.c b/drivers/misc/uid_stat.c deleted file mode 100644 index 2141124a6c12..000000000000 --- a/drivers/misc/uid_stat.c +++ /dev/null @@ -1,156 +0,0 @@ -/* drivers/misc/uid_stat.c - * - * Copyright (C) 2008 - 2009 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_SPINLOCK(uid_lock); -static LIST_HEAD(uid_list); -static struct proc_dir_entry *parent; - -struct uid_stat { - struct list_head link; - uid_t uid; - atomic_t tcp_rcv; - atomic_t tcp_snd; -}; - -static struct uid_stat *find_uid_stat(uid_t uid) { - unsigned long flags; - struct uid_stat *entry; - - spin_lock_irqsave(&uid_lock, flags); - list_for_each_entry(entry, &uid_list, link) { - if (entry->uid == uid) { - spin_unlock_irqrestore(&uid_lock, flags); - return entry; - } - } - spin_unlock_irqrestore(&uid_lock, flags); - return NULL; -} - -static int tcp_snd_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_snd) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -static int tcp_rcv_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - unsigned int bytes; - char *p = page; - struct uid_stat *uid_entry = (struct uid_stat *) data; - if (!data) - return 0; - - bytes = (unsigned int) (atomic_read(&uid_entry->tcp_rcv) + INT_MIN); - p += sprintf(p, "%u\n", bytes); - len = (p - page) - off; - *eof = (len <= count) ? 1 : 0; - *start = page + off; - return len; -} - -/* Create a new entry for tracking the specified uid. */ -static struct uid_stat *create_stat(uid_t uid) { - unsigned long flags; - char uid_s[32]; - struct uid_stat *new_uid; - struct proc_dir_entry *entry; - - /* Create the uid stat struct and append it to the list. */ - if ((new_uid = kmalloc(sizeof(struct uid_stat), GFP_KERNEL)) == NULL) - return NULL; - - new_uid->uid = uid; - /* Counters start at INT_MIN, so we can track 4GB of network traffic. */ - atomic_set(&new_uid->tcp_rcv, INT_MIN); - atomic_set(&new_uid->tcp_snd, INT_MIN); - - spin_lock_irqsave(&uid_lock, flags); - list_add_tail(&new_uid->link, &uid_list); - spin_unlock_irqrestore(&uid_lock, flags); - - sprintf(uid_s, "%d", uid); - entry = proc_mkdir(uid_s, parent); - - /* Keep reference to uid_stat so we know what uid to read stats from. */ - create_proc_read_entry("tcp_snd", S_IRUGO, entry , tcp_snd_read_proc, - (void *) new_uid); - - create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc, - (void *) new_uid); - - return new_uid; -} - -int uid_stat_tcp_snd(uid_t uid, int size) { - struct uid_stat *entry; - activity_stats_update(); - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - return -1; - } - atomic_add(size, &entry->tcp_snd); - return 0; -} - -int uid_stat_tcp_rcv(uid_t uid, int size) { - struct uid_stat *entry; - activity_stats_update(); - if ((entry = find_uid_stat(uid)) == NULL && - ((entry = create_stat(uid)) == NULL)) { - return -1; - } - atomic_add(size, &entry->tcp_rcv); - return 0; -} - -static int __init uid_stat_init(void) -{ - parent = proc_mkdir("uid_stat", NULL); - if (!parent) { - pr_err("uid_stat: failed to create proc entry\n"); - return -1; - } - return 0; -} - -__initcall(uid_stat_init); diff --git a/drivers/misc/wl127x-rfkill.c b/drivers/misc/wl127x-rfkill.c deleted file mode 100644 index f5b95152948b..000000000000 --- a/drivers/misc/wl127x-rfkill.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Bluetooth TI wl127x rfkill power control via GPIO - * - * Copyright (C) 2009 Motorola, Inc. - * Copyright (C) 2008 Texas Instruments - * Initial code: Pavan Savoy (wl127x_power.c) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -static int wl127x_rfkill_set_power(void *data, enum rfkill_state state) -{ - int nshutdown_gpio = (int) data; - - switch (state) { - case RFKILL_STATE_UNBLOCKED: - gpio_set_value(nshutdown_gpio, 1); - break; - case RFKILL_STATE_SOFT_BLOCKED: - gpio_set_value(nshutdown_gpio, 0); - break; - default: - printk(KERN_ERR "invalid bluetooth rfkill state %d\n", state); - } - return 0; -} - -static int wl127x_rfkill_probe(struct platform_device *pdev) -{ - int rc = 0; - struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; - enum rfkill_state default_state = RFKILL_STATE_SOFT_BLOCKED; /* off */ - - rc = gpio_request(pdata->nshutdown_gpio, "wl127x_nshutdown_gpio"); - if (unlikely(rc)) - return rc; - - rc = gpio_direction_output(pdata->nshutdown_gpio, 0); - if (unlikely(rc)) - return rc; - - rfkill_set_default(RFKILL_TYPE_BLUETOOTH, default_state); - wl127x_rfkill_set_power(NULL, default_state); - - pdata->rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_BLUETOOTH); - if (unlikely(!pdata->rfkill)) - return -ENOMEM; - - pdata->rfkill->name = "wl127x"; - pdata->rfkill->state = default_state; - /* userspace cannot take exclusive control */ - pdata->rfkill->user_claim_unsupported = 1; - pdata->rfkill->user_claim = 0; - pdata->rfkill->data = (void *) pdata->nshutdown_gpio; - pdata->rfkill->toggle_radio = wl127x_rfkill_set_power; - - rc = rfkill_register(pdata->rfkill); - - if (unlikely(rc)) - rfkill_free(pdata->rfkill); - - return 0; -} - -static int wl127x_rfkill_remove(struct platform_device *pdev) -{ - struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; - - rfkill_unregister(pdata->rfkill); - rfkill_free(pdata->rfkill); - gpio_free(pdata->nshutdown_gpio); - - return 0; -} - -static struct platform_driver wl127x_rfkill_platform_driver = { - .probe = wl127x_rfkill_probe, - .remove = wl127x_rfkill_remove, - .driver = { - .name = "wl127x-rfkill", - .owner = THIS_MODULE, - }, -}; - -static int __init wl127x_rfkill_init(void) -{ - return platform_driver_register(&wl127x_rfkill_platform_driver); -} - -static void __exit wl127x_rfkill_exit(void) -{ - platform_driver_unregister(&wl127x_rfkill_platform_driver); -} - -module_init(wl127x_rfkill_init); -module_exit(wl127x_rfkill_exit); - -MODULE_ALIAS("platform:wl127x"); -MODULE_DESCRIPTION("wl127x-rfkill"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 86948f90c3ff..3f2a912659af 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -32,15 +32,6 @@ config MMC_BLOCK_BOUNCE If unsure, say Y here. -config MMC_BLOCK_DEFERRED_RESUME - bool "Deferr MMC layer resume until I/O is requested" - depends on MMC_BLOCK - default n - help - Say Y here to enable deferred MMC resume until I/O - is requested. This will reduce overall resume latency and - save power when theres an SD card inserted but not being used. - config SDIO_UART tristate "SDIO UART/GPS class support" help diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e6f74718e06f..d545f79f6000 100755 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -45,13 +45,6 @@ MODULE_ALIAS("mmc:block"); -#define INAND_CMD38_ARG_EXT_CSD 113 -#define INAND_CMD38_ARG_ERASE 0x00 -#define INAND_CMD38_ARG_TRIM 0x01 -#define INAND_CMD38_ARG_SECERASE 0x80 -#define INAND_CMD38_ARG_SECTRIM1 0x81 -#define INAND_CMD38_ARG_SECTRIM2 0x88 - /* * max 8 partitions per card */ @@ -94,7 +87,11 @@ static void mmc_blk_put(struct mmc_blk_data *md) mutex_lock(&open_lock); md->usage--; if (md->usage == 0) { - int devidx = md->disk->first_minor >> MMC_SHIFT; + int devmaj = MAJOR(disk_devt(md->disk)); + int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; + + if (!devmaj) + devidx = md->disk->first_minor >> MMC_SHIFT; blk_cleanup_queue(md->queue.queue); @@ -272,15 +269,6 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) else arg = MMC_ERASE_ARG; - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - arg == MMC_TRIM_ARG ? - INAND_CMD38_ARG_TRIM : - INAND_CMD38_ARG_ERASE); - if (err) - goto out; - } err = mmc_erase(card, from, nr, arg); out: spin_lock_irq(&md->lock); @@ -315,26 +303,9 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, else arg = MMC_SECURE_ERASE_ARG; - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - arg == MMC_SECURE_TRIM1_ARG ? - INAND_CMD38_ARG_SECTRIM1 : - INAND_CMD38_ARG_SECERASE); - if (err) - goto out; - } err = mmc_erase(card, from, nr, arg); - if (!err && arg == MMC_SECURE_TRIM1_ARG) { - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - INAND_CMD38_ARG_SECTRIM2); - if (err) - goto out; - } + if (!err && arg == MMC_SECURE_TRIM1_ARG) err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); - } out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); @@ -455,8 +426,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) continue; } status = get_card_status(card, req); - } else if (disable_multi == 1) { - disable_multi = 0; } if (brq.cmd.error) { @@ -575,21 +544,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) return 0; } -static int -mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card); - static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) { -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - - if (mmc_bus_needs_resume(card->host)) { - mmc_resume_bus(card->host); - mmc_blk_set_blksize(md, card); - } -#endif - if (req->cmd_flags & REQ_DISCARD) { if (req->cmd_flags & REQ_SECURE) return mmc_blk_issue_secdiscard_rq(mq, req); @@ -651,7 +607,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->disk->private_data = md; md->disk->queue = md->queue.queue; md->disk->driverfs_dev = &card->dev; - md->disk->flags = GENHD_FL_EXT_DEVT; /* * As discussed on lkml, GENHD_FL_REMOVABLE should: @@ -712,20 +667,13 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) if (err) { printk(KERN_ERR "%s: unable to set block size to %d: %d\n", - md->disk->disk_name, cmd.arg, err); + md->disk->disk_name, cmd.arg, err); return -EINVAL; } return 0; } -static const struct mmc_fixup blk_fixups[] = -{ - MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), - MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), - END_FIXUP -}; - static int mmc_blk_probe(struct mmc_card *card) { struct mmc_blk_data *md; @@ -754,11 +702,6 @@ static int mmc_blk_probe(struct mmc_card *card) cap_str, md->read_only ? "(ro)" : ""); mmc_set_drvdata(card, md); - mmc_fixup_device(card, blk_fixups); - -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - mmc_set_bus_resume_policy(card->host, 1); -#endif add_disk(md->disk); return 0; @@ -783,9 +726,6 @@ static void mmc_blk_remove(struct mmc_card *card) mmc_blk_put(md); } mmc_set_drvdata(card, NULL); -#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME - mmc_set_bus_resume_policy(card->host, 0); -#endif } #ifdef CONFIG_PM @@ -804,9 +744,7 @@ static int mmc_blk_resume(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { -#ifndef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_blk_set_blksize(md, card); -#endif mmc_queue_resume(&md->queue); } return 0; diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index 0eba6658233a..bb22ffd76ef8 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -16,20 +16,3 @@ config MMC_UNSAFE_RESUME This option sets a default which can be overridden by the module parameter "removable=0" or "removable=1". - -config MMC_EMBEDDED_SDIO - boolean "MMC embedded SDIO device support (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - If you say Y here, support will be added for embedded SDIO - devices which do not contain the necessary enumeration - support in hardware to be properly detected. - -config MMC_PARANOID_SD_INIT - bool "Enable paranoid SD card initialization (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - If you say Y here, the MMC layer will be extra paranoid - about re-trying SD init requests. This can be a useful - work-around for buggy controllers and hardware. Enable - if you are experiencing issues with SD detection. diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index f25f6a5d6ddd..889e5f898f6f 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_MMC) += mmc_core.o mmc_core-y := core.o bus.o host.o \ mmc.o mmc_ops.o sd.o sd_ops.o \ sdio.o sdio_ops.o sdio_bus.o \ - sdio_cis.o sdio_io.o sdio_irq.o \ - quirks.o + sdio_cis.o sdio_io.o sdio_irq.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ad32bd77321f..09eee6df0653 100755 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -39,7 +38,6 @@ #include "sdio_ops.h" static struct workqueue_struct *workqueue; -static struct wake_lock mmc_delayed_work_wake_lock; /* * Enabling software CRCs on the data blocks can be a significant (30%) @@ -71,7 +69,6 @@ MODULE_PARM_DESC( static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { - wake_lock(&mmc_delayed_work_wake_lock); return queue_delayed_work(workqueue, work, delay); } @@ -548,12 +545,9 @@ void mmc_host_deeper_disable(struct work_struct *work) /* If the host is claimed then we do not want to disable it anymore */ if (!mmc_try_claim_host(host)) - goto out; + return; mmc_host_do_disable(host, 1); mmc_do_release_host(host); - -out: - wake_unlock(&mmc_delayed_work_wake_lock); } /** @@ -913,7 +907,12 @@ static void mmc_power_up(struct mmc_host *host) */ mmc_delay(10); - host->ios.clock = host->f_min; + if (host->f_min > 400000) { + pr_warning("%s: Minimum clock frequency too high for " + "identification mode\n", mmc_hostname(host)); + host->ios.clock = host->f_min; + } else + host->ios.clock = 400000; host->ios.power_mode = MMC_POWER_ON; mmc_set_ios(host); @@ -978,36 +977,6 @@ static inline void mmc_bus_put(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); } -int mmc_resume_bus(struct mmc_host *host) -{ - unsigned long flags; - - if (!mmc_bus_needs_resume(host)) - return -EINVAL; - - printk("%s: Starting deferred resume\n", mmc_hostname(host)); - spin_lock_irqsave(&host->lock, flags); - host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; - host->rescan_disable = 0; - spin_unlock_irqrestore(&host->lock, flags); - - mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead) { - mmc_power_up(host); - BUG_ON(!host->bus_ops->resume); - host->bus_ops->resume(host); - } - - if (host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); - - mmc_bus_put(host); - printk("%s: Deferred resume completed\n", mmc_hostname(host)); - return 0; -} - -EXPORT_SYMBOL(mmc_resume_bus); - /* * Assign a mmc bus handler to a host. Only one bus handler may control a * host at any given time. @@ -1435,7 +1404,6 @@ void mmc_rescan(struct work_struct *work) u32 ocr; int err; unsigned long flags; - int extend_wakelock = 0; spin_lock_irqsave(&host->lock, flags); @@ -1453,12 +1421,6 @@ void mmc_rescan(struct work_struct *work) if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) host->bus_ops->detect(host); - /* If the card was removed the bus will be marked - * as dead - extend the wakelock so userspace - * can respond */ - if (host->bus_dead) - extend_wakelock = 1; - mmc_bus_put(host); @@ -1502,7 +1464,6 @@ void mmc_rescan(struct work_struct *work) if (mmc_attach_sd(host, ocr)) mmc_power_off(host); - extend_wakelock = 1; } goto out; } @@ -1514,7 +1475,6 @@ void mmc_rescan(struct work_struct *work) if (!err) { if (mmc_attach_sd(host, ocr)) mmc_power_off(host); - extend_wakelock = 1; goto out; } @@ -1525,7 +1485,6 @@ void mmc_rescan(struct work_struct *work) if (!err) { if (mmc_attach_mmc(host, ocr)) mmc_power_off(host); - extend_wakelock = 1; goto out; } @@ -1534,11 +1493,6 @@ out_fail: mmc_power_off(host); out: - if (extend_wakelock) - wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2); - else - wake_unlock(&mmc_delayed_work_wake_lock); - if (host->caps & MMC_CAP_NEEDS_POLL) mmc_schedule_delayed_work(&host->detect, HZ); } @@ -1560,7 +1514,7 @@ void mmc_stop_host(struct mmc_host *host) if (host->caps & MMC_CAP_DISABLE) cancel_delayed_work(&host->disable); - cancel_delayed_work_sync(&host->detect); + cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); /* clear pm flags now and let card drivers set them as needed */ @@ -1668,9 +1622,6 @@ int mmc_suspend_host(struct mmc_host *host) { int err = 0; - if (mmc_bus_needs_resume(host)) - return 0; - if (host->caps & MMC_CAP_DISABLE) cancel_delayed_work(&host->disable); cancel_delayed_work(&host->detect); @@ -1713,12 +1664,6 @@ int mmc_resume_host(struct mmc_host *host) int err = 0; mmc_bus_get(host); - if (mmc_bus_manual_resume(host)) { - host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME; - mmc_bus_put(host); - return 0; - } - if (host->bus_ops && !host->bus_dead) { if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { mmc_power_up(host); @@ -1756,10 +1701,6 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_SUSPEND_PREPARE: spin_lock_irqsave(&host->lock, flags); - if (mmc_bus_needs_resume(host)) { - spin_unlock_irqrestore(&host->lock, flags); - break; - } host->rescan_disable = 1; spin_unlock_irqrestore(&host->lock, flags); cancel_delayed_work_sync(&host->detect); @@ -1779,13 +1720,8 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_POST_SUSPEND: case PM_POST_HIBERNATION: - case PM_POST_RESTORE: spin_lock_irqsave(&host->lock, flags); - if (mmc_bus_manual_resume(host)) { - spin_unlock_irqrestore(&host->lock, flags); - break; - } host->rescan_disable = 0; spin_unlock_irqrestore(&host->lock, flags); mmc_detect_change(host, 0); @@ -1796,28 +1732,10 @@ int mmc_pm_notify(struct notifier_block *notify_block, } #endif -#ifdef CONFIG_MMC_EMBEDDED_SDIO -void mmc_set_embedded_sdio_data(struct mmc_host *host, - struct sdio_cis *cis, - struct sdio_cccr *cccr, - struct sdio_embedded_func *funcs, - int num_funcs) -{ - host->embedded_sdio_data.cis = cis; - host->embedded_sdio_data.cccr = cccr; - host->embedded_sdio_data.funcs = funcs; - host->embedded_sdio_data.num_funcs = num_funcs; -} - -EXPORT_SYMBOL(mmc_set_embedded_sdio_data); -#endif - static int __init mmc_init(void) { int ret; - wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND, "mmc_delayed_work"); - workqueue = create_singlethread_workqueue("kmmcd"); if (!workqueue) return -ENOMEM; @@ -1852,7 +1770,6 @@ static void __exit mmc_exit(void) mmc_unregister_host_class(); mmc_unregister_bus(); destroy_workqueue(workqueue); - wake_lock_destroy(&mmc_delayed_work_wake_lock); } subsys_initcall(mmc_init); diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index ba684e6d2b6b..d80cfdc8edd2 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -137,8 +137,7 @@ int mmc_add_host(struct mmc_host *host) #endif mmc_start_host(host); - if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) - register_pm_notifier(&host->pm_notify); + register_pm_notifier(&host->pm_notify); return 0; } @@ -155,9 +154,7 @@ EXPORT_SYMBOL(mmc_add_host); */ void mmc_remove_host(struct mmc_host *host) { - if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) - unregister_pm_notifier(&host->pm_notify); - + unregister_pm_notifier(&host->pm_notify); mmc_stop_host(host); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index b6d75eec4b36..326447c9ede8 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -387,15 +387,6 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) return err; } -/** - * mmc_switch - modify EXT_CSD register - * @card: the MMC card associated with the data transfer - * @set: cmd set values - * @index: EXT_CSD register index - * @value: value to program into EXT_CSD register - * - * Modifies the EXT_CSD register for selected card. - */ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) { int err; @@ -443,8 +434,6 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) return 0; } -EXPORT_SYMBOL(mmc_switch); - int mmc_send_status(struct mmc_card *card, u32 *status) { int err; diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index b1a806fbd396..653eb8e84178 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -20,6 +20,7 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid); int mmc_set_relative_addr(struct mmc_card *card); int mmc_send_csd(struct mmc_card *card, u32 *csd); int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); +int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); int mmc_send_status(struct mmc_card *card, u32 *status); int mmc_send_cid(struct mmc_host *host, u32 *cid); int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c deleted file mode 100644 index 981c11343f45..000000000000 --- a/drivers/mmc/core/quirks.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file contains work-arounds for many known sdio hardware - * bugs. - * - * Copyright (c) 2011 Pierre Tardy - * Inspired from pci fixup code: - * Copyright (c) 1999 Martin Mares - * - */ - -#include -#include -#include - -static const struct mmc_fixup mmc_fixup_methods[] = { - END_FIXUP -}; - -void mmc_fixup_device(struct mmc_card *card, - const struct mmc_fixup *table) -{ - const struct mmc_fixup *f; - u64 rev = cid_rev_card(card); - - /* Non-core specific workarounds. */ - if (!table) - table = mmc_fixup_methods; - - for (f = table; f->vendor_fixup; f++) { - if ((f->manfid == CID_MANFID_ANY - || f->manfid == card->cid.manfid) && - (f->oemid == CID_OEMID_ANY - || f->oemid == card->cid.oemid) && - (f->name == CID_NAME_ANY - || !strcmp(f->name, card->cid.prod_name)) && - (f->cis_vendor == card->cis.vendor - || f->cis_vendor == (u16) SDIO_ANY_ID) && - (f->cis_device == card->cis.device - || f->cis_device == (u16) SDIO_ANY_ID) && - rev >= f->rev_start && - rev <= f->rev_end) { - dev_dbg(&card->dev, "calling %pF\n", f->vendor_fixup); - f->vendor_fixup(card, f->data); - } - } -} -EXPORT_SYMBOL(mmc_fixup_device); - diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7ab8fdc61c77..0f5241085557 100755 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -455,9 +455,6 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, bool reinit) { int err; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif if (!reinit) { /* @@ -484,26 +481,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, /* * Fetch switch information from card. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - for (retries = 1; retries <= 3; retries++) { - err = mmc_read_switch(card); - if (!err) { - if (retries > 1) { - printk(KERN_WARNING - "%s: recovered\n", - mmc_hostname(host)); - } - break; - } else { - printk(KERN_WARNING - "%s: read switch failed (attempt %d)\n", - mmc_hostname(host), retries); - } - } -#else err = mmc_read_switch(card); -#endif - if (err) return err; } @@ -684,36 +662,18 @@ static void mmc_sd_remove(struct mmc_host *host) */ static void mmc_sd_detect(struct mmc_host *host) { - int err = 0; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries = 5; -#endif + int err; BUG_ON(!host); BUG_ON(!host->card); - + mmc_claim_host(host); /* * Just check if our card has been removed. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - while(retries) { - err = mmc_send_status(host->card, NULL); - if (err) { - retries--; - udelay(5); - continue; - } - break; - } - if (!retries) { - printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n", - __func__, mmc_hostname(host), err); - } -#else err = mmc_send_status(host->card, NULL); -#endif + mmc_release_host(host); if (err) { @@ -751,31 +711,12 @@ static int mmc_sd_suspend(struct mmc_host *host) static int mmc_sd_resume(struct mmc_host *host) { int err; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); -#ifdef CONFIG_MMC_PARANOID_SD_INIT - retries = 5; - while (retries) { - err = mmc_sd_init_card(host, host->ocr, host->card); - - if (err) { - printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n", - mmc_hostname(host), err, retries); - mdelay(5); - retries--; - continue; - } - break; - } -#else err = mmc_sd_init_card(host, host->ocr, host->card); -#endif mmc_release_host(host); return err; @@ -822,9 +763,6 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host) int mmc_attach_sd(struct mmc_host *host, u32 ocr) { int err; -#ifdef CONFIG_MMC_PARANOID_SD_INIT - int retries; -#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -873,27 +811,9 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) /* * Detect and init the card. */ -#ifdef CONFIG_MMC_PARANOID_SD_INIT - retries = 5; - while (retries) { - err = mmc_sd_init_card(host, host->ocr, NULL); - if (err) { - retries--; - continue; - } - break; - } - - if (!retries) { - printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n", - mmc_hostname(host), err); - goto err; - } -#else err = mmc_sd_init_card(host, host->ocr, NULL); if (err) goto err; -#endif mmc_release_host(host); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index d3ec4dc18d14..f332c52968b7 100755 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -25,10 +25,6 @@ #include "sdio_ops.h" #include "sdio_cis.h" -#ifdef CONFIG_MMC_EMBEDDED_SDIO -#include -#endif - static int sdio_read_fbr(struct sdio_func *func) { int ret; @@ -262,13 +258,11 @@ static int mmc_sdio_switch_hs(struct mmc_card *card, int enable) int ret; u8 speed; - if (!(card->host->caps & MMC_CAP_FORCE_HS)) { - if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) - return 0; + if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) + return 0; - if (!card->cccr.high_speed) - return 0; - } + if (!card->cccr.high_speed) + return 0; ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); if (ret) @@ -440,35 +434,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, goto finish; } -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.cccr) - memcpy(&card->cccr, host->embedded_sdio_data.cccr, sizeof(struct sdio_cccr)); - else { -#endif - /* - * Read the common registers. - */ - err = sdio_read_cccr(card); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + /* + * Read the common registers. + */ + err = sdio_read_cccr(card); + if (err) + goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.cis) - memcpy(&card->cis, host->embedded_sdio_data.cis, sizeof(struct sdio_cis)); - else { -#endif - /* - * Read the common CIS tuples. - */ - err = sdio_read_common_cis(card); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + /* + * Read the common CIS tuples. + */ + err = sdio_read_common_cis(card); + if (err) + goto remove; if (oldcard) { int same = (card->cis.vendor == oldcard->cis.vendor && @@ -480,7 +458,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, card = oldcard; return 0; } - mmc_fixup_device(card, NULL); if (card->type == MMC_TYPE_SD_COMBO) { err = mmc_sd_setup_card(host, card, oldcard != NULL); @@ -728,36 +705,13 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) funcs = (ocr & 0x70000000) >> 28; card->sdio_funcs = 0; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.funcs) - card->sdio_funcs = funcs = host->embedded_sdio_data.num_funcs; -#endif - /* * Initialize (but don't add) all present functions. */ for (i = 0; i < funcs; i++, card->sdio_funcs++) { -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (host->embedded_sdio_data.funcs) { - struct sdio_func *tmp; - - tmp = sdio_alloc_func(host->card); - if (IS_ERR(tmp)) - goto remove; - tmp->num = (i + 1); - card->sdio_func[i] = tmp; - tmp->class = host->embedded_sdio_data.funcs[i].f_class; - tmp->max_blksize = host->embedded_sdio_data.funcs[i].f_maxblksize; - tmp->vendor = card->cis.vendor; - tmp->device = card->cis.device; - } else { -#endif - err = sdio_init_func(host->card, i + 1); - if (err) - goto remove; -#ifdef CONFIG_MMC_EMBEDDED_SDIO - } -#endif + err = sdio_init_func(host->card, i + 1); + if (err) + goto remove; } mmc_release_host(host); @@ -799,77 +753,3 @@ err: return err; } -int sdio_reset_comm(struct mmc_card *card) -{ - struct mmc_host *host = card->host; - u32 ocr; - int err; - - printk("%s():\n", __func__); - mmc_claim_host(host); - - mmc_go_idle(host); - - mmc_set_clock(host, host->f_min); - - err = mmc_send_io_op_cond(host, 0, &ocr); - if (err) - goto err; - - host->ocr = mmc_select_voltage(host, ocr); - if (!host->ocr) { - err = -EINVAL; - goto err; - } - - err = mmc_send_io_op_cond(host, host->ocr, &ocr); - if (err) - goto err; - - if (mmc_host_is_spi(host)) { - err = mmc_spi_set_crc(host, use_spi_crc); - if (err) - goto err; - } - - if (!mmc_host_is_spi(host)) { - err = mmc_send_relative_addr(host, &card->rca); - if (err) - goto err; - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); - } - if (!mmc_host_is_spi(host)) { - err = mmc_select_card(card); - if (err) - goto err; - } - - /* - * Switch to high-speed (if supported). - */ - err = sdio_enable_hs(card); - if (err > 0) - mmc_sd_go_highspeed(card); - else if (err) - goto err; - - /* - * Change to the card's maximum speed. - */ - mmc_set_clock(host, mmc_sdio_get_max_clock(card)); - - err = sdio_enable_4bit_bus(card); - if (err > 0) - mmc_set_bus_width(host, MMC_BUS_WIDTH_4); - else if (err) - goto err; - - mmc_release_host(host); - return 0; -err: - printk("%s: Error resetting SDIO communications (%d)\n", - mmc_hostname(host), err); - mmc_release_host(host); - return err; -} -EXPORT_SYMBOL(sdio_reset_comm); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index f59f92554482..4a890dcb95ab 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -21,10 +21,6 @@ #include "sdio_cis.h" #include "sdio_bus.h" -#ifdef CONFIG_MMC_EMBEDDED_SDIO -#include -#endif - /* show configuration fields */ #define sdio_config_attr(field, format_string) \ static ssize_t \ @@ -204,14 +200,7 @@ static void sdio_release_func(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); -#ifdef CONFIG_MMC_EMBEDDED_SDIO - /* - * If this device is embedded then we never allocated - * cis tables for this func - */ - if (!func->card->host->embedded_sdio_data.funcs) -#endif - sdio_free_func_cis(func); + sdio_free_func_cis(func); if (func->info) kfree(func->info); diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 549a34144646..0f687cdeb064 100755 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -382,39 +382,6 @@ u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret) } EXPORT_SYMBOL_GPL(sdio_readb); -/** - * sdio_readb_ext - read a single byte from a SDIO function - * @func: SDIO function to access - * @addr: address to read - * @err_ret: optional status value from transfer - * @in: value to add to argument - * - * Reads a single byte from the address space of a given SDIO - * function. If there is a problem reading the address, 0xff - * is returned and @err_ret will contain the error code. - */ -unsigned char sdio_readb_ext(struct sdio_func *func, unsigned int addr, - int *err_ret, unsigned in) -{ - int ret; - unsigned char val; - - BUG_ON(!func); - - if (err_ret) - *err_ret = 0; - - ret = mmc_io_rw_direct(func->card, 0, func->num, addr, (u8)in, &val); - if (ret) { - if (err_ret) - *err_ret = ret; - return 0xFF; - } - - return val; -} -EXPORT_SYMBOL_GPL(sdio_readb_ext); - /** * sdio_writeb - write a single byte to a SDIO function * @func: SDIO function to access diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7ce601d3b281..886dbc95f135 100755 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -454,12 +454,6 @@ config MMC_TMIO This provides support for the SD/MMC cell found in TC6393XB, T7L66XB and also HTC ASIC3 -config MMC_SDHCI_TEGRA - tristate "Tegra SD/MMC Controller Support" - depends on ARCH_TEGRA && MMC_SDHCI - help - This selects the Tegra SD/MMC controller. - config MMC_CB710 tristate "ENE CB710 MMC/SD Interface support" depends on PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index ba4c798b7cf6..840bcb52d82f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o -obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 57bb421ba1b2..87226cd202a5 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -69,7 +69,6 @@ #include #include -#include #include #include @@ -494,14 +493,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command else if (data->flags & MMC_DATA_WRITE) cmdr |= AT91_MCI_TRCMD_START; - if (cmd->opcode == SD_IO_RW_EXTENDED) { - cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK; - } else { - if (data->flags & MMC_DATA_STREAM) - cmdr |= AT91_MCI_TRTYP_STREAM; - if (data->blocks > 1) - cmdr |= AT91_MCI_TRTYP_MULTIPLE; - } + if (data->flags & MMC_DATA_STREAM) + cmdr |= AT91_MCI_TRTYP_STREAM; + if (data->blocks > 1) + cmdr |= AT91_MCI_TRTYP_MULTIPLE; } else { block_length = 0; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 3a569bfe3886..95ef864ad8f9 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -533,17 +532,12 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, data = cmd->data; if (data) { cmdr |= MCI_CMDR_START_XFER; - - if (cmd->opcode == SD_IO_RW_EXTENDED) { - cmdr |= MCI_CMDR_SDIO_BLOCK; - } else { - if (data->flags & MMC_DATA_STREAM) - cmdr |= MCI_CMDR_STREAM; - else if (data->blocks > 1) - cmdr |= MCI_CMDR_MULTI_BLOCK; - else - cmdr |= MCI_CMDR_BLOCK; - } + if (data->flags & MMC_DATA_STREAM) + cmdr |= MCI_CMDR_STREAM; + else if (data->blocks > 1) + cmdr |= MCI_CMDR_MULTI_BLOCK; + else + cmdr |= MCI_CMDR_BLOCK; if (data->flags & MMC_DATA_READ) cmdr |= MCI_CMDR_TRDIR_READ; diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c deleted file mode 100644 index 793915f8b239..000000000000 --- a/drivers/mmc/host/sdhci-tegra.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * drivers/mmc/host/sdhci-tegra.c - * - * Copyright (C) 2009 Palm, Inc. - * Author: Yvonne Yip - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "sdhci.h" - -#define DRIVER_NAME "sdhci-tegra" - -#define SDHCI_VENDOR_CLOCK_CNTRL 0x100 - -struct tegra_sdhci_host { - struct sdhci_host *sdhci; - struct clk *clk; - struct tegra_sdhci_platform_data *plat; - int clk_enabled; -}; - -static irqreturn_t carddetect_irq(int irq, void *data) -{ - struct sdhci_host *sdhost = (struct sdhci_host *)data; - - sdhci_card_detect_callback(sdhost); - return IRQ_HANDLED; -}; - -static void sdhci_status_notify_cb(int card_present, void *dev_id) -{ - struct sdhci_host *host = (struct sdhci_host *)dev_id; - struct tegra_sdhci_host *tegra_host = sdhci_priv(host); - unsigned int status, oldstat; - - pr_debug("%s: card_present %d\n", mmc_hostname(host->mmc), - card_present); - - if (!tegra_host->plat->mmc_data.status) { - mmc_detect_change(host->mmc, 0); - return; - } - - status = tegra_host->plat->mmc_data.status(mmc_dev(host->mmc)); - - oldstat = host->card_present; - host->card_present = status; - if (status ^ oldstat) { - pr_debug("%s: Slot status change detected (%d -> %d)\n", - mmc_hostname(host->mmc), oldstat, status); - if (status && !tegra_host->plat->mmc_data.built_in) - mmc_detect_change(host->mmc, (5 * HZ) / 2); - else - mmc_detect_change(host->mmc, 0); - } -} - -static int tegra_sdhci_enable_dma(struct sdhci_host *host) -{ - return 0; -} - -static void tegra_sdhci_enable_clock(struct tegra_sdhci_host *host, int enable) -{ - if (enable && !host->clk_enabled) { - clk_enable(host->clk); - sdhci_writeb(host->sdhci, 1, SDHCI_VENDOR_CLOCK_CNTRL); - host->clk_enabled = 1; - } else if (!enable && host->clk_enabled) { - sdhci_writeb(host->sdhci, 0, SDHCI_VENDOR_CLOCK_CNTRL); - clk_disable(host->clk); - host->clk_enabled = 0; - } -} - -static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock) -{ - struct tegra_sdhci_host *host = sdhci_priv(sdhci); - pr_debug("tegra sdhci clock %s %u enabled=%d\n", - mmc_hostname(sdhci->mmc), clock, host->clk_enabled); - - tegra_sdhci_enable_clock(host, clock); -} - -static struct sdhci_ops tegra_sdhci_ops = { - .enable_dma = tegra_sdhci_enable_dma, - .set_clock = tegra_sdhci_set_clock, -}; - -static int __devinit tegra_sdhci_probe(struct platform_device *pdev) -{ - int rc; - struct tegra_sdhci_platform_data *plat; - struct sdhci_host *sdhci; - struct tegra_sdhci_host *host; - struct resource *res; - int irq; - void __iomem *ioaddr; - - plat = pdev->dev.platform_data; - if (plat == NULL) - return -ENXIO; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) - return -ENODEV; - - irq = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) - return -ENODEV; - - ioaddr = ioremap(res->start, res->end - res->start); - - sdhci = sdhci_alloc_host(&pdev->dev, sizeof(struct tegra_sdhci_host)); - if (IS_ERR(sdhci)) { - rc = PTR_ERR(sdhci); - goto err_unmap; - } - - host = sdhci_priv(sdhci); - host->sdhci = sdhci; - host->plat = plat; - -#ifdef CONFIG_MMC_EMBEDDED_SDIO - if (plat->mmc_data.embedded_sdio) - mmc_set_embedded_sdio_data(sdhci->mmc, - &plat->mmc_data.embedded_sdio->cis, - &plat->mmc_data.embedded_sdio->cccr, - plat->mmc_data.embedded_sdio->funcs, - plat->mmc_data.embedded_sdio->num_funcs); -#endif - - host->clk = clk_get(&pdev->dev, plat->clk_id); - if (IS_ERR(host->clk)) { - rc = PTR_ERR(host->clk); - goto err_free_host; - } - - rc = clk_enable(host->clk); - if (rc != 0) - goto err_clkput; - - host->clk_enabled = 1; - sdhci->hw_name = "tegra"; - sdhci->ops = &tegra_sdhci_ops; - sdhci->irq = irq; - sdhci->ioaddr = ioaddr; - sdhci->version = SDHCI_SPEC_200; - sdhci->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | - SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_ENABLE_INTERRUPT_AT_BLOCK_GAP | - SDHCI_QUIRK_BROKEN_WRITE_PROTECT | - SDHCI_QUIRK_BROKEN_CTRL_HISPD | - SDHCI_QUIRK_NO_HISPD_BIT | - SDHCI_QUIRK_8_BIT_DATA | - SDHCI_QUIRK_NO_VERSION_REG | - SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | - SDHCI_QUIRK_NO_SDIO_IRQ; - - if (plat->force_hs != 0) - sdhci->quirks |= SDHCI_QUIRK_FORCE_HIGH_SPEED_MODE; - - sdhci->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY; - if (plat->mmc_data.built_in) - sdhci->mmc->pm_flags = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY; - - if (plat->rt_disable != 0) - sdhci->quirks |= SDHCI_QUIRK_RUNTIME_DISABLE; - - rc = sdhci_add_host(sdhci); - if (rc) - goto err_clk_disable; - - platform_set_drvdata(pdev, host); - - if (plat->cd_gpio != -1) { - rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - mmc_hostname(sdhci->mmc), sdhci); - - if (rc) - goto err_remove_host; - } else if (plat->mmc_data.register_status_notify) { - plat->mmc_data.register_status_notify(sdhci_status_notify_cb, sdhci); - } - - if (plat->mmc_data.status) { - sdhci->card_present = host->plat->mmc_data.status(mmc_dev(sdhci->mmc)); - } - - if (plat->board_probe) - plat->board_probe(pdev->id, sdhci->mmc); - - printk(KERN_INFO "sdhci%d: initialized irq %d ioaddr %p\n", pdev->id, - sdhci->irq, sdhci->ioaddr); - - return 0; - -err_remove_host: - sdhci_remove_host(sdhci, 1); -err_clk_disable: - clk_disable(host->clk); -err_clkput: - clk_put(host->clk); -err_free_host: - if (sdhci) - sdhci_free_host(sdhci); -err_unmap: - iounmap(sdhci->ioaddr); - - return rc; -} - -static int tegra_sdhci_remove(struct platform_device *pdev) -{ - struct tegra_sdhci_host *host = platform_get_drvdata(pdev); - if (host) { - struct tegra_sdhci_platform_data *plat; - plat = pdev->dev.platform_data; - if (plat && plat->board_probe) - plat->board_probe(pdev->id, host->sdhci->mmc); - - sdhci_remove_host(host->sdhci, 0); - sdhci_free_host(host->sdhci); - } - return 0; -} - -#ifdef CONFIG_PM -static int tegra_sdhci_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct tegra_sdhci_host *host = platform_get_drvdata(pdev); - struct mmc_host *mmc = host->sdhci->mmc; - int ret; - - if (host->plat->mmc_data.built_in) - mmc->pm_flags |= MMC_PM_KEEP_POWER; - - ret = sdhci_suspend_host(host->sdhci, state); - if (ret) - pr_err("%s: failed, error = %d\n", __func__, ret); - - tegra_sdhci_enable_clock(host, 0); - return ret; -} - -static int tegra_sdhci_resume(struct platform_device *pdev) -{ - struct tegra_sdhci_host *host = platform_get_drvdata(pdev); - int ret; - - tegra_sdhci_enable_clock(host, 1); - ret = sdhci_resume_host(host->sdhci); - if (ret) - pr_err("%s: failed, error = %d\n", __func__, ret); - - return ret; -} -#else -#define tegra_sdhci_suspend NULL -#define tegra_sdhci_resume NULL -#endif - -static struct platform_driver tegra_sdhci_driver = { - .probe = tegra_sdhci_probe, - .remove = tegra_sdhci_remove, - .suspend = tegra_sdhci_suspend, - .resume = tegra_sdhci_resume, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init tegra_sdhci_init(void) -{ - return platform_driver_register(&tegra_sdhci_driver); -} - -static void __exit tegra_sdhci_exit(void) -{ - platform_driver_unregister(&tegra_sdhci_driver); -} - -module_init(tegra_sdhci_init); -module_exit(tegra_sdhci_exit); - -MODULE_DESCRIPTION("Tegra SDHCI controller driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ba32a2ef93a1..401527d273b5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -24,7 +24,6 @@ #include #include -#include #include "sdhci.h" @@ -988,7 +987,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) u16 clk; unsigned long timeout; - if (clock && clock == host->clock) + if (clock == host->clock) return; if (host->ops->set_clock) { @@ -1030,7 +1029,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); out: - host->clock = clock; } @@ -1179,6 +1177,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->bus_width == MMC_BUS_WIDTH_4) ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; if (ios->timing == MMC_TIMING_SD_HS && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) @@ -1211,47 +1211,16 @@ static int sdhci_get_ro(struct mmc_host *mmc) spin_lock_irqsave(&host->lock, flags); - if (host->flags & SDHCI_DEVICE_DEAD) { + if (host->flags & SDHCI_DEVICE_DEAD) present = 0; - } else if (!(host->quirks & SDHCI_QUIRK_BROKEN_WRITE_PROTECT)) { + else present = sdhci_readl(host, SDHCI_PRESENT_STATE); - present = !(present & SDHCI_WRITE_PROTECT); - } else if (host->ops->get_ro) { - present = host->ops->get_ro(host); - } else { - present = 0; - } spin_unlock_irqrestore(&host->lock, flags); if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT) return !!(present & SDHCI_WRITE_PROTECT); - return present; -} - -static int sdhci_enable(struct mmc_host *mmc) -{ - struct sdhci_host *host = mmc_priv(mmc); - - if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO) - return 0; - - if (mmc->ios.clock) - sdhci_set_clock(host, mmc->ios.clock); - - return 0; -} - -static int sdhci_disable(struct mmc_host *mmc, int lazy) -{ - struct sdhci_host *host = mmc_priv(mmc); - - if (!mmc->card || mmc->card->type == MMC_TYPE_SDIO) - return 0; - - sdhci_set_clock(host, 0); - - return 0; + return !(present & SDHCI_WRITE_PROTECT); } static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) @@ -1270,16 +1239,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT); else sdhci_mask_irqs(host, SDHCI_INT_CARD_INT); - - if (host->quirks & SDHCI_QUIRK_ENABLE_INTERRUPT_AT_BLOCK_GAP) { - u8 gap_ctrl = readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); - if (enable) - gap_ctrl |= 0x8; - else - gap_ctrl &= ~0x8; - writeb(gap_ctrl, host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); - } - out: mmiowb(); @@ -1290,15 +1249,22 @@ static const struct mmc_host_ops sdhci_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, .get_ro = sdhci_get_ro, - .enable = sdhci_enable, - .disable = sdhci_disable, .enable_sdio_irq = sdhci_enable_sdio_irq, }; -void sdhci_card_detect_callback(struct sdhci_host *host) +/*****************************************************************************\ + * * + * Tasklets * + * * +\*****************************************************************************/ + +static void sdhci_tasklet_card(unsigned long param) { + struct sdhci_host *host; unsigned long flags; + host = (struct sdhci_host*)param; + spin_lock_irqsave(&host->lock, flags); if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { @@ -1320,22 +1286,6 @@ void sdhci_card_detect_callback(struct sdhci_host *host) mmc_detect_change(host->mmc, msecs_to_jiffies(200)); } -EXPORT_SYMBOL_GPL(sdhci_card_detect_callback); - -/*****************************************************************************\ - * * - * Tasklets * - * * -\*****************************************************************************/ - -static void sdhci_tasklet_card(unsigned long param) -{ - struct sdhci_host *host; - - host = (struct sdhci_host *)param; - - sdhci_card_detect_callback(host); -} static void sdhci_tasklet_finish(unsigned long param) { @@ -1447,8 +1397,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) host->cmd->error = -EILSEQ; if (host->cmd->error) { - if (intmask & SDHCI_INT_RESPONSE) - tasklet_schedule(&host->finish_tasklet); + tasklet_schedule(&host->finish_tasklet); return; } @@ -1661,22 +1610,19 @@ out: int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) { - int ret = 0; - struct mmc_host *mmc = host->mmc; + int ret; sdhci_disable_card_detection(host); - if (mmc->card && (mmc->card->type != MMC_TYPE_SDIO)) - ret = mmc_suspend_host(host->mmc); + ret = mmc_suspend_host(host->mmc); + if (ret) + return ret; - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK); + free_irq(host->irq, host); if (host->vmmc) ret = regulator_disable(host->vmmc); - if (host->irq) - disable_irq(host->irq); - return ret; } @@ -1684,8 +1630,7 @@ EXPORT_SYMBOL_GPL(sdhci_suspend_host); int sdhci_resume_host(struct sdhci_host *host) { - int ret = 0; - struct mmc_host *mmc = host->mmc; + int ret; if (host->vmmc) { int ret = regulator_enable(host->vmmc); @@ -1699,15 +1644,15 @@ int sdhci_resume_host(struct sdhci_host *host) host->ops->enable_dma(host); } - if (host->irq) - enable_irq(host->irq); + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, + mmc_hostname(host->mmc), host); + if (ret) + return ret; sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); mmiowb(); - if (mmc->card && (mmc->card->type != MMC_TYPE_SDIO)) - ret = mmc_resume_host(host->mmc); - + ret = mmc_resume_host(host->mmc); sdhci_enable_card_detection(host); return ret; @@ -1760,12 +1705,9 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_reset(host, SDHCI_RESET_ALL); - if (!(host->quirks & SDHCI_QUIRK_NO_VERSION_REG)) { - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - host->version = (host->version & SDHCI_SPEC_VER_MASK) - >> SDHCI_SPEC_VER_SHIFT; - } - + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + host->version = (host->version & SDHCI_SPEC_VER_MASK) + >> SDHCI_SPEC_VER_SHIFT; if (host->version > SDHCI_SPEC_200) { printk(KERN_ERR "%s: Unknown controller version (%d). " "You may experience problems.\n", mmc_hostname(mmc), @@ -1876,35 +1818,17 @@ int sdhci_add_host(struct sdhci_host *host) else mmc->f_min = host->max_clk / 256; mmc->f_max = host->max_clk; - mmc->caps = 0; - - if (host->quirks & SDHCI_QUIRK_8_BIT_DATA) - mmc->caps |= MMC_CAP_8_BIT_DATA; + mmc->caps |= MMC_CAP_SDIO_IRQ; if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (!(host->quirks & SDHCI_QUIRK_NO_SDIO_IRQ)) - mmc->caps |= MMC_CAP_SDIO_IRQ; - - if (caps & SDHCI_CAN_DO_HISPD) { + if (caps & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED; - mmc->caps |= MMC_CAP_MMC_HIGHSPEED; - } - - if (host->quirks & SDHCI_QUIRK_FORCE_HIGH_SPEED_MODE) - mmc->caps |= MMC_CAP_FORCE_HS; if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) mmc->caps |= MMC_CAP_NEEDS_POLL; - if (host->quirks & SDHCI_QUIRK_RUNTIME_DISABLE) { - mmc->caps |= MMC_CAP_DISABLE; - mmc_set_disable_delay(mmc, 50); - } - - mmc->caps |= MMC_CAP_ERASE; - mmc->ocr_avail = 0; if (caps & SDHCI_CAN_VDD_330) mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; @@ -1944,14 +1868,10 @@ int sdhci_add_host(struct sdhci_host *host) * of bytes. When doing hardware scatter/gather, each entry cannot * be larger than 64 KiB though. */ - if (host->flags & SDHCI_USE_ADMA) { - if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) - mmc->max_seg_size = 0xffff; - else - mmc->max_seg_size = 65536; - } else { + if (host->flags & SDHCI_USE_ADMA) + mmc->max_seg_size = 65536; + else mmc->max_seg_size = mmc->max_req_size; - } /* * Maximum block size. This varies from controller to controller and @@ -1975,7 +1895,7 @@ int sdhci_add_host(struct sdhci_host *host) * Maximum block count. */ mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; - + /* * Init tasklets. */ diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 9cac859561ff..d316bc79b636 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -66,7 +66,6 @@ #define SDHCI_HOST_CONTROL 0x28 #define SDHCI_CTRL_LED 0x01 #define SDHCI_CTRL_4BITBUS 0x02 -#define SDHCI_CTRL_8BITBUS 0x20 #define SDHCI_CTRL_HISPD 0x04 #define SDHCI_CTRL_DMA_MASK 0x18 #define SDHCI_CTRL_SDMA 0x00 @@ -186,86 +185,68 @@ struct sdhci_host { /* Data set by hardware interface driver */ const char *hw_name; /* Hardware bus name */ - u64 quirks; /* Deviations from spec. */ + unsigned int quirks; /* Deviations from spec. */ /* Controller doesn't honor resets unless we touch the clock register */ -#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1LL<<0) +#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) /* Controller has bad caps bits, but really supports DMA */ -#define SDHCI_QUIRK_FORCE_DMA (1LL<<1) +#define SDHCI_QUIRK_FORCE_DMA (1<<1) /* Controller doesn't like to be reset when there is no card inserted. */ -#define SDHCI_QUIRK_NO_CARD_NO_RESET (1LL<<2) +#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) /* Controller doesn't like clearing the power reg before a change */ -#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1LL<<3) +#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) /* Controller has flaky internal state so reset it on each ios change */ -#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1LL<<4) +#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) /* Controller has an unusable DMA engine */ -#define SDHCI_QUIRK_BROKEN_DMA (1LL<<5) +#define SDHCI_QUIRK_BROKEN_DMA (1<<5) /* Controller has an unusable ADMA engine */ -#define SDHCI_QUIRK_BROKEN_ADMA (1LL<<6) +#define SDHCI_QUIRK_BROKEN_ADMA (1<<6) /* Controller can only DMA from 32-bit aligned addresses */ -#define SDHCI_QUIRK_32BIT_DMA_ADDR (1LL<<7) +#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<7) /* Controller can only DMA chunk sizes that are a multiple of 32 bits */ -#define SDHCI_QUIRK_32BIT_DMA_SIZE (1LL<<8) +#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<8) /* Controller can only ADMA chunks that are a multiple of 32 bits */ -#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1LL<<9) +#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1<<9) /* Controller needs to be reset after each request to stay stable */ -#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1LL<<10) +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<10) /* Controller needs voltage and power writes to happen separately */ -#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1LL<<11) +#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) /* Controller provides an incorrect timeout value for transfers */ -#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1LL<<12) +#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) /* Controller has an issue with buffer bits for small transfers */ -#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1LL<<13) +#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) /* Controller does not provide transfer-complete interrupt when not busy */ -#define SDHCI_QUIRK_NO_BUSY_IRQ (1LL<<14) +#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14) /* Controller has unreliable card detection */ -#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1LL<<15) +#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15) /* Controller reports inverted write-protect state */ -#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1LL<<16) +#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16) /* Controller has nonstandard clock management */ -#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1LL<<17) +#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17) /* Controller does not like fast PIO transfers */ -#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1LL<<18) +#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18) /* Controller losing signal/interrupt enable states after reset */ -#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1LL<<19) +#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19) /* Controller has to be forced to use block size of 2048 bytes */ -#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1LL<<20) +#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20) /* Controller cannot do multi-block transfers */ -#define SDHCI_QUIRK_NO_MULTIBLOCK (1LL<<21) +#define SDHCI_QUIRK_NO_MULTIBLOCK (1<<21) /* Controller can only handle 1-bit data transfers */ -#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1LL<<22) +#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22) /* Controller needs 10ms delay between applying power and clock */ -#define SDHCI_QUIRK_DELAY_AFTER_POWER (1LL<<23) +#define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) /* Controller uses SDCLK instead of TMCLK for data timeouts */ -#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1LL<<24) +#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) /* Controller reports wrong base clock capability */ -#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1LL<<25) +#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) /* Controller cannot support End Attribute in NOP ADMA descriptor */ -#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1LL<<26) +#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26) /* Controller is missing device caps. Use caps provided by host */ -#define SDHCI_QUIRK_MISSING_CAPS (1LL<<27) +#define SDHCI_QUIRK_MISSING_CAPS (1<<27) /* Controller uses Auto CMD12 command to stop the transfer */ -#define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1LL<<28) +#define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) /* Controller doesn't have HISPD bit field in HI-SPEED SD card */ -#define SDHCI_QUIRK_NO_HISPD_BIT (1LL<<29) -/* Controller write protect bit is broken. Assume no write protection */ -#define SDHCI_QUIRK_BROKEN_WRITE_PROTECT (1LL<<30) -/* Controller needs INTERRUPT_AT_BLOCK_GAP enabled to detect card interrupts */ -#define SDHCI_QUIRK_ENABLE_INTERRUPT_AT_BLOCK_GAP (1LL<<31) -/* Controller should not program HIGH_SPEED_EN after switching to high speed */ -#define SDHCI_QUIRK_BROKEN_CTRL_HISPD (1LL<<32) -/* Controller supports 8-bit data width */ -#define SDHCI_QUIRK_8_BIT_DATA (1LL<<33) -/* Controller has no version register */ -#define SDHCI_QUIRK_NO_VERSION_REG (1LL<<34) -/* Controller treats ADMA descriptors with length 0000h incorrectly */ -#define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1LL<<35) -/* Controller should not use SDIO IRQ */ -#define SDHCI_QUIRK_NO_SDIO_IRQ (1LL<<36) -/* Controller should only use high-speed mode */ -#define SDHCI_QUIRK_FORCE_HIGH_SPEED_MODE (1LL<<37) -/* Controller allows runtime enable / disable */ -#define SDHCI_QUIRK_RUNTIME_DISABLE (1LL<<38) +#define SDHCI_QUIRK_NO_HISPD_BIT (1<<29) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ @@ -321,7 +302,6 @@ struct sdhci_host { struct timer_list timer; /* Timer for timeouts */ unsigned int caps; /* Alternative capabilities */ - unsigned int card_present; /* Previous card detect */ unsigned long private[0] ____cacheline_aligned; }; @@ -340,7 +320,6 @@ struct sdhci_ops { void (*set_clock)(struct sdhci_host *host, unsigned int clock); int (*enable_dma)(struct sdhci_host *host); - int (*get_ro)(struct sdhci_host *host); unsigned int (*get_max_clock)(struct sdhci_host *host); unsigned int (*get_min_clock)(struct sdhci_host *host); unsigned int (*get_timeout_clock)(struct sdhci_host *host); @@ -433,7 +412,6 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg) extern struct sdhci_host *sdhci_alloc_host(struct device *dev, size_t priv_size); extern void sdhci_free_host(struct sdhci_host *host); -extern void sdhci_card_detect_callback(struct sdhci_host *host); static inline void *sdhci_priv(struct sdhci_host *host) { diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 943d90f08c08..35081ce77fbd 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -78,12 +78,6 @@ config MTD_DATAFLASH_OTP other key product data. The second half is programmed with a unique-to-each-chip bit pattern at the factory. -config MTD_NAND_TEGRA - tristate "Support for NAND Controller on NVIDIA Tegra" - depends on ARCH_TEGRA - help - Enables NAND flash support for NVIDIA's Tegra family of chips. - config MTD_M25P80 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" depends on SPI_MASTER && EXPERIMENTAL diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 4793bcfe6211..f3226b1d38fc 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -17,4 +17,3 @@ obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o obj-$(CONFIG_MTD_SST25L) += sst25l.o -obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o diff --git a/drivers/mtd/devices/tegra_nand.c b/drivers/mtd/devices/tegra_nand.c deleted file mode 100644 index 6982a74ce65b..000000000000 --- a/drivers/mtd/devices/tegra_nand.c +++ /dev/null @@ -1,1605 +0,0 @@ -/* - * drivers/mtd/devices/tegra_nand.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * Colin Cross - * - * 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. - * - * Derived from: drivers/mtd/nand/nand_base.c - * drivers/mtd/nand/pxa3xx.c - * - * TODO: - * - Add support for 16bit bus width - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "tegra_nand.h" - -#define DRIVER_NAME "tegra_nand" -#define DRIVER_DESC "Nvidia Tegra NAND Flash Controller driver" - -#define MAX_DMA_SZ SZ_64K -#define ECC_BUF_SZ SZ_1K - -/* FIXME: is this right?! - * NvRM code says it should be 128 bytes, but that seems awfully small - */ - -/*#define TEGRA_NAND_DEBUG -#define TEGRA_NAND_DEBUG_PEDANTIC*/ - -#ifdef TEGRA_NAND_DEBUG -#define TEGRA_DBG(fmt, args...) \ - do { pr_info(fmt, ##args); } while (0) -#else -#define TEGRA_DBG(fmt, args...) -#endif - -/* TODO: will vary with devices, move into appropriate device spcific header */ -#define SCAN_TIMING_VAL 0x3f0bd214 -#define SCAN_TIMING2_VAL 0xb - -/* TODO: pull in the register defs (fields, masks, etc) from Nvidia files - * so we don't have to redefine them */ - -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probes[] = { "cmdlinepart", NULL, }; -#endif - -struct tegra_nand_chip { - spinlock_t lock; - uint32_t chipsize; - int num_chips; - int curr_chip; - - /* addr >> chip_shift == chip number */ - uint32_t chip_shift; - /* (addr >> page_shift) & page_mask == page number within chip */ - uint32_t page_shift; - uint32_t page_mask; - /* column within page */ - uint32_t column_mask; - /* addr >> block_shift == block number (across the whole mtd dev, not - * just a single chip. */ - uint32_t block_shift; - - void *priv; -}; - -struct tegra_nand_info { - struct tegra_nand_chip chip; - struct mtd_info mtd; - struct tegra_nand_platform *plat; - struct device *dev; - struct mtd_partition *parts; - - /* synchronizes access to accessing the actual NAND controller */ - struct mutex lock; - - - void *oob_dma_buf; - dma_addr_t oob_dma_addr; - /* ecc error vector info (offset into page and data mask to apply */ - void *ecc_buf; - dma_addr_t ecc_addr; - /* ecc error status (page number, err_cnt) */ - uint32_t *ecc_errs; - uint32_t num_ecc_errs; - uint32_t max_ecc_errs; - spinlock_t ecc_lock; - - uint32_t command_reg; - uint32_t config_reg; - uint32_t dmactrl_reg; - - struct completion cmd_complete; - struct completion dma_complete; - - /* bad block bitmap: 1 == good, 0 == bad/unknown */ - unsigned long *bb_bitmap; - - struct clk *clk; -}; -#define MTD_TO_INFO(mtd) container_of((mtd), struct tegra_nand_info, mtd) - -/* 64 byte oob block info for large page (== 2KB) device - * - * OOB flash layout for Tegra with Reed-Solomon 4 symbol correct ECC: - * Skipped bytes(4) - * Main area Ecc(36) - * Tag data(20) - * Tag data Ecc(4) - * - * Yaffs2 will use 16 tag bytes. - */ - -static struct nand_ecclayout tegra_nand_oob_64 = { - .eccbytes = 36, - .eccpos = { - 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, 35, 36, 37, 38, 39, - }, - .oobavail = 20, - .oobfree = { - { .offset = 40, - .length = 20, - }, - }, -}; - -static struct nand_flash_dev * -find_nand_flash_device(int dev_id) -{ - struct nand_flash_dev *dev = &nand_flash_ids[0]; - - while (dev->name && dev->id != dev_id) - dev++; - return dev->name ? dev : NULL; -} - -static struct nand_manufacturers * -find_nand_flash_vendor(int vendor_id) -{ - struct nand_manufacturers *vendor = &nand_manuf_ids[0]; - - while (vendor->id && vendor->id != vendor_id) - vendor++; - return vendor->id ? vendor : NULL; -} - -#define REG_NAME(name) { name, #name } -static struct { - uint32_t addr; - char *name; -} reg_names[] = { - REG_NAME(COMMAND_REG), - REG_NAME(STATUS_REG), - REG_NAME(ISR_REG), - REG_NAME(IER_REG), - REG_NAME(CONFIG_REG), - REG_NAME(TIMING_REG), - REG_NAME(RESP_REG), - REG_NAME(TIMING2_REG), - REG_NAME(CMD_REG1), - REG_NAME(CMD_REG2), - REG_NAME(ADDR_REG1), - REG_NAME(ADDR_REG2), - REG_NAME(DMA_MST_CTRL_REG), - REG_NAME(DMA_CFG_A_REG), - REG_NAME(DMA_CFG_B_REG), - REG_NAME(FIFO_CTRL_REG), - REG_NAME(DATA_BLOCK_PTR_REG), - REG_NAME(TAG_PTR_REG), - REG_NAME(ECC_PTR_REG), - REG_NAME(DEC_STATUS_REG), - REG_NAME(HWSTATUS_CMD_REG), - REG_NAME(HWSTATUS_MASK_REG), - { 0, NULL }, -}; -#undef REG_NAME - - -static int -dump_nand_regs(void) -{ - int i = 0; - - TEGRA_DBG("%s: dumping registers\n", __func__); - while (reg_names[i].name != NULL) { - TEGRA_DBG("%s = 0x%08x\n", reg_names[i].name, readl(reg_names[i].addr)); - i++; - } - TEGRA_DBG("%s: end of reg dump\n", __func__); - return 1; -} - - -static inline void -enable_ints(struct tegra_nand_info *info, uint32_t mask) -{ - (void)info; - writel(readl(IER_REG) | mask, IER_REG); -} - - -static inline void -disable_ints(struct tegra_nand_info *info, uint32_t mask) -{ - (void)info; - writel(readl(IER_REG) & ~mask, IER_REG); -} - - -static inline void -split_addr(struct tegra_nand_info *info, loff_t offset, int *chipnr, uint32_t *page, - uint32_t *column) -{ - *chipnr = (int)(offset >> info->chip.chip_shift); - *page = (offset >> info->chip.page_shift) & info->chip.page_mask; - *column = offset & info->chip.column_mask; -} - - -static irqreturn_t -tegra_nand_irq(int irq, void *dev_id) -{ - struct tegra_nand_info *info = dev_id; - uint32_t isr; - uint32_t ier; - uint32_t dma_ctrl; - uint32_t tmp; - - isr = readl(ISR_REG); - ier = readl(IER_REG); - dma_ctrl = readl(DMA_MST_CTRL_REG); -#ifdef DEBUG_DUMP_IRQ - pr_info("IRQ: ISR=0x%08x IER=0x%08x DMA_IS=%d DMA_IE=%d\n", - isr, ier, !!(dma_ctrl & (1 << 20)), !!(dma_ctrl & (1 << 28))); -#endif - if (isr & ISR_CMD_DONE) { - if (likely(!(readl(COMMAND_REG) & COMMAND_GO))) - complete(&info->cmd_complete); - else - pr_err("tegra_nand_irq: Spurious cmd done irq!\n"); - } - - if (isr & ISR_ECC_ERR) { - /* always want to read the decode status so xfers don't stall. */ - tmp = readl(DEC_STATUS_REG); - - /* was ECC check actually enabled */ - if ((ier & IER_ECC_ERR)) { - unsigned long flags; - spin_lock_irqsave(&info->ecc_lock, flags); - info->ecc_errs[info->num_ecc_errs++] = tmp; - spin_unlock_irqrestore(&info->ecc_lock, flags); - } - } - - if ((dma_ctrl & DMA_CTRL_IS_DMA_DONE) && - (dma_ctrl & DMA_CTRL_IE_DMA_DONE)) { - complete(&info->dma_complete); - writel(dma_ctrl, DMA_MST_CTRL_REG); - } - - if ((isr & ISR_UND) && (ier & IER_UND)) - pr_err("%s: fifo underrun.\n", __func__); - - if ((isr & ISR_OVR) && (ier & IER_OVR)) - pr_err("%s: fifo overrun.\n", __func__); - - /* clear ALL interrupts?! */ - writel(isr & 0xfffc, ISR_REG); - - return IRQ_HANDLED; -} - -static inline int -tegra_nand_is_cmd_done(struct tegra_nand_info *info) -{ - return (readl(COMMAND_REG) & COMMAND_GO) ? 0 : 1; -} - -static int -tegra_nand_wait_cmd_done(struct tegra_nand_info *info) -{ - uint32_t timeout = (2 * HZ); /* TODO: make this realistic */ - int ret; - - ret = wait_for_completion_timeout(&info->cmd_complete, timeout); - -#ifdef TEGRA_NAND_DEBUG_PEDANTIC - BUG_ON(!ret && dump_nand_regs()); -#endif - - return ret ? 0 : ret; -} - -static inline void -select_chip(struct tegra_nand_info *info, int chipnr) -{ - BUG_ON(chipnr != -1 && chipnr >= info->plat->max_chips); - info->chip.curr_chip = chipnr; -} - -static void -cfg_hwstatus_mon(struct tegra_nand_info *info) -{ - uint32_t val; - - val = (HWSTATUS_RDSTATUS_MASK(1) | - HWSTATUS_RDSTATUS_EXP_VAL(0) | - HWSTATUS_RBSY_MASK(NAND_STATUS_READY) | - HWSTATUS_RBSY_EXP_VAL(NAND_STATUS_READY)); - writel(NAND_CMD_STATUS, HWSTATUS_CMD_REG); - writel(val, HWSTATUS_MASK_REG); -} - -/* Tells the NAND controller to initiate the command. */ -static int -tegra_nand_go(struct tegra_nand_info *info) -{ - BUG_ON(!tegra_nand_is_cmd_done(info)); - - INIT_COMPLETION(info->cmd_complete); - writel(info->command_reg | COMMAND_GO, COMMAND_REG); - - if (unlikely(tegra_nand_wait_cmd_done(info))) { - /* TODO: abort command if needed? */ - pr_err("%s: Timeout while waiting for command\n", __func__); - return -ETIMEDOUT; - } - - /* TODO: maybe wait for dma here? */ - return 0; -} - -static void -tegra_nand_prep_readid(struct tegra_nand_info *info) -{ - info->command_reg = (COMMAND_CLE | COMMAND_ALE | COMMAND_PIO | COMMAND_RX | - COMMAND_ALE_BYTE_SIZE(0) | COMMAND_TRANS_SIZE(3) | - (COMMAND_CE(info->chip.curr_chip))); - writel(NAND_CMD_READID, CMD_REG1); - writel(0, CMD_REG2); - writel(0, ADDR_REG1); - writel(0, ADDR_REG2); - writel(0, CONFIG_REG); -} - -static int -tegra_nand_cmd_readid(struct tegra_nand_info *info, uint32_t *chip_id) -{ - int err; - -#ifdef TEGRA_NAND_DEBUG_PEDANTIC - BUG_ON(info->chip.curr_chip == -1); -#endif - - tegra_nand_prep_readid(info); - err = tegra_nand_go(info); - if (err != 0) - return err; - - *chip_id = readl(RESP_REG); - return 0; -} - - -/* assumes right locks are held */ -static int -nand_cmd_get_status(struct tegra_nand_info *info, uint32_t *status) -{ - int err; - - info->command_reg = (COMMAND_CLE | COMMAND_PIO | COMMAND_RX | - COMMAND_RBSY_CHK | (COMMAND_CE(info->chip.curr_chip))); - writel(NAND_CMD_STATUS, CMD_REG1); - writel(0, CMD_REG2); - writel(0, ADDR_REG1); - writel(0, ADDR_REG2); - writel(CONFIG_COM_BSY, CONFIG_REG); - - err = tegra_nand_go(info); - if (err != 0) - return err; - - *status = readl(RESP_REG) & 0xff; - return 0; -} - - -/* must be called with lock held */ -static int -check_block_isbad(struct mtd_info *mtd, loff_t offs) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - uint32_t block = offs >> info->chip.block_shift; - int chipnr; - uint32_t page; - uint32_t column; - int ret = 0; - int i; - - if (info->bb_bitmap[BIT_WORD(block)] & BIT_MASK(block)) - return 0; - - offs &= ~(mtd->erasesize - 1); - - /* Only set COM_BSY. */ - /* TODO: should come from board file */ - writel(CONFIG_COM_BSY, CONFIG_REG); - - split_addr(info, offs, &chipnr, &page, &column); - select_chip(info, chipnr); - - column = mtd->writesize & 0xffff; /* force to be the offset of OOB */ - - /* check fist two pages of the block */ - for (i = 0; i < 2; ++i) { - info->command_reg = - COMMAND_CE(info->chip.curr_chip) | COMMAND_CLE | COMMAND_ALE | - COMMAND_ALE_BYTE_SIZE(4) | COMMAND_RX | COMMAND_PIO | - COMMAND_TRANS_SIZE(1) | COMMAND_A_VALID | COMMAND_RBSY_CHK | - COMMAND_SEC_CMD; - writel(NAND_CMD_READ0, CMD_REG1); - writel(NAND_CMD_READSTART, CMD_REG2); - - writel(column | ((page & 0xffff) << 16), ADDR_REG1); - writel((page >> 16) & 0xff, ADDR_REG2); - - /* ... poison me ... */ - writel(0xaa55aa55, RESP_REG); - ret = tegra_nand_go(info); - if (ret != 0) { - pr_info("baaaaaad\n"); - goto out; - } - - if ((readl(RESP_REG) & 0xffff) != 0xffff) { - ret = 1; - goto out; - } - - /* Note: The assumption here is that we cannot cross chip - * boundary since the we are only looking at the first 2 pages in - * a block, i.e. erasesize > writesize ALWAYS */ - page++; - } - -out: - /* update the bitmap if the block is good */ - if (ret == 0) - set_bit(block, info->bb_bitmap); - return ret; -} - - -static int -tegra_nand_block_isbad(struct mtd_info *mtd, loff_t offs) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - int ret; - - if (offs >= mtd->size) - return -EINVAL; - - mutex_lock(&info->lock); - ret = check_block_isbad(mtd, offs); - mutex_unlock(&info->lock); - -#if 0 - if (ret > 0) - pr_info("block @ 0x%llx is bad.\n", offs); - else if (ret < 0) - pr_err("error checking block @ 0x%llx for badness.\n", offs); -#endif - - return ret; -} - - -static int -tegra_nand_block_markbad(struct mtd_info *mtd, loff_t offs) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - uint32_t block = offs >> info->chip.block_shift; - int chipnr; - uint32_t page; - uint32_t column; - int ret = 0; - int i; - - if (offs >= mtd->size) - return -EINVAL; - - pr_info("tegra_nand: setting block %d bad\n", block); - - mutex_lock(&info->lock); - offs &= ~(mtd->erasesize - 1); - - /* mark the block bad in our bitmap */ - clear_bit(block, info->bb_bitmap); - mtd->ecc_stats.badblocks++; - - /* Only set COM_BSY. */ - /* TODO: should come from board file */ - writel(CONFIG_COM_BSY, CONFIG_REG); - - split_addr(info, offs, &chipnr, &page, &column); - select_chip(info, chipnr); - - column = mtd->writesize & 0xffff; /* force to be the offset of OOB */ - - /* write to fist two pages in the block */ - for (i = 0; i < 2; ++i) { - info->command_reg = - COMMAND_CE(info->chip.curr_chip) | COMMAND_CLE | COMMAND_ALE | - COMMAND_ALE_BYTE_SIZE(4) | COMMAND_TX | COMMAND_PIO | - COMMAND_TRANS_SIZE(1) | COMMAND_A_VALID | COMMAND_RBSY_CHK | - COMMAND_AFT_DAT | COMMAND_SEC_CMD; - writel(NAND_CMD_SEQIN, CMD_REG1); - writel(NAND_CMD_PAGEPROG, CMD_REG2); - - writel(column | ((page & 0xffff) << 16), ADDR_REG1); - writel((page >> 16) & 0xff, ADDR_REG2); - - writel(0x0, RESP_REG); - ret = tegra_nand_go(info); - if (ret != 0) - goto out; - - /* TODO: check if the program op worked? */ - page++; - } - -out: - mutex_unlock(&info->lock); - return ret; -} - - -static int -tegra_nand_erase(struct mtd_info *mtd, struct erase_info *instr) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - uint32_t num_blocks; - uint32_t offs; - int chipnr; - uint32_t page; - uint32_t column; - uint32_t status = 0; - - TEGRA_DBG("tegra_nand_erase: addr=0x%08llx len=%lld\n", instr->addr, - instr->len); - - if ((instr->addr + instr->len) > mtd->size) { - pr_err("tegra_nand_erase: Can't erase past end of device\n"); - instr->state = MTD_ERASE_FAILED; - return -EINVAL; - } - - if (instr->addr & (mtd->erasesize - 1)) { - pr_err("tegra_nand_erase: addr=0x%08llx not block-aligned\n", - instr->addr); - instr->state = MTD_ERASE_FAILED; - return -EINVAL; - } - - if (instr->len & (mtd->erasesize - 1)) { - pr_err("tegra_nand_erase: len=%lld not block-aligned\n", - instr->len); - instr->state = MTD_ERASE_FAILED; - return -EINVAL; - } - - instr->fail_addr = 0xffffffff; - - mutex_lock(&info->lock); - - instr->state = MTD_ERASING; - - offs = instr->addr; - num_blocks = instr->len >> info->chip.block_shift; - - select_chip(info, -1); - - while (num_blocks--) { - split_addr(info, offs, &chipnr, &page, &column); - if (chipnr != info->chip.curr_chip) - select_chip(info, chipnr); - TEGRA_DBG("tegra_nand_erase: addr=0x%08x, page=0x%08x\n", offs, page); - - if (check_block_isbad(mtd, offs)) { - pr_info("%s: skipping bad block @ 0x%08x\n", __func__, offs); - goto next_block; - } - - info->command_reg = - COMMAND_CE(info->chip.curr_chip) | COMMAND_CLE | COMMAND_ALE | - COMMAND_ALE_BYTE_SIZE(2) | COMMAND_RBSY_CHK | COMMAND_SEC_CMD; - writel(NAND_CMD_ERASE1, CMD_REG1); - writel(NAND_CMD_ERASE2, CMD_REG2); - - writel(page & 0xffffff, ADDR_REG1); - writel(0, ADDR_REG2); - writel(CONFIG_COM_BSY, CONFIG_REG); - - if (tegra_nand_go(info) != 0) { - instr->fail_addr = offs; - goto out_err; - } - - /* TODO: do we want a timeout here? */ - if ((nand_cmd_get_status(info, &status) != 0) || - (status & NAND_STATUS_FAIL) || - ((status & NAND_STATUS_READY) != NAND_STATUS_READY)) { - instr->fail_addr = offs; - pr_info("%s: erase failed @ 0x%08x (stat=0x%08x)\n", - __func__, offs, status); - goto out_err; - } -next_block: - offs += mtd->erasesize; - } - - instr->state = MTD_ERASE_DONE; - mutex_unlock(&info->lock); - mtd_erase_callback(instr); - return 0; - -out_err: - instr->state = MTD_ERASE_FAILED; - mutex_unlock(&info->lock); - return -EIO; -} - - -static inline void -dump_mtd_oob_ops(struct mtd_oob_ops *ops) -{ - pr_info("%s: oob_ops: mode=%s len=0x%x ooblen=0x%x " - "ooboffs=0x%x dat=0x%p oob=0x%p\n", __func__, - (ops->mode == MTD_OOB_AUTO ? "MTD_OOB_AUTO" : - (ops->mode == MTD_OOB_PLACE ? "MTD_OOB_PLACE" : "MTD_OOB_RAW")), - ops->len, ops->ooblen, ops->ooboffs, ops->datbuf, ops->oobbuf); -} - -static int -tegra_nand_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, uint8_t *buf) -{ - struct mtd_oob_ops ops; - int ret; - - pr_debug("%s: read: from=0x%llx len=0x%x\n", __func__, from, len); - ops.mode = MTD_OOB_AUTO; - ops.len = len; - ops.datbuf = buf; - ops.oobbuf = NULL; - ret = mtd->read_oob(mtd, from, &ops); - *retlen = ops.retlen; - return ret; -} - -static void -correct_ecc_errors_on_blank_page(struct tegra_nand_info *info, u8 *datbuf, u8 *oobbuf, unsigned int a_len, unsigned int b_len) { - int i; - int all_ff = 1; - unsigned long flags; - - spin_lock_irqsave(&info->ecc_lock, flags); - if (info->num_ecc_errs) { - if (datbuf) { - for (i = 0; i < a_len; i++) - if (datbuf[i] != 0xFF) - all_ff = 0; - } - if (oobbuf) { - for (i = 0; i < b_len; i++) - if (oobbuf[i] != 0xFF) - all_ff = 0; - } - if (all_ff) - info->num_ecc_errs = 0; - } - spin_unlock_irqrestore(&info->ecc_lock, flags); -} - -static void -update_ecc_counts(struct tegra_nand_info *info, int check_oob) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&info->ecc_lock, flags); - for (i = 0; i < info->num_ecc_errs; ++i) { - /* correctable */ - info->mtd.ecc_stats.corrected += - DEC_STATUS_ERR_CNT(info->ecc_errs[i]); - - /* uncorrectable */ - if (info->ecc_errs[i] & DEC_STATUS_ECC_FAIL_A) - info->mtd.ecc_stats.failed++; - if (check_oob && (info->ecc_errs[i] & DEC_STATUS_ECC_FAIL_B)) - info->mtd.ecc_stats.failed++; - } - info->num_ecc_errs = 0; - spin_unlock_irqrestore(&info->ecc_lock, flags); -} - -static inline void -clear_regs(struct tegra_nand_info *info) -{ - info->command_reg = 0; - info->config_reg = 0; - info->dmactrl_reg = 0; -} - -static void -prep_transfer_dma(struct tegra_nand_info *info, int rx, int do_ecc, uint32_t page, - uint32_t column, dma_addr_t data_dma, - uint32_t data_len, dma_addr_t oob_dma, uint32_t oob_len) -{ - uint32_t tag_sz = oob_len; - -#if 0 - pr_info("%s: rx=%d ecc=%d page=%d col=%d data_dma=0x%x " - "data_len=0x%08x oob_dma=0x%x ooblen=%d\n", __func__, - rx, do_ecc, page, column, data_dma, data_len, oob_dma, - oob_len); -#endif - - info->command_reg = - COMMAND_CE(info->chip.curr_chip) | COMMAND_CLE | COMMAND_ALE | - COMMAND_ALE_BYTE_SIZE(4) | COMMAND_SEC_CMD | COMMAND_RBSY_CHK | - COMMAND_TRANS_SIZE(8); - - info->config_reg = (CONFIG_PAGE_SIZE_SEL(3) | CONFIG_PIPELINE_EN | - CONFIG_COM_BSY); - - info->dmactrl_reg = (DMA_CTRL_DMA_GO | - DMA_CTRL_DMA_PERF_EN | DMA_CTRL_IE_DMA_DONE | - DMA_CTRL_IS_DMA_DONE | DMA_CTRL_BURST_SIZE(4)); - - if (rx) { - if (do_ecc) - info->config_reg |= CONFIG_HW_ERR_CORRECTION; - info->command_reg |= COMMAND_RX; - info->dmactrl_reg |= DMA_CTRL_REUSE_BUFFER; - writel(NAND_CMD_READ0, CMD_REG1); - writel(NAND_CMD_READSTART, CMD_REG2); - } else { - info->command_reg |= (COMMAND_TX | COMMAND_AFT_DAT); - info->dmactrl_reg |= DMA_CTRL_DIR; /* DMA_RD == TX */ - writel(NAND_CMD_SEQIN, CMD_REG1); - writel(NAND_CMD_PAGEPROG, CMD_REG2); - } - - if (data_len) { - if (do_ecc) - info->config_reg |= - CONFIG_HW_ECC | CONFIG_ECC_SEL | CONFIG_TVALUE(0) | - CONFIG_SKIP_SPARE | CONFIG_SKIP_SPARE_SEL(0); - info->command_reg |= COMMAND_A_VALID; - info->dmactrl_reg |= DMA_CTRL_DMA_EN_A; - writel(DMA_CFG_BLOCK_SIZE(data_len - 1), DMA_CFG_A_REG); - writel(data_dma, DATA_BLOCK_PTR_REG); - } else { - column = info->mtd.writesize; - if (do_ecc) - column += info->mtd.ecclayout->oobfree[0].offset; - writel(0, DMA_CFG_A_REG); - writel(0, DATA_BLOCK_PTR_REG); - } - - if (oob_len) { - oob_len = info->mtd.oobavail; - tag_sz = info->mtd.oobavail; - if (do_ecc) { - tag_sz += 4; /* size of tag ecc */ - if (rx) - oob_len += 4; /* size of tag ecc */ - info->config_reg |= CONFIG_ECC_EN_TAG; - } - if (data_len && rx) - oob_len += 4; /* num of skipped bytes */ - - info->command_reg |= COMMAND_B_VALID; - info->config_reg |= CONFIG_TAG_BYTE_SIZE(tag_sz - 1); - info->dmactrl_reg |= DMA_CTRL_DMA_EN_B; - writel(DMA_CFG_BLOCK_SIZE(oob_len - 1), DMA_CFG_B_REG); - writel(oob_dma, TAG_PTR_REG); - } else { - writel(0, DMA_CFG_B_REG); - writel(0, TAG_PTR_REG); - } - - writel((column & 0xffff) | ((page & 0xffff) << 16), ADDR_REG1); - writel((page >> 16) & 0xff, ADDR_REG2); -} - -static dma_addr_t -tegra_nand_dma_map(struct device *dev, void *addr, size_t size, - enum dma_data_direction dir) -{ - struct page *page; - unsigned long offset = (unsigned long)addr & ~PAGE_MASK; - if (virt_addr_valid(addr)) - page = virt_to_page(addr); - else { - if (WARN_ON(size + offset > PAGE_SIZE)) - return ~0; - page = vmalloc_to_page(addr); - } - return dma_map_page(dev, page, offset, size, dir); -} - -/* if mode == RAW, then we read data only, with no ECC - * if mode == PLACE, we read ONLY the OOB data from a raw offset into the spare - * area (ooboffs). - * if mode == AUTO, we read main data and the OOB data from the oobfree areas as - * specified by nand_ecclayout. - */ -static int -do_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - struct mtd_ecc_stats old_ecc_stats; - int chipnr; - uint32_t page; - uint32_t column; - uint8_t *datbuf = ops->datbuf; - uint8_t *oobbuf = ops->oobbuf; - uint32_t len = datbuf ? ops->len : 0; - uint32_t ooblen = oobbuf ? ops->ooblen : 0; - uint32_t oobsz; - uint32_t page_count; - int err; - int do_ecc = 1; - dma_addr_t datbuf_dma_addr = 0; - -#if 0 - dump_mtd_oob_ops(mtd, ops); -#endif - - ops->retlen = 0; - ops->oobretlen = 0; - - /* TODO: Worry about reads from non-page boundaries later */ - if (unlikely(from & info->chip.column_mask)) { - pr_err("%s: Unaligned read (from 0x%llx) not supported\n", - __func__, from); - return -EINVAL; - } - - if (likely(ops->mode == MTD_OOB_AUTO)) { - oobsz = mtd->oobavail; - } else { - oobsz = mtd->oobsize; - do_ecc = 0; - } - - if (unlikely(ops->oobbuf && ops->ooblen > oobsz)) { - pr_err("%s: can't read OOB from multiple pages (%d > %d)\n", __func__, - ops->ooblen, oobsz); - return -EINVAL; - } else if (ops->oobbuf) { - page_count = 1; - } else { - page_count = max((uint32_t)(ops->len / mtd->writesize), (uint32_t)1); - } - - mutex_lock(&info->lock); - - memcpy(&old_ecc_stats, &mtd->ecc_stats, sizeof(old_ecc_stats)); - - if (do_ecc) { - enable_ints(info, IER_ECC_ERR); - writel(info->ecc_addr, ECC_PTR_REG); - } else - disable_ints(info, IER_ECC_ERR); - - split_addr(info, from, &chipnr, &page, &column); - select_chip(info, chipnr); - - /* reset it to point back to beginning of page */ - from -= column; - - while (page_count--) { - int a_len = min(mtd->writesize - column, len); - int b_len = min(oobsz, ooblen); - -#if 0 - pr_info("%s: chip:=%d page=%d col=%d\n", __func__, chipnr, - page, column); -#endif - - clear_regs(info); - if (datbuf) - datbuf_dma_addr = tegra_nand_dma_map(info->dev, datbuf, a_len, DMA_FROM_DEVICE); - - prep_transfer_dma(info, 1, do_ecc, page, column, datbuf_dma_addr, - a_len, info->oob_dma_addr, - b_len); - writel(info->config_reg, CONFIG_REG); - writel(info->dmactrl_reg, DMA_MST_CTRL_REG); - - INIT_COMPLETION(info->dma_complete); - err = tegra_nand_go(info); - if (err != 0) - goto out_err; - - if (!wait_for_completion_timeout(&info->dma_complete, 2*HZ)) { - pr_err("%s: dma completion timeout\n", __func__); - dump_nand_regs(); - err = -ETIMEDOUT; - goto out_err; - } - - /*pr_info("tegra_read_oob: DMA complete\n");*/ - - /* if we are here, transfer is done */ - if (datbuf) - dma_unmap_page(info->dev, datbuf_dma_addr, a_len, DMA_FROM_DEVICE); - - if (oobbuf) { - uint32_t ofs = datbuf && oobbuf ? 4 : 0; /* skipped bytes */ - memcpy(oobbuf, info->oob_dma_buf + ofs, b_len); - } - - correct_ecc_errors_on_blank_page(info, datbuf, oobbuf, a_len, b_len); - - if (datbuf) { - len -= a_len; - datbuf += a_len; - ops->retlen += a_len; - } - - if (oobbuf) { - ooblen -= b_len; - oobbuf += b_len; - ops->oobretlen += b_len; - } - - update_ecc_counts(info, oobbuf != NULL); - - if (!page_count) - break; - - from += mtd->writesize; - column = 0; - - split_addr(info, from, &chipnr, &page, &column); - if (chipnr != info->chip.curr_chip) - select_chip(info, chipnr); - } - - disable_ints(info, IER_ECC_ERR); - - if (mtd->ecc_stats.failed != old_ecc_stats.failed) - err = -EBADMSG; - else if (mtd->ecc_stats.corrected != old_ecc_stats.corrected) - err = -EUCLEAN; - else - err = 0; - - mutex_unlock(&info->lock); - return err; - -out_err: - ops->retlen = 0; - ops->oobretlen = 0; - - disable_ints(info, IER_ECC_ERR); - mutex_unlock(&info->lock); - return err; -} - -/* just does some parameter checking and calls do_read_oob */ -static int -tegra_nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) -{ - if (ops->datbuf && unlikely((from + ops->len) > mtd->size)) { - pr_err("%s: Can't read past end of device.\n", __func__); - return -EINVAL; - } - - if (unlikely(ops->oobbuf && !ops->ooblen)) { - pr_err("%s: Reading 0 bytes from OOB is meaningless\n", __func__); - return -EINVAL; - } - - if (unlikely(ops->mode != MTD_OOB_AUTO)) { - if (ops->oobbuf && ops->datbuf) { - pr_err("%s: can't read OOB + Data in non-AUTO mode.\n", - __func__); - return -EINVAL; - } - if ((ops->mode == MTD_OOB_RAW) && !ops->datbuf) { - pr_err("%s: Raw mode only supports reading data area.\n", - __func__); - return -EINVAL; - } - } - - return do_read_oob(mtd, from, ops); -} - -static int -tegra_nand_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const uint8_t *buf) -{ - struct mtd_oob_ops ops; - int ret; - - pr_debug("%s: write: to=0x%llx len=0x%x\n", __func__, to, len); - ops.mode = MTD_OOB_AUTO; - ops.len = len; - ops.datbuf = (uint8_t *)buf; - ops.oobbuf = NULL; - ret = mtd->write_oob(mtd, to, &ops); - *retlen = ops.retlen; - return ret; -} - -static int -do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - int chipnr; - uint32_t page; - uint32_t column; - uint8_t *datbuf = ops->datbuf; - uint8_t *oobbuf = ops->oobbuf; - uint32_t len = datbuf ? ops->len : 0; - uint32_t ooblen = oobbuf ? ops->ooblen : 0; - uint32_t oobsz; - uint32_t page_count; - int err; - int do_ecc = 1; - dma_addr_t datbuf_dma_addr = 0; - -#if 0 - dump_mtd_oob_ops(mtd, ops); -#endif - - ops->retlen = 0; - ops->oobretlen = 0; - - if (!ops->len) - return 0; - - - if (likely(ops->mode == MTD_OOB_AUTO)) { - oobsz = mtd->oobavail; - } else { - oobsz = mtd->oobsize; - do_ecc = 0; - } - - if (unlikely(ops->oobbuf && ops->ooblen > oobsz)) { - pr_err("%s: can't write OOB to multiple pages (%d > %d)\n", - __func__, ops->ooblen, oobsz); - return -EINVAL; - } else if (ops->oobbuf) { - page_count = 1; - } else - page_count = max((uint32_t)(ops->len / mtd->writesize), (uint32_t)1); - - mutex_lock(&info->lock); - - split_addr(info, to, &chipnr, &page, &column); - select_chip(info, chipnr); - - while (page_count--) { - int a_len = min(mtd->writesize, len); - int b_len = min(oobsz, ooblen); - - if (datbuf) - datbuf_dma_addr = tegra_nand_dma_map(info->dev, datbuf, a_len, DMA_TO_DEVICE); - if (oobbuf) - memcpy(info->oob_dma_buf, oobbuf, b_len); - - clear_regs(info); - prep_transfer_dma(info, 0, do_ecc, page, column, datbuf_dma_addr, - a_len, info->oob_dma_addr, b_len); - - writel(info->config_reg, CONFIG_REG); - writel(info->dmactrl_reg, DMA_MST_CTRL_REG); - - INIT_COMPLETION(info->dma_complete); - err = tegra_nand_go(info); - if (err != 0) - goto out_err; - - if (!wait_for_completion_timeout(&info->dma_complete, 2*HZ)) { - pr_err("%s: dma completion timeout\n", __func__); - dump_nand_regs(); - goto out_err; - } - - if (datbuf) { - dma_unmap_page(info->dev, datbuf_dma_addr, a_len, DMA_TO_DEVICE); - len -= a_len; - datbuf += a_len; - ops->retlen += a_len; - } - if (oobbuf) { - ooblen -= b_len; - oobbuf += b_len; - ops->oobretlen += b_len; - } - - if (!page_count) - break; - - to += mtd->writesize; - column = 0; - - split_addr(info, to, &chipnr, &page, &column); - if (chipnr != info->chip.curr_chip) - select_chip(info, chipnr); - } - - mutex_unlock(&info->lock); - return err; - -out_err: - ops->retlen = 0; - ops->oobretlen = 0; - - mutex_unlock(&info->lock); - return err; -} - -static int -tegra_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - - if (unlikely(to & info->chip.column_mask)) { - pr_err("%s: Unaligned write (to 0x%llx) not supported\n", - __func__, to); - return -EINVAL; - } - - if (unlikely(ops->oobbuf && !ops->ooblen)) { - pr_err("%s: Writing 0 bytes to OOB is meaningless\n", __func__); - return -EINVAL; - } - - return do_write_oob(mtd, to, ops); -} - -static int -tegra_nand_suspend(struct mtd_info *mtd) -{ - return 0; -} - -static void -tegra_nand_resume(struct mtd_info *mtd) -{ -} - -static int -scan_bad_blocks(struct tegra_nand_info *info) -{ - struct mtd_info *mtd = &info->mtd; - int num_blocks = mtd->size >> info->chip.block_shift; - uint32_t block; - int is_bad = 0; - - for (block = 0; block < num_blocks; ++block) { - /* make sure the bit is cleared, meaning it's bad/unknown before - * we check. */ - clear_bit(block, info->bb_bitmap); - is_bad = mtd->block_isbad(mtd, block << info->chip.block_shift); - - if (is_bad == 0) - set_bit(block, info->bb_bitmap); - else if (is_bad > 0) - pr_info("block 0x%08x is bad.\n", block); - else { - pr_err("Fatal error (%d) while scanning for " - "bad blocks\n", is_bad); - return is_bad; - } - } - return 0; -} - -static void -set_chip_timing(struct tegra_nand_info *info) -{ - struct tegra_nand_chip_parms *chip_parms = &info->plat->chip_parms[0]; - uint32_t tmp; - - /* TODO: Actually search the chip_parms list for the correct device. */ - /* TODO: Get the appropriate frequency from the clock subsystem */ -#define NAND_CLK_FREQ 108000 -#define CNT(t) (((((t) * NAND_CLK_FREQ) + 1000000 - 1) / 1000000) - 1) - tmp = (TIMING_TRP_RESP(CNT(chip_parms->timing.trp_resp)) | - TIMING_TWB(CNT(chip_parms->timing.twb)) | - TIMING_TCR_TAR_TRR(CNT(chip_parms->timing.tcr_tar_trr)) | - TIMING_TWHR(CNT(chip_parms->timing.twhr)) | - TIMING_TCS(CNT(chip_parms->timing.tcs)) | - TIMING_TWH(CNT(chip_parms->timing.twh)) | - TIMING_TWP(CNT(chip_parms->timing.twp)) | - TIMING_TRH(CNT(chip_parms->timing.trh)) | - TIMING_TRP(CNT(chip_parms->timing.trp))); - writel(tmp, TIMING_REG); - writel(TIMING2_TADL(CNT(chip_parms->timing.tadl)), TIMING2_REG); -#undef CNT -#undef NAND_CLK_FREQ -} - -/* Scans for nand flash devices, identifies them, and fills in the - * device info. */ -static int -tegra_nand_scan(struct mtd_info *mtd, int maxchips) -{ - struct tegra_nand_info *info = MTD_TO_INFO(mtd); - struct nand_flash_dev *dev_info; - struct nand_manufacturers *vendor_info; - uint32_t tmp; - uint32_t dev_id; - uint32_t vendor_id; - uint32_t dev_parms; - uint32_t mlc_parms; - int cnt; - int err = 0; - - writel(SCAN_TIMING_VAL, TIMING_REG); - writel(SCAN_TIMING2_VAL, TIMING2_REG); - writel(0, CONFIG_REG); - - select_chip(info, 0); - err = tegra_nand_cmd_readid(info, &tmp); - if (err != 0) - goto out_error; - - vendor_id = tmp & 0xff; - dev_id = (tmp >> 8) & 0xff; - mlc_parms = (tmp >> 16) & 0xff; - dev_parms = (tmp >> 24) & 0xff; - - dev_info = find_nand_flash_device(dev_id); - if (dev_info == NULL) { - pr_err("%s: unknown flash device id (0x%02x) found.\n", __func__, - dev_id); - err = -ENODEV; - goto out_error; - } - - vendor_info = find_nand_flash_vendor(vendor_id); - if (vendor_info == NULL) { - pr_err("%s: unknown flash vendor id (0x%02x) found.\n", __func__, - vendor_id); - err = -ENODEV; - goto out_error; - } - - /* loop through and see if we can find more devices */ - for (cnt = 1; cnt < info->plat->max_chips; ++cnt) { - select_chip(info, cnt); - /* TODO: figure out what to do about errors here */ - err = tegra_nand_cmd_readid(info, &tmp); - if (err != 0) - goto out_error; - if ((dev_id != ((tmp >> 8) & 0xff)) || - (vendor_id != (tmp & 0xff))) - break; - } - - pr_info("%s: %d NAND chip(s) found (vend=0x%02x, dev=0x%02x) (%s %s)\n", - DRIVER_NAME, cnt, vendor_id, dev_id, vendor_info->name, - dev_info->name); - info->chip.num_chips = cnt; - info->chip.chipsize = dev_info->chipsize << 20; - mtd->size = info->chip.num_chips * info->chip.chipsize; - - /* format of 4th id byte returned by READ ID - * bit 7 = rsvd - * bit 6 = bus width. 1 == 16bit, 0 == 8bit - * bits 5:4 = data block size. 64kb * (2^val) - * bit 3 = rsvd - * bit 2 = spare area size / 512 bytes. 0 == 8bytes, 1 == 16bytes - * bits 1:0 = page size. 1kb * (2^val) - */ - - /* TODO: we should reconcile the information read from chip and - * the data given to us in tegra_nand_platform->chip_parms?? - * platform data will give us timing information. */ - - /* page_size */ - tmp = dev_parms & 0x3; - mtd->writesize = 1024 << tmp; - info->chip.column_mask = mtd->writesize - 1; - - /* Note: See oob layout description of why we only support 2k pages. */ - if (mtd->writesize > 2048) { - pr_err("%s: Large page devices with pagesize > 2kb are NOT " - "supported\n", __func__); - goto out_error; - } else if (mtd->writesize < 2048) { - pr_err("%s: Small page devices are NOT supported\n", __func__); - goto out_error; - } - - /* spare area, must be at least 64 bytes */ - tmp = (dev_parms >> 2) & 0x1; - tmp = (8 << tmp) * (mtd->writesize / 512); - if (tmp < 64) { - pr_err("%s: Spare area (%d bytes) too small\n", __func__, tmp); - goto out_error; - } - mtd->oobsize = tmp; - mtd->oobavail = tegra_nand_oob_64.oobavail; - - /* data block size (erase size) (w/o spare) */ - tmp = (dev_parms >> 4) & 0x3; - mtd->erasesize = (64 * 1024) << tmp; - info->chip.block_shift = ffs(mtd->erasesize) - 1; - - /* used to select the appropriate chip/page in case multiple devices - * are connected */ - info->chip.chip_shift = ffs(info->chip.chipsize) - 1; - info->chip.page_shift = ffs(mtd->writesize) - 1; - info->chip.page_mask = - (info->chip.chipsize >> info->chip.page_shift) - 1; - - /* now fill in the rest of the mtd fields */ - mtd->ecclayout = &tegra_nand_oob_64; - mtd->type = MTD_NANDFLASH; - mtd->flags = MTD_CAP_NANDFLASH; - - mtd->erase = tegra_nand_erase; - mtd->lock = NULL; - mtd->point = NULL; - mtd->unpoint = NULL; - mtd->read = tegra_nand_read; - mtd->write = tegra_nand_write; - mtd->read_oob = tegra_nand_read_oob; - mtd->write_oob = tegra_nand_write_oob; - - mtd->resume = tegra_nand_resume; - mtd->suspend = tegra_nand_suspend; - mtd->block_isbad = tegra_nand_block_isbad; - mtd->block_markbad = tegra_nand_block_markbad; - - /* TODO: should take vendor_id/device_id */ - set_chip_timing(info); - - return 0; - -out_error: - pr_err("%s: NAND device scan aborted due to error(s).\n", __func__); - return err; -} - -static int __devinit -tegra_nand_probe(struct platform_device *pdev) -{ - struct tegra_nand_platform *plat = pdev->dev.platform_data; - struct tegra_nand_info *info = NULL; - struct tegra_nand_chip *chip = NULL; - struct mtd_info *mtd = NULL; - int err = 0; - uint64_t num_erase_blocks; - - pr_debug("%s: probing (%p)\n", __func__, pdev); - - if (!plat) { - pr_err("%s: no platform device info\n", __func__); - return -EINVAL; - } else if (!plat->chip_parms) { - pr_err("%s: no platform nand parms\n", __func__); - return -EINVAL; - } - - info = kzalloc(sizeof(struct tegra_nand_info), GFP_KERNEL); - if (!info) { - pr_err("%s: no memory for flash info\n", __func__); - return -ENOMEM; - } - - info->dev = &pdev->dev; - info->plat = plat; - - platform_set_drvdata(pdev, info); - - init_completion(&info->cmd_complete); - init_completion(&info->dma_complete); - - mutex_init(&info->lock); - spin_lock_init(&info->ecc_lock); - - chip = &info->chip; - chip->priv = &info->mtd; - chip->curr_chip = -1; - - mtd = &info->mtd; - mtd->name = dev_name(&pdev->dev); - mtd->priv = &info->chip; - mtd->owner = THIS_MODULE; - - /* HACK: allocate a dma buffer to hold 1 page oob data */ - info->oob_dma_buf = dma_alloc_coherent(NULL, 64, - &info->oob_dma_addr, GFP_KERNEL); - if (!info->oob_dma_buf) { - err = -ENOMEM; - goto out_free_info; - } - - /* this will store the ecc error vector info */ - info->ecc_buf = dma_alloc_coherent(NULL, ECC_BUF_SZ, &info->ecc_addr, - GFP_KERNEL); - if (!info->ecc_buf) { - err = -ENOMEM; - goto out_free_dma_buf; - } - - /* grab the irq */ - if (!(pdev->resource[0].flags & IORESOURCE_IRQ)) { - pr_err("NAND IRQ resource not defined\n"); - err = -EINVAL; - goto out_free_ecc_buf; - } - - err = request_irq(pdev->resource[0].start, tegra_nand_irq, - IRQF_SHARED, DRIVER_NAME, info); - if (err) { - pr_err("Unable to request IRQ %d (%d)\n", - pdev->resource[0].start, err); - goto out_free_ecc_buf; - } - - /* TODO: configure pinmux here?? */ - info->clk = clk_get(&pdev->dev, NULL); - clk_set_rate(info->clk, 108000000); - - cfg_hwstatus_mon(info); - - /* clear all pending interrupts */ - writel(readl(ISR_REG), ISR_REG); - - /* clear dma interrupt */ - writel(DMA_CTRL_IS_DMA_DONE, DMA_MST_CTRL_REG); - - /* enable interrupts */ - disable_ints(info, 0xffffffff); - enable_ints(info, IER_ERR_TRIG_VAL(4) | IER_UND | IER_OVR | IER_CMD_DONE | - IER_ECC_ERR | IER_GIE); - - if (tegra_nand_scan(mtd, plat->max_chips)) { - err = -ENXIO; - goto out_dis_irq; - } - pr_info("%s: NVIDIA Tegra NAND controller @ base=0x%08x irq=%d.\n", - DRIVER_NAME, TEGRA_NAND_PHYS, pdev->resource[0].start); - - /* allocate memory to hold the ecc error info */ - info->max_ecc_errs = MAX_DMA_SZ / mtd->writesize; - info->ecc_errs = kmalloc(info->max_ecc_errs * sizeof(uint32_t), - GFP_KERNEL); - if (!info->ecc_errs) { - err = -ENOMEM; - goto out_dis_irq; - } - - /* alloc the bad block bitmap */ - num_erase_blocks = mtd->size; - do_div(num_erase_blocks, mtd->erasesize); - info->bb_bitmap = kzalloc(BITS_TO_LONGS(num_erase_blocks) * - sizeof(unsigned long), GFP_KERNEL); - if (!info->bb_bitmap) { - err = -ENOMEM; - goto out_free_ecc; - } - - err = scan_bad_blocks(info); - if (err != 0) - goto out_free_bbbmap; - -#if 0 - dump_nand_regs(); -#endif - -#ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(mtd, part_probes, &info->parts, 0); - if (err > 0) { - err = add_mtd_partitions(mtd, info->parts, err); - } else if (err <= 0 && plat->parts) { - err = add_mtd_partitions(mtd, plat->parts, plat->nr_parts); - } else -#endif - err = add_mtd_device(mtd); - if (err != 0) - goto out_free_bbbmap; - - dev_set_drvdata(&pdev->dev, info); - - pr_debug("%s: probe done.\n", __func__); - return 0; - -out_free_bbbmap: - kfree(info->bb_bitmap); - -out_free_ecc: - kfree(info->ecc_errs); - -out_dis_irq: - disable_ints(info, 0xffffffff); - free_irq(pdev->resource[0].start, info); - -out_free_ecc_buf: - dma_free_coherent(NULL, ECC_BUF_SZ, info->ecc_buf, info->ecc_addr); - -out_free_dma_buf: - dma_free_coherent(NULL, 64, info->oob_dma_buf, - info->oob_dma_addr); - -out_free_info: - platform_set_drvdata(pdev, NULL); - kfree(info); - - return err; -} - -static int __devexit -tegra_nand_remove(struct platform_device *pdev) -{ - struct tegra_nand_info *info = dev_get_drvdata(&pdev->dev); - - dev_set_drvdata(&pdev->dev, NULL); - - if (info) { - free_irq(pdev->resource[0].start, info); - kfree(info->bb_bitmap); - kfree(info->ecc_errs); - dma_free_coherent(NULL, ECC_BUF_SZ, info->ecc_buf, info->ecc_addr); - dma_free_coherent(NULL, info->mtd.writesize + info->mtd.oobsize, - info->oob_dma_buf, info->oob_dma_addr); - kfree(info); - } - - return 0; -} - -static struct platform_driver tegra_nand_driver = { - .probe = tegra_nand_probe, - .remove = __devexit_p(tegra_nand_remove), - .suspend = NULL, - .resume = NULL, - .driver = { - .name = "tegra_nand", - .owner = THIS_MODULE, - }, -}; - -static int __init -tegra_nand_init(void) -{ - return platform_driver_register(&tegra_nand_driver); -} - -static void __exit -tegra_nand_exit(void) -{ - platform_driver_unregister(&tegra_nand_driver); -} - -module_init(tegra_nand_init); -module_exit(tegra_nand_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/mtd/devices/tegra_nand.h b/drivers/mtd/devices/tegra_nand.h deleted file mode 100644 index cc310d577631..000000000000 --- a/drivers/mtd/devices/tegra_nand.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * drivers/mtd/devices/tegra_nand.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Dima Zavin - * Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MTD_DEV_TEGRA_NAND_H -#define __MTD_DEV_TEGRA_NAND_H - -#include - -#define __BITMASK0(len) ((1 << (len)) - 1) -#define __BITMASK(start, len) (__BITMASK0(len) << (start)) -#define REG_BIT(bit) (1 << (bit)) -#define REG_FIELD(val, start, len) (((val) & __BITMASK0(len)) << (start)) -#define REG_FIELD_MASK(start, len) (~(__BITMASK((start), (len)))) -#define REG_GET_FIELD(val, start, len) (((val) >> (start)) & __BITMASK0(len)) - -/* tegra nand registers... */ -#define TEGRA_NAND_PHYS 0x70008000 -#define TEGRA_NAND_BASE IO_TO_VIRT(TEGRA_NAND_PHYS) -#define COMMAND_REG (TEGRA_NAND_BASE + 0x00) -#define STATUS_REG (TEGRA_NAND_BASE + 0x04) -#define ISR_REG (TEGRA_NAND_BASE + 0x08) -#define IER_REG (TEGRA_NAND_BASE + 0x0c) -#define CONFIG_REG (TEGRA_NAND_BASE + 0x10) -#define TIMING_REG (TEGRA_NAND_BASE + 0x14) -#define RESP_REG (TEGRA_NAND_BASE + 0x18) -#define TIMING2_REG (TEGRA_NAND_BASE + 0x1c) -#define CMD_REG1 (TEGRA_NAND_BASE + 0x20) -#define CMD_REG2 (TEGRA_NAND_BASE + 0x24) -#define ADDR_REG1 (TEGRA_NAND_BASE + 0x28) -#define ADDR_REG2 (TEGRA_NAND_BASE + 0x2c) -#define DMA_MST_CTRL_REG (TEGRA_NAND_BASE + 0x30) -#define DMA_CFG_A_REG (TEGRA_NAND_BASE + 0x34) -#define DMA_CFG_B_REG (TEGRA_NAND_BASE + 0x38) -#define FIFO_CTRL_REG (TEGRA_NAND_BASE + 0x3c) -#define DATA_BLOCK_PTR_REG (TEGRA_NAND_BASE + 0x40) -#define TAG_PTR_REG (TEGRA_NAND_BASE + 0x44) -#define ECC_PTR_REG (TEGRA_NAND_BASE + 0x48) -#define DEC_STATUS_REG (TEGRA_NAND_BASE + 0x4c) -#define HWSTATUS_CMD_REG (TEGRA_NAND_BASE + 0x50) -#define HWSTATUS_MASK_REG (TEGRA_NAND_BASE + 0x54) -#define LL_CONFIG_REG (TEGRA_NAND_BASE + 0x58) -#define LL_PTR_REG (TEGRA_NAND_BASE + 0x5c) -#define LL_STATUS_REG (TEGRA_NAND_BASE + 0x60) - -/* nand_command bits */ -#define COMMAND_GO REG_BIT(31) -#define COMMAND_CLE REG_BIT(30) -#define COMMAND_ALE REG_BIT(29) -#define COMMAND_PIO REG_BIT(28) -#define COMMAND_TX REG_BIT(27) -#define COMMAND_RX REG_BIT(26) -#define COMMAND_SEC_CMD REG_BIT(25) -#define COMMAND_AFT_DAT REG_BIT(24) -#define COMMAND_TRANS_SIZE(val) REG_FIELD((val), 20, 4) -#define COMMAND_A_VALID REG_BIT(19) -#define COMMAND_B_VALID REG_BIT(18) -#define COMMAND_RD_STATUS_CHK REG_BIT(17) -#define COMMAND_RBSY_CHK REG_BIT(16) -#define COMMAND_CE(val) REG_BIT(8 + ((val) & 0x7)) -#define COMMAND_CLE_BYTE_SIZE(val) REG_FIELD((val), 4, 2) -#define COMMAND_ALE_BYTE_SIZE(val) REG_FIELD((val), 0, 4) - -/* nand isr bits */ -#define ISR_UND REG_BIT(7) -#define ISR_OVR REG_BIT(6) -#define ISR_CMD_DONE REG_BIT(5) -#define ISR_ECC_ERR REG_BIT(4) - -/* nand ier bits */ -#define IER_ERR_TRIG_VAL(val) REG_FIELD((val), 16, 4) -#define IER_UND REG_BIT(7) -#define IER_OVR REG_BIT(6) -#define IER_CMD_DONE REG_BIT(5) -#define IER_ECC_ERR REG_BIT(4) -#define IER_GIE REG_BIT(0) - -/* nand config bits */ -#define CONFIG_HW_ECC REG_BIT(31) -#define CONFIG_ECC_SEL REG_BIT(30) -#define CONFIG_HW_ERR_CORRECTION REG_BIT(29) -#define CONFIG_PIPELINE_EN REG_BIT(28) -#define CONFIG_ECC_EN_TAG REG_BIT(27) -#define CONFIG_TVALUE(val) REG_FIELD((val), 24, 2) -#define CONFIG_SKIP_SPARE REG_BIT(23) -#define CONFIG_COM_BSY REG_BIT(22) -#define CONFIG_BUS_WIDTH REG_BIT(21) -#define CONFIG_PAGE_SIZE_SEL(val) REG_FIELD((val), 16, 3) -#define CONFIG_SKIP_SPARE_SEL(val) REG_FIELD((val), 14, 2) -#define CONFIG_TAG_BYTE_SIZE(val) REG_FIELD((val), 0, 8) - -/* nand timing bits */ -#define TIMING_TRP_RESP(val) REG_FIELD((val), 28, 4) -#define TIMING_TWB(val) REG_FIELD((val), 24, 4) -#define TIMING_TCR_TAR_TRR(val) REG_FIELD((val), 20, 4) -#define TIMING_TWHR(val) REG_FIELD((val), 16, 4) -#define TIMING_TCS(val) REG_FIELD((val), 14, 2) -#define TIMING_TWH(val) REG_FIELD((val), 12, 2) -#define TIMING_TWP(val) REG_FIELD((val), 8, 4) -#define TIMING_TRH(val) REG_FIELD((val), 4, 2) -#define TIMING_TRP(val) REG_FIELD((val), 0, 4) - -/* nand timing2 bits */ -#define TIMING2_TADL(val) REG_FIELD((val), 0, 4) - -/* nand dma_mst_ctrl bits */ -#define DMA_CTRL_DMA_GO REG_BIT(31) -#define DMA_CTRL_DIR REG_BIT(30) -#define DMA_CTRL_DMA_PERF_EN REG_BIT(29) -#define DMA_CTRL_IE_DMA_DONE REG_BIT(28) -#define DMA_CTRL_REUSE_BUFFER REG_BIT(27) -#define DMA_CTRL_BURST_SIZE(val) REG_FIELD((val), 24, 3) -#define DMA_CTRL_IS_DMA_DONE REG_BIT(20) -#define DMA_CTRL_DMA_EN_A REG_BIT(2) -#define DMA_CTRL_DMA_EN_B REG_BIT(1) - -/* nand dma_cfg_a/cfg_b bits */ -#define DMA_CFG_BLOCK_SIZE(val) REG_FIELD((val), 0, 16) - -/* nand dec_status bits */ -#define DEC_STATUS_ERR_PAGE_NUM(val) REG_GET_FIELD((val), 24, 8) -#define DEC_STATUS_ERR_CNT(val) REG_GET_FIELD((val), 16, 8) -#define DEC_STATUS_ECC_FAIL_A REG_BIT(1) -#define DEC_STATUS_ECC_FAIL_B REG_BIT(0) - -/* nand hwstatus_mask bits */ -#define HWSTATUS_RDSTATUS_MASK(val) REG_FIELD((val), 24, 8) -#define HWSTATUS_RDSTATUS_EXP_VAL(val) REG_FIELD((val), 16, 8) -#define HWSTATUS_RBSY_MASK(val) REG_FIELD((val), 8, 8) -#define HWSTATUS_RBSY_EXP_VAL(val) REG_FIELD((val), 0, 8) - -#endif - diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index f9d35ac42d18..63fa16f935ad 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,10 +1,3 @@ -config MTD_NAND_IDS - tristate "Include chip ids for known NAND devices." - depends on MTD - help - Useful for NAND drivers that do not use the NAND subsystem but - still like to take advantage of the known chip information. - config MTD_NAND_ECC tristate @@ -129,6 +122,9 @@ config MTD_NAND_OMAP_PREFETCH_DMA or in DMA interrupt mode. Say y for DMA mode or MPU mode will be used +config MTD_NAND_IDS + tristate + config MTD_NAND_RICOH tristate "Ricoh xD card reader" default n diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6823b1f77d27..720e8036c073 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3065,44 +3065,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, return 0; } -static void nand_panic_wait(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - int i; - - if (chip->state != FL_READY) - for (i = 0; i < 40; i++) { - if (chip->dev_ready(mtd)) - break; - mdelay(10); - } - chip->state = FL_READY; -} - -static int nand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct nand_chip *chip = mtd->priv; - int ret; - - /* Do not allow reads past end of device */ - if ((to + len) > mtd->size) - return -EINVAL; - if (!len) - return 0; - - nand_panic_wait(mtd); - - chip->ops.len = len; - chip->ops.datbuf = (uint8_t *)buf; - chip->ops.oobbuf = NULL; - - ret = nand_do_write_ops(mtd, to, &chip->ops); - - *retlen = chip->ops.retlen; - return ret; -} - /** * nand_scan_tail - [NAND Interface] Scan for the NAND device @@ -3312,7 +3274,6 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->panic_write = panic_nand_write; mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; - mtd->panic_write = nand_panic_write; mtd->sync = nand_sync; mtd->lock = NULL; mtd->unlock = NULL; diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 70609eefc2de..4a4f6b81e32d 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -490,11 +490,13 @@ static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; - if (((protocol == RxProtoTCP) && !(status & TCPFail)) || - ((protocol == RxProtoUDP) && !(status & UDPFail))) + if (likely((protocol == RxProtoTCP) && (!(status & TCPFail)))) return 1; - else - return 0; + else if ((protocol == RxProtoUDP) && (!(status & UDPFail))) + return 1; + else if ((protocol == RxProtoIP) && (!(status & IPFail))) + return 1; + return 0; } static int cp_rx_poll(struct napi_struct *napi, int budget) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2c945d17ac5f..e473def09a96 100755 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3240,23 +3240,6 @@ config PPPOL2TP used by ISPs and enterprises to tunnel PPP traffic over UDP tunnels. L2TP is replacing PPTP for VPN uses. -config PPPOLAC - tristate "PPP on L2TP Access Concentrator" - depends on PPP && INET - help - L2TP (RFC 2661) is a tunneling protocol widely used in virtual private - networks. This driver handles L2TP data packets between a UDP socket - and a PPP channel, but only permits one session per socket. Thus it is - fairly simple and suited for clients. - -config PPPOPNS - tristate "PPP on PPTP Network Server" - depends on PPP && INET - help - PPTP (RFC 2637) is a tunneling protocol widely used in virtual private - networks. This driver handles PPTP data packets between a RAW socket - and a PPP channel. It is fairly simple and easy to use. - config SLIP tristate "SLIP (serial line) support" ---help--- diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 707cf7ea4171..c6176c1190de 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -163,8 +163,6 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_PPPOL2TP) += pppox.o -obj-$(CONFIG_PPPOLAC) += pppox.o pppolac.o -obj-$(CONFIG_PPPOPNS) += pppox.o pppopns.o obj-$(CONFIG_SLIP) += slip.o obj-$(CONFIG_SLHC) += slhc.o diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index dc913b986795..34abcc9403d6 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1179,7 +1179,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; } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c867cf901f9f..c6fdd851579a 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -240,11 +240,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) { - return slave; + break; } } - return 0; + return slave; } static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 71324286b1e7..5cc39ed289c6 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -31,7 +31,7 @@ char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -#define DRV_VERSION "7.3.21-k8-NAPI" +#define DRV_VERSION "7.3.21-k6-NAPI" const char e1000_driver_version[] = DRV_VERSION; static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -483,6 +483,9 @@ void e1000_down(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u32 rctl, tctl; + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + set_bit(__E1000_DOWN, &adapter->flags); /* disable receives in the hardware */ rctl = er32(RCTL); @@ -503,13 +506,6 @@ void e1000_down(struct e1000_adapter *adapter) e1000_irq_disable(adapter); - /* - * Setting DOWN must be after irq_disable to prevent - * a screaming interrupt. Setting DOWN also prevents - * timers and tasks from rescheduling. - */ - set_bit(__E1000_DOWN, &adapter->flags); - del_timer_sync(&adapter->tx_fifo_stall_timer); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index fe337bd121aa..ab9f675c5b8b 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -104,8 +104,6 @@ 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(); diff --git a/drivers/net/jme.c b/drivers/net/jme.c index f0643ac4aff1..99f24f5cac53 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -1575,16 +1575,6 @@ jme_free_irq(struct jme_adapter *jme) } } -static inline void -jme_phy_on(struct jme_adapter *jme) -{ - u32 bmcr; - - bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); - bmcr &= ~BMCR_PDOWN; - jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); -} - static int jme_open(struct net_device *netdev) { @@ -1605,12 +1595,10 @@ jme_open(struct net_device *netdev) jme_start_irq(jme); - if (test_bit(JME_FLAG_SSET, &jme->flags)) { - jme_phy_on(jme); + if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); - } else { + else jme_reset_phy_processor(jme); - } jme_reset_link(jme); @@ -3018,12 +3006,10 @@ jme_resume(struct pci_dev *pdev) jme_clear_pm(jme); pci_restore_state(pdev); - if (test_bit(JME_FLAG_SSET, &jme->flags)) { - jme_phy_on(jme); + if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); - } else { + else jme_reset_phy_processor(jme); - } jme_start_irq(jme); netif_device_attach(netdev); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index b12553bb5ecc..f9b509a6b09a 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1622,7 +1622,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9), PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), - PCMCIA_DEVICE_PROD_ID12("corega", "Ether CF-TD", 0x0a21501a, 0x6589340a), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d), PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index c1ba49b772ff..0101f2bdf400 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -196,27 +196,20 @@ static int m88e1121_config_aneg(struct phy_device *phydev) MII_88E1121_PHY_MSCR_PAGE); if (err < 0) return err; + mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & + MII_88E1121_PHY_MSCR_DELAY_MASK; - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - - mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & - MII_88E1121_PHY_MSCR_DELAY_MASK; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | - MII_88E1121_PHY_MSCR_TX_DELAY); - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) - mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) - mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | + MII_88E1121_PHY_MSCR_TX_DELAY); + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; - err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); - if (err < 0) - return err; - } + err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); + if (err < 0) + return err; phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 49ca2493db74..af50a530daee 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -100,7 +100,7 @@ static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb); static int ppp_async_push(struct asyncppp *ap); static void ppp_async_flush_output(struct asyncppp *ap); static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count, struct sk_buff *skbuf); + char *flags, int count); static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg); static void ppp_async_process(unsigned long arg); @@ -344,18 +344,12 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { struct asyncppp *ap = ap_get(tty); - struct sk_buff *skb; unsigned long flags; if (!ap) return; - - skb = __dev_alloc_skb(ap->mru + PPP_HDRLEN + 2, GFP_KERNEL); - if (!skb) - return; - spin_lock_irqsave(&ap->recv_lock, flags); - ppp_async_input(ap, buf, cflags, count, skb); + ppp_async_input(ap, buf, cflags, count); spin_unlock_irqrestore(&ap->recv_lock, flags); if (!skb_queue_empty(&ap->rqueue)) tasklet_schedule(&ap->tsk); @@ -837,7 +831,7 @@ process_input_packet(struct asyncppp *ap) static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count, struct sk_buff *skbuf) + char *flags, int count) { struct sk_buff *skb; int c, i, j, n, s, f; @@ -879,14 +873,9 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf, /* stuff the chars in the skb */ skb = ap->rpkt; if (!skb) { - if (skbuf) { - skb = skbuf; - skbuf = NULL; - } else { - skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); - if (!skb) - goto nomem; - } + skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); + if (!skb) + goto nomem; ap->rpkt = skb; } if (skb->len == 0) { @@ -936,13 +925,11 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf, flags += n; count -= n; } - kfree(skbuf); return; nomem: printk(KERN_ERR "PPPasync: no memory (input pkt)\n"); ap->state |= SC_TOSS; - kfree(skbuf); } /* diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index bda70852c5ef..695bc83e0cfd 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c @@ -306,7 +306,7 @@ static void z_decomp_free(void *arg) if (state) { zlib_inflateEnd(&state->strm); - vfree(state->strm.workspace); + kfree(state->strm.workspace); kfree(state); } } @@ -346,7 +346,8 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len) state->w_size = w_size; state->strm.next_out = NULL; - state->strm.workspace = vmalloc(zlib_inflate_workspacesize()); + state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), + GFP_KERNEL|__GFP_REPEAT); if (state->strm.workspace == NULL) goto out_free; diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 6a3eae2407c1..c07de359dc07 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 1; + return 0; } /************************************************************************ diff --git a/drivers/net/pppolac.c b/drivers/net/pppolac.c deleted file mode 100644 index c94b8507d92b..000000000000 --- a/drivers/net/pppolac.c +++ /dev/null @@ -1,449 +0,0 @@ -/* drivers/net/pppolac.c - * - * Driver for PPP on L2TP Access Concentrator / PPPoLAC Socket (RFC 2661) - * - * Copyright (C) 2009 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. - */ - -/* This driver handles L2TP data packets between a UDP socket and a PPP channel. - * The socket must keep connected, and only one session per socket is permitted. - * Sequencing of outgoing packets is controlled by LNS. Incoming packets with - * sequences are reordered within a sliding window of one second. Currently - * reordering only happens when a packet is received. It is done for simplicity - * since no additional locks or threads are required. This driver only works on - * IPv4 due to the lack of UDP encapsulation support in IPv6. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define L2TP_CONTROL_BIT 0x80 -#define L2TP_LENGTH_BIT 0x40 -#define L2TP_SEQUENCE_BIT 0x08 -#define L2TP_OFFSET_BIT 0x02 -#define L2TP_VERSION 0x02 -#define L2TP_VERSION_MASK 0x0F - -#define PPP_ADDR 0xFF -#define PPP_CTRL 0x03 - -union unaligned { - __u32 u32; -} __attribute__((packed)); - -static inline union unaligned *unaligned(void *ptr) -{ - return (union unaligned *)ptr; -} - -struct meta { - __u32 sequence; - __u32 timestamp; -}; - -static inline struct meta *skb_meta(struct sk_buff *skb) -{ - return (struct meta *)skb->cb; -} - -/******************************************************************************/ - -static int pppolac_recv_core(struct sock *sk_udp, struct sk_buff *skb) -{ - struct sock *sk = (struct sock *)sk_udp->sk_user_data; - struct pppolac_opt *opt = &pppox_sk(sk)->proto.lac; - struct meta *meta = skb_meta(skb); - __u32 now = jiffies; - __u8 bits; - __u8 *ptr; - - /* Drop the packet if L2TP header is missing. */ - if (skb->len < sizeof(struct udphdr) + 6) - goto drop; - - /* Put it back if it is a control packet. */ - if (skb->data[sizeof(struct udphdr)] & L2TP_CONTROL_BIT) - return opt->backlog_rcv(sk_udp, skb); - - /* Skip UDP header. */ - skb_pull(skb, sizeof(struct udphdr)); - - /* Check the version. */ - if ((skb->data[1] & L2TP_VERSION_MASK) != L2TP_VERSION) - goto drop; - bits = skb->data[0]; - ptr = &skb->data[2]; - - /* Check the length if it is present. */ - if (bits & L2TP_LENGTH_BIT) { - if ((ptr[0] << 8 | ptr[1]) != skb->len) - goto drop; - ptr += 2; - } - - /* Skip all fields including optional ones. */ - if (!skb_pull(skb, 6 + (bits & L2TP_SEQUENCE_BIT ? 4 : 0) + - (bits & L2TP_LENGTH_BIT ? 2 : 0) + - (bits & L2TP_OFFSET_BIT ? 2 : 0))) - goto drop; - - /* Skip the offset padding if it is present. */ - if (bits & L2TP_OFFSET_BIT && - !skb_pull(skb, skb->data[-2] << 8 | skb->data[-1])) - goto drop; - - /* Check the tunnel and the session. */ - if (unaligned(ptr)->u32 != opt->local) - goto drop; - - /* Check the sequence if it is present. */ - if (bits & L2TP_SEQUENCE_BIT) { - meta->sequence = ptr[4] << 8 | ptr[5]; - if ((__s16)(meta->sequence - opt->recv_sequence) < 0) - goto drop; - } - - /* Skip PPP address and control if they are present. */ - if (skb->len >= 2 && skb->data[0] == PPP_ADDR && - skb->data[1] == PPP_CTRL) - skb_pull(skb, 2); - - /* Fix PPP protocol if it is compressed. */ - if (skb->len >= 1 && skb->data[0] & 1) - skb_push(skb, 1)[0] = 0; - - /* Drop the packet if PPP protocol is missing. */ - if (skb->len < 2) - goto drop; - - /* Perform reordering if sequencing is enabled. */ - atomic_set(&opt->sequencing, bits & L2TP_SEQUENCE_BIT); - if (bits & L2TP_SEQUENCE_BIT) { - struct sk_buff *skb1; - - /* Insert the packet into receive queue in order. */ - skb_set_owner_r(skb, sk); - skb_queue_walk(&sk->sk_receive_queue, skb1) { - struct meta *meta1 = skb_meta(skb1); - __s16 order = meta->sequence - meta1->sequence; - if (order == 0) - goto drop; - if (order < 0) { - meta->timestamp = meta1->timestamp; - skb_insert(skb1, skb, &sk->sk_receive_queue); - skb = NULL; - break; - } - } - if (skb) { - meta->timestamp = now; - skb_queue_tail(&sk->sk_receive_queue, skb); - } - - /* Remove packets from receive queue as long as - * 1. the receive buffer is full, - * 2. they are queued longer than one second, or - * 3. there are no missing packets before them. */ - skb_queue_walk_safe(&sk->sk_receive_queue, skb, skb1) { - meta = skb_meta(skb); - if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && - now - meta->timestamp < HZ && - meta->sequence != opt->recv_sequence) - break; - skb_unlink(skb, &sk->sk_receive_queue); - opt->recv_sequence = (__u16)(meta->sequence + 1); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - } - return NET_RX_SUCCESS; - } - - /* Flush receive queue if sequencing is disabled. */ - skb_queue_purge(&sk->sk_receive_queue); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - return NET_RX_SUCCESS; -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - -static int pppolac_recv(struct sock *sk_udp, struct sk_buff *skb) -{ - sock_hold(sk_udp); - sk_receive_skb(sk_udp, skb, 0); - return 0; -} - -static struct sk_buff_head delivery_queue; - -static void pppolac_xmit_core(struct work_struct *delivery_work) -{ - mm_segment_t old_fs = get_fs(); - struct sk_buff *skb; - - set_fs(KERNEL_DS); - while ((skb = skb_dequeue(&delivery_queue))) { - struct sock *sk_udp = skb->sk; - struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len}; - struct msghdr msg = { - .msg_iov = (struct iovec *)&iov, - .msg_iovlen = 1, - .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT, - }; - sk_udp->sk_prot->sendmsg(NULL, sk_udp, &msg, skb->len); - kfree_skb(skb); - } - set_fs(old_fs); -} - -static DECLARE_WORK(delivery_work, pppolac_xmit_core); - -static int pppolac_xmit(struct ppp_channel *chan, struct sk_buff *skb) -{ - struct sock *sk_udp = (struct sock *)chan->private; - struct pppolac_opt *opt = &pppox_sk(sk_udp->sk_user_data)->proto.lac; - - /* Install PPP address and control. */ - skb_push(skb, 2); - skb->data[0] = PPP_ADDR; - skb->data[1] = PPP_CTRL; - - /* Install L2TP header. */ - if (atomic_read(&opt->sequencing)) { - skb_push(skb, 10); - skb->data[0] = L2TP_SEQUENCE_BIT; - skb->data[6] = opt->xmit_sequence >> 8; - skb->data[7] = opt->xmit_sequence; - skb->data[8] = 0; - skb->data[9] = 0; - opt->xmit_sequence++; - } else { - skb_push(skb, 6); - skb->data[0] = 0; - } - skb->data[1] = L2TP_VERSION; - unaligned(&skb->data[2])->u32 = opt->remote; - - /* Now send the packet via the delivery queue. */ - skb_set_owner_w(skb, sk_udp); - skb_queue_tail(&delivery_queue, skb); - schedule_work(&delivery_work); - return 1; -} - -/******************************************************************************/ - -static struct ppp_channel_ops pppolac_channel_ops = { - .start_xmit = pppolac_xmit, -}; - -static int pppolac_connect(struct socket *sock, struct sockaddr *useraddr, - int addrlen, int flags) -{ - struct sock *sk = sock->sk; - struct pppox_sock *po = pppox_sk(sk); - struct sockaddr_pppolac *addr = (struct sockaddr_pppolac *)useraddr; - struct socket *sock_udp = NULL; - struct sock *sk_udp; - int error; - - if (addrlen != sizeof(struct sockaddr_pppolac) || - !addr->local.tunnel || !addr->local.session || - !addr->remote.tunnel || !addr->remote.session) { - return -EINVAL; - } - - lock_sock(sk); - error = -EALREADY; - if (sk->sk_state != PPPOX_NONE) - goto out; - - sock_udp = sockfd_lookup(addr->udp_socket, &error); - if (!sock_udp) - goto out; - sk_udp = sock_udp->sk; - lock_sock(sk_udp); - - /* Remove this check when IPv6 supports UDP encapsulation. */ - error = -EAFNOSUPPORT; - if (sk_udp->sk_family != AF_INET) - goto out; - error = -EPROTONOSUPPORT; - if (sk_udp->sk_protocol != IPPROTO_UDP) - goto out; - error = -EDESTADDRREQ; - if (sk_udp->sk_state != TCP_ESTABLISHED) - goto out; - error = -EBUSY; - if (udp_sk(sk_udp)->encap_type || sk_udp->sk_user_data) - goto out; - if (!sk_udp->sk_bound_dev_if) { - struct dst_entry *dst = sk_dst_get(sk_udp); - error = -ENODEV; - if (!dst) - goto out; - sk_udp->sk_bound_dev_if = dst->dev->ifindex; - dst_release(dst); - } - - po->chan.hdrlen = 12; - po->chan.private = sk_udp; - po->chan.ops = &pppolac_channel_ops; - po->chan.mtu = PPP_MTU - 80; - po->proto.lac.local = unaligned(&addr->local)->u32; - po->proto.lac.remote = unaligned(&addr->remote)->u32; - atomic_set(&po->proto.lac.sequencing, 1); - po->proto.lac.backlog_rcv = sk_udp->sk_backlog_rcv; - - error = ppp_register_channel(&po->chan); - if (error) - goto out; - - sk->sk_state = PPPOX_CONNECTED; - udp_sk(sk_udp)->encap_type = UDP_ENCAP_L2TPINUDP; - udp_sk(sk_udp)->encap_rcv = pppolac_recv; - sk_udp->sk_backlog_rcv = pppolac_recv_core; - sk_udp->sk_user_data = sk; -out: - if (sock_udp) { - release_sock(sk_udp); - if (error) - sockfd_put(sock_udp); - } - release_sock(sk); - return error; -} - -static int pppolac_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (!sk) - return 0; - - lock_sock(sk); - if (sock_flag(sk, SOCK_DEAD)) { - release_sock(sk); - return -EBADF; - } - - if (sk->sk_state != PPPOX_NONE) { - struct sock *sk_udp = (struct sock *)pppox_sk(sk)->chan.private; - lock_sock(sk_udp); - skb_queue_purge(&sk->sk_receive_queue); - pppox_unbind_sock(sk); - udp_sk(sk_udp)->encap_type = 0; - udp_sk(sk_udp)->encap_rcv = NULL; - sk_udp->sk_backlog_rcv = pppox_sk(sk)->proto.lac.backlog_rcv; - sk_udp->sk_user_data = NULL; - release_sock(sk_udp); - sockfd_put(sk_udp->sk_socket); - } - - sock_orphan(sk); - sock->sk = NULL; - release_sock(sk); - sock_put(sk); - return 0; -} - -/******************************************************************************/ - -static struct proto pppolac_proto = { - .name = "PPPOLAC", - .owner = THIS_MODULE, - .obj_size = sizeof(struct pppox_sock), -}; - -static struct proto_ops pppolac_proto_ops = { - .family = PF_PPPOX, - .owner = THIS_MODULE, - .release = pppolac_release, - .bind = sock_no_bind, - .connect = pppolac_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = sock_no_poll, - .ioctl = pppox_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .mmap = sock_no_mmap, -}; - -static int pppolac_create(struct net *net, struct socket *sock) -{ - struct sock *sk; - - sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppolac_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - sock->state = SS_UNCONNECTED; - sock->ops = &pppolac_proto_ops; - sk->sk_protocol = PX_PROTO_OLAC; - sk->sk_state = PPPOX_NONE; - return 0; -} - -/******************************************************************************/ - -static struct pppox_proto pppolac_pppox_proto = { - .create = pppolac_create, - .owner = THIS_MODULE, -}; - -static int __init pppolac_init(void) -{ - int error; - - error = proto_register(&pppolac_proto, 0); - if (error) - return error; - - error = register_pppox_proto(PX_PROTO_OLAC, &pppolac_pppox_proto); - if (error) - proto_unregister(&pppolac_proto); - else - skb_queue_head_init(&delivery_queue); - return error; -} - -static void __exit pppolac_exit(void) -{ - unregister_pppox_proto(PX_PROTO_OLAC); - proto_unregister(&pppolac_proto); -} - -module_init(pppolac_init); -module_exit(pppolac_exit); - -MODULE_DESCRIPTION("PPP on L2TP Access Concentrator (PPPoLAC)"); -MODULE_AUTHOR("Chia-chi Yeh "); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/pppopns.c b/drivers/net/pppopns.c deleted file mode 100644 index fb8198447938..000000000000 --- a/drivers/net/pppopns.c +++ /dev/null @@ -1,428 +0,0 @@ -/* drivers/net/pppopns.c - * - * Driver for PPP on PPTP Network Server / PPPoPNS Socket (RFC 2637) - * - * Copyright (C) 2009 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. - */ - -/* This driver handles PPTP data packets between a RAW socket and a PPP channel. - * The socket is created in the kernel space and connected to the same address - * of the control socket. Outgoing packets are always sent with sequences but - * without acknowledgements. Incoming packets with sequences are reordered - * within a sliding window of one second. Currently reordering only happens when - * a packet is received. It is done for simplicity since no additional locks or - * threads are required. This driver should work on both IPv4 and IPv6. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GRE_HEADER_SIZE 8 - -#define PPTP_GRE_BITS htons(0x2001) -#define PPTP_GRE_BITS_MASK htons(0xEF7F) -#define PPTP_GRE_SEQ_BIT htons(0x1000) -#define PPTP_GRE_ACK_BIT htons(0x0080) -#define PPTP_GRE_TYPE htons(0x880B) - -#define PPP_ADDR 0xFF -#define PPP_CTRL 0x03 - -struct header { - __u16 bits; - __u16 type; - __u16 length; - __u16 call; - __u32 sequence; -} __attribute__((packed)); - -struct meta { - __u32 sequence; - __u32 timestamp; -}; - -static inline struct meta *skb_meta(struct sk_buff *skb) -{ - return (struct meta *)skb->cb; -} - -/******************************************************************************/ - -static int pppopns_recv_core(struct sock *sk_raw, struct sk_buff *skb) -{ - struct sock *sk = (struct sock *)sk_raw->sk_user_data; - struct pppopns_opt *opt = &pppox_sk(sk)->proto.pns; - struct meta *meta = skb_meta(skb); - __u32 now = jiffies; - struct header *hdr; - - /* Skip transport header */ - skb_pull(skb, skb_transport_header(skb) - skb->data); - - /* Drop the packet if GRE header is missing. */ - if (skb->len < GRE_HEADER_SIZE) - goto drop; - hdr = (struct header *)skb->data; - - /* Check the header. */ - if (hdr->type != PPTP_GRE_TYPE || hdr->call != opt->local || - (hdr->bits & PPTP_GRE_BITS_MASK) != PPTP_GRE_BITS) - goto drop; - - /* Skip all fields including optional ones. */ - if (!skb_pull(skb, GRE_HEADER_SIZE + - (hdr->bits & PPTP_GRE_SEQ_BIT ? 4 : 0) + - (hdr->bits & PPTP_GRE_ACK_BIT ? 4 : 0))) - goto drop; - - /* Check the length. */ - if (skb->len != ntohs(hdr->length)) - goto drop; - - /* Check the sequence if it is present. */ - if (hdr->bits & PPTP_GRE_SEQ_BIT) { - meta->sequence = ntohl(hdr->sequence); - if ((__s32)(meta->sequence - opt->recv_sequence) < 0) - goto drop; - } - - /* Skip PPP address and control if they are present. */ - if (skb->len >= 2 && skb->data[0] == PPP_ADDR && - skb->data[1] == PPP_CTRL) - skb_pull(skb, 2); - - /* Fix PPP protocol if it is compressed. */ - if (skb->len >= 1 && skb->data[0] & 1) - skb_push(skb, 1)[0] = 0; - - /* Drop the packet if PPP protocol is missing. */ - if (skb->len < 2) - goto drop; - - /* Perform reordering if sequencing is enabled. */ - if (hdr->bits & PPTP_GRE_SEQ_BIT) { - struct sk_buff *skb1; - - /* Insert the packet into receive queue in order. */ - skb_set_owner_r(skb, sk); - skb_queue_walk(&sk->sk_receive_queue, skb1) { - struct meta *meta1 = skb_meta(skb1); - __s32 order = meta->sequence - meta1->sequence; - if (order == 0) - goto drop; - if (order < 0) { - meta->timestamp = meta1->timestamp; - skb_insert(skb1, skb, &sk->sk_receive_queue); - skb = NULL; - break; - } - } - if (skb) { - meta->timestamp = now; - skb_queue_tail(&sk->sk_receive_queue, skb); - } - - /* Remove packets from receive queue as long as - * 1. the receive buffer is full, - * 2. they are queued longer than one second, or - * 3. there are no missing packets before them. */ - skb_queue_walk_safe(&sk->sk_receive_queue, skb, skb1) { - meta = skb_meta(skb); - if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && - now - meta->timestamp < HZ && - meta->sequence != opt->recv_sequence) - break; - skb_unlink(skb, &sk->sk_receive_queue); - opt->recv_sequence = meta->sequence + 1; - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - } - return NET_RX_SUCCESS; - } - - /* Flush receive queue if sequencing is disabled. */ - skb_queue_purge(&sk->sk_receive_queue); - skb_orphan(skb); - ppp_input(&pppox_sk(sk)->chan, skb); - return NET_RX_SUCCESS; -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void pppopns_recv(struct sock *sk_raw, int length) -{ - struct sk_buff *skb; - while ((skb = skb_dequeue(&sk_raw->sk_receive_queue))) { - sock_hold(sk_raw); - sk_receive_skb(sk_raw, skb, 0); - } -} - -static struct sk_buff_head delivery_queue; - -static void pppopns_xmit_core(struct work_struct *delivery_work) -{ - mm_segment_t old_fs = get_fs(); - struct sk_buff *skb; - - set_fs(KERNEL_DS); - while ((skb = skb_dequeue(&delivery_queue))) { - struct sock *sk_raw = skb->sk; - struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len}; - struct msghdr msg = { - .msg_iov = (struct iovec *)&iov, - .msg_iovlen = 1, - .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT, - }; - sk_raw->sk_prot->sendmsg(NULL, sk_raw, &msg, skb->len); - kfree_skb(skb); - } - set_fs(old_fs); -} - -static DECLARE_WORK(delivery_work, pppopns_xmit_core); - -static int pppopns_xmit(struct ppp_channel *chan, struct sk_buff *skb) -{ - struct sock *sk_raw = (struct sock *)chan->private; - struct pppopns_opt *opt = &pppox_sk(sk_raw->sk_user_data)->proto.pns; - struct header *hdr; - __u16 length; - - /* Install PPP address and control. */ - skb_push(skb, 2); - skb->data[0] = PPP_ADDR; - skb->data[1] = PPP_CTRL; - length = skb->len; - - /* Install PPTP GRE header. */ - hdr = (struct header *)skb_push(skb, 12); - hdr->bits = PPTP_GRE_BITS | PPTP_GRE_SEQ_BIT; - hdr->type = PPTP_GRE_TYPE; - hdr->length = htons(length); - hdr->call = opt->remote; - hdr->sequence = htonl(opt->xmit_sequence); - opt->xmit_sequence++; - - /* Now send the packet via the delivery queue. */ - skb_set_owner_w(skb, sk_raw); - skb_queue_tail(&delivery_queue, skb); - schedule_work(&delivery_work); - return 1; -} - -/******************************************************************************/ - -static struct ppp_channel_ops pppopns_channel_ops = { - .start_xmit = pppopns_xmit, -}; - -static int pppopns_connect(struct socket *sock, struct sockaddr *useraddr, - int addrlen, int flags) -{ - struct sock *sk = sock->sk; - struct pppox_sock *po = pppox_sk(sk); - struct sockaddr_pppopns *addr = (struct sockaddr_pppopns *)useraddr; - struct sockaddr_storage ss; - struct socket *sock_tcp = NULL; - struct socket *sock_raw = NULL; - struct sock *sk_tcp; - struct sock *sk_raw; - int error; - - if (addrlen != sizeof(struct sockaddr_pppopns)) - return -EINVAL; - - lock_sock(sk); - error = -EALREADY; - if (sk->sk_state != PPPOX_NONE) - goto out; - - sock_tcp = sockfd_lookup(addr->tcp_socket, &error); - if (!sock_tcp) - goto out; - sk_tcp = sock_tcp->sk; - error = -EPROTONOSUPPORT; - if (sk_tcp->sk_protocol != IPPROTO_TCP) - goto out; - addrlen = sizeof(struct sockaddr_storage); - error = kernel_getpeername(sock_tcp, (struct sockaddr *)&ss, &addrlen); - if (error) - goto out; - if (!sk_tcp->sk_bound_dev_if) { - struct dst_entry *dst = sk_dst_get(sk_tcp); - error = -ENODEV; - if (!dst) - goto out; - sk_tcp->sk_bound_dev_if = dst->dev->ifindex; - dst_release(dst); - } - - error = sock_create(ss.ss_family, SOCK_RAW, IPPROTO_GRE, &sock_raw); - if (error) - goto out; - sk_raw = sock_raw->sk; - sk_raw->sk_bound_dev_if = sk_tcp->sk_bound_dev_if; - error = kernel_connect(sock_raw, (struct sockaddr *)&ss, addrlen, 0); - if (error) - goto out; - - po->chan.hdrlen = 14; - po->chan.private = sk_raw; - po->chan.ops = &pppopns_channel_ops; - po->chan.mtu = PPP_MTU - 80; - po->proto.pns.local = addr->local; - po->proto.pns.remote = addr->remote; - po->proto.pns.data_ready = sk_raw->sk_data_ready; - po->proto.pns.backlog_rcv = sk_raw->sk_backlog_rcv; - - error = ppp_register_channel(&po->chan); - if (error) - goto out; - - sk->sk_state = PPPOX_CONNECTED; - lock_sock(sk_raw); - sk_raw->sk_data_ready = pppopns_recv; - sk_raw->sk_backlog_rcv = pppopns_recv_core; - sk_raw->sk_user_data = sk; - release_sock(sk_raw); -out: - if (sock_tcp) - sockfd_put(sock_tcp); - if (error && sock_raw) - sock_release(sock_raw); - release_sock(sk); - return error; -} - -static int pppopns_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (!sk) - return 0; - - lock_sock(sk); - if (sock_flag(sk, SOCK_DEAD)) { - release_sock(sk); - return -EBADF; - } - - if (sk->sk_state != PPPOX_NONE) { - struct sock *sk_raw = (struct sock *)pppox_sk(sk)->chan.private; - lock_sock(sk_raw); - skb_queue_purge(&sk->sk_receive_queue); - pppox_unbind_sock(sk); - sk_raw->sk_data_ready = pppox_sk(sk)->proto.pns.data_ready; - sk_raw->sk_backlog_rcv = pppox_sk(sk)->proto.pns.backlog_rcv; - sk_raw->sk_user_data = NULL; - release_sock(sk_raw); - sock_release(sk_raw->sk_socket); - } - - sock_orphan(sk); - sock->sk = NULL; - release_sock(sk); - sock_put(sk); - return 0; -} - -/******************************************************************************/ - -static struct proto pppopns_proto = { - .name = "PPPOPNS", - .owner = THIS_MODULE, - .obj_size = sizeof(struct pppox_sock), -}; - -static struct proto_ops pppopns_proto_ops = { - .family = PF_PPPOX, - .owner = THIS_MODULE, - .release = pppopns_release, - .bind = sock_no_bind, - .connect = pppopns_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = sock_no_poll, - .ioctl = pppox_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .mmap = sock_no_mmap, -}; - -static int pppopns_create(struct net *net, struct socket *sock) -{ - struct sock *sk; - - sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppopns_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - sock->state = SS_UNCONNECTED; - sock->ops = &pppopns_proto_ops; - sk->sk_protocol = PX_PROTO_OPNS; - sk->sk_state = PPPOX_NONE; - return 0; -} - -/******************************************************************************/ - -static struct pppox_proto pppopns_pppox_proto = { - .create = pppopns_create, - .owner = THIS_MODULE, -}; - -static int __init pppopns_init(void) -{ - int error; - - error = proto_register(&pppopns_proto, 0); - if (error) - return error; - - error = register_pppox_proto(PX_PROTO_OPNS, &pppopns_pppox_proto); - if (error) - proto_unregister(&pppopns_proto); - else - skb_queue_head_init(&delivery_queue); - return error; -} - -static void __exit pppopns_exit(void) -{ - unregister_pppox_proto(PX_PROTO_OPNS); - proto_unregister(&pppopns_proto); -} - -module_init(pppopns_init); -module_exit(pppopns_exit); - -MODULE_DESCRIPTION("PPP on PPTP Network Server (PPPoPNS)"); -MODULE_AUTHOR("Chia-chi Yeh "); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 80666f097ce6..142c381e1d73 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -893,18 +893,16 @@ static void r6040_multicast_list(struct net_device *dev) /* Multicast Address 1~4 case */ i = 0; netdev_for_each_mc_addr(ha, dev) { - if (i >= MCAST_MAX) - break; - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - i++; - } - while (i < MCAST_MAX) { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); + if (i < MCAST_MAX) { + adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + } else { + iowrite16(0xffff, ioaddr + MID_1L + 8 * i); + iowrite16(0xffff, ioaddr + MID_1M + 8 * i); + iowrite16(0xffff, ioaddr + MID_1H + 8 * i); + } i++; } } diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ed65e4a473ec..992db2fa136e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -855,10 +855,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) else tp->features &= ~RTL_FEATURE_WOL; __rtl8169_set_wol(tp, wol->wolopts); - spin_unlock_irq(&tp->lock); - device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); + spin_unlock_irq(&tp->lock); + return 0; } @@ -2936,7 +2936,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | + .intr_event = SYSErr | RxFIFOOver | LinkChg | RxOverflow | TxErr | TxOK | RxOK | RxErr, .napi_event = TxErr | TxOK | RxOK | RxOverflow, .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, @@ -4455,12 +4455,14 @@ static inline int rtl8169_fragmented_frame(u32 status) return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); } -static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) +static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) { + u32 opts1 = le32_to_cpu(desc->opts1); u32 status = opts1 & RxProtoMask; if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || - ((status == RxProtoUDP) && !(opts1 & UDPFail))) + ((status == RxProtoUDP) && !(opts1 & UDPFail)) || + ((status == RxProtoIP) && !(opts1 & IPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb->ip_summed = CHECKSUM_NONE; @@ -4549,6 +4551,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev, continue; } + rtl8169_rx_csum(skb, desc); + if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { dma_sync_single_for_device(&pdev->dev, addr, pkt_size, PCI_DMA_FROMDEVICE); @@ -4559,7 +4563,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev, tp->Rx_skbuff[entry] = NULL; } - rtl8169_rx_csum(skb, status); skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); @@ -4627,8 +4630,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) } /* Work around for rx fifo overflow */ - if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + if (unlikely(status & RxFIFOOver)) { netif_stop_queue(dev); rtl8169_tx_timeout(dev); break; @@ -4889,9 +4891,6 @@ static int rtl8169_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - - rtl8169_init_phy(dev, tp); if (netif_running(dev)) __rtl8169_resume(dev); @@ -4932,8 +4931,6 @@ static int rtl8169_runtime_resume(struct device *device) tp->saved_wolopts = 0; spin_unlock_irq(&tp->lock); - rtl8169_init_phy(dev, tp); - __rtl8169_resume(dev); return 0; diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 2ce585a511d9..737df6032bbc 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/bdx.bin", &priv->pdev->dev); + rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev); if (rc) goto out; bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); @@ -2516,4 +2516,4 @@ module_exit(bdx_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(BDX_DRV_DESC); -MODULE_FIRMWARE("tehuti/bdx.bin"); +MODULE_FIRMWARE("tehuti/firmware.bin"); diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 14b9e1d4fa9d..a3f88214d144 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -424,10 +424,4 @@ config USB_SIERRA_NET To compile this driver as a module, choose M here: the module will be called sierra_net. -config USB_NET_GOBI - tristate "Qualcomm Gobi" - depends on USB_USBNET - help - Choose this option if you have a Qualcomm Gobi 2000 cellular modem. - endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 90459d56b6d3..4c101eb1972a 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -27,4 +27,4 @@ obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o -obj-$(CONFIG_USB_NET_GOBI) += qcusbnet/ + diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index c29546ddee47..b3fe0de40469 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -31,7 +31,6 @@ #include #include #include -#include #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) @@ -470,35 +469,6 @@ static const struct driver_info mbm_info = { .manage_power = cdc_manage_power, }; -#ifdef CONFIG_USB_OOBWAKE -/* out of band wake devices */ -static void oob_wake_cdc_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - pr_info("%s: unregister interface for out of band wakeups\n", __func__); - oob_wake_unregister(intf); - usbnet_cdc_unbind(dev, intf); -} - -static int oob_wake_cdc_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int status; - - pr_info("%s: register interface for out of band wakeups\n", __func__); - status = cdc_bind(dev, intf); - oob_wake_register(intf); - return status; -} - -static const struct driver_info oob_wake_cdc_info = { - .description = "CDC Wakeable Ethernet Device", - .flags = FLAG_ETHER, - .bind = oob_wake_cdc_bind, - .unbind = oob_wake_cdc_unbind, - .status = cdc_status, - .manage_power = cdc_manage_power, -}; -#endif /* CONFIG_USB_OOBWAKE */ - /*-------------------------------------------------------------------------*/ @@ -603,14 +573,6 @@ static const struct usb_device_id products [] = { * NOTE: this match must come AFTER entries blacklisting devices * because of bugs/quirks in a given product (like Zaurus, above). */ -#ifdef CONFIG_USB_OOBWAKE -{ - /* Motorola Wrigley LTE Modem */ - USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x4267, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &oob_wake_cdc_info, -}, -#endif /* CONFIG_USB_OOBWAKE */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), diff --git a/drivers/net/usb/qcusbnet/Makefile b/drivers/net/usb/qcusbnet/Makefile deleted file mode 100644 index a186c19940ca..000000000000 --- a/drivers/net/usb/qcusbnet/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_USB_NET_GOBI) += qcusbnet2k.o -qcusbnet2k-objs += qcusbnet.o qmidevice.o qmi.o diff --git a/drivers/net/usb/qcusbnet/README b/drivers/net/usb/qcusbnet/README deleted file mode 100644 index a59513f632e3..000000000000 --- a/drivers/net/usb/qcusbnet/README +++ /dev/null @@ -1,115 +0,0 @@ -Gobi2000 network driver for HP 1.0.110 -06/18/2010 - -This readme covers important information concerning -the QCUSBNet2kHP driver, provided in correlation with -the Gobi2000-Linux-Package. - -Table of Contents - -1. Prerequisites -2. Installation instructions -3. What's new in this release -4. Notes -5. Known issues - -------------------------------------------------------------------------------- - -1. PREREQUISITES - -a. Kernel headers or full kernel source installed for the currently - running kernel. There must be a link "/lib/modules//build" - that points to these kernel headers or sources. -b. The kernel must support the usbcore and usbnet drivers, either as - modules or built into the kernel. -c. Tools required for building the kernel. These tools usually come in a - package called "kernel-devel". -d. "gcc" compiler -e. "make" tool - -------------------------------------------------------------------------------- - -2. INSTALLATION INSTRUCTIONS - -a. Navigate to the folder "QCUSBNet2k" that contains: - Makefile - QCUSBNetHP.c - QMIDevice.c - qmidevice.h - structs.h - QMI.c - qmi.h -b. (only required for kernels prior to 2.6.25) Create a symbolic link - to the usbnet.h file in your kernel sources: - ln -s /drivers/net/usb/usbnet.h ./ -c. Run the command: - make -d. Copy the newly created QCUSBNet2kHP.ko into the directory - /lib/modules/`uname -r`/kernel/drivers/net/usb/ -e. Run the command: - depmod -f. (Optional) Load the driver manually with the command: - modprobe QCUSBNet2kHP - - This is only required the first time after you install the - drivers. If you restart or plug the Gobi device in the drivers - will be automatically loaded. - -------------------------------------------------------------------------------- - -3. WHAT'S NEW - -This Release (Gobi2000 network driver for HP 1.0.110) 06/18/2010 -a. Correctly initialize semaphore during probe function. - -Prior Release (Gobi2000 network driver for HP 1.0.100) 06/02/2010 -a. Merge QCQMI driver into QCUSBNet2k driver, removing dependency. - -Prior Release (Gobi2000 network driver for HP 1.0.90) 05/13/2010 -a. Fix devqmi_close() from a thread -b. Add 2.6.33 kernel support - -Prior Release (Gobi2000 network driver for HP 1.0.80) 04/19/2010 -a. Add support to check for duplicate or out of sequence QMI messages. - -Prior Release (Gobi2000 network driver for HP 1.0.70) 03/15/2010 -a. Added support for CDC CONNECTION_SPEED_CHANGE indication. -b. Modified device cleanup function to better handle the device - losing power during suspend or hibernate. -c. Replaced autosuspend feature with more aggressive "Selective suspend" - style power management. Even if QCWWAN2k or Network connections are - active the device will still enter autosuspend after the delay time, - and wake on remote wakeup or new data being sent. - -Prior Release (Gobi2000 Serial driver for HP 1.0.60) 02/16/2010 -a. Fix to allow proper fork() functionality -b. Add supports_autosuspend flag -c. Ignore EOVERFLOW errors on interrupt endpoint and resubmit URB -d. Change driver versions to match installer package -e. Minor update for 2.6.23 kernel compatibility - -Prior Release (in correlation with Gobi2000-Linux-Package 1.0.30) 12/04/2009 -a. Modify ioctl numbering to avoid conflict in 2.6.31 kernel - This release is only compatible with GOBI2000_LINUX_SDK 1.0.30 and newer. -b. Made minor compatibility changes for 2.6.31 kernel - -Prior Release (in correlation with Gobi2000-Linux-Package 1.0.20) 11/20/2009 -a. Initial release - -------------------------------------------------------------------------------- - -4. NOTES - -a. In Composite mode, the Gobi device will enumerate a network interface - usb<#> where <#> signifies the next available USB network interface. -b. In Composite mode, the Gobi device will enumerate a device node - /dev/qcqmi<#>. This device node is for use by the QCWWANCMAPI2k. -c. Ownership, group, and permissions are managed by your system - configuration. - -------------------------------------------------------------------------------- - -5. KNOWN ISSUES - -No known issues. - -------------------------------------------------------------------------------- diff --git a/drivers/net/usb/qcusbnet/qcusbnet.c b/drivers/net/usb/qcusbnet/qcusbnet.c deleted file mode 100644 index d279bcac2864..000000000000 --- a/drivers/net/usb/qcusbnet/qcusbnet.c +++ /dev/null @@ -1,649 +0,0 @@ -/* qcusbnet.c - gobi network device - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "structs.h" -#include "qmidevice.h" -#include "qmi.h" -#include "qcusbnet.h" - -#define DRIVER_VERSION "1.0.110" -#define DRIVER_AUTHOR "Qualcomm Innovation Center" -#define DRIVER_DESC "QCUSBNet2k" - -int debug; -static struct class *devclass; - -int qc_suspend(struct usb_interface *iface, pm_message_t event) -{ - struct usbnet *usbnet; - struct qcusbnet *dev; - - if (!iface) - return -ENOMEM; - - usbnet = usb_get_intfdata(iface); - - if (!usbnet || !usbnet->net) { - ERR("failed to get netdevice\n"); - return -ENXIO; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return -ENXIO; - } - - if (!(event.event & PM_EVENT_AUTO)) { - DBG("device suspended to power level %d\n", - event.event); - qc_setdown(dev, DOWN_DRIVER_SUSPENDED); - } else { - DBG("device autosuspend\n"); - } - - if (event.event & PM_EVENT_SUSPEND) { - qc_stopread(dev); - usbnet->udev->reset_resume = 0; - iface->dev.power.power_state.event = event.event; - } else { - usbnet->udev->reset_resume = 1; - } - - return usbnet_suspend(iface, event); -} - -static int qc_resume(struct usb_interface *iface) -{ - struct usbnet *usbnet; - struct qcusbnet *dev; - int ret; - int oldstate; - - if (iface == 0) - return -ENOMEM; - - usbnet = usb_get_intfdata(iface); - - if (!usbnet || !usbnet->net) { - ERR("failed to get netdevice\n"); - return -ENXIO; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return -ENXIO; - } - - oldstate = iface->dev.power.power_state.event; - iface->dev.power.power_state.event = PM_EVENT_ON; - DBG("resuming from power mode %d\n", oldstate); - - if (oldstate & PM_EVENT_SUSPEND) { - qc_cleardown(dev, DOWN_DRIVER_SUSPENDED); - - ret = usbnet_resume(iface); - if (ret) { - ERR("usbnet_resume error %d\n", ret); - return ret; - } - - ret = qc_startread(dev); - if (ret) { - ERR("qc_startread error %d\n", ret); - return ret; - } - - complete(&dev->worker.work); - } else { - DBG("nothing to resume\n"); - return 0; - } - - return ret; -} - -static int qc_reset_resume(struct usb_interface *iface) -{ - return qc_resume(iface); -} - -static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface) -{ - int numends; - int i; - struct usb_host_endpoint *endpoint = NULL; - struct usb_host_endpoint *in = NULL; - struct usb_host_endpoint *out = NULL; - - if (iface->num_altsetting != 1) { - ERR("invalid num_altsetting %u\n", iface->num_altsetting); - return -EINVAL; - } - - numends = iface->cur_altsetting->desc.bNumEndpoints; - for (i = 0; i < numends; i++) { - endpoint = iface->cur_altsetting->endpoint + i; - if (!endpoint) { - ERR("invalid endpoint %u\n", i); - return -EINVAL; - } - - if (usb_endpoint_is_bulk_in(&endpoint->desc)) - in = endpoint; - else if (usb_endpoint_is_bulk_out(&endpoint->desc)) - out = endpoint; - } - - if (!in || !out) { - ERR("invalid bulk endpoints\n"); - return -EINVAL; - } - - if (usb_set_interface(usbnet->udev, - iface->cur_altsetting->desc.bInterfaceNumber, 0)) { - ERR("unable to set interface\n"); - return -EINVAL; - } - - usbnet->in = usb_rcvbulkpipe(usbnet->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - usbnet->out = usb_sndbulkpipe(usbnet->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - - DBG("in %x, out %x\n", - in->desc.bEndpointAddress, - out->desc.bEndpointAddress); - - strcpy(usbnet->net->name, "qmi%d"); - random_ether_addr(&usbnet->net->dev_addr[0]); - - return 0; -} - -static void qcnet_unbind(struct usbnet *usbnet, struct usb_interface *iface) -{ - struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0]; - - netif_carrier_off(usbnet->net); - qc_deregister(dev); - - kfree(usbnet->net->netdev_ops); - usbnet->net->netdev_ops = NULL; - - kfree(dev); -} - -static void qcnet_urbhook(struct urb *urb) -{ - unsigned long flags; - struct worker *worker = urb->context; - if (!worker) { - ERR("bad context\n"); - return; - } - - if (urb->status) - ERR("urb finished with error %d\n", urb->status); - - spin_lock_irqsave(&worker->active_lock, flags); - worker->active = ERR_PTR(-EAGAIN); - spin_unlock_irqrestore(&worker->active_lock, flags); - /* XXX-fix race against qcnet_stop()? */ - complete(&worker->work); - usb_free_urb(urb); -} - -static void qcnet_txtimeout(struct net_device *netdev) -{ - struct list_head *node, *tmp; - struct qcusbnet *dev; - struct worker *worker; - struct urbreq *req; - unsigned long activeflags, listflags; - struct usbnet *usbnet = netdev_priv(netdev); - - if (!usbnet || !usbnet->net) { - ERR("failed to get usbnet device\n"); - return; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return; - } - worker = &dev->worker; - - DBG("\n"); - - spin_lock_irqsave(&worker->active_lock, activeflags); - if (worker->active) - usb_kill_urb(worker->active); - spin_unlock_irqrestore(&worker->active_lock, activeflags); - - spin_lock_irqsave(&worker->urbs_lock, listflags); - list_for_each_safe(node, tmp, &worker->urbs) { - req = list_entry(node, struct urbreq, node); - usb_free_urb(req->urb); - list_del(&req->node); - kfree(req); - } - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - - complete(&worker->work); -} - -static int qcnet_worker(void *arg) -{ - struct list_head *node, *tmp; - unsigned long activeflags, listflags; - struct urbreq *req; - int status; - struct usb_device *usbdev; - struct worker *worker = arg; - if (!worker) { - ERR("passed null pointer\n"); - return -EINVAL; - } - - usbdev = interface_to_usbdev(worker->iface); - - DBG("traffic thread started\n"); - - while (!kthread_should_stop()) { - wait_for_completion_interruptible(&worker->work); - - if (kthread_should_stop()) { - spin_lock_irqsave(&worker->active_lock, activeflags); - if (worker->active) - usb_kill_urb(worker->active); - spin_unlock_irqrestore(&worker->active_lock, activeflags); - - spin_lock_irqsave(&worker->urbs_lock, listflags); - list_for_each_safe(node, tmp, &worker->urbs) { - req = list_entry(node, struct urbreq, node); - usb_free_urb(req->urb); - list_del(&req->node); - kfree(req); - } - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - - break; - } - - spin_lock_irqsave(&worker->active_lock, activeflags); - if (IS_ERR(worker->active) && PTR_ERR(worker->active) == -EAGAIN) { - worker->active = NULL; - spin_unlock_irqrestore(&worker->active_lock, activeflags); - usb_autopm_put_interface(worker->iface); - spin_lock_irqsave(&worker->active_lock, activeflags); - } - - if (worker->active) { - spin_unlock_irqrestore(&worker->active_lock, activeflags); - continue; - } - - spin_lock_irqsave(&worker->urbs_lock, listflags); - if (list_empty(&worker->urbs)) { - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - spin_unlock_irqrestore(&worker->active_lock, activeflags); - continue; - } - - req = list_first_entry(&worker->urbs, struct urbreq, node); - list_del(&req->node); - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - - worker->active = req->urb; - spin_unlock_irqrestore(&worker->active_lock, activeflags); - - status = usb_autopm_get_interface(worker->iface); - if (status < 0) { - ERR("unable to autoresume interface: %d\n", status); - if (status == -EPERM) - qc_suspend(worker->iface, PMSG_SUSPEND); - - spin_lock_irqsave(&worker->urbs_lock, listflags); - list_add(&req->node, &worker->urbs); - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - - spin_lock_irqsave(&worker->active_lock, activeflags); - worker->active = NULL; - spin_unlock_irqrestore(&worker->active_lock, activeflags); - - continue; - } - - status = usb_submit_urb(worker->active, GFP_KERNEL); - if (status < 0) { - ERR("Failed to submit URB: %d. Packet dropped\n", status); - spin_lock_irqsave(&worker->active_lock, activeflags); - usb_free_urb(worker->active); - worker->active = NULL; - spin_unlock_irqrestore(&worker->active_lock, activeflags); - usb_autopm_put_interface(worker->iface); - complete(&worker->work); - } - - kfree(req); - } - - DBG("traffic thread exiting\n"); - worker->thread = NULL; - return 0; -} - -static int qcnet_startxmit(struct sk_buff *skb, struct net_device *netdev) -{ - unsigned long listflags; - struct qcusbnet *dev; - struct worker *worker; - struct urbreq *req; - void *data; - struct usbnet *usbnet = netdev_priv(netdev); - - DBG("\n"); - - if (!usbnet || !usbnet->net) { - ERR("failed to get usbnet device\n"); - return NETDEV_TX_BUSY; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return NETDEV_TX_BUSY; - } - worker = &dev->worker; - - if (qc_isdown(dev, DOWN_DRIVER_SUSPENDED)) { - ERR("device is suspended\n"); - dump_stack(); - return NETDEV_TX_BUSY; - } - - req = kmalloc(sizeof(*req), GFP_ATOMIC); - if (!req) { - ERR("unable to allocate URBList memory\n"); - return NETDEV_TX_BUSY; - } - - req->urb = usb_alloc_urb(0, GFP_ATOMIC); - - if (!req->urb) { - kfree(req); - ERR("unable to allocate URB\n"); - return NETDEV_TX_BUSY; - } - - data = kmalloc(skb->len, GFP_ATOMIC); - if (!data) { - usb_free_urb(req->urb); - kfree(req); - ERR("unable to allocate URB data\n"); - return NETDEV_TX_BUSY; - } - memcpy(data, skb->data, skb->len); - - usb_fill_bulk_urb(req->urb, dev->usbnet->udev, dev->usbnet->out, - data, skb->len, qcnet_urbhook, worker); - - spin_lock_irqsave(&worker->urbs_lock, listflags); - list_add_tail(&req->node, &worker->urbs); - spin_unlock_irqrestore(&worker->urbs_lock, listflags); - - complete(&worker->work); - - netdev->trans_start = jiffies; - dev_kfree_skb_any(skb); - - return NETDEV_TX_OK; -} - -static int qcnet_open(struct net_device *netdev) -{ - int status = 0; - struct qcusbnet *dev; - struct usbnet *usbnet = netdev_priv(netdev); - - if (!usbnet) { - ERR("failed to get usbnet device\n"); - return -ENXIO; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return -ENXIO; - } - - DBG("\n"); - - dev->worker.iface = dev->iface; - INIT_LIST_HEAD(&dev->worker.urbs); - dev->worker.active = NULL; - spin_lock_init(&dev->worker.urbs_lock); - spin_lock_init(&dev->worker.active_lock); - init_completion(&dev->worker.work); - - dev->worker.thread = kthread_run(qcnet_worker, &dev->worker, "qcnet_worker"); - if (IS_ERR(dev->worker.thread)) { - ERR("AutoPM thread creation error\n"); - return PTR_ERR(dev->worker.thread); - } - - qc_cleardown(dev, DOWN_NET_IFACE_STOPPED); - if (dev->open) { - status = dev->open(netdev); - if (status == 0) - usb_autopm_put_interface(dev->iface); - } else { - ERR("no USBNetOpen defined\n"); - } - - return status; -} - -int qcnet_stop(struct net_device *netdev) -{ - struct qcusbnet *dev; - struct usbnet *usbnet = netdev_priv(netdev); - - if (!usbnet || !usbnet->net) { - ERR("failed to get netdevice\n"); - return -ENXIO; - } - - dev = (struct qcusbnet *)usbnet->data[0]; - if (!dev) { - ERR("failed to get QMIDevice\n"); - return -ENXIO; - } - - qc_setdown(dev, DOWN_NET_IFACE_STOPPED); - complete(&dev->worker.work); - kthread_stop(dev->worker.thread); - DBG("thread stopped\n"); - - if (dev->stop != NULL) - return dev->stop(netdev); - return 0; -} - -static const struct driver_info qc_netinfo = { - .description = "QCUSBNet Ethernet Device", - .flags = FLAG_ETHER, - .bind = qcnet_bind, - .unbind = qcnet_unbind, - .data = 0, -}; - -#define MKVIDPID(v, p) \ -{ \ - USB_DEVICE(v, p), \ - .driver_info = (unsigned long)&qc_netinfo, \ -} - -static const struct usb_device_id qc_vidpids[] = { - MKVIDPID(0x05c6, 0x9215), /* Acer Gobi 2000 */ - MKVIDPID(0x05c6, 0x9265), /* Asus Gobi 2000 */ - MKVIDPID(0x16d8, 0x8002), /* CMOTech Gobi 2000 */ - MKVIDPID(0x413c, 0x8186), /* Dell Gobi 2000 */ - MKVIDPID(0x1410, 0xa010), /* Entourage Gobi 2000 */ - MKVIDPID(0x1410, 0xa011), /* Entourage Gobi 2000 */ - MKVIDPID(0x1410, 0xa012), /* Entourage Gobi 2000 */ - MKVIDPID(0x1410, 0xa013), /* Entourage Gobi 2000 */ - MKVIDPID(0x03f0, 0x251d), /* HP Gobi 2000 */ - MKVIDPID(0x05c6, 0x9205), /* Lenovo Gobi 2000 */ - MKVIDPID(0x05c6, 0x920b), /* Generic Gobi 2000 */ - MKVIDPID(0x04da, 0x250f), /* Panasonic Gobi 2000 */ - MKVIDPID(0x05c6, 0x9245), /* Samsung Gobi 2000 */ - MKVIDPID(0x1199, 0x9001), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9002), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9003), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9004), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9005), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9006), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9007), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9008), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x9009), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x1199, 0x900a), /* Sierra Wireless Gobi 2000 */ - MKVIDPID(0x05c6, 0x9225), /* Sony Gobi 2000 */ - MKVIDPID(0x05c6, 0x9235), /* Top Global Gobi 2000 */ - MKVIDPID(0x05c6, 0x9275), /* iRex Technologies Gobi 2000 */ - { - USB_DEVICE_AND_INTERFACE_INFO(0x22B8, 0x2A70, 0xff, 0xfb, 0xff), /* Motorola Xoom */ - .driver_info = (unsigned long)&qc_netinfo - }, - { } -}; - -MODULE_DEVICE_TABLE(usb, qc_vidpids); - -int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids) -{ - int status; - struct usbnet *usbnet; - struct qcusbnet *dev; - struct net_device_ops *netdevops; - - status = usbnet_probe(iface, vidpids); - if (status < 0) { - ERR("usbnet_probe failed %d\n", status); - return status; - } - - usbnet = usb_get_intfdata(iface); - - if (!usbnet || !usbnet->net) { - ERR("failed to get netdevice\n"); - return -ENXIO; - } - - dev = kmalloc(sizeof(struct qcusbnet), GFP_KERNEL); - if (!dev) { - ERR("failed to allocate device buffers\n"); - return -ENOMEM; - } - - usbnet->data[0] = (unsigned long)dev; - - dev->usbnet = usbnet; - - netdevops = kmalloc(sizeof(struct net_device_ops), GFP_KERNEL); - if (!netdevops) { - ERR("failed to allocate net device ops\n"); - return -ENOMEM; - } - memcpy(netdevops, usbnet->net->netdev_ops, sizeof(struct net_device_ops)); - - dev->open = netdevops->ndo_open; - netdevops->ndo_open = qcnet_open; - dev->stop = netdevops->ndo_stop; - netdevops->ndo_stop = qcnet_stop; - netdevops->ndo_start_xmit = qcnet_startxmit; - netdevops->ndo_tx_timeout = qcnet_txtimeout; - - usbnet->net->netdev_ops = netdevops; - - memset(&(dev->usbnet->net->stats), 0, sizeof(struct net_device_stats)); - - dev->iface = iface; - memset(&(dev->meid), '0', 14); - - DBG("Mac Address: %pM\n", dev->usbnet->net->dev_addr); - - dev->valid = false; - memset(&dev->qmi, 0, sizeof(struct qmidev)); - - dev->qmi.devclass = devclass; - - INIT_LIST_HEAD(&dev->qmi.clients); - init_completion(&dev->worker.work); - spin_lock_init(&dev->qmi.clients_lock); - - dev->down = 0; - qc_setdown(dev, DOWN_NO_NDIS_CONNECTION); - qc_setdown(dev, DOWN_NET_IFACE_STOPPED); - - status = qc_register(dev); - if (status) - qc_deregister(dev); - - return status; -} -EXPORT_SYMBOL_GPL(qcnet_probe); - -static struct usb_driver qcusbnet = { - .name = "QCUSBNet2k", - .id_table = qc_vidpids, - .probe = qcnet_probe, - .disconnect = usbnet_disconnect, - .suspend = qc_suspend, - .resume = qc_resume, - .reset_resume = qc_reset_resume, - .supports_autosuspend = true, -}; - -static int __init modinit(void) -{ - devclass = class_create(THIS_MODULE, "QCQMI"); - if (IS_ERR(devclass)) { - ERR("error at class_create %ld\n", PTR_ERR(devclass)); - return -ENOMEM; - } - printk(KERN_INFO "%s: %s\n", DRIVER_DESC, DRIVER_VERSION); - return usb_register(&qcusbnet); -} -module_init(modinit); - -static void __exit modexit(void) -{ - usb_deregister(&qcusbnet); - class_destroy(devclass); -} -module_exit(modexit); - -MODULE_VERSION(DRIVER_VERSION); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("Dual BSD/GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debuging enabled or not"); diff --git a/drivers/net/usb/qcusbnet/qcusbnet.h b/drivers/net/usb/qcusbnet/qcusbnet.h deleted file mode 100644 index 2f2086847a32..000000000000 --- a/drivers/net/usb/qcusbnet/qcusbnet.h +++ /dev/null @@ -1,24 +0,0 @@ -/* qcusbnet.h - gobi network device header - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef QCUSBNET_QCUSBNET_H -#define QCUSBNET_QCUSBNET_H - -extern int qc_suspend(struct usb_interface *iface, pm_message_t event); - -#endif /* !QCUSBNET_QCUSBNET_H */ diff --git a/drivers/net/usb/qcusbnet/qmi.c b/drivers/net/usb/qcusbnet/qmi.c deleted file mode 100644 index cdbdbaf7acc2..000000000000 --- a/drivers/net/usb/qcusbnet/qmi.c +++ /dev/null @@ -1,358 +0,0 @@ -/* qmi.c - QMI protocol implementation - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "qmi.h" - -#include - -struct qmux { - u8 tf; /* always 1 */ - u16 len; - u8 ctrl; - u8 service; - u8 qmicid; -} __attribute__((__packed__)); - -struct getcid_req { - struct qmux header; - u8 req; - u8 tid; - u16 msgid; - u16 tlvsize; - u8 service; - u16 size; - u8 qmisvc; -} __attribute__((__packed__)); - -struct releasecid_req { - struct qmux header; - u8 req; - u8 tid; - u16 msgid; - u16 tlvsize; - u8 rlscid; - u16 size; - u16 cid; -} __attribute__((__packed__)); - -struct ready_req { - struct qmux header; - u8 req; - u8 tid; - u16 msgid; - u16 tlvsize; -} __attribute__((__packed__)); - -struct seteventreport_req { - struct qmux header; - u8 req; - u16 tid; - u16 msgid; - u16 tlvsize; - u8 reportchanrate; - u16 size; - u8 period; - u32 mask; -} __attribute__((__packed__)); - -struct getpkgsrvcstatus_req { - struct qmux header; - u8 req; - u16 tid; - u16 msgid; - u16 tlvsize; -} __attribute__((__packed__)); - -struct getmeid_req { - struct qmux header; - u8 req; - u16 tid; - u16 msgid; - u16 tlvsize; -} __attribute__((__packed__)); - -const size_t qmux_size = sizeof(struct qmux); - -void *qmictl_new_getcid(u8 tid, u8 svctype, size_t *size) -{ - struct getcid_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->req = 0x00; - req->tid = tid; - req->msgid = 0x0022; - req->tlvsize = 0x0004; - req->service = 0x01; - req->size = 0x0001; - req->qmisvc = svctype; - *size = sizeof(*req); - return req; -} - -void *qmictl_new_releasecid(u8 tid, u16 cid, size_t *size) -{ - struct releasecid_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->req = 0x00; - req->tid = tid; - req->msgid = 0x0023; - req->tlvsize = 0x05; - req->rlscid = 0x01; - req->size = 0x0002; - req->cid = cid; - *size = sizeof(*req); - return req; -} - -void *qmictl_new_ready(u8 tid, size_t *size) -{ - struct ready_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->req = 0x00; - req->tid = tid; - req->msgid = 0x21; - req->tlvsize = 0; - *size = sizeof(*req); - return req; -} - -void *qmiwds_new_seteventreport(u8 tid, size_t *size) -{ - struct seteventreport_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - req->req = 0x00; - req->tid = tid; - req->msgid = 0x0001; - req->tlvsize = 0x0008; - req->reportchanrate = 0x11; - req->size = 0x0005; - req->period = 0x01; - req->mask = 0x000000ff; - *size = sizeof(*req); - return req; -} - -void *qmiwds_new_getpkgsrvcstatus(u8 tid, size_t *size) -{ - struct getpkgsrvcstatus_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->req = 0x00; - req->tid = tid; - req->msgid = 0x22; - req->tlvsize = 0x0000; - *size = sizeof(*req); - return req; -} - -void *qmidms_new_getmeid(u8 tid, size_t *size) -{ - struct getmeid_req *req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->req = 0x00; - req->tid = tid; - req->msgid = 0x25; - req->tlvsize = 0x0000; - *size = sizeof(*req); - return req; -} - -int qmux_parse(u16 *cid, void *buf, size_t size) -{ - struct qmux *qmux = buf; - - if (!buf || size < 12) - return -ENOMEM; - - if (qmux->tf != 1 || qmux->len != size - 1 || qmux->ctrl != 0x80) - return -EINVAL; - - *cid = (qmux->qmicid << 8) + qmux->service; - return sizeof(*qmux); -} - -int qmux_fill(u16 cid, void *buf, size_t size) -{ - struct qmux *qmux = buf; - - if (!buf || size < sizeof(*qmux)) - return -ENOMEM; - - qmux->tf = 1; - qmux->len = size - 1; - qmux->ctrl = 0; - qmux->service = cid & 0xff; - qmux->qmicid = cid >> 8; - return 0; -} - -static u16 tlv_get(void *msg, u16 msgsize, u8 type, void *buf, u16 bufsize) -{ - u16 pos; - u16 msize = 0; - - if (!msg || !buf) - return -ENOMEM; - - for (pos = 4; pos + 3 < msgsize; pos += msize + 3) { - msize = *(u16 *)(msg + pos + 1); - if (*(u8 *)(msg + pos) == type) { - if (bufsize < msize) - return -ENOMEM; - - memcpy(buf, msg + pos + 3, msize); - return msize; - } - } - - return -ENOMSG; -} - -int qmi_msgisvalid(void *msg, u16 size) -{ - char tlv[4]; - - if (tlv_get(msg, size, 2, &tlv[0], 4) == 4) { - if (*(u16 *)&tlv[0] != 0) - return *(u16 *)&tlv[2]; - else - return 0; - } - return -ENOMSG; -} - -int qmi_msgid(void *msg, u16 size) -{ - return size < 2 ? -ENODATA : *(u16 *)msg; -} - -int qmictl_alloccid_resp(void *buf, u16 size, u16 *cid) -{ - int result; - u8 offset = sizeof(struct qmux) + 2; - - if (!buf || size < offset) - return -ENOMEM; - - buf = buf + offset; - size -= offset; - - result = qmi_msgid(buf, size); - if (result != 0x22) - return -EFAULT; - - result = qmi_msgisvalid(buf, size); - if (result != 0) - return -EFAULT; - - result = tlv_get(buf, size, 0x01, cid, 2); - if (result != 2) - return -EFAULT; - - return 0; -} - -int qmictl_freecid_resp(void *buf, u16 size) -{ - int result; - u8 offset = sizeof(struct qmux) + 2; - - if (!buf || size < offset) - return -ENOMEM; - - buf = buf + offset; - size -= offset; - - result = qmi_msgid(buf, size); - if (result != 0x23) - return -EFAULT; - - result = qmi_msgisvalid(buf, size); - if (result != 0) - return -EFAULT; - - return 0; -} - -int qmiwds_event_resp(void *buf, u16 size, struct qmiwds_stats *stats) -{ - int result; - u8 status[2]; - - u8 offset = sizeof(struct qmux) + 3; - - if (!buf || size < offset || !stats) - return -ENOMEM; - - buf = buf + offset; - size -= offset; - - result = qmi_msgid(buf, size); - if (result == 0x01) { - tlv_get(buf, size, 0x10, &stats->txok, 4); - tlv_get(buf, size, 0x11, &stats->rxok, 4); - tlv_get(buf, size, 0x12, &stats->txerr, 4); - tlv_get(buf, size, 0x13, &stats->rxerr, 4); - tlv_get(buf, size, 0x14, &stats->txofl, 4); - tlv_get(buf, size, 0x15, &stats->rxofl, 4); - tlv_get(buf, size, 0x19, &stats->txbytesok, 8); - tlv_get(buf, size, 0x1A, &stats->rxbytesok, 8); - } else if (result == 0x22) { - result = tlv_get(buf, size, 0x01, &status[0], 2); - if (result >= 1) - stats->linkstate = status[0] == 0x02; - if (result == 2) - stats->reconfigure = status[1] == 0x01; - - if (result < 0) - return result; - } else { - return -EFAULT; - } - - return 0; -} - -int qmidms_meid_resp(void *buf, u16 size, char *meid, int meidsize) -{ - int result; - - u8 offset = sizeof(struct qmux) + 3; - - if (!buf || size < offset || meidsize < 14) - return -ENOMEM; - - buf = buf + offset; - size -= offset; - - result = qmi_msgid(buf, size); - if (result != 0x25) - return -EFAULT; - - result = qmi_msgisvalid(buf, size); - if (result) - return -EFAULT; - - result = tlv_get(buf, size, 0x12, meid, 14); - if (result != 14) - return -EFAULT; - - return 0; -} diff --git a/drivers/net/usb/qcusbnet/qmi.h b/drivers/net/usb/qcusbnet/qmi.h deleted file mode 100644 index adbc8a651663..000000000000 --- a/drivers/net/usb/qcusbnet/qmi.h +++ /dev/null @@ -1,58 +0,0 @@ -/* qmi.h - QMI protocol header - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef QCUSBNET_QMI_H -#define QCUSBNET_QMI_H - -#include - -#define QMICTL 0 -#define QMIWDS 1 -#define QMIDMS 2 - -int qmux_parse(u16 *cid, void *buf, size_t size); -int qmux_fill(u16 cid, void *buf, size_t size); - -extern const size_t qmux_size; - -void *qmictl_new_getcid(u8 tid, u8 svctype, size_t *size); -void *qmictl_new_releasecid(u8 tid, u16 cid, size_t *size); -void *qmictl_new_ready(u8 tid, size_t *size); -void *qmiwds_new_seteventreport(u8 tid, size_t *size); -void *qmiwds_new_getpkgsrvcstatus(u8 tid, size_t *size); -void *qmidms_new_getmeid(u8 tid, size_t *size); - -struct qmiwds_stats { - u32 txok; - u32 rxok; - u32 txerr; - u32 rxerr; - u32 txofl; - u32 rxofl; - u64 txbytesok; - u64 rxbytesok; - bool linkstate; - bool reconfigure; -}; - -int qmictl_alloccid_resp(void *buf, u16 size, u16 *cid); -int qmictl_freecid_resp(void *buf, u16 size); -int qmiwds_event_resp(void *buf, u16 size, struct qmiwds_stats *stats); -int qmidms_meid_resp(void *buf, u16 size, char *meid, int meidsize); - -#endif /* !QCUSBNET_QMI_H */ diff --git a/drivers/net/usb/qcusbnet/qmidevice.c b/drivers/net/usb/qcusbnet/qmidevice.c deleted file mode 100644 index e4706451653f..000000000000 --- a/drivers/net/usb/qcusbnet/qmidevice.c +++ /dev/null @@ -1,1669 +0,0 @@ -/* qmidevice.c - gobi QMI device - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "qmidevice.h" -#include "qcusbnet.h" -#include - -struct readreq { - struct list_head node; - void *data; - u16 tid; - u16 size; -}; - -struct notifyreq { - struct list_head node; - void (*func)(struct qcusbnet *, u16, void *); - u16 tid; - void *data; -}; - -struct client { - struct list_head node; - u16 cid; - struct list_head reads; - struct list_head notifies; - struct list_head urbs; - wait_queue_head_t read_wait; -}; - -struct urbsetup { - u8 type; - u8 code; - u16 value; - u16 index; - u16 len; -}; - -struct qmihandle { - u16 cid; - struct qcusbnet *dev; -}; - -extern int debug; -static int qcusbnet2k_fwdelay; - -static bool device_valid(struct qcusbnet *dev); -static struct client *client_bycid(struct qcusbnet *dev, u16 cid); -static bool client_addread(struct qcusbnet *dev, u16 cid, u16 tid, void *data, u16 size); -static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data, u16 *size); -static bool client_addnotify(struct qcusbnet *dev, u16 cid, u16 tid, - void (*hook)(struct qcusbnet *, u16 cid, void *), - void *data); -static bool client_notify(struct qcusbnet *dev, u16 cid, u16 tid); -static bool client_addurb(struct qcusbnet *dev, u16 cid, struct urb *urb); -static struct urb *client_delurb(struct qcusbnet *dev, u16 cid); - -static int devqmi_open(struct inode *inode, struct file *file); -static long devqmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static int devqmi_close(struct file *file, fl_owner_t ftable); -static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size, - loff_t *pos); -static ssize_t devqmi_write(struct file *file, const char __user *buf, - size_t size, loff_t *pos); -static unsigned int devqmi_poll(struct file *file, poll_table *wait); - -static bool qmi_ready(struct qcusbnet *dev, u16 timeout); -static void wds_callback(struct qcusbnet *dev, u16 cid, void *data); -static int setup_wds_callback(struct qcusbnet *dev); -static int qmidms_getmeid(struct qcusbnet *dev); - -#define IOCTL_QMI_GET_SERVICE_FILE (0x8BE0 + 1) -#define IOCTL_QMI_GET_DEVICE_VIDPID (0x8BE0 + 2) -#define IOCTL_QMI_GET_DEVICE_MEID (0x8BE0 + 3) -#define CDC_GET_MASK 0xFFFFll -#define CDC_GET_ENCAPSULATED_RESPONSE 0x01A1ll -#define CDC_CONNECTION_SPEED_CHANGE 0x08000000002AA1ll - -static const struct file_operations devqmi_fops = { - .owner = THIS_MODULE, - .read = devqmi_read, - .write = devqmi_write, - .unlocked_ioctl = devqmi_ioctl, - .open = devqmi_open, - .flush = devqmi_close, - .poll = devqmi_poll, -}; - -#ifdef CONFIG_SMP -static inline void assert_locked(struct qcusbnet *dev) -{ - BUG_ON(!spin_is_locked(&dev->qmi.clients_lock)); -} -#else -static inline void assert_locked(struct qcusbnet *dev) -{ - -} -#endif - -static bool device_valid(struct qcusbnet *dev) -{ - return dev && dev->valid; -} - -void qc_setdown(struct qcusbnet *dev, u8 reason) -{ - set_bit(reason, &dev->down); - netif_carrier_off(dev->usbnet->net); -} - -void qc_cleardown(struct qcusbnet *dev, u8 reason) -{ - clear_bit(reason, &dev->down); - if (!dev->down) - netif_carrier_on(dev->usbnet->net); -} - -bool qc_isdown(struct qcusbnet *dev, u8 reason) -{ - return test_bit(reason, &dev->down); -} - -static void read_callback(struct urb *urb) -{ - struct list_head *node; - int result; - u16 cid; - struct client *client; - void *data; - void *copy; - u16 size; - struct qcusbnet *dev; - unsigned long flags; - u16 tid; - - if (!urb) { - ERR("bad read URB\n"); - return; - } - - dev = urb->context; - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return; - } - - if (urb->status) { - DBG("Read status = %d\n", urb->status); - return; - } - - DBG("Read %d bytes\n", urb->actual_length); - - data = urb->transfer_buffer; - size = urb->actual_length; - - if (debug) - print_hex_dump(KERN_INFO, "QCUSBNet2k: ", DUMP_PREFIX_OFFSET, - 16, 1, data, size, true); - - result = qmux_parse(&cid, data, size); - if (result < 0) { - ERR("Read error parsing QMUX %d\n", result); - return; - } - - if (size < result + 3) { - DBG("Data buffer too small to parse\n"); - return; - } - - if (cid == QMICTL) - tid = *(u8 *)(data + result + 1); - else - tid = *(u16 *)(data + result + 1); - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - - list_for_each(node, &dev->qmi.clients) { - client = list_entry(node, struct client, node); - if (client->cid == cid || (client->cid | 0xff00) == cid) { - copy = kmalloc(size, GFP_ATOMIC); - if (!copy) { - ERR("malloc failed\n"); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return; - } - memcpy(copy, data, size); - if (!client_addread(dev, client->cid, tid, copy, size)) { - ERR("Error allocating pReadMemListEntry " - "read will be discarded\n"); - kfree(copy); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return; - } - - wake_up_interruptible(&client->read_wait); - - DBG("Creating new readListEntry for client 0x%04X, TID %x\n", - cid, tid); - - client_notify(dev, client->cid, tid); - - if (cid >> 8 != 0xff) - break; - } - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); -} - -static void int_callback(struct urb *urb) -{ - int status; - int interval; - struct qcusbnet *dev = (struct qcusbnet *)urb->context; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return; - } - - if (urb->status) { - DBG("Int status = %d\n", urb->status); - if (urb->status != -EOVERFLOW) - return; - } else { - if ((urb->actual_length == 8) && - (*(u64 *)urb->transfer_buffer & CDC_GET_MASK) == - CDC_GET_ENCAPSULATED_RESPONSE) { - usb_fill_control_urb(dev->qmi.readurb, dev->usbnet->udev, - usb_rcvctrlpipe(dev->usbnet->udev, 0), - (unsigned char *)dev->qmi.readsetup, - dev->qmi.readbuf, - DEFAULT_READ_URB_LENGTH, - read_callback, dev); - status = usb_submit_urb(dev->qmi.readurb, GFP_ATOMIC); - if (status) { - ERR("Error submitting Read URB %d\n", status); - return; - } - } else if ((urb->actual_length == 16) && - (*(u64 *)urb->transfer_buffer == CDC_CONNECTION_SPEED_CHANGE)) { - /* if upstream or downstream is 0, stop traffic. - * Otherwise resume it */ - if ((*(u32 *)(urb->transfer_buffer + 8) == 0) || - (*(u32 *)(urb->transfer_buffer + 12) == 0)) { - qc_setdown(dev, DOWN_CDC_CONNECTION_SPEED); - DBG("traffic stopping due to CONNECTION_SPEED_CHANGE\n"); - } else { - qc_cleardown(dev, DOWN_CDC_CONNECTION_SPEED); - DBG("resuming traffic due to CONNECTION_SPEED_CHANGE\n"); - } - } else { - DBG("ignoring invalid interrupt in packet\n"); - if (debug) - print_hex_dump(KERN_INFO, "QCUSBNet2k: ", - DUMP_PREFIX_OFFSET, 16, 1, - urb->transfer_buffer, - urb->actual_length, true); - } - } - - interval = (dev->usbnet->udev->speed == USB_SPEED_HIGH) ? 7 : 3; - - usb_fill_int_urb(urb, urb->dev, urb->pipe, urb->transfer_buffer, - urb->transfer_buffer_length, urb->complete, - urb->context, interval); - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) - ERR("Error re-submitting Int URB %d\n", status); - return; -} - -int qc_startread(struct qcusbnet *dev) -{ - int interval; - int numends; - int i; - struct usb_host_endpoint *endpoint = NULL; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - dev->qmi.readurb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->qmi.readurb) { - ERR("Error allocating read urb\n"); - return -ENOMEM; - } - - dev->qmi.inturb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->qmi.inturb) { - usb_free_urb(dev->qmi.readurb); - ERR("Error allocating int urb\n"); - return -ENOMEM; - } - - dev->qmi.readbuf = kmalloc(DEFAULT_READ_URB_LENGTH, GFP_KERNEL); - if (!dev->qmi.readbuf) { - usb_free_urb(dev->qmi.readurb); - usb_free_urb(dev->qmi.inturb); - ERR("Error allocating read buffer\n"); - return -ENOMEM; - } - - dev->qmi.intbuf = kmalloc(DEFAULT_READ_URB_LENGTH, GFP_KERNEL); - if (!dev->qmi.intbuf) { - usb_free_urb(dev->qmi.readurb); - usb_free_urb(dev->qmi.inturb); - kfree(dev->qmi.readbuf); - ERR("Error allocating int buffer\n"); - return -ENOMEM; - } - - dev->qmi.readsetup = kmalloc(sizeof(*dev->qmi.readsetup), GFP_KERNEL); - if (!dev->qmi.readsetup) { - usb_free_urb(dev->qmi.readurb); - usb_free_urb(dev->qmi.inturb); - kfree(dev->qmi.readbuf); - kfree(dev->qmi.intbuf); - ERR("Error allocating setup packet buffer\n"); - return -ENOMEM; - } - - dev->qmi.readsetup->type = 0xA1; - dev->qmi.readsetup->code = 1; - dev->qmi.readsetup->value = 0; - dev->qmi.readsetup->index = dev->iface->cur_altsetting->desc.bInterfaceNumber; - dev->qmi.readsetup->len = DEFAULT_READ_URB_LENGTH; - - interval = (dev->usbnet->udev->speed == USB_SPEED_HIGH) ? 7 : 3; - - numends = dev->iface->cur_altsetting->desc.bNumEndpoints; - for (i = 0; i < numends; i++) { - endpoint = dev->iface->cur_altsetting->endpoint + i; - if (!endpoint) { - ERR("invalid endpoint %u\n", i); - return -EINVAL; - } - - if (usb_endpoint_dir_in(&endpoint->desc) - && usb_endpoint_xfer_int(&endpoint->desc)) { - DBG("Interrupt endpoint is %x\n", endpoint->desc.bEndpointAddress); - break; - } - } - - usb_fill_int_urb(dev->qmi.inturb, dev->usbnet->udev, - usb_rcvintpipe(dev->usbnet->udev, endpoint->desc.bEndpointAddress), - dev->qmi.intbuf, DEFAULT_READ_URB_LENGTH, - int_callback, dev, interval); - - return usb_submit_urb(dev->qmi.inturb, GFP_KERNEL); -} - -void qc_stopread(struct qcusbnet *dev) -{ - if (dev->qmi.readurb) { - DBG("Killing read URB\n"); - usb_kill_urb(dev->qmi.readurb); - } - - if (dev->qmi.inturb) { - DBG("Killing int URB\n"); - usb_kill_urb(dev->qmi.inturb); - } - - kfree(dev->qmi.readsetup); - dev->qmi.readsetup = NULL; - kfree(dev->qmi.readbuf); - dev->qmi.readbuf = NULL; - kfree(dev->qmi.intbuf); - dev->qmi.intbuf = NULL; - - usb_free_urb(dev->qmi.readurb); - dev->qmi.readurb = NULL; - usb_free_urb(dev->qmi.inturb); - dev->qmi.inturb = NULL; -} - -static int read_async(struct qcusbnet *dev, u16 cid, u16 tid, - void (*hook)(struct qcusbnet *, u16, void *), - void *data) -{ - struct list_head *node; - struct client *client; - struct readreq *readreq; - - unsigned long flags; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find matching client ID 0x%04X\n", cid); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -ENXIO; - } - - list_for_each(node, &client->reads) { - readreq = list_entry(node, struct readreq, node); - if (!tid || tid == readreq->tid) { - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - hook(dev, cid, data); - return 0; - } - } - - if (!client_addnotify(dev, cid, tid, hook, data)) - ERR("Unable to register for notification\n"); - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return 0; -} - -static void upsem(struct qcusbnet *dev, u16 cid, void *data) -{ - DBG("0x%04X\n", cid); - up((struct semaphore *)data); -} - -static int read_sync(struct qcusbnet *dev, void **buf, u16 cid, u16 tid) -{ - struct list_head *node; - int result; - struct client *client; - struct notifyreq *notify; - struct semaphore sem; - void *data; - unsigned long flags; - u16 size; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find matching client ID 0x%04X\n", cid); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -ENXIO; - } - - while (!client_delread(dev, cid, tid, &data, &size)) { - sema_init(&sem, 0); - if (!client_addnotify(dev, cid, tid, upsem, &sem)) { - ERR("unable to register for notification\n"); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -EFAULT; - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - - result = down_interruptible(&sem); - if (result) { - DBG("Interrupted %d\n", result); - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - list_for_each(node, &client->notifies) { - notify = list_entry(node, struct notifyreq, node); - if (notify->data == &sem) { - list_del(¬ify->node); - kfree(notify); - break; - } - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -EINTR; - } - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - *buf = data; - return size; -} - -static void write_callback(struct urb *urb) -{ - if (!urb) { - ERR("null urb\n"); - return; - } - - DBG("Write status/size %d/%d\n", urb->status, urb->actual_length); - up((struct semaphore *)urb->context); -} - -static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid) -{ - int result; - struct semaphore sem; - struct urb *urb; - struct urbsetup setup; - unsigned long flags; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - ERR("URB mem error\n"); - return -ENOMEM; - } - - result = qmux_fill(cid, buf, size); - if (result < 0) { - usb_free_urb(urb); - return result; - } - - /* CDC Send Encapsulated Request packet */ - setup.type = 0x21; - setup.code = 0; - setup.value = 0; - setup.index = dev->iface->cur_altsetting->desc.bInterfaceNumber; - setup.len = 0; - setup.len = size; - - usb_fill_control_urb(urb, dev->usbnet->udev, - usb_sndctrlpipe(dev->usbnet->udev, 0), - (unsigned char *)&setup, (void *)buf, size, - NULL, dev); - - DBG("Actual Write:\n"); - if (debug) - print_hex_dump(KERN_INFO, "QCUSBNet2k: ", DUMP_PREFIX_OFFSET, - 16, 1, buf, size, true); - - sema_init(&sem, 0); - - urb->complete = write_callback; - urb->context = &sem; - - result = usb_autopm_get_interface(dev->iface); - if (result < 0) { - ERR("unable to resume interface: %d\n", result); - if (result == -EPERM) - qc_suspend(dev->iface, PMSG_SUSPEND); - - return result; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - - if (!client_addurb(dev, cid, urb)) { - usb_free_urb(urb); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - usb_autopm_put_interface(dev->iface); - return -EINVAL; - } - - result = usb_submit_urb(urb, GFP_KERNEL); - if (result < 0) { - ERR("submit URB error %d\n", result); - if (client_delurb(dev, cid) != urb) - ERR("Didn't get write URB back\n"); - - usb_free_urb(urb); - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - usb_autopm_put_interface(dev->iface); - return result; - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - result = down_interruptible(&sem); - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - usb_autopm_put_interface(dev->iface); - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - if (client_delurb(dev, cid) != urb) { - ERR("Didn't get write URB back\n"); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -EINVAL; - } - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - - if (!result) { - if (!urb->status) { - result = size; - } else { - ERR("bad status = %d\n", urb->status); - result = urb->status; - } - } else { - ERR("Interrupted %d !!!\n", result); - ERR("Device may be in bad state and need reset !!!\n"); - usb_kill_urb(urb); - } - - usb_free_urb(urb); - return result; -} - -static int client_alloc(struct qcusbnet *dev, u8 type) -{ - u16 cid; - struct client *client; - int result; - void *wbuf; - size_t wbufsize; - void *rbuf; - u16 rbufsize; - unsigned long flags; - u8 tid; - - if (!device_valid(dev)) { - ERR("Invalid device!\n"); - return -ENXIO; - } - - if (type) { - tid = atomic_add_return(1, &dev->qmi.qmitid); - if (!tid) - atomic_add_return(1, &dev->qmi.qmitid); - wbuf = qmictl_new_getcid(tid, type, &wbufsize); - if (!wbuf) - return -ENOMEM; - result = write_sync(dev, wbuf, wbufsize, QMICTL); - kfree(wbuf); - - if (result < 0) - return result; - - result = read_sync(dev, &rbuf, QMICTL, tid); - if (result < 0) { - ERR("bad read data %d\n", result); - return result; - } - rbufsize = result; - - result = qmictl_alloccid_resp(rbuf, rbufsize, &cid); - kfree(rbuf); - - if (result < 0) - return result; - } else { - cid = 0; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - if (client_bycid(dev, cid)) { - DBG("Client memory already exists\n"); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -ETOOMANYREFS; - } - - client = kmalloc(sizeof(*client), GFP_ATOMIC); - if (!client) { - ERR("Error allocating read list\n"); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return -ENOMEM; - } - - list_add_tail(&client->node, &dev->qmi.clients); - client->cid = cid; - INIT_LIST_HEAD(&client->reads); - INIT_LIST_HEAD(&client->notifies); - INIT_LIST_HEAD(&client->urbs); - init_waitqueue_head(&client->read_wait); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - return cid; -} - -static void client_free(struct qcusbnet *dev, u16 cid) -{ - struct list_head *node, *tmp; - int result; - struct client *client; - struct urb *urb; - void *data; - u16 size; - void *wbuf; - size_t wbufsize; - void *rbuf; - u16 rbufsize; - unsigned long flags; - u8 tid; - - if (!device_valid(dev)) { - ERR("invalid device\n"); - return; - } - - DBG("releasing 0x%04X\n", cid); - - if (cid != QMICTL) { - tid = atomic_add_return(1, &dev->qmi.qmitid); - if (!tid) - tid = atomic_add_return(1, &dev->qmi.qmitid); - wbuf = qmictl_new_releasecid(tid, cid, &wbufsize); - if (!wbuf) { - ERR("memory error\n"); - } else { - result = write_sync(dev, wbuf, wbufsize, QMICTL); - kfree(wbuf); - - if (result < 0) { - ERR("bad write status %d\n", result); - } else { - result = read_sync(dev, &rbuf, QMICTL, tid); - if (result < 0) { - ERR("bad read status %d\n", result); - } else { - rbufsize = result; - result = qmictl_freecid_resp(rbuf, rbufsize); - kfree(rbuf); - if (result < 0) - ERR("error %d parsing response\n", result); - } - } - } - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - list_for_each_safe(node, tmp, &dev->qmi.clients) { - client = list_entry(node, struct client, node); - if (client->cid == cid) { - while (client_notify(dev, cid, 0)) - ; - - urb = client_delurb(dev, cid); - while (urb != NULL) { - usb_kill_urb(urb); - usb_free_urb(urb); - urb = client_delurb(dev, cid); - } - - while (client_delread(dev, cid, 0, &data, &size)) - kfree(data); - - list_del(&client->node); - kfree(client); - } - } - - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); -} - -struct client *client_bycid(struct qcusbnet *dev, u16 cid) -{ - struct list_head *node; - struct client *client; - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return NULL; - } - - assert_locked(dev); - - list_for_each(node, &dev->qmi.clients) { - client = list_entry(node, struct client, node); - if (client->cid == cid) - return client; - } - - DBG("Could not find client mem 0x%04X\n", cid); - return NULL; -} - -static bool client_addread(struct qcusbnet *dev, u16 cid, u16 tid, void *data, - u16 size) -{ - struct client *client; - struct readreq *req; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return false; - } - - req = kmalloc(sizeof(*req), GFP_ATOMIC); - if (!req) { - ERR("Mem error\n"); - return false; - } - - req->data = data; - req->size = size; - req->tid = tid; - - list_add_tail(&req->node, &client->reads); - - return true; -} - -static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data, - u16 *size) -{ - struct client *client; - struct readreq *req; - struct list_head *node; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return false; - } - - list_for_each(node, &client->reads) { - req = list_entry(node, struct readreq, node); - if (!tid || tid == req->tid) { - *data = req->data; - *size = req->size; - list_del(&req->node); - kfree(req); - return true; - } - - DBG("skipping 0x%04X data TID = %x\n", cid, req->tid); - } - - DBG("No read memory to pop, Client 0x%04X, TID = %x\n", cid, tid); - return false; -} - -static bool client_addnotify(struct qcusbnet *dev, u16 cid, u16 tid, - void (*hook)(struct qcusbnet *, u16, void *), - void *data) -{ - struct client *client; - struct notifyreq *req; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return false; - } - - req = kmalloc(sizeof(*req), GFP_ATOMIC); - if (!req) { - ERR("Mem error\n"); - return false; - } - - list_add_tail(&req->node, &client->notifies); - req->func = hook; - req->data = data; - req->tid = tid; - - return true; -} - -static bool client_notify(struct qcusbnet *dev, u16 cid, u16 tid) -{ - struct client *client; - struct notifyreq *delnotify, *notify; - struct list_head *node; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return false; - } - - delnotify = NULL; - - list_for_each(node, &client->notifies) { - notify = list_entry(node, struct notifyreq, node); - if (!tid || !notify->tid || tid == notify->tid) { - delnotify = notify; - break; - } - - DBG("skipping data TID = %x\n", notify->tid); - } - - if (delnotify) { - list_del(&delnotify->node); - if (delnotify->func) { - spin_unlock(&dev->qmi.clients_lock); - delnotify->func(dev, cid, delnotify->data); - spin_lock(&dev->qmi.clients_lock); - } - kfree(delnotify); - return true; - } - - DBG("no one to notify for TID %x\n", tid); - return false; -} - -static bool client_addurb(struct qcusbnet *dev, u16 cid, struct urb *urb) -{ - struct client *client; - struct urbreq *req; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return false; - } - - req = kmalloc(sizeof(*req), GFP_ATOMIC); - if (!req) { - ERR("Mem error\n"); - return false; - } - - req->urb = urb; - list_add_tail(&req->node, &client->urbs); - - return true; -} - -static struct urb *client_delurb(struct qcusbnet *dev, u16 cid) -{ - struct client *client; - struct urbreq *req; - struct urb *urb; - - assert_locked(dev); - - client = client_bycid(dev, cid); - if (!client) { - ERR("Could not find this client's memory 0x%04X\n", cid); - return NULL; - } - - if (list_empty(&client->urbs)) { - DBG("No URB's to pop\n"); - return NULL; - } - - req = list_first_entry(&client->urbs, struct urbreq, node); - list_del(&req->node); - urb = req->urb; - kfree(req); - return urb; -} - -static int devqmi_open(struct inode *inode, struct file *file) -{ - struct qmihandle *handle; - struct qmidev *qmidev = container_of(inode->i_cdev, struct qmidev, cdev); - struct qcusbnet *dev = container_of(qmidev, struct qcusbnet, qmi); - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return -ENXIO; - } - - file->private_data = kmalloc(sizeof(struct qmihandle), GFP_KERNEL); - if (!file->private_data) { - ERR("Mem error\n"); - return -ENOMEM; - } - - handle = (struct qmihandle *)file->private_data; - handle->cid = (u16)-1; - handle->dev = dev; - - return 0; -} - -static long devqmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int result; - u32 vidpid; - - struct qmihandle *handle = (struct qmihandle *)file->private_data; - - if (!handle) { - ERR("Bad file data\n"); - return -EBADF; - } - - if (!device_valid(handle->dev)) { - ERR("Invalid device! Updating f_ops\n"); - file->f_op = file->f_dentry->d_inode->i_fop; - return -ENXIO; - } - - switch (cmd) { - case IOCTL_QMI_GET_SERVICE_FILE: - - DBG("Setting up QMI for service %lu\n", arg); - if (!(u8)arg) { - ERR("Cannot use QMICTL from userspace\n"); - return -EINVAL; - } - - if (handle->cid != (u16)-1) { - ERR("Close the current connection before opening a new one\n"); - return -EBADR; - } - - result = client_alloc(handle->dev, (u8)arg); - if (result < 0) - return result; - handle->cid = result; - - return 0; - break; - - - case IOCTL_QMI_GET_DEVICE_VIDPID: - if (!arg) { - ERR("Bad VIDPID buffer\n"); - return -EINVAL; - } - - if (!handle->dev->usbnet) { - ERR("Bad usbnet\n"); - return -ENOMEM; - } - - if (!handle->dev->usbnet->udev) { - ERR("Bad udev\n"); - return -ENOMEM; - } - - vidpid = ((le16_to_cpu(handle->dev->usbnet->udev->descriptor.idVendor) << 16) - + le16_to_cpu(handle->dev->usbnet->udev->descriptor.idProduct)); - - result = copy_to_user((unsigned int *)arg, &vidpid, 4); - if (result) - ERR("Copy to userspace failure\n"); - - return result; - break; - - case IOCTL_QMI_GET_DEVICE_MEID: - if (!arg) { - ERR("Bad MEID buffer\n"); - return -EINVAL; - } - - result = copy_to_user((unsigned int *)arg, &handle->dev->meid[0], 14); - if (result) - ERR("copy to userspace failure\n"); - - return result; - break; - default: - return -EBADRQC; - } -} - -static int devqmi_close(struct file *file, fl_owner_t ftable) -{ - struct qmihandle *handle = (struct qmihandle *)file->private_data; - struct list_head *tasks; - struct task_struct *task; - struct fdtable *fdtable; - int count = 0; - int used = 0; - unsigned long flags; - - if (!handle) { - ERR("bad file data\n"); - return -EBADF; - } - - if (file_count(file) != 1) { - /* XXX: This can't possibly be safe. We don't hold any sort of - * lock here, and we're walking a list of threads... */ - list_for_each(tasks, ¤t->group_leader->tasks) { - task = container_of(tasks, struct task_struct, tasks); - if (!task || !task->files) - continue; - spin_lock_irqsave(&task->files->file_lock, flags); - fdtable = files_fdtable(task->files); - for (count = 0; count < fdtable->max_fds; count++) { - /* Before this function was called, this file was removed - * from our task's file table so if we find it in a file - * table then it is being used by another task - */ - if (fdtable->fd[count] == file) { - used++; - break; - } - } - spin_unlock_irqrestore(&task->files->file_lock, flags); - } - - if (used > 0) { - DBG("not closing, as this FD is open by %d other process\n", used); - return 0; - } - } - - if (!device_valid(handle->dev)) { - ERR("Invalid device! Updating f_ops\n"); - file->f_op = file->f_dentry->d_inode->i_fop; - return -ENXIO; - } - - DBG("0x%04X\n", handle->cid); - - file->private_data = NULL; - - if (handle->cid != (u16)-1) - client_free(handle->dev, handle->cid); - - kfree(handle); - return 0; -} - -static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size, - loff_t *pos) -{ - int result; - void *data = NULL; - void *smalldata; - struct qmihandle *handle = (struct qmihandle *)file->private_data; - - if (!handle) { - ERR("Bad file data\n"); - return -EBADF; - } - - if (!device_valid(handle->dev)) { - ERR("Invalid device! Updating f_ops\n"); - file->f_op = file->f_dentry->d_inode->i_fop; - return -ENXIO; - } - - if (handle->cid == (u16)-1) { - ERR("Client ID must be set before reading 0x%04X\n", - handle->cid); - return -EBADR; - } - - result = read_sync(handle->dev, &data, handle->cid, 0); - if (result <= 0) - return result; - - result -= qmux_size; - smalldata = data + qmux_size; - - if (result > size) { - ERR("Read data is too large for amount user has requested\n"); - kfree(data); - return -EOVERFLOW; - } - - if (copy_to_user(buf, smalldata, result)) { - ERR("Error copying read data to user\n"); - result = -EFAULT; - } - - kfree(data); - return result; -} - -static ssize_t devqmi_write(struct file *file, const char __user * buf, - size_t size, loff_t *pos) -{ - int status; - void *wbuf; - struct qmihandle *handle = (struct qmihandle *)file->private_data; - - if (!handle) { - ERR("Bad file data\n"); - return -EBADF; - } - - if (!device_valid(handle->dev)) { - ERR("Invalid device! Updating f_ops\n"); - file->f_op = file->f_dentry->d_inode->i_fop; - return -ENXIO; - } - - if (handle->cid == (u16)-1) { - ERR("Client ID must be set before writing 0x%04X\n", - handle->cid); - return -EBADR; - } - - wbuf = kmalloc(size + qmux_size, GFP_KERNEL); - if (!wbuf) - return -ENOMEM; - status = copy_from_user(wbuf + qmux_size, buf, size); - if (status) { - ERR("Unable to copy data from userspace %d\n", status); - kfree(wbuf); - return status; - } - - status = write_sync(handle->dev, wbuf, size + qmux_size, - handle->cid); - - kfree(wbuf); - if (status == size + qmux_size) - return size; - return status; -} - -static unsigned int devqmi_poll(struct file *file, poll_table *wait) -{ - struct qmihandle *handle = (struct qmihandle *)file->private_data; - struct client *client; - unsigned int mask = 0; - unsigned long flags; - - if (!handle) { - ERR("Bad file data\n"); - return -EBADF; - } - - if (!device_valid(handle->dev)) { - ERR("Invalid device! Updating f_ops\n"); - file->f_op = file->f_dentry->d_inode->i_fop; - return -ENXIO; - } - - if (handle->cid == (u16)-1) { - ERR("Client ID must be set before polling 0x%04X\n", - handle->cid); - return -EBADR; - } - - spin_lock_irqsave(&handle->dev->qmi.clients_lock, flags); - - client = client_bycid(handle->dev, handle->cid); - if (!client) { - ERR("Could not find matching client ID 0x%04X\n", handle->cid); - spin_unlock_irqrestore(&handle->dev->qmi.clients_lock, flags); - return -ENXIO; - } - - poll_wait(file, &client->read_wait, wait); - - if (!list_empty(&client->reads)) - mask |= POLLIN | POLLRDNORM; - - spin_unlock_irqrestore(&handle->dev->qmi.clients_lock, flags); - - return mask; -} - -int qc_register(struct qcusbnet *dev) -{ - int result; - int qmiidx = 0; - dev_t devno; - char *name; - - cdev_init(&dev->qmi.cdev, &devqmi_fops); - dev->qmi.cdev.owner = THIS_MODULE; - dev->valid = true; - - result = client_alloc(dev, QMICTL); - if (result) { - dev->valid = false; - return result; - } - atomic_set(&dev->qmi.qmitid, 1); - - result = qc_startread(dev); - if (result) { - dev->valid = false; - return result; - } - - if (!qmi_ready(dev, 30000)) { - ERR("Device unresponsive to QMI\n"); - return -ETIMEDOUT; - } - - result = setup_wds_callback(dev); - if (result) { - dev->valid = false; - return result; - } - - result = qmidms_getmeid(dev); - if (result) { - dev->valid = false; - return result; - } - - result = alloc_chrdev_region(&devno, 0, 1, "qcqmi"); - if (result < 0) - return result; - - result = cdev_add(&dev->qmi.cdev, devno, 1); - if (result) { - ERR("error adding cdev\n"); - return result; - } - - name = strstr(dev->usbnet->net->name, "qmi"); - if (!name) { - ERR("Bad net name: %s\n", dev->usbnet->net->name); - return -ENXIO; - } - name += strlen("qmi"); - qmiidx = simple_strtoul(name, NULL, 10); - if (qmiidx < 0) { - ERR("Bad minor number\n"); - return -ENXIO; - } - - printk(KERN_INFO "creating qcqmi%d\n", qmiidx); - device_create(dev->qmi.devclass, NULL, devno, NULL, "qcqmi%d", qmiidx); - - dev->qmi.devnum = devno; - return 0; -} - -void qc_deregister(struct qcusbnet *dev) -{ - struct list_head *node; - struct list_head *next; - struct client *client; - struct inode *inode; - struct list_head *inodes; - struct list_head *tasks; - struct task_struct *task; - struct fdtable *fdtable; - struct file *file; - unsigned long flags; - int count = 0; - - if (!device_valid(dev)) { - ERR("wrong device\n"); - return; - } - - list_for_each_safe(node, next, &dev->qmi.clients) { - client = list_entry(node, struct client, node); - DBG("release 0x%04X\n", client->cid); - client_free(dev, client->cid); - } - - qc_stopread(dev); - dev->valid = false; - list_for_each(inodes, &dev->qmi.cdev.list) { - inode = container_of(inodes, struct inode, i_devices); - if (inode != NULL && !IS_ERR(inode)) { - list_for_each(tasks, ¤t->group_leader->tasks) { - task = container_of(tasks, struct task_struct, tasks); - if (!task || !task->files) - continue; - spin_lock_irqsave(&task->files->file_lock, flags); - fdtable = files_fdtable(task->files); - for (count = 0; count < fdtable->max_fds; count++) { - file = fdtable->fd[count]; - if (file != NULL && file->f_dentry != NULL) { - if (file->f_dentry->d_inode == inode) { - rcu_assign_pointer(fdtable->fd[count], NULL); - spin_unlock_irqrestore(&task->files->file_lock, flags); - DBG("forcing close of open file handle\n"); - filp_close(file, task->files); - spin_lock_irqsave(&task->files->file_lock, flags); - } - } - } - spin_unlock_irqrestore(&task->files->file_lock, flags); - } - } - } - - if (!IS_ERR(dev->qmi.devclass)) - device_destroy(dev->qmi.devclass, dev->qmi.devnum); - cdev_del(&dev->qmi.cdev); - unregister_chrdev_region(dev->qmi.devnum, 1); -} - -static bool qmi_ready(struct qcusbnet *dev, u16 timeout) -{ - int result; - void *wbuf; - size_t wbufsize; - void *rbuf; - u16 rbufsize; - struct semaphore sem; - u16 now; - unsigned long flags; - u8 tid; - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return -EFAULT; - } - - - for (now = 0; now < timeout; now += 100) { - sema_init(&sem, 0); - - tid = atomic_add_return(1, &dev->qmi.qmitid); - if (!tid) - tid = atomic_add_return(1, &dev->qmi.qmitid); - kfree(wbuf); - wbuf = qmictl_new_ready(tid, &wbufsize); - if (!wbuf) - return -ENOMEM; - - result = read_async(dev, QMICTL, tid, upsem, &sem); - if (result) { - kfree(wbuf); - return false; - } - - write_sync(dev, wbuf, wbufsize, QMICTL); - - msleep(100); - if (!down_trylock(&sem)) { - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - if (client_delread(dev, QMICTL, tid, &rbuf, &rbufsize)) { - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - kfree(rbuf); - break; - } - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - } else { - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - client_notify(dev, QMICTL, tid); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - } - } - - kfree(wbuf); - - if (now >= timeout) - return false; - - DBG("QMI Ready after %u milliseconds\n", now); - - /* 3580 and newer doesn't need a delay; older needs 5000ms */ - if (qcusbnet2k_fwdelay) - msleep(qcusbnet2k_fwdelay * 1000); - - return true; -} - -static void wds_callback(struct qcusbnet *dev, u16 cid, void *data) -{ - bool ret; - int result; - void *rbuf; - u16 rbufsize; - - struct net_device_stats *stats = &(dev->usbnet->net->stats); - - struct qmiwds_stats dstats = { - .txok = (u32)-1, - .rxok = (u32)-1, - .txerr = (u32)-1, - .rxerr = (u32)-1, - .txofl = (u32)-1, - .rxofl = (u32)-1, - .txbytesok = (u64)-1, - .rxbytesok = (u64)-1, - }; - unsigned long flags; - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return; - } - - spin_lock_irqsave(&dev->qmi.clients_lock, flags); - ret = client_delread(dev, cid, 0, &rbuf, &rbufsize); - spin_unlock_irqrestore(&dev->qmi.clients_lock, flags); - - if (!ret) { - ERR("WDS callback failed to get data\n"); - return; - } - - dstats.linkstate = !qc_isdown(dev, DOWN_NO_NDIS_CONNECTION); - dstats.reconfigure = false; - - result = qmiwds_event_resp(rbuf, rbufsize, &dstats); - if (result < 0) { - ERR("bad WDS packet\n"); - } else { - if (dstats.txofl != (u32)-1) - stats->tx_fifo_errors = dstats.txofl; - - if (dstats.rxofl != (u32)-1) - stats->rx_fifo_errors = dstats.rxofl; - - if (dstats.txerr != (u32)-1) - stats->tx_errors = dstats.txerr; - - if (dstats.rxerr != (u32)-1) - stats->rx_errors = dstats.rxerr; - - if (dstats.txok != (u32)-1) - stats->tx_packets = dstats.txok + stats->tx_errors; - - if (dstats.rxok != (u32)-1) - stats->rx_packets = dstats.rxok + stats->rx_errors; - - if (dstats.txbytesok != (u64)-1) - stats->tx_bytes = dstats.txbytesok; - - if (dstats.rxbytesok != (u64)-1) - stats->rx_bytes = dstats.rxbytesok; - - if (dstats.reconfigure) { - DBG("Net device link reset\n"); - qc_setdown(dev, DOWN_NO_NDIS_CONNECTION); - qc_cleardown(dev, DOWN_NO_NDIS_CONNECTION); - } else { - if (dstats.linkstate) { - DBG("Net device link is connected\n"); - qc_cleardown(dev, DOWN_NO_NDIS_CONNECTION); - } else { - DBG("Net device link is disconnected\n"); - qc_setdown(dev, DOWN_NO_NDIS_CONNECTION); - } - } - } - - kfree(rbuf); - - result = read_async(dev, cid, 0, wds_callback, data); - if (result != 0) - ERR("unable to setup next async read\n"); -} - -static int setup_wds_callback(struct qcusbnet *dev) -{ - int result; - void *buf; - size_t size; - u16 cid; - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return -EFAULT; - } - - result = client_alloc(dev, QMIWDS); - if (result < 0) - return result; - cid = result; - - buf = qmiwds_new_seteventreport(1, &size); - if (!buf) - return -ENOMEM; - - result = write_sync(dev, buf, size, cid); - kfree(buf); - - if (result < 0) - return result; - - buf = qmiwds_new_getpkgsrvcstatus(2, &size); - if (buf == NULL) - return -ENOMEM; - - result = write_sync(dev, buf, size, cid); - kfree(buf); - - if (result < 0) - return result; - - result = read_async(dev, cid, 0, wds_callback, NULL); - if (result) { - ERR("unable to setup async read\n"); - return result; - } - - result = usb_control_msg(dev->usbnet->udev, - usb_sndctrlpipe(dev->usbnet->udev, 0), - 0x22, 0x21, 1, - dev->iface->cur_altsetting->desc.bInterfaceNumber, - NULL, 0, 100); - if (result < 0) { - ERR("Bad SetControlLineState status %d\n", result); - return result; - } - - return 0; -} - -static int qmidms_getmeid(struct qcusbnet *dev) -{ - int result; - void *wbuf; - size_t wbufsize; - void *rbuf; - u16 rbufsize; - u16 cid; - - if (!device_valid(dev)) { - ERR("Invalid device\n"); - return -EFAULT; - } - - result = client_alloc(dev, QMIDMS); - if (result < 0) - return result; - cid = result; - - wbuf = qmidms_new_getmeid(1, &wbufsize); - if (!wbuf) - return -ENOMEM; - - result = write_sync(dev, wbuf, wbufsize, cid); - kfree(wbuf); - - if (result < 0) - return result; - - result = read_sync(dev, &rbuf, cid, 1); - if (result < 0) - return result; - rbufsize = result; - - result = qmidms_meid_resp(rbuf, rbufsize, &dev->meid[0], 14); - kfree(rbuf); - - if (result < 0) { - ERR("bad get MEID resp\n"); - memset(&dev->meid[0], '0', 14); - } - - client_free(dev, cid); - return 0; -} - -module_param(qcusbnet2k_fwdelay, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(qcusbnet2k_fwdelay, "Delay for old firmware"); diff --git a/drivers/net/usb/qcusbnet/qmidevice.h b/drivers/net/usb/qcusbnet/qmidevice.h deleted file mode 100644 index 5274a0dde58f..000000000000 --- a/drivers/net/usb/qcusbnet/qmidevice.h +++ /dev/null @@ -1,35 +0,0 @@ -/* qmidevice.h - gobi QMI device header - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef QCUSBNET_QMIDEVICE_H -#define QCUSBNET_QMIDEVICE_H - -#include "structs.h" -#include "qmi.h" - -void qc_setdown(struct qcusbnet *dev, u8 reason); -void qc_cleardown(struct qcusbnet *dev, u8 reason); -bool qc_isdown(struct qcusbnet *dev, u8 reason); - -int qc_startread(struct qcusbnet *dev); -void qc_stopread(struct qcusbnet *dev); - -int qc_register(struct qcusbnet *dev); -void qc_deregister(struct qcusbnet *dev); - -#endif /* !QCUSBNET_QMIDEVICE_H */ diff --git a/drivers/net/usb/qcusbnet/structs.h b/drivers/net/usb/qcusbnet/structs.h deleted file mode 100644 index 8c25c83fe108..000000000000 --- a/drivers/net/usb/qcusbnet/structs.h +++ /dev/null @@ -1,95 +0,0 @@ -/* structs.h - shared structures - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef QCUSBNET_STRUCTS_H -#define QCUSBNET_STRUCTS_H - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define DBG(fmt, arg...) \ -do { \ - if (debug == 1) \ - printk(KERN_INFO "QCUSBNet2k::%s " fmt, __func__, ##arg); \ -} while (0) - -#define ERR(fmt, arg...)\ - printk(KERN_ERR "QCUSBNet2k::%s " fmt, __func__, ##arg) - -struct qcusbnet; - -struct urbreq { - struct list_head node; - struct urb *urb; -}; - -#define DEFAULT_READ_URB_LENGTH 0x1000 - -struct worker { - struct task_struct *thread; - struct completion work; - struct list_head urbs; - spinlock_t urbs_lock; - struct urb *active; - spinlock_t active_lock; - struct usb_interface *iface; -}; - -struct qmidev { - dev_t devnum; - struct class *devclass; - struct cdev cdev; - struct urb *readurb; - struct urbsetup *readsetup; - void *readbuf; - struct urb *inturb; - void *intbuf; - struct list_head clients; - spinlock_t clients_lock; - atomic_t qmitid; -}; - -enum { - DOWN_NO_NDIS_CONNECTION = 0, - DOWN_CDC_CONNECTION_SPEED = 1, - DOWN_DRIVER_SUSPENDED = 2, - DOWN_NET_IFACE_STOPPED = 3, -}; - -struct qcusbnet { - struct usbnet *usbnet; - struct usb_interface *iface; - int (*open)(struct net_device *); - int (*stop)(struct net_device *); - unsigned long down; - bool valid; - struct qmidev qmi; - char meid[14]; - struct worker worker; -}; - -#endif /* !QCUSBNET_STRUCTS_H */ diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 2928586bcb82..1fab9672271b 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -45,7 +45,6 @@ #include #include #include -#include #define DRIVER_VERSION "22-Aug-2005" @@ -1277,16 +1276,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) struct usb_device *xdev; int status; const char *name; - struct usb_driver *driver = to_usb_driver(udev->dev.driver); - - /* usbnet already took usb runtime pm, so have to enable the feature - * for usb interface, otherwise usb_autopm_get_interface may return - * failure if USB_SUSPEND(RUNTIME_PM) is enabled. - */ - if (!driver->supports_autosuspend) { - driver->supports_autosuspend = 1; - pm_runtime_enable(&udev->dev); - } name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index a37a8293f43b..174e3442d519 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -271,7 +271,6 @@ config MWL8K source "drivers/net/wireless/ath/Kconfig" source "drivers/net/wireless/b43/Kconfig" source "drivers/net/wireless/b43legacy/Kconfig" -source "drivers/net/wireless/bcm4329/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 06cf827833cf..5d4ce4d2b32b 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -52,5 +52,3 @@ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o obj-$(CONFIG_WL12XX) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ - -obj-$(CONFIG_BCM4329) += bcm4329/ diff --git a/drivers/net/wireless/bcm4329/Kconfig b/drivers/net/wireless/bcm4329/Kconfig deleted file mode 100644 index ca5760d32385..000000000000 --- a/drivers/net/wireless/bcm4329/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -config BCM4329 - tristate "Broadcom 4329 wireless cards support" - depends on MMC - select WIRELESS_EXT - select WEXT_PRIV - ---help--- - This module adds support for wireless adapters based on - Broadcom 4329 chipset. - - This driver uses the kernel's wireless extensions subsystem. - - If you choose to build a module, it'll be called dhd. Say M if - unsure. - -config BCM4329_FW_PATH - depends on BCM4329 - string "Firmware path" - default "/system/etc/firmware/fw_bcm4329.bin" - ---help--- - Path to the firmware file. - -config BCM4329_NVRAM_PATH - depends on BCM4329 - string "NVRAM path" - default "/proc/calibration" - ---help--- - Path to the calibration file. diff --git a/drivers/net/wireless/bcm4329/Makefile b/drivers/net/wireless/bcm4329/Makefile deleted file mode 100755 index 5a662be7fc53..000000000000 --- a/drivers/net/wireless/bcm4329/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# bcm4329 -DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2 \ - -DUNRELEASEDCHIP -Dlinux -DDHD_SDALIGN=64 -DMAX_HDR_READ=64 \ - -DDHD_FIRSTREAD=64 -DDHD_GPL -DDHD_SCHED -DBDC -DTOE -DDHD_BCMEVENTS \ - -DSHOW_EVENTS -DBCMSDIO -DDHD_GPL -DBCMLXSDMMC -DBCMPLATFORM_BUS \ - -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2 \ - -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DDHD_DEBUG_TRAP -DSOFTAP \ - -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT \ - -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN -DHW_OOB \ - -DKEEP_ALIVE -DPNO_SUPPORT \ - -Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include - -DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \ - wl_iw.o siutils.o sbutils.o aiutils.o hndpmu.o bcmwifi.o dhd_sdio.o \ - dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \ - bcmsdh_sdmmc_linux.o - -obj-$(CONFIG_BCM4329) += bcm4329.o -bcm4329-objs += $(DHDOFILES) -EXTRA_CFLAGS = $(DHDCFLAGS) -EXTRA_LDFLAGS += --strip-debug diff --git a/drivers/net/wireless/bcm4329/aiutils.c b/drivers/net/wireless/bcm4329/aiutils.c deleted file mode 100644 index df48ac0d83d4..000000000000 --- a/drivers/net/wireless/bcm4329/aiutils.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: aiutils.c,v 1.6.4.7.4.6 2010/04/21 20:43:47 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -STATIC uint32 -get_asd(si_t *sih, uint32 *eromptr, uint sp, uint ad, uint st, - uint32 *addrl, uint32 *addrh, uint32 *sizel, uint32 *sizeh); - - -/* EROM parsing */ - -static uint32 -get_erom_ent(si_t *sih, uint32 *eromptr, uint32 mask, uint32 match) -{ - uint32 ent; - uint inv = 0, nom = 0; - - while (TRUE) { - ent = R_REG(si_osh(sih), (uint32 *)(uintptr)(*eromptr)); - *eromptr += sizeof(uint32); - - if (mask == 0) - break; - - if ((ent & ER_VALID) == 0) { - inv++; - continue; - } - - if (ent == (ER_END | ER_VALID)) - break; - - if ((ent & mask) == match) - break; - - nom++; - } - - SI_MSG(("%s: Returning ent 0x%08x\n", __FUNCTION__, ent)); - if (inv + nom) - SI_MSG((" after %d invalid and %d non-matching entries\n", inv, nom)); - return ent; -} - -STATIC uint32 -get_asd(si_t *sih, uint32 *eromptr, uint sp, uint ad, uint st, - uint32 *addrl, uint32 *addrh, uint32 *sizel, uint32 *sizeh) -{ - uint32 asd, sz, szd; - - asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); - if (((asd & ER_TAG1) != ER_ADD) || - (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || - ((asd & AD_ST_MASK) != st)) { - /* This is not what we want, "push" it back */ - *eromptr -= sizeof(uint32); - return 0; - } - *addrl = asd & AD_ADDR_MASK; - if (asd & AD_AG32) - *addrh = get_erom_ent(sih, eromptr, 0, 0); - else - *addrh = 0; - *sizeh = 0; - sz = asd & AD_SZ_MASK; - if (sz == AD_SZ_SZD) { - szd = get_erom_ent(sih, eromptr, 0, 0); - *sizel = szd & SD_SZ_MASK; - if (szd & SD_SG32) - *sizeh = get_erom_ent(sih, eromptr, 0, 0); - } else - *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); - - SI_MSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", - sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); - - return asd; -} - -/* parse the enumeration rom to identify all cores */ -void -ai_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii = SI_INFO(sih); - chipcregs_t *cc = (chipcregs_t *)regs; - uint32 erombase, eromptr, eromlim; - - erombase = R_REG(sii->osh, &cc->eromptr); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - eromptr = (uintptr)REG_MAP(erombase, SI_CORE_SIZE); - break; - - case PCI_BUS: - /* Set wrappers address */ - sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); - - /* Now point the window at the erom */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); - eromptr = (uint32)(uintptr)regs; - break; - - case SPI_BUS: - case SDIO_BUS: - eromptr = erombase; - break; - - case PCMCIA_BUS: - default: - SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", sih->bustype)); - ASSERT(0); - return; - } - eromlim = eromptr + ER_REMAPCONTROL; - - SI_MSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%08x, eromlim = 0x%08x\n", - regs, erombase, eromptr, eromlim)); - while (eromptr < eromlim) { - uint32 cia, cib, base, cid, mfg, crev, nmw, nsw, nmp, nsp; - uint32 mpd, asd, addrl, addrh, sizel, sizeh; - uint i, j, idx; - bool br; - - br = FALSE; - - /* Grok a component */ - cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); - if (cia == (ER_END | ER_VALID)) { - SI_MSG(("Found END of erom after %d cores\n", sii->numcores)); - return; - } - base = eromptr - sizeof(uint32); - cib = get_erom_ent(sih, &eromptr, 0, 0); - - if ((cib & ER_TAG) != ER_CI) { - SI_ERROR(("CIA not followed by CIB\n")); - goto error; - } - - cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; - mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; - crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; - nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; - nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; - nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; - nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; - - SI_MSG(("Found component 0x%04x/0x%4x rev %d at erom addr 0x%08x, with nmw = %d, " - "nsw = %d, nmp = %d & nsp = %d\n", - mfg, cid, crev, base, nmw, nsw, nmp, nsp)); - - if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) - continue; - if ((nmw + nsw == 0)) { - /* A component which is not a core */ - if (cid == OOB_ROUTER_CORE_ID) { - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, - &addrl, &addrh, &sizel, &sizeh); - if (asd != 0) { - sii->common_info->oob_router = addrl; - } - } - continue; - } - - idx = sii->numcores; -/* sii->eromptr[idx] = base; */ - sii->common_info->cia[idx] = cia; - sii->common_info->cib[idx] = cib; - sii->common_info->coreid[idx] = cid; - - for (i = 0; i < nmp; i++) { - mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); - if ((mpd & ER_TAG) != ER_MP) { - SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); - goto error; - } - SI_MSG((" Master port %d, mp: %d id: %d\n", i, - (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, - (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); - } - - /* First Slave Address Descriptor should be port 0: - * the main register space for the core - */ - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); - if (asd == 0) { - /* Try again to see if it is a bridge */ - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, - &sizel, &sizeh); - if (asd != 0) - br = TRUE; - else - if ((addrh != 0) || (sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("First Slave ASD for core 0x%04x malformed " - "(0x%08x)\n", cid, asd)); - goto error; - } - } - sii->common_info->coresba[idx] = addrl; - sii->common_info->coresba_size[idx] = sizel; - /* Get any more ASDs in port 0 */ - j = 1; - do { - asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) - sii->common_info->coresba2[idx] = addrl; - sii->common_info->coresba2_size[idx] = sizel; - j++; - } while (asd != 0); - - /* Go through the ASDs for other slave ports */ - for (i = 1; i < nsp; i++) { - j = 0; - do { - asd = get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - } while (asd != 0); - if (j == 0) { - SI_ERROR((" SP %d has no address descriptors\n", i)); - goto error; - } - } - - /* Now get master wrappers */ - for (i = 0; i < nmw; i++) { - asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for MW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Master wrapper %d is not 4KB\n", i)); - goto error; - } - if (i == 0) - sii->common_info->wrapba[idx] = addrl; - } - - /* And finally slave wrappers */ - for (i = 0; i < nsw; i++) { - uint fwp = (nsp == 1) ? 0 : 1; - asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for SW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); - goto error; - } - if ((nmw == 0) && (i == 0)) - sii->common_info->wrapba[idx] = addrl; - } - - /* Don't record bridges */ - if (br) - continue; - - /* Done with core */ - sii->numcores++; - } - - SI_ERROR(("Reached end of erom without finding END")); - -error: - sii->numcores = 0; - return; -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -void * -ai_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii = SI_INFO(sih); - uint32 addr = sii->common_info->coresba[coreidx]; - uint32 wrap = sii->common_info->wrapba[coreidx]; - void *regs; - - if (coreidx >= sii->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - switch (BUSTYPE(sih->bustype)) { - case SI_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - sii->curmap = regs = sii->common_info->regs[coreidx]; - if (!sii->common_info->wrappers[coreidx]) { - sii->common_info->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->wrappers[coreidx])); - } - sii->curwrap = sii->common_info->wrappers[coreidx]; - break; - - - case SPI_BUS: - case SDIO_BUS: - sii->curmap = regs = (void *)((uintptr)addr); - sii->curwrap = (void *)((uintptr)wrap); - break; - - case PCMCIA_BUS: - default: - ASSERT(0); - regs = NULL; - break; - } - - sii->curmap = regs; - sii->curidx = coreidx; - - return regs; -} - -/* Return the number of address spaces in current core */ -int -ai_numaddrspaces(si_t *sih) -{ - return 2; -} - -/* Return the address of the nth address space in the current core */ -uint32 -ai_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->common_info->coresba[cidx]; - else if (asidx == 1) - return sii->common_info->coresba2[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - -/* Return the size of the nth address space in the current core */ -uint32 -ai_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->common_info->coresba_size[cidx]; - else if (asidx == 1) - return sii->common_info->coresba2_size[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", - __FUNCTION__, asidx)); - return 0; - } -} - -uint -ai_flag(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); -} - -void -ai_setint(si_t *sih, int siflag) -{ -} - -void -ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val) -{ - si_info_t *sii = SI_INFO(sih); - aidmp_t *ai = sii->curwrap; - W_REG(sii->osh, (uint32 *)((uint8 *)ai+offset), val); - return; -} - -uint -ai_corevendor(si_t *sih) -{ - si_info_t *sii; - uint32 cia; - - sii = SI_INFO(sih); - cia = sii->common_info->cia[sii->curidx]; - return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); -} - -uint -ai_corerev(si_t *sih) -{ - si_info_t *sii; - uint32 cib; - - sii = SI_INFO(sih); - cib = sii->common_info->cib[sii->curidx]; - return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); -} - -bool -ai_iscoreup(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && - ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint -ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sih->bustype) == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = TRUE; - /* map if does not exist */ - if (!sii->common_info->wrappers[coreidx]) { - sii->common_info->regs[coreidx] = - REG_MAP(sii->common_info->coresba[coreidx], SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->common_info->regs[coreidx] + regoff); - } else if (BUSTYPE(sih->bustype) == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->common_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - - /* readback */ - w = R_REG(sii->osh, r); - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - ai_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -void -ai_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - aidmp_t *ai; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* if core is already in reset, just return */ - if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) - return; - - W_REG(sii->osh, &ai->ioctrl, bits); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(10); - - W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); - OSL_DELAY(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void -ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - aidmp_t *ai; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - ai_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - W_REG(sii->osh, &ai->resetctrl, 0); - OSL_DELAY(1); - - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - OSL_DELAY(1); -} - - -void -ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } -} - -uint32 -ai_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); - } - - return R_REG(sii->osh, &ai->ioctrl); -} - -uint32 -ai_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - aidmp_t *ai; - uint32 w; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - if (mask || val) { - w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); - W_REG(sii->osh, &ai->iostatus, w); - } - - return R_REG(sii->osh, &ai->iostatus); -} diff --git a/drivers/net/wireless/bcm4329/bcmpcispi.c b/drivers/net/wireless/bcm4329/bcmpcispi.c deleted file mode 100644 index 1a8b6717f924..000000000000 --- a/drivers/net/wireless/bcm4329/bcmpcispi.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Broadcom SPI over PCI-SPI Host Controller, low-level hardware driver - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmpcispi.c,v 1.22.2.4.4.5.6.1 2010/08/13 00:26:05 Exp $ - */ - -#include -#include - -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include -#include -#include -#include /* BRCM PCI-SPI Host Controller Register definitions */ - - -/* ndis_osl.h needs to do a runtime check of the osh to map - * R_REG/W_REG to bus specific access similar to linux_osl.h. - * Until then... - */ -/* linux */ - -#define SPIPCI_RREG R_REG -#define SPIPCI_WREG W_REG - - -#define SPIPCI_ANDREG(osh, r, v) SPIPCI_WREG(osh, (r), (SPIPCI_RREG(osh, r) & (v))) -#define SPIPCI_ORREG(osh, r, v) SPIPCI_WREG(osh, (r), (SPIPCI_RREG(osh, r) | (v))) - - -int bcmpcispi_dump = 0; /* Set to dump complete trace of all SPI bus transactions */ - -typedef struct spih_info_ { - uint bar0; /* BAR0 of PCI Card */ - uint bar1; /* BAR1 of PCI Card */ - osl_t *osh; /* osh handle */ - spih_pciregs_t *pciregs; /* PCI Core Registers */ - spih_regs_t *regs; /* SPI Controller Registers */ - uint8 rev; /* PCI Card Revision ID */ -} spih_info_t; - - -/* Attach to PCI-SPI Host Controller Hardware */ -bool -spi_hw_attach(sdioh_info_t *sd) -{ - osl_t *osh; - spih_info_t *si; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - osh = sd->osh; - - if ((si = (spih_info_t *)MALLOC(osh, sizeof(spih_info_t))) == NULL) { - sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); - return FALSE; - } - - bzero(si, sizeof(spih_info_t)); - - sd->controller = si; - - si->osh = sd->osh; - si->rev = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_REV, 4) & 0xFF; - - if (si->rev < 3) { - sd_err(("Host controller %d not supported, please upgrade to rev >= 3\n", si->rev)); - MFREE(osh, si, sizeof(spih_info_t)); - return (FALSE); - } - - sd_err(("Attaching to Generic PCI SPI Host Controller Rev %d\n", si->rev)); - - /* FPGA Revision < 3 not supported by driver anymore. */ - ASSERT(si->rev >= 3); - - si->bar0 = sd->bar0; - - /* Rev < 10 PciSpiHost has 2 BARs: - * BAR0 = PCI Core Registers - * BAR1 = PciSpiHost Registers (all other cores on backplane) - * - * Rev 10 and up use a different PCI core which only has a single - * BAR0 which contains the PciSpiHost Registers. - */ - if (si->rev < 10) { - si->pciregs = (spih_pciregs_t *)spi_reg_map(osh, - (uintptr)si->bar0, - sizeof(spih_pciregs_t)); - sd_err(("Mapped PCI Core regs to BAR0 at %p\n", si->pciregs)); - - si->bar1 = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR1, 4); - si->regs = (spih_regs_t *)spi_reg_map(osh, - (uintptr)si->bar1, - sizeof(spih_regs_t)); - sd_err(("Mapped SPI Controller regs to BAR1 at %p\n", si->regs)); - } else { - si->regs = (spih_regs_t *)spi_reg_map(osh, - (uintptr)si->bar0, - sizeof(spih_regs_t)); - sd_err(("Mapped SPI Controller regs to BAR0 at %p\n", si->regs)); - si->pciregs = NULL; - } - /* Enable SPI Controller, 16.67MHz SPI Clock */ - SPIPCI_WREG(osh, &si->regs->spih_ctrl, 0x000000d1); - - /* Set extended feature register to defaults */ - SPIPCI_WREG(osh, &si->regs->spih_ext, 0x00000000); - - /* Set GPIO CS# High (de-asserted) */ - SPIPCI_WREG(osh, &si->regs->spih_gpio_data, SPIH_CS); - - /* set GPIO[0] to output for CS# */ - /* set GPIO[1] to output for power control */ - /* set GPIO[2] to input for card detect */ - SPIPCI_WREG(osh, &si->regs->spih_gpio_ctrl, (SPIH_CS | SPIH_SLOT_POWER)); - - /* Clear out the Read FIFO in case there is any stuff left in there from a previous run. */ - while ((SPIPCI_RREG(osh, &si->regs->spih_stat) & SPIH_RFEMPTY) == 0) { - SPIPCI_RREG(osh, &si->regs->spih_data); - } - - /* Wait for power to stabilize to the SDIO Card (100msec was insufficient) */ - OSL_DELAY(250000); - - /* Check card detect on FPGA Revision >= 4 */ - if (si->rev >= 4) { - if (SPIPCI_RREG(osh, &si->regs->spih_gpio_data) & SPIH_CARD_DETECT) { - sd_err(("%s: no card detected in SD slot\n", __FUNCTION__)); - spi_reg_unmap(osh, (uintptr)si->regs, sizeof(spih_regs_t)); - if (si->pciregs) { - spi_reg_unmap(osh, (uintptr)si->pciregs, sizeof(spih_pciregs_t)); - } - MFREE(osh, si, sizeof(spih_info_t)); - return FALSE; - } - } - - /* Interrupts are level sensitive */ - SPIPCI_WREG(osh, &si->regs->spih_int_edge, 0x80000000); - - /* Interrupts are active low. */ - SPIPCI_WREG(osh, &si->regs->spih_int_pol, 0x40000004); - - /* Enable interrupts through PCI Core. */ - if (si->pciregs) { - SPIPCI_WREG(osh, &si->pciregs->ICR, PCI_INT_PROP_EN); - } - - sd_trace(("%s: exit\n", __FUNCTION__)); - return TRUE; -} - -/* Detach and return PCI-SPI Hardware to unconfigured state */ -bool -spi_hw_detach(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - spih_pciregs_t *pciregs = si->pciregs; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - SPIPCI_WREG(osh, ®s->spih_ctrl, 0x00000010); - SPIPCI_WREG(osh, ®s->spih_gpio_ctrl, 0x00000000); /* Disable GPIO for CS# */ - SPIPCI_WREG(osh, ®s->spih_int_mask, 0x00000000); /* Clear Intmask */ - SPIPCI_WREG(osh, ®s->spih_hex_disp, 0x0000DEAF); - SPIPCI_WREG(osh, ®s->spih_int_edge, 0x00000000); - SPIPCI_WREG(osh, ®s->spih_int_pol, 0x00000000); - SPIPCI_WREG(osh, ®s->spih_hex_disp, 0x0000DEAD); - - /* Disable interrupts through PCI Core. */ - if (si->pciregs) { - SPIPCI_WREG(osh, &pciregs->ICR, 0x00000000); - spi_reg_unmap(osh, (uintptr)pciregs, sizeof(spih_pciregs_t)); - } - spi_reg_unmap(osh, (uintptr)regs, sizeof(spih_regs_t)); - - MFREE(osh, si, sizeof(spih_info_t)); - - sd->controller = NULL; - - sd_trace(("%s: exit\n", __FUNCTION__)); - return TRUE; -} - -/* Switch between internal (PCI) and external clock oscillator */ -static bool -sdspi_switch_clock(sdioh_info_t *sd, bool ext_clk) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - /* Switch to desired clock, and reset the PLL. */ - SPIPCI_WREG(osh, ®s->spih_pll_ctrl, ext_clk ? SPIH_EXT_CLK : 0); - - SPINWAIT(((SPIPCI_RREG(osh, ®s->spih_pll_status) & SPIH_PLL_LOCKED) - != SPIH_PLL_LOCKED), 1000); - if ((SPIPCI_RREG(osh, ®s->spih_pll_status) & SPIH_PLL_LOCKED) != SPIH_PLL_LOCKED) { - sd_err(("%s: timeout waiting for PLL to lock\n", __FUNCTION__)); - return (FALSE); - } - return (TRUE); - -} - -/* Configure PCI-SPI Host Controller's SPI Clock rate as a divisor into the - * base clock rate. The base clock is either the PCI Clock (33MHz) or the - * external clock oscillator at U17 on the PciSpiHost. - */ -bool -spi_start_clock(sdioh_info_t *sd, uint16 div) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint32 t, espr, disp; - uint32 disp_xtal_freq; - bool ext_clock = FALSE; - char disp_string[5]; - - if (div > 2048) { - sd_err(("%s: divisor %d too large; using max of 2048\n", __FUNCTION__, div)); - div = 2048; - } else if (div & (div - 1)) { /* Not a power of 2? */ - /* Round up to a power of 2 */ - while ((div + 1) & div) - div |= div >> 1; - div++; - } - - /* For FPGA Rev >= 5, the use of an external clock oscillator is supported. - * If the oscillator is populated, use it to provide the SPI base clock, - * otherwise, default to the PCI clock as the SPI base clock. - */ - if (si->rev >= 5) { - uint32 clk_tick; - /* Enable the External Clock Oscillator as PLL clock source. */ - if (!sdspi_switch_clock(sd, TRUE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - - /* Check to make sure the external clock is running. If not, then it - * is not populated on the card, so we will default to the PCI clock. - */ - clk_tick = SPIPCI_RREG(osh, ®s->spih_clk_count); - if (clk_tick == SPIPCI_RREG(osh, ®s->spih_clk_count)) { - - /* Switch back to the PCI clock as the clock source. */ - if (!sdspi_switch_clock(sd, FALSE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - } else { - ext_clock = TRUE; - } - } - - /* Hack to allow hot-swapping oscillators: - * 1. Force PCI clock as clock source, using sd_divisor of 0. - * 2. Swap oscillator - * 3. Set desired sd_divisor (will switch to external oscillator as clock source. - */ - if (div == 0) { - ext_clock = FALSE; - div = 2; - - /* Select PCI clock as the clock source. */ - if (!sdspi_switch_clock(sd, FALSE)) { - sd_err(("%s: error switching to external clock\n", __FUNCTION__)); - } - - sd_err(("%s: Ok to hot-swap oscillators.\n", __FUNCTION__)); - } - - /* If using the external oscillator, read the clock frequency from the controller - * The value read is in units of 10000Hz, and it's not a nice round number because - * it is calculated by the FPGA. So to make up for that, we round it off. - */ - if (ext_clock == TRUE) { - uint32 xtal_freq; - - OSL_DELAY(1000); - xtal_freq = SPIPCI_RREG(osh, ®s->spih_xtal_freq) * 10000; - - sd_info(("%s: Oscillator is %dHz\n", __FUNCTION__, xtal_freq)); - - - disp_xtal_freq = xtal_freq / 10000; - - /* Round it off to a nice number. */ - if ((disp_xtal_freq % 100) > 50) { - disp_xtal_freq += 100; - } - - disp_xtal_freq = (disp_xtal_freq / 100) * 100; - } else { - sd_err(("%s: no external oscillator installed, using PCI clock.\n", __FUNCTION__)); - disp_xtal_freq = 3333; - } - - /* Convert the SPI Clock frequency to BCD format. */ - sprintf(disp_string, "%04d", disp_xtal_freq / div); - - disp = (disp_string[0] - '0') << 12; - disp |= (disp_string[1] - '0') << 8; - disp |= (disp_string[2] - '0') << 4; - disp |= (disp_string[3] - '0'); - - /* Select the correct ESPR register value based on the divisor. */ - switch (div) { - case 1: espr = 0x0; break; - case 2: espr = 0x1; break; - case 4: espr = 0x2; break; - case 8: espr = 0x5; break; - case 16: espr = 0x3; break; - case 32: espr = 0x4; break; - case 64: espr = 0x6; break; - case 128: espr = 0x7; break; - case 256: espr = 0x8; break; - case 512: espr = 0x9; break; - case 1024: espr = 0xa; break; - case 2048: espr = 0xb; break; - default: espr = 0x0; ASSERT(0); break; - } - - t = SPIPCI_RREG(osh, ®s->spih_ctrl); - t &= ~3; - t |= espr & 3; - SPIPCI_WREG(osh, ®s->spih_ctrl, t); - - t = SPIPCI_RREG(osh, ®s->spih_ext); - t &= ~3; - t |= (espr >> 2) & 3; - SPIPCI_WREG(osh, ®s->spih_ext, t); - - SPIPCI_WREG(osh, ®s->spih_hex_disp, disp); - - /* For Rev 8, writing to the PLL_CTRL register resets - * the PLL, and it can re-acquire in 200uS. For - * Rev 7 and older, we use a software delay to allow - * the PLL to re-acquire, which takes more than 2mS. - */ - if (si->rev < 8) { - /* Wait for clock to settle. */ - OSL_DELAY(5000); - } - - sd_info(("%s: SPI_CTRL=0x%08x SPI_EXT=0x%08x\n", - __FUNCTION__, - SPIPCI_RREG(osh, ®s->spih_ctrl), - SPIPCI_RREG(osh, ®s->spih_ext))); - - return TRUE; -} - -/* Configure PCI-SPI Host Controller High-Speed Clocking mode setting */ -bool -spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - if (si->rev >= 10) { - if (hsmode) { - SPIPCI_ORREG(osh, ®s->spih_ext, 0x10); - } else { - SPIPCI_ANDREG(osh, ®s->spih_ext, ~0x10); - } - } - - return TRUE; -} - -/* Disable device interrupt */ -void -spi_devintr_off(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - sd->intmask &= ~SPIH_DEV_INTR; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); /* Clear Intmask */ - } -} - -/* Enable device interrupt */ -void -spi_devintr_on(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - - ASSERT(sd->lockcount == 0); - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - if (SPIPCI_RREG(osh, ®s->spih_ctrl) & 0x02) { - /* Ack in case one was pending but is no longer... */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_DEV_INTR); - } - sd->intmask |= SPIH_DEV_INTR; - /* Set device intr in Intmask */ - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - } -} - -/* Check to see if an interrupt belongs to the PCI-SPI Host or a SPI Device */ -bool -spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - bool ours = FALSE; - - uint32 raw_int, cur_int; - ASSERT(sd); - - if (is_dev_intr) - *is_dev_intr = FALSE; - raw_int = SPIPCI_RREG(osh, ®s->spih_int_status); - cur_int = raw_int & sd->intmask; - if (cur_int & SPIH_DEV_INTR) { - if (sd->client_intr_enabled && sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - if (is_dev_intr) - *is_dev_intr = TRUE; - } else { - sd_trace(("%s: Not ready for intr: enabled %d, handler 0x%p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_DEV_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - ours = TRUE; - } else if (cur_int & SPIH_CTLR_INTR) { - /* Interrupt is from SPI FIFO... just clear and ack it... */ - sd_trace(("%s: SPI CTLR interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - - /* Clear the interrupt in the SPI_STAT register */ - SPIPCI_WREG(osh, ®s->spih_stat, 0x00000080); - - /* Ack the interrupt in the interrupt controller */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_CTLR_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - - ours = TRUE; - } else if (cur_int & SPIH_WFIFO_INTR) { - sd_trace(("%s: SPI WR FIFO Empty interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - - /* Disable the FIFO Empty Interrupt */ - sd->intmask &= ~SPIH_WFIFO_INTR; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - - sd->local_intrcount++; - sd->got_hcint = TRUE; - ours = TRUE; - } else { - /* Not an error: can share interrupts... */ - sd_trace(("%s: Not my interrupt: raw_int 0x%08x cur_int 0x%08x\n", - __FUNCTION__, raw_int, cur_int)); - ours = FALSE; - } - - return ours; -} - -static void -hexdump(char *pfx, unsigned char *msg, int msglen) -{ - int i, col; - char buf[80]; - - ASSERT(strlen(pfx) + 49 <= sizeof(buf)); - - col = 0; - - for (i = 0; i < msglen; i++, col++) { - if (col % 16 == 0) - strcpy(buf, pfx); - sprintf(buf + strlen(buf), "%02x", msg[i]); - if ((col + 1) % 16 == 0) - printf("%s\n", buf); - else - sprintf(buf + strlen(buf), " "); - } - - if (col % 16 != 0) - printf("%s\n", buf); -} - -/* Send/Receive an SPI Packet */ -void -spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint32 count; - uint32 spi_data_out; - uint32 spi_data_in; - bool yield; - - sd_trace(("%s: enter\n", __FUNCTION__)); - - if (bcmpcispi_dump) { - printf("SENDRECV(len=%d)\n", msglen); - hexdump(" OUT: ", msg_out, msglen); - } - -#ifdef BCMSDYIELD - /* Only yield the CPU and wait for interrupt on Rev 8 and newer FPGA images. */ - yield = ((msglen > 500) && (si->rev >= 8)); -#else - yield = FALSE; -#endif /* BCMSDYIELD */ - - ASSERT(msglen % 4 == 0); - - - SPIPCI_ANDREG(osh, ®s->spih_gpio_data, ~SPIH_CS); /* Set GPIO CS# Low (asserted) */ - - for (count = 0; count < (uint32)msglen/4; count++) { - spi_data_out = ((uint32)((uint32 *)msg_out)[count]); - SPIPCI_WREG(osh, ®s->spih_data, spi_data_out); - } - -#ifdef BCMSDYIELD - if (yield) { - /* Ack the interrupt in the interrupt controller */ - SPIPCI_WREG(osh, ®s->spih_int_status, SPIH_WFIFO_INTR); - SPIPCI_RREG(osh, ®s->spih_int_status); - - /* Enable the FIFO Empty Interrupt */ - sd->intmask |= SPIH_WFIFO_INTR; - sd->got_hcint = FALSE; - SPIPCI_WREG(osh, ®s->spih_int_mask, sd->intmask); - - } -#endif /* BCMSDYIELD */ - - /* Wait for write fifo to empty... */ - SPIPCI_ANDREG(osh, ®s->spih_gpio_data, ~0x00000020); /* Set GPIO 5 Low */ - - if (yield) { - ASSERT((SPIPCI_RREG(sd->osh, ®s->spih_stat) & SPIH_WFEMPTY) == 0); - } - - spi_waitbits(sd, yield); - SPIPCI_ORREG(osh, ®s->spih_gpio_data, 0x00000020); /* Set GPIO 5 High (de-asserted) */ - - for (count = 0; count < (uint32)msglen/4; count++) { - spi_data_in = SPIPCI_RREG(osh, ®s->spih_data); - ((uint32 *)msg_in)[count] = spi_data_in; - } - - /* Set GPIO CS# High (de-asserted) */ - SPIPCI_ORREG(osh, ®s->spih_gpio_data, SPIH_CS); - - if (bcmpcispi_dump) { - hexdump(" IN : ", msg_in, msglen); - } -} - -void -spi_spinbits(sdioh_info_t *sd) -{ - spih_info_t *si = (spih_info_t *)sd->controller; - osl_t *osh = si->osh; - spih_regs_t *regs = si->regs; - uint spin_count; /* Spin loop bound check */ - - spin_count = 0; - while ((SPIPCI_RREG(sd->osh, ®s->spih_stat) & SPIH_WFEMPTY) == 0) { - if (spin_count > SPI_SPIN_BOUND) { - sd_err(("%s: SPIH_WFEMPTY spin bits out of bound %u times \n", - __FUNCTION__, spin_count)); - ASSERT(FALSE); - } - spin_count++; - } - - /* Wait for SPI Transfer state machine to return to IDLE state. - * The state bits are only implemented in Rev >= 5 FPGA. These - * bits are hardwired to 00 for Rev < 5, so this check doesn't cause - * any problems. - */ - spin_count = 0; - while ((SPIPCI_RREG(osh, ®s->spih_stat) & SPIH_STATE_MASK) != 0) { - if (spin_count > SPI_SPIN_BOUND) { - sd_err(("%s: SPIH_STATE_MASK spin bits out of bound %u times \n", - __FUNCTION__, spin_count)); - ASSERT(FALSE); - } - spin_count++; - } -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh.c b/drivers/net/wireless/bcm4329/bcmsdh.c deleted file mode 100644 index 4bf5889e5a68..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * BCMSDH interface glue - * implement bcmsdh API for SDIOH driver - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh.c,v 1.35.2.1.4.8.6.13 2010/04/06 03:26:57 Exp $ - */ -/* ****************** BCMSDH Interface Functions *************************** */ - -#include -#include -#include -#include -#include -#include -#include - -#include /* BRCM API for SDIO clients (such as wl, dhd) */ -#include /* common SDIO/controller interface */ -#include /* BRCM sdio device core */ - -#include /* sdio spec */ - -#define SDIOH_API_ACCESS_RETRY_LIMIT 2 -const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; - - -struct bcmsdh_info -{ - bool init_success; /* underlying driver successfully attached */ - void *sdioh; /* handler for sdioh */ - uint32 vendevid; /* Target Vendor and Device ID on SD bus */ - osl_t *osh; - bool regfail; /* Save status of last reg_read/reg_write call */ - uint32 sbwad; /* Save backplane window address */ -}; -/* local copy of bcm sd handler */ -bcmsdh_info_t * l_bcmsdh = NULL; - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern int -sdioh_enable_hw_oob_intr(void *sdioh, bool enable); - -void -bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) -{ - sdioh_enable_hw_oob_intr(sdh->sdioh, enable); -} -#endif - -bcmsdh_info_t * -bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) -{ - bcmsdh_info_t *bcmsdh; - - if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) { - BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)bcmsdh, sizeof(bcmsdh_info_t)); - - /* save the handler locally */ - l_bcmsdh = bcmsdh; - - if (!(bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq))) { - bcmsdh_detach(osh, bcmsdh); - return NULL; - } - - bcmsdh->osh = osh; - bcmsdh->init_success = TRUE; - - *regsva = (uint32 *)SI_ENUM_BASE; - - /* Report the BAR, to fix if needed */ - bcmsdh->sbwad = SI_ENUM_BASE; - return bcmsdh; -} - -int -bcmsdh_detach(osl_t *osh, void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (bcmsdh != NULL) { - if (bcmsdh->sdioh) { - sdioh_detach(osh, bcmsdh->sdioh); - bcmsdh->sdioh = NULL; - } - MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t)); - } - - l_bcmsdh = NULL; - return 0; -} - -int -bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set); -} - -bool -bcmsdh_intr_query(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - bool on; - - ASSERT(bcmsdh); - status = sdioh_interrupt_query(bcmsdh->sdioh, &on); - if (SDIOH_API_SUCCESS(status)) - return FALSE; - else - return on; -} - -int -bcmsdh_intr_enable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_disable(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_intr_dereg(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_deregister(bcmsdh->sdioh); - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -#if defined(DHD_DEBUG) -bool -bcmsdh_intr_pending(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - ASSERT(sdh); - return sdioh_interrupt_pending(bcmsdh->sdioh); -} -#endif - - -int -bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - ASSERT(sdh); - - /* don't support yet */ - return BCME_UNSUPPORTED; -} - -uint8 -bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - uint8 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - int32 retry = 0; -#endif - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - do { - if (retry) /* wait for 1 ms till bus get settled down */ - OSL_DELAY(1000); -#endif - status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif - if (err) - *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); -} - -uint32 -bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 data = 0; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, - fnc_num, addr, data)); - - return data; -} - -void -bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num, - addr, &data, 4); - - if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num, - addr, data)); -} - - -int -bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - uint8 *tmp_buf, *tmp_ptr; - uint8 *ptr; - bool ascii = func & ~0xf; - func &= 0x7; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - ASSERT(cis); - ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT); - - status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length); - - if (ascii) { - /* Move binary bits to tmp and format them into the provided buffer. */ - if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) { - BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__)); - return BCME_NOMEM; - } - bcopy(cis, tmp_buf, length); - for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) { - ptr += sprintf((char*)ptr, "%.2x ", *tmp_ptr & 0xff); - if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0) - ptr += sprintf((char *)ptr, "\n"); - } - MFREE(bcmsdh->osh, tmp_buf, length); - } - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - - -static int -bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address) -{ - int err = 0; - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - - - return err; -} - -uint32 -bcmsdh_reg_read(void *sdh, uint32 addr, uint size) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint32 word = 0; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0)) - return 0xFFFFFFFF; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, - SDIOH_READ, SDIO_FUNC_1, addr, &word, size); - - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - BCMSDH_INFO(("uint32data = 0x%x\n", word)); - - /* if ok, return appropriately masked word */ - if (SDIOH_API_SUCCESS(status)) { - switch (size) { - case sizeof(uint8): - return (word & 0xff); - case sizeof(uint16): - return (word & 0xffff); - case sizeof(uint32): - return word; - default: - bcmsdh->regfail = TRUE; - - } - } - - /* otherwise, bad sdio access or invalid size */ - BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size)); - return 0xFFFFFFFF; -} - -uint32 -bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", - __FUNCTION__, addr, size*8, data)); - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - if (size == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, - addr, &data, size); - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); - - if (SDIOH_API_SUCCESS(status)) - return 0; - - BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", - __FUNCTION__, data, addr, size)); - return 0xFFFFFFFF; -} - -bool -bcmsdh_regfail(void *sdh) -{ - return ((bcmsdh_info_t *)sdh)->regfail; -} - -int -bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_READ, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -} - -int -bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - uint incr_fix; - uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - int err = 0; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __FUNCTION__, fn, addr, nbytes)); - - /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); - if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; - - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - - incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - SDIOH_API_RC status; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0); - - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC, - (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, - addr, 4, nbytes, buf, NULL); - - return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -} - -int -bcmsdh_abort(void *sdh, uint fn) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_abort(bcmsdh->sdioh, fn); -} - -int -bcmsdh_start(void *sdh, int stage) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_start(bcmsdh->sdioh, stage); -} - -int -bcmsdh_stop(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_stop(bcmsdh->sdioh); -} - - -int -bcmsdh_query_device(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; - return (bcmsdh->vendevid); -} - -uint -bcmsdh_query_iofnum(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (sdioh_query_iofnum(bcmsdh->sdioh)); -} - -int -bcmsdh_reset(bcmsdh_info_t *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - return sdioh_sdio_reset(bcmsdh->sdioh); -} - -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh) -{ - ASSERT(sdh); - return sdh->sdioh; -} - -/* Function to pass device-status bits to DHD. */ -uint32 -bcmsdh_get_dstatus(void *sdh) -{ - return 0; -} -uint32 -bcmsdh_cur_sbwad(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return (bcmsdh->sbwad); -} - -void -bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev) -{ - return; -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_linux.c deleted file mode 100644 index 94f19a1c46a4..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_linux.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * SDIO access interface for drivers - linux specific (pci only) - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $ - */ - -/** - * @file bcmsdh_linux.c - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#if defined(OOB_INTR_ONLY) -#include -extern void dhdsdio_isr(void * args); -#include -#include -#include -#endif /* defined(OOB_INTR_ONLY) */ -#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270) -#if !defined(BCMPLATFORM_BUS) -#define BCMPLATFORM_BUS -#endif /* !defined(BCMPLATFORM_BUS) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -#include -#endif /* KERNEL_VERSION(2, 6, 19) */ -#endif /* CONFIG_MACH_SANDGATE2G || CONFIG_MACH_LOGICPD_PXA270 */ - -/** - * SDIO Host Controller info - */ -typedef struct bcmsdh_hc bcmsdh_hc_t; - -struct bcmsdh_hc { - bcmsdh_hc_t *next; -#ifdef BCMPLATFORM_BUS - struct device *dev; /* platform device handle */ -#else - struct pci_dev *dev; /* pci device handle */ -#endif /* BCMPLATFORM_BUS */ - osl_t *osh; - void *regs; /* SDIO Host Controller address */ - bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ - void *ch; - unsigned int oob_irq; - unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ - bool oob_irq_registered; -#if defined(OOB_INTR_ONLY) - spinlock_t irq_lock; -#endif -}; -static bcmsdh_hc_t *sdhcinfo = NULL; - -/* driver info, initialized when bcmsdh_register is called */ -static bcmsdh_driver_t drvinfo = {NULL, NULL}; - -/* debugging macros */ -#define SDLX_MSG(x) - -/** - * Checks to see if vendor and device IDs match a supported SDIO Host Controller. - */ -bool -bcmsdh_chipmatch(uint16 vendor, uint16 device) -{ - /* Add other vendors and devices as required */ - -#ifdef BCMSDIOH_STD - /* Check for Arasan host controller */ - if (vendor == VENDOR_SI_IMAGE) { - return (TRUE); - } - /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { - return (TRUE); - } - /* Check for TI PCIxx21 Standard host controller */ - if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { - return (TRUE); - } - if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { - return (TRUE); - } - /* Ricoh R5C822 Standard SDIO Host */ - if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { - return (TRUE); - } - /* JMicron Standard SDIO Host */ - if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { - return (TRUE); - } - -#endif /* BCMSDIOH_STD */ -#ifdef BCMSDIOH_SPI - /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { - printf("Found PCI SPI Host Controller\n"); - return (TRUE); - } - -#endif /* BCMSDIOH_SPI */ - - return (FALSE); -} - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) -/* forward declarations */ -int bcmsdh_probe(struct device *dev); -int bcmsdh_remove(struct device *dev); - -EXPORT_SYMBOL(bcmsdh_probe); -EXPORT_SYMBOL(bcmsdh_remove); - -#else -/* forward declarations */ -static int __devinit bcmsdh_probe(struct device *dev); -static int __devexit bcmsdh_remove(struct device *dev); -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static struct device_driver bcmsdh_driver = { - .name = "pxa2xx-mci", - .bus = &platform_bus_type, - .probe = bcmsdh_probe, - .remove = bcmsdh_remove, - .suspend = NULL, - .resume = NULL, - }; -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_probe(struct device *dev) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs = 0; - bcmsdh_info_t *sdh = NULL; -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - struct platform_device *pdev; - struct resource *r; -#endif /* BCMLXSDMMC */ - int irq = 0; - uint32 vendevid; - unsigned long irq_flags = 0; - -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - pdev = to_platform_device(dev); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!r || irq == NO_IRQ) - return -ENXIO; -#endif /* BCMLXSDMMC */ - -#if defined(OOB_INTR_ONLY) -#ifdef HW_OOB - irq_flags = \ - IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; -#else - irq_flags = IRQF_TRIGGER_FALLING; -#endif /* HW_OOB */ - irq = dhd_customer_oob_irq_map(&irq_flags); - if (irq < 0) { - SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); - return 1; - } -#endif /* defined(OOB_INTR_ONLY) */ - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = (void *)dev; - -#ifdef BCMLXSDMMC - if (!(sdh = bcmsdh_attach(osh, (void *)0, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#else - if (!(sdh = bcmsdh_attach(osh, (void *)r->start, - (void **)®s, irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } -#endif /* BCMLXSDMMC */ - sdhc->sdh = sdh; - sdhc->oob_irq = irq; - sdhc->oob_flags = irq_flags; - sdhc->oob_irq_registered = FALSE; /* to make sure.. */ -#if defined(OOB_INTR_ONLY) - spin_lock_init(&sdhc->irq_lock); -#endif - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - /* Read the vendor/device ID from the CIS */ - vendevid = bcmsdh_query_device(sdh); - - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), - (vendevid & 0xFFFF), 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - return 0; - - /* error handling */ -err: - if (sdhc) { - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - } - if (osh) - osl_detach(osh); - return -ENODEV; -} - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_remove(struct device *dev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - sdhc = sdhcinfo; - drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->osh, sdhc->sdh); - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == (void *)dev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) { - SDLX_MSG(("%s: failed\n", __FUNCTION__)); - return 0; - } - - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); - -#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) - dev_set_drvdata(dev, NULL); -#endif /* !defined(BCMLXSDMMC) */ - - return 0; -} - -#else /* BCMPLATFORM_BUS */ - -#if !defined(BCMLXSDMMC) -/* forward declarations for PCI probe and remove functions. */ -static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); - -/** - * pci id table - */ -static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { - { vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - class: 0, - class_mask: 0, - driver_data: 0, - }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); - -/** - * SDIO Host Controller pci driver info - */ -static struct pci_driver bcmsdh_pci_driver = { - node: {}, - name: "bcmsdh", - id_table: bcmsdh_pci_devid, - probe: bcmsdh_pci_probe, - remove: bcmsdh_pci_remove, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - save_state: NULL, -#endif - suspend: NULL, - resume: NULL, -}; - - -extern uint sd_pci_slot; /* Force detection to a particular PCI */ - /* slot only . Allows for having multiple */ - /* WL devices at once in a PC */ - /* Only one instance of dhd will be */ - /* usable at a time */ - /* Upper word is bus number, */ - /* lower word is slot number */ - /* Default value of 0xFFFFffff turns this */ - /* off */ -module_param(sd_pci_slot, uint, 0); - - -/** - * Detect supported SDIO Host Controller and attach if found. - * - * Determine if the device described by pdev is a supported SDIO Host - * Controller. If so, attach to it and attach to the target device. - */ -static int __devinit -bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - ulong regs; - bcmsdh_info_t *sdh = NULL; - int rc; - - if (sd_pci_slot != 0xFFFFffff) { - if (pdev->bus->number != (sd_pci_slot>>16) || - PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { - SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Found compatible SDIOHC" : - "Probing unknown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), - pdev->vendor, pdev->device)); - return -ENODEV; - } - SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", - __FUNCTION__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Using compatible SDIOHC" : - "WARNING, forced use of unkown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), - pdev->vendor, pdev->device)); - } - - if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || - (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { - uint32 config_reg; - - SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - - config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); - - /* - * Set MMC_SD_DIS bit in FlashMedia Controller. - * Disbling the SD/MMC Controller in the FlashMedia Controller - * allows the Standard SD Host Controller to take over control - * of the SD Slot. - */ - config_reg |= 0x02; - OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); - osl_detach(osh); - } - /* match this pci device with what we support */ - /* we can't solely rely on this to believe it is our SDIO Host Controller! */ - if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { - return -ENODEV; - } - - /* this is a pci device we might support */ - SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", - __FUNCTION__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq)); - - /* use bcmsdh_query_device() to get the vendor ID of the target device so - * it will eventually appear in the Broadcom string on the console - */ - - /* allocate SDIO Host Controller state info */ - if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { - SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); - goto err; - } - if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { - SDLX_MSG(("%s: out of memory, allocated %d bytes\n", - __FUNCTION__, - MALLOCED(osh))); - goto err; - } - bzero(sdhc, sizeof(bcmsdh_hc_t)); - sdhc->osh = osh; - - sdhc->dev = pdev; - - /* map to address where host can access */ - pci_set_master(pdev); - rc = pci_enable_device(pdev); - if (rc) { - SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__)); - goto err; - } - if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), - (void **)®s, pdev->irq))) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); - goto err; - } - - sdhc->sdh = sdh; - - /* try to attach to the target device */ - if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ - bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, - (void *)regs, NULL, sdh))) { - SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); - goto err; - } - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - - return 0; - - /* error handling */ -err: - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - if (sdhc) - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - if (osh) - osl_detach(osh); - return -ENODEV; -} - - -/** - * Detach from target devices and SDIO Host Controller - */ -static void __devexit -bcmsdh_pci_remove(struct pci_dev *pdev) -{ - bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; - - /* find the SDIO Host Controller state for this pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == pdev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) - return; - - drvinfo.detach(sdhc->ch); - - bcmsdh_detach(sdhc->osh, sdhc->sdh); - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - osl_detach(osh); -} -#endif /* BCMLXSDMMC */ -#endif /* BCMPLATFORM_BUS */ - -extern int sdio_function_init(void); - -int -bcmsdh_register(bcmsdh_driver_t *driver) -{ - int error = 0; - - drvinfo = *driver; - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) - SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); - error = sdio_function_init(); -#else - SDLX_MSG(("Intel PXA270 SDIO Driver\n")); - error = driver_register(&bcmsdh_driver); -#endif /* defined(BCMLXSDMMC) */ - return error; -#endif /* defined(BCMPLATFORM_BUS) */ - -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (!(error = pci_module_init(&bcmsdh_pci_driver))) - return 0; -#else - if (!(error = pci_register_driver(&bcmsdh_pci_driver))) - return 0; -#endif - - SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); -#endif /* BCMPLATFORM_BUS */ - - return error; -} - -extern void sdio_function_cleanup(void); - -void -bcmsdh_unregister(void) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - if (bcmsdh_pci_driver.node.next) -#endif - -#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - driver_unregister(&bcmsdh_driver); -#endif -#if defined(BCMLXSDMMC) - sdio_function_cleanup(); -#endif /* BCMLXSDMMC */ -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - pci_unregister_driver(&bcmsdh_pci_driver); -#endif /* BCMPLATFORM_BUS */ -} - -#if defined(OOB_INTR_ONLY) -void bcmsdh_oob_intr_set(bool enable) -{ - static bool curstate = 1; - unsigned long flags; - - spin_lock_irqsave(&sdhcinfo->irq_lock, flags); - if (curstate != enable) { - if (enable) - enable_irq(sdhcinfo->oob_irq); - else - disable_irq_nosync(sdhcinfo->oob_irq); - curstate = enable; - } - spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); -} - -static irqreturn_t wlan_oob_irq(int irq, void *dev_id) -{ - dhd_pub_t *dhdp; - - dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); - - bcmsdh_oob_intr_set(0); - - if (dhdp == NULL) { - SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); - return IRQ_HANDLED; - } - - dhdsdio_isr((void *)dhdp->bus); - - return IRQ_HANDLED; -} - -int bcmsdh_register_oob_intr(void * dhdp) -{ - int error = 0; - - SDLX_MSG(("%s Enter\n", __FUNCTION__)); - -/* Example of HW_OOB for HW2: please refer to your host specifiction */ -/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ - - dev_set_drvdata(sdhcinfo->dev, dhdp); - - if (!sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \ - (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); - /* Refer to customer Host IRQ docs about proper irqflags definition */ - error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, - "bcmsdh_sdmmc", NULL); - if (error) - return -ENODEV; - - set_irq_wake(sdhcinfo->oob_irq, 1); - sdhcinfo->oob_irq_registered = TRUE; - } - - return 0; -} - -void bcmsdh_set_irq(int flag) -{ - if (sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); - if (flag) { - enable_irq(sdhcinfo->oob_irq); - enable_irq_wake(sdhcinfo->oob_irq); - } else { - disable_irq_wake(sdhcinfo->oob_irq); - disable_irq(sdhcinfo->oob_irq); - } - } -} - -void bcmsdh_unregister_oob_intr(void) -{ - SDLX_MSG(("%s: Enter\n", __FUNCTION__)); - - if (sdhcinfo->oob_irq_registered) { - set_irq_wake(sdhcinfo->oob_irq, 0); - disable_irq(sdhcinfo->oob_irq); /* just in case.. */ - free_irq(sdhcinfo->oob_irq, NULL); - sdhcinfo->oob_irq_registered = FALSE; - } -} -#endif /* defined(OOB_INTR_ONLY) */ -/* Module parameters specific to each host-controller driver */ - -extern uint sd_msglevel; /* Debug message level */ -module_param(sd_msglevel, uint, 0); - -extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ -module_param(sd_power, uint, 0); - -extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ -module_param(sd_clock, uint, 0); - -extern uint sd_divisor; /* Divisor (-1 means external clock) */ -module_param(sd_divisor, uint, 0); - -extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ -module_param(sd_sdmode, uint, 0); - -extern uint sd_hiok; /* Ok to use hi-speed mode */ -module_param(sd_hiok, uint, 0); - -extern uint sd_f2_blocksize; -module_param(sd_f2_blocksize, int, 0); - - -#ifdef BCMSDH_MODULE -EXPORT_SYMBOL(bcmsdh_attach); -EXPORT_SYMBOL(bcmsdh_detach); -EXPORT_SYMBOL(bcmsdh_intr_query); -EXPORT_SYMBOL(bcmsdh_intr_enable); -EXPORT_SYMBOL(bcmsdh_intr_disable); -EXPORT_SYMBOL(bcmsdh_intr_reg); -EXPORT_SYMBOL(bcmsdh_intr_dereg); - -#if defined(DHD_DEBUG) -EXPORT_SYMBOL(bcmsdh_intr_pending); -#endif - -EXPORT_SYMBOL(bcmsdh_devremove_reg); -EXPORT_SYMBOL(bcmsdh_cfg_read); -EXPORT_SYMBOL(bcmsdh_cfg_write); -EXPORT_SYMBOL(bcmsdh_cis_read); -EXPORT_SYMBOL(bcmsdh_reg_read); -EXPORT_SYMBOL(bcmsdh_reg_write); -EXPORT_SYMBOL(bcmsdh_regfail); -EXPORT_SYMBOL(bcmsdh_send_buf); -EXPORT_SYMBOL(bcmsdh_recv_buf); - -EXPORT_SYMBOL(bcmsdh_rwdata); -EXPORT_SYMBOL(bcmsdh_abort); -EXPORT_SYMBOL(bcmsdh_query_device); -EXPORT_SYMBOL(bcmsdh_query_iofnum); -EXPORT_SYMBOL(bcmsdh_iovar_op); -EXPORT_SYMBOL(bcmsdh_register); -EXPORT_SYMBOL(bcmsdh_unregister); -EXPORT_SYMBOL(bcmsdh_chipmatch); -EXPORT_SYMBOL(bcmsdh_reset); - -EXPORT_SYMBOL(bcmsdh_get_dstatus); -EXPORT_SYMBOL(bcmsdh_cfg_read_word); -EXPORT_SYMBOL(bcmsdh_cfg_write_word); -EXPORT_SYMBOL(bcmsdh_cur_sbwad); -EXPORT_SYMBOL(bcmsdh_chipinfo); - -#endif /* BCMSDH_MODULE */ diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c deleted file mode 100644 index 031367b8f18f..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c +++ /dev/null @@ -1,1304 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.30.4.1 2010/09/02 23:12:21 Exp $ - */ -#include - -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - -#include -#include -#include - -#include -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -extern volatile bool dhd_mmc_suspend; -#endif -#include "bcmsdh_sdmmc.h" - -#ifndef BCMSDH_MODULE -extern int sdio_function_init(void); -extern void sdio_function_cleanup(void); -#endif /* BCMSDH_MODULE */ - -#if !defined(OOB_INTR_ONLY) -static void IRQHandler(struct sdio_func *func); -static void IRQHandlerF2(struct sdio_func *func); -#endif /* !defined(OOB_INTR_ONLY) */ -static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr); -extern int sdio_reset_comm(struct mmc_card *card); - -extern PBCMSDH_SDMMC_INSTANCE gInstance; - -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */ -uint sd_msglevel = 0x01; -uint sd_use_dma = TRUE; -DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); - -#define DMA_ALIGN_MASK 0x03 - -int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data); - -static int -sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) -{ - int err_ret; - uint32 fbraddr; - uint8 func; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Enable Function 1 */ - sdio_claim_host(gInstance->func[1]); - err_ret = sdio_enable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret)); - } - - return FALSE; -} - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - int err_ret; - - sd_trace(("%s\n", __FUNCTION__)); - - if (gInstance == NULL) { - sd_err(("%s: SDIO Device not present\n", __FUNCTION__)); - return NULL; - } - - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - if (sdioh_sdmmc_osinit(sd) != 0) { - sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - - gInstance->sd = sd; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - err_ret = sdio_set_block_size(gInstance->func[1], 64); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n", - sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if (sd) { - - /* Disable Function 2 */ - sdio_claim_host(gInstance->func[2]); - sdio_disable_func(gInstance->func[2]); - sdio_release_host(gInstance->func[2]); - - /* Disable Function 1 */ - sdio_claim_host(gInstance->func[1]); - sdio_disable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - - /* deregister irq */ - sdioh_sdmmc_osfree(sd); - - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -extern SDIOH_API_RC -sdioh_enable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - /* Enable F1 and F2 interrupts, set master enable */ - reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN); - - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - sdio_release_host(gInstance->func[0]); - - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_disable_func_intr(void) -{ - uint8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); - /* Disable master interrupt with the last function interrupt */ - if (!(reg & 0xFE)) - reg = 0; - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - - sdio_release_host(gInstance->func[0]); - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err)); - return SDIOH_API_RC_FAIL; - } - } - return SDIOH_API_RC_SUCCESS; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - if (fn == NULL) { - sd_err(("%s: interrupt handler is NULL, not registering\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#if !defined(OOB_INTR_ONLY) - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - - /* register and unmask irq */ - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_release_host(gInstance->func[2]); - } - - if (gInstance->func[1]) { - sdio_claim_host(gInstance->func[1]); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[1]); - } -#elif defined(HW_OOB) - sdioh_enable_func_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - -#if !defined(OOB_INTR_ONLY) - if (gInstance->func[1]) { - /* register and unmask irq */ - sdio_claim_host(gInstance->func[1]); - sdio_release_irq(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - } - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - sdio_release_irq(gInstance->func[2]); - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; -#elif defined(HW_OOB) - sdioh_disable_func_intr(); -#endif /* !defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return (0); -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_RXCHAIN -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0 }, - {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - si->client_block_size[func] = blksize; - - break; - } - - case IOV_GVAL(IOV_RXCHAIN): - int_val = FALSE; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool)int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)0; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */ - else if (sd_ptr->offset & 2) - int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */ - else - int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */ - - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = 0; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -SDIOH_API_RC -sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable) -{ - SDIOH_API_RC status; - uint8 data; - - if (enable) - data = 3; /* enable hw oob interrupt */ - else - data = 4; /* disable hw oob interrupt */ - data |= 4; /* Active HIGH */ - - status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data); - return status; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -static int -sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i; - uint32 scratch, regdata; - uint8 *ptr = (uint8 *)&scratch; - for (i = 0; i < 3; i++) { - if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - sd_err(("%s: Can't read!\n", __FUNCTION__)); - - *ptr++ = (uint8) regdata; - regaddr++; - } - - /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); - scratch &= 0x0001FFFF; - return (scratch); -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - sd_err(("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func)); - return SDIOH_API_RC_FAIL; - } - - sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func])); - - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - *cis = (uint8)(foo & 0xff); - cis++; - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int err_ret; - - sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr)); - - DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - if(rw) { /* CMD52 Write */ - if (func == 0) { - /* Can only directly write to some F0 registers. Handle F2 enable - * as a special case. - */ - if (regaddr == SDIOD_CCCR_IOEN) { - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: enable F2 failed:%d", - err_ret)); - } - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(gInstance->func[2]); - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d", - err_ret)); - } - } - sdio_release_host(gInstance->func[2]); - } - } -#if defined(MMC_SDIO_ABORT) - /* to allow abort command through F1 */ - else if (regaddr == SDIOD_CCCR_IOABORT) { - sdio_claim_host(gInstance->func[func]); - /* - * this sdio_f0_writeb() can be replaced with another api - * depending upon MMC driver change. - * As of this time, this is temporaray one - */ - sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } -#endif /* MMC_SDIO_ABORT */ - else if (regaddr < 0xF0) { - sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr)); - } else { - /* Claim host controller, perform F0 write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_f0_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } else { - /* Claim host controller, perform Fn write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); - } - } else { /* CMD52 Read */ - /* Claim host controller, perform Fn read, and release */ - sdio_claim_host(gInstance->func[func]); - - if (func == 0) { - *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret); - } else { - *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret); - } - - sdio_release_host(gInstance->func[func]); - } - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int err_ret = SDIOH_API_RC_FAIL; - - if (func == 0) { - sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - __FUNCTION__, cmd_type, rw, func, addr, nbytes)); - - DHD_PM_RESUME_WAIT(sdioh_request_word_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - - if(rw) { /* CMD52 Write */ - if (nbytes == 4) { - sdio_writel(gInstance->func[func], *word, addr, &err_ret); - } else if (nbytes == 2) { - sdio_writew(gInstance->func[func], (*word & 0xFFFF), addr, &err_ret); - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } else { /* CMD52 Read */ - if (nbytes == 4) { - *word = sdio_readl(gInstance->func[func], addr, &err_ret); - } else if (nbytes == 2) { - *word = sdio_readw(gInstance->func[func], addr, &err_ret) & 0xFFFF; - } else { - sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes)); - } - } - - /* Release host controller */ - sdio_release_host(gInstance->func[func]); - - if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", - rw ? "Write" : "Read", err_ret)); - } - - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -static SDIOH_API_RC -sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, - uint addr, void *pkt) -{ - bool fifo = (fix_inc == SDIOH_DATA_FIX); - uint32 SGCount = 0; - int err_ret = 0; - - void *pnext; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - ASSERT(pkt); - DHD_PM_RESUME_WAIT(sdioh_request_packet_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - - /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); - for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) { - uint pkt_len = PKTLEN(sd->osh, pnext); - pkt_len += 3; - pkt_len &= 0xFFFFFFFC; - -#ifdef CONFIG_MMC_MSM7X00A - if ((pkt_len % 64) == 32) { - sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__)); - pkt_len += 32; - } -#endif /* CONFIG_MMC_MSM7X00A */ - /* Make sure the packet is aligned properly. If it isn't, then this - * is the fault of sdioh_request_buffer() which is supposed to give - * us something we can work with. - */ - ASSERT(((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) == 0); - - if ((write) && (!fifo)) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((uint8*)PKTDATA(sd->osh, pnext)), - pkt_len); - } else if (write) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((uint8*)PKTDATA(sd->osh, pnext)), - pkt_len); - } else if (fifo) { - err_ret = sdio_readsb(gInstance->func[func], - ((uint8*)PKTDATA(sd->osh, pnext)), - addr, - pkt_len); - } else { - err_ret = sdio_memcpy_fromio(gInstance->func[func], - ((uint8*)PKTDATA(sd->osh, pnext)), - addr, - pkt_len); - } - - if (err_ret) { - sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len, err_ret)); - } else { - sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", - __FUNCTION__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len)); - } - - if (!fifo) { - addr += pkt_len; - } - SGCount ++; - - } - - /* Release host controller */ - sdio_release_host(gInstance->func[func]); - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - - -/* - * This function takes a buffer or packet, and fixes everything up so that in the - * end, a DMA-able packet is created. - * - * A buffer does not have an associated packet pointer, and may or may not be aligned. - * A packet may consist of a single packet, or a packet chain. If it is a packet chain, - * then all the packets in the chain must be properly aligned. If the packet data is not - * aligned, then there may only be one packet, and in this case, it is copied to a new - * aligned packet. - * - */ -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - SDIOH_API_RC Status; - void *mypkt = NULL; - - sd_trace(("%s: Enter\n", __FUNCTION__)); - - DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - /* Case 1: we don't have a packet. */ - if (pkt == NULL) { - sd_data(("%s: Creating new %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", buflen_u)); -#ifdef DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, buflen_u)); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); - } -#ifdef DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ - } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { - /* Case 2: We have a packet, but it is unaligned. */ - - /* In this case, we cannot have a chain. */ - ASSERT(PKTNEXT(sd->osh, pkt) == NULL); - - sd_data(("%s: Creating aligned %s Packet, len=%d\n", - __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt))); -#ifdef DHD_USE_STATIC_BUF - if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#else - if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ - sd_err(("%s: PKTGET failed: len %d\n", - __FUNCTION__, PKTLEN(sd->osh, pkt))); - return SDIOH_API_RC_FAIL; - } - - /* For a write, copy the buffer data into the packet. */ - if (write) { - bcopy(PKTDATA(sd->osh, pkt), - PKTDATA(sd->osh, mypkt), - PKTLEN(sd->osh, pkt)); - } - - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - - /* For a read, copy the packet data back to the buffer. */ - if (!write) { - bcopy(PKTDATA(sd->osh, mypkt), - PKTDATA(sd->osh, pkt), - PKTLEN(sd->osh, mypkt)); - } -#ifdef DHD_USE_STATIC_BUF - PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -#else - PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ - } else { /* case 3: We have a packet and it is aligned. */ - sd_data(("%s: Aligned %s Packet, direct DMA\n", - __FUNCTION__, write ? "Tx" : "Rx")); - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); - } - - return (Status); -} - -/* this function performs "abort" for both of host & device */ -extern int -sdioh_abort(sdioh_info_t *sd, uint func) -{ -#if defined(MMC_SDIO_ABORT) - char t_func = (char) func; -#endif /* defined(MMC_SDIO_ABORT) */ - sd_trace(("%s: Enter\n", __FUNCTION__)); - -#if defined(MMC_SDIO_ABORT) - /* issue abort cmd52 command through F1 */ - sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func); -#endif /* defined(MMC_SDIO_ABORT) */ - - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Reset and re-initialize the device */ -int sdioh_sdio_reset(sdioh_info_t *si) -{ - sd_trace(("%s: Enter\n", __FUNCTION__)); - sd_trace(("%s: Exit\n", __FUNCTION__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Disable device interrupt */ -void -sdioh_sdmmc_devintr_off(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask &= ~CLIENT_INTR; -} - -/* Enable device interrupt */ -void -sdioh_sdmmc_devintr_on(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - sd->intmask |= CLIENT_INTR; -} - -/* Read client card reg */ -int -sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp = 0; - - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - *data = temp; - *data &= 0xff; - sd_data(("%s: byte read data=0x%02x\n", - __FUNCTION__, *data)); - } else { - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize); - if (regsize == 2) - *data &= 0xffff; - - sd_data(("%s: word read data=0x%08x\n", - __FUNCTION__, *data)); - } - - return SUCCESS; -} - -#if !defined(OOB_INTR_ONLY) -/* bcmsdh_sdmmc interrupt handler */ -static void IRQHandler(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n")); - sd = gInstance->sd; - - ASSERT(sd != NULL); - sdio_release_host(gInstance->func[0]); - - if (sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - } else { - sd_err(("bcmsdh_sdmmc: ***IRQHandler\n")); - - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - - sdio_claim_host(gInstance->func[0]); -} - -/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */ -static void IRQHandlerF2(struct sdio_func *func) -{ - sdioh_info_t *sd; - - sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n")); - - sd = gInstance->sd; - - ASSERT(sd != NULL); -} -#endif /* !defined(OOB_INTR_ONLY) */ - -#ifdef NOTUSED -/* Write client card reg */ -static int -sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - - if ((func == 0) || (regsize == 1)) { - uint8 temp; - - temp = data & 0xff; - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - sd_data(("%s: byte write data=0x%02x\n", - __FUNCTION__, data)); - } else { - if (regsize == 2) - data &= 0xffff; - - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize); - - sd_data(("%s: word write data=0x%08x\n", - __FUNCTION__, data)); - } - - return SUCCESS; -} -#endif /* NOTUSED */ - -int -sdioh_start(sdioh_info_t *si, int stage) -{ - int ret; - sdioh_info_t *sd = gInstance->sd; - - /* Need to do this stages as we can't enable the interrupt till - downloading of the firmware is complete, other wise polling - sdio access will come in way - */ - if (gInstance->func[0]) { - if (stage == 0) { - /* Since the power to the chip is killed, we will have - re enumerate the device again. Set the block size - and enable the fucntion 1 for in preparation for - downloading the code - */ - /* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux - 2.6.27. The implementation prior to that is buggy, and needs broadcom's - patch for it - */ - if ((ret = sdio_reset_comm(gInstance->func[0]->card))) - sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret)); - else { - sd->num_funcs = 2; - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->client_block_size[0] = 64; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - if (sdio_set_block_size(gInstance->func[1], 64)) { - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - } - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - if (sdio_set_block_size(gInstance->func[2], - sd_f2_blocksize)) { - sd_err(("bcmsdh_sdmmc: Failed to set F2 " - "blocksize to %d\n", sd_f2_blocksize)); - } - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sdioh_sdmmc_card_enablefuncs(sd); - } - } else { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); - sdio_claim_irq(gInstance->func[1], IRQHandler); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_enable_func_intr(); -#endif - bcmsdh_oob_intr_set(TRUE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - - return (0); -} - -int -sdioh_stop(sdioh_info_t *si) -{ - /* MSM7201A Android sdio stack has bug with interrupt - So internaly within SDIO stack they are polling - which cause issue when device is turned off. So - unregister interrupt with SDIO stack to stop the - polling - */ - if (gInstance->func[0]) { -#if !defined(OOB_INTR_ONLY) - sdio_claim_host(gInstance->func[0]); - sdio_release_irq(gInstance->func[1]); - sdio_release_irq(gInstance->func[2]); - sdio_release_host(gInstance->func[0]); -#else /* defined(OOB_INTR_ONLY) */ -#if defined(HW_OOB) - sdioh_disable_func_intr(); -#endif - bcmsdh_oob_intr_set(FALSE); -#endif /* !defined(OOB_INTR_ONLY) */ - } - else - sd_err(("%s Failed\n", __FUNCTION__)); - return (0); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c deleted file mode 100644 index 5a1a46c93571..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.17 2010/08/13 00:36:19 Exp $ - */ - -#include -#include -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq() */ - -#include -#include -#include -#include - -#if !defined(SDIO_VENDOR_ID_BROADCOM) -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 -#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ - -#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 - -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) -#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) -#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) -#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ - -#include - -#include - -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); - -int sdio_function_init(void); -void sdio_function_cleanup(void); - -#define DESCRIPTION "bcmsdh_sdmmc Driver" -#define AUTHOR "Broadcom Corporation" - -/* module param defaults */ -static int clockoverride = 0; - -module_param(clockoverride, int, 0644); -MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); - -PBCMSDH_SDMMC_INSTANCE gInstance; - -/* Maximum number of bcmsdh_sdmmc devices supported by driver */ -#define BCMSDH_SDMMC_MAX_DEVICES 1 - -extern int bcmsdh_probe(struct device *dev); -extern int bcmsdh_remove(struct device *dev); - -static int bcmsdh_sdmmc_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret = 0; - static struct sdio_func sdio_func_0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_trace(("sdio_device: 0x%04x\n", func->device)); - sd_trace(("Function#: 0x%04x\n", func->num)); - - if (func->num == 1) { - sdio_func_0.num = 0; - sdio_func_0.card = func->card; - gInstance->func[0] = &sdio_func_0; - if(func->device == 0x4) { /* 4318 */ - gInstance->func[2] = NULL; - sd_trace(("NIC found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - } - - gInstance->func[func->num] = func; - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&func->dev); - } - - return ret; -} - -static void bcmsdh_sdmmc_remove(struct sdio_func *func) -{ - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - sd_info(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_info(("sdio_device: 0x%04x\n", func->device)); - sd_info(("Function#: 0x%04x\n", func->num)); - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_remove...\n")); - bcmsdh_remove(&func->dev); - } -} - -/* devices we support, null terminated */ -static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); - -static struct sdio_driver bcmsdh_sdmmc_driver = { - .probe = bcmsdh_sdmmc_probe, - .remove = bcmsdh_sdmmc_remove, - .name = "bcmsdh_sdmmc", - .id_table = bcmsdh_sdmmc_ids, - }; - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; -}; - - -int -sdioh_sdmmc_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - return BCME_OK; -} - -void -sdioh_sdmmc_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - -#if !defined(OOB_INTR_ONLY) - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } -#endif /* !defined(OOB_INTR_ONLY) */ - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable) { - sdioh_sdmmc_devintr_on(sd); - } else { - sdioh_sdmmc_devintr_off(sd); - } - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - - -#ifdef BCMSDH_MODULE -static int __init -bcmsdh_module_init(void) -{ - int error = 0; - sdio_function_init(); - return error; -} - -static void __exit -bcmsdh_module_cleanup(void) -{ - sdio_function_cleanup(); -} - -module_init(bcmsdh_module_init); -module_exit(bcmsdh_module_cleanup); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION(DESCRIPTION); -MODULE_AUTHOR(AUTHOR); - -#endif /* BCMSDH_MODULE */ -/* - * module init -*/ -int sdio_function_init(void) -{ - int error = 0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); - - gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL); - if (!gInstance) - return -ENOMEM; - - error = sdio_register_driver(&bcmsdh_sdmmc_driver); - - return error; -} - -/* - * module cleanup -*/ -extern int bcmsdh_remove(struct device *dev); -void sdio_function_cleanup(void) -{ - sd_trace(("%s Enter\n", __FUNCTION__)); - - sdio_unregister_driver(&bcmsdh_sdmmc_driver); - - if (gInstance) - kfree(gInstance); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdspi.c b/drivers/net/wireless/bcm4329/bcmsdspi.c deleted file mode 100644 index 636539be5ea5..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdspi.c +++ /dev/null @@ -1,1596 +0,0 @@ -/* - * Broadcom BCMSDH to SPI Protocol Conversion Layer - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdspi.c,v 1.14.4.2.4.4.6.5 2010/03/10 03:09:48 Exp $ - */ - -#include - -#include -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - -#include - - -#include -#include - -#include - -#define SD_PAGE 4096 - -/* Globals */ - -uint sd_msglevel = SDH_ERROR_VAL; -uint sd_hiok = FALSE; /* Use hi-speed mode if available? */ -uint sd_sdmode = SDIOH_MODE_SPI; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 33MHz/2 = 16MHz for dongle */ -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_crc = 0; /* Default to SPI CRC Check turned OFF */ -uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */ - -uint sd_toctl = 7; - -/* Prototypes */ -static bool sdspi_start_power(sdioh_info_t *sd); -static int sdspi_set_highspeed_mode(sdioh_info_t *sd, bool HSMode); -static int sdspi_card_enablefuncs(sdioh_info_t *sd); -static void sdspi_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count); -static int sdspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg, - uint32 *data, uint32 datalen); -static int sdspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 *data); -static int sdspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 data); -static int sdspi_driver_init(sdioh_info_t *sd); -static bool sdspi_reset(sdioh_info_t *sd, bool host_reset, bool client_reset); -static int sdspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data); -static int sdspi_abort(sdioh_info_t *sd, uint func); - -static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize); - -static uint8 sdspi_crc7(unsigned char* p, uint32 len); -static uint16 sdspi_crc16(unsigned char* p, uint32 len); -static int sdspi_crc_onoff(sdioh_info_t *sd, bool use_crc); - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - - sd_trace(("%s\n", __FUNCTION__)); - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - - if (spi_osinit(sd) != 0) { - sd_err(("%s: spi_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->bar0 = (uintptr)bar0; - sd->irq = irq; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - sd->intr_handler_valid = FALSE; - - /* Set defaults */ - sd->sd_blockmode = FALSE; - sd->use_client_ints = TRUE; - sd->sd_use_dma = FALSE; /* DMA Not supported */ - - /* Haven't figured out how to make bytemode work with dma */ - if (!sd->sd_blockmode) - sd->sd_use_dma = 0; - - if (!spi_hw_attach(sd)) { - sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__)); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - if (sdspi_driver_init(sd) != SUCCESS) { - if (sdspi_driver_init(sd) != SUCCESS) { - sd_err(("%s:sdspi_driver_init() failed()\n", __FUNCTION__)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - } - - if (spi_register_irq(sd, irq) != SUCCESS) { - sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if (sd) { - if (sd->card_init_done) - sdspi_reset(sd, 1, 1); - - sd_info(("%s: detaching from hardware\n", __FUNCTION__)); - spi_free_irq(sd->irq, sd); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - - return SDIOH_API_RC_SUCCESS; -} - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - - *onoff = sd->client_intr_enabled; - - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return 0; -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_CRC -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_crc", IOV_CRC, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - if (!si->sd_blockmode) - si->sd_use_dma = 0; - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - spi_lock(si); - bcmerror = set_client_block_size(si, func, blksize); - spi_unlock(si); - break; - } - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - if (!spi_start_clock(si, (uint16)sd_divisor)) { - sd_err(("set clock failed!\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_CRC): - int_val = (uint32)sd_crc; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CRC): - /* Apply new setting, but don't change sd_crc until - * after the CRC-mode is selected in the device. This - * is required because the software must generate a - * correct CRC for the CMD59 in order to be able to - * turn OFF the CRC. - */ - sdspi_crc_onoff(si, int_val ? 1 : 0); - sd_crc = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - - if (!sdspi_set_highspeed_mode(si, (bool)sd_hiok)) { - sd_err(("Failed changing highspeed mode to %d.\n", sd_hiok)); - bcmerror = BCME_ERROR; - return ERROR; - } - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)si->local_intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sd_err(("IOV_HOSTREG unsupported\n")); - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - return SDIOH_API_RC_FAIL; - } - - spi_lock(sd); - *cis = 0; - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdspi_card_regread (sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - *cis = (uint8)(foo & 0xff); - cis++; - } - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - spi_lock(sd); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte); - - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x\n", __FUNCTION__, rw, func, regaddr)); - - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_52, cmd_arg, NULL, 0)) != SUCCESS) { - spi_unlock(sd); - return status; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - if (rsp5 != 0x00) { - sd_err(("%s: rsp5 flags is 0x%x func=%d\n", - __FUNCTION__, rsp5, func)); - /* ASSERT(0); */ - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - - if (rw == SDIOH_READ) - *byte = sd->card_rsp_data >> 24; - - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int status; - - spi_lock(sd); - - if (rw == SDIOH_READ) - status = sdspi_card_regread(sd, func, addr, nbytes, word); - else - status = sdspi_card_regwrite(sd, func, addr, nbytes, *word); - - spi_unlock(sd); - return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - int len; - int buflen = (int)buflen_u; - bool fifo = (fix_inc == SDIOH_DATA_FIX); - - spi_lock(sd); - - ASSERT(reg_width == 4); - ASSERT(buflen_u < (1 << 30)); - ASSERT(sd->client_block_size[func]); - - sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", - __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', - buflen_u, sd->r_cnt, sd->t_cnt, pkt)); - - /* Break buffer down into blocksize chunks: - * Bytemode: 1 block at a time. - */ - while (buflen > 0) { - if (sd->sd_blockmode) { - /* Max xfer is Page size */ - len = MIN(SD_PAGE, buflen); - - /* Round down to a block boundry */ - if (buflen > sd->client_block_size[func]) - len = (len/sd->client_block_size[func]) * - sd->client_block_size[func]; - } else { - /* Byte mode: One block at a time */ - len = MIN(sd->client_block_size[func], buflen); - } - - if (sdspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - buffer += len; - buflen -= len; - if (!fifo) - addr += len; - } - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -static int -sdspi_abort(sdioh_info_t *sd, uint func) -{ - uint8 spi_databuf[] = { 0x74, 0x80, 0x00, 0x0C, 0xFF, 0x95, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - uint8 spi_rspbuf[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - int err = 0; - - sd_err(("Sending SPI Abort to F%d\n", func)); - spi_databuf[4] = func & 0x7; - /* write to function 0, addr 6 (IOABORT) func # in 3 LSBs. */ - spi_sendrecv(sd, spi_databuf, spi_rspbuf, sizeof(spi_databuf)); - - return err; -} - -extern int -sdioh_abort(sdioh_info_t *sd, uint fnum) -{ - int ret; - - spi_lock(sd); - ret = sdspi_abort(sd, fnum); - spi_unlock(sd); - - return ret; -} - -int -sdioh_start(sdioh_info_t *sd, int stage) -{ - return SUCCESS; -} - -int -sdioh_stop(sdioh_info_t *sd) -{ - return SUCCESS; -} - - -/* - * Private/Static work routines - */ -static bool -sdspi_reset(sdioh_info_t *sd, bool host_reset, bool client_reset) -{ - if (!sd) - return TRUE; - - spi_lock(sd); - /* Reset client card */ - if (client_reset && (sd->adapter_slot != -1)) { - if (sdspi_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS) - sd_err(("%s: Cannot write to card reg 0x%x\n", - __FUNCTION__, SDIOD_CCCR_IOABORT)); - else - sd->card_rca = 0; - } - - /* The host reset is a NOP in the sd-spi case. */ - if (host_reset) { - sd->sd_mode = SDIOH_MODE_SPI; - } - spi_unlock(sd); - return TRUE; -} - -static int -sdspi_host_init(sdioh_info_t *sd) -{ - sdspi_reset(sd, 1, 0); - - /* Default power on mode is SD1 */ - sd->sd_mode = SDIOH_MODE_SPI; - sd->polled_mode = TRUE; - sd->host_init_done = TRUE; - sd->card_init_done = FALSE; - sd->adapter_slot = 1; - - return (SUCCESS); -} - -#define CMD0_RETRIES 3 -#define CMD5_RETRIES 10 - -static int -get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp) -{ - uint32 rsp5; - int retries, status; - - /* First issue a CMD0 to get the card into SPI mode. */ - for (retries = 0; retries <= CMD0_RETRIES; retries++) { - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_0, *cmd_arg, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD0\n", __FUNCTION__)); - continue; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, SPI_RSP_ILL_CMD)) { - printf("%s: Card already initialized (continuing)\n", __FUNCTION__); - break; - } - - if (GFIELD(rsp5, SPI_RSP_IDLE)) { - printf("%s: Card in SPI mode\n", __FUNCTION__); - break; - } - } - - if (retries > CMD0_RETRIES) { - sd_err(("%s: Too many retries for CMD0\n", __FUNCTION__)); - return ERROR; - } - - /* Get the Card's Operation Condition. */ - /* Occasionally the board takes a while to become ready. */ - for (retries = 0; retries <= CMD5_RETRIES; retries++) { - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_5, *cmd_arg, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD5\n", __FUNCTION__)); - continue; - } - - printf("CMD5 response data was: 0x%08x\n", sd->card_rsp_data); - - if (GFIELD(sd->card_rsp_data, RSP4_CARD_READY)) { - printf("%s: Card ready\n", __FUNCTION__); - break; - } - } - - if (retries > CMD5_RETRIES) { - sd_err(("%s: Too many retries for CMD5\n", __FUNCTION__)); - return ERROR; - } - - *cmd_rsp = sd->card_rsp_data; - - sdspi_crc_onoff(sd, sd_crc ? 1 : 0); - - return (SUCCESS); -} - -static int -sdspi_crc_onoff(sdioh_info_t *sd, bool use_crc) -{ - uint32 args; - int status; - - args = use_crc ? 1 : 0; - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, - SDIOH_CMD_59, args, NULL, 0)) != SUCCESS) { - sd_err(("%s: No response to CMD59\n", __FUNCTION__)); - } - - sd_info(("CMD59 response data was: 0x%08x\n", sd->card_rsp_data)); - - sd_err(("SD-SPI CRC turned %s\n", use_crc ? "ON" : "OFF")); - return (SUCCESS); -} - -static int -sdspi_client_init(sdioh_info_t *sd) -{ - uint8 fn_ints; - - sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); - - /* Start at ~400KHz clock rate for initialization */ - if (!spi_start_clock(sd, 128)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } - - if (!sdspi_start_power(sd)) { - sd_err(("sdspi_start_power failed\n")); - return ERROR; - } - - if (sd->num_funcs == 0) { - sd_err(("%s: No IO funcs!\n", __FUNCTION__)); - return ERROR; - } - - sdspi_card_enablefuncs(sd); - - set_client_block_size(sd, 1, BLOCK_SIZE_4318); - fn_ints = INTR_CTL_FUNC1_EN; - - if (sd->num_funcs >= 2) { - set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */); - fn_ints |= INTR_CTL_FUNC2_EN; - } - - /* Enable/Disable Client interrupts */ - /* Turn on here but disable at host controller */ - if (sdspi_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1, - (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) { - sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__)); - return ERROR; - } - - /* Switch to High-speed clocking mode if both host and device support it */ - sdspi_set_highspeed_mode(sd, (bool)sd_hiok); - - /* After configuring for High-Speed mode, set the desired clock rate. */ - if (!spi_start_clock(sd, (uint16)sd_divisor)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } - - sd->card_init_done = TRUE; - - return SUCCESS; -} - -static int -sdspi_set_highspeed_mode(sdioh_info_t *sd, bool HSMode) -{ - uint32 regdata; - int status; - bool hsmode; - - if (HSMode == TRUE) { - - sd_err(("Attempting to enable High-Speed mode.\n")); - - if ((status = sdspi_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return status; - } - if (regdata & SDIO_SPEED_SHS) { - sd_err(("Device supports High-Speed mode.\n")); - - regdata |= SDIO_SPEED_EHS; - - sd_err(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - - hsmode = 1; - - sd_err(("High-speed clocking mode enabled.\n")); - } - else { - sd_err(("Device does not support High-Speed Mode.\n")); - hsmode = 0; - } - } else { - if ((status = sdspi_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return status; - } - - regdata = ~SDIO_SPEED_EHS; - - sd_err(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - - sd_err(("Low-speed clocking mode enabled.\n")); - hsmode = 0; - } - - spi_controller_highspeed_mode(sd, hsmode); - - return TRUE; -} - -bool -sdspi_start_power(sdioh_info_t *sd) -{ - uint32 cmd_arg; - uint32 cmd_rsp; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - - cmd_arg = 0; - if (get_ocr(sd, &cmd_arg, &cmd_rsp) != SUCCESS) { - sd_err(("%s: Failed to get OCR; bailing\n", __FUNCTION__)); - return FALSE; - } - - sd_err(("mem_present = %d\n", GFIELD(cmd_rsp, RSP4_MEM_PRESENT))); - sd_err(("num_funcs = %d\n", GFIELD(cmd_rsp, RSP4_NUM_FUNCS))); - sd_err(("card_ready = %d\n", GFIELD(cmd_rsp, RSP4_CARD_READY))); - sd_err(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - - /* Verify that the card supports I/O mode */ - if (GFIELD(cmd_rsp, RSP4_NUM_FUNCS) == 0) { - sd_err(("%s: Card does not support I/O\n", __FUNCTION__)); - return ERROR; - } - - sd->num_funcs = GFIELD(cmd_rsp, RSP4_NUM_FUNCS); - - /* Examine voltage: Arasan only supports 3.3 volts, - * so look for 3.2-3.3 Volts and also 3.3-3.4 volts. - */ - - if ((GFIELD(cmd_rsp, RSP4_IO_OCR) & (0x3 << 20)) == 0) { - sd_err(("This client does not support 3.3 volts!\n")); - return ERROR; - } - - - return TRUE; -} - -static int -sdspi_driver_init(sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - - if ((sdspi_host_init(sd)) != SUCCESS) { - return ERROR; - } - - if (sdspi_client_init(sd) != SUCCESS) { - return ERROR; - } - - return SUCCESS; -} - -static int -sdspi_card_enablefuncs(sdioh_info_t *sd) -{ - int status; - uint32 regdata; - uint32 regaddr, fbraddr; - uint8 func; - uint8 *ptr; - - sd_trace(("%s\n", __FUNCTION__)); - /* Get the Card's common CIS address */ - ptr = (uint8 *) &sd->com_cis_ptr; - for (regaddr = SDIOD_CCCR_CISPTR_0; regaddr <= SDIOD_CCCR_CISPTR_2; regaddr++) { - if ((status = sdspi_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - return status; - - *ptr++ = (uint8) regdata; - } - - /* Only the lower 17-bits are valid */ - sd->com_cis_ptr &= 0x0001FFFF; - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - ptr = (uint8 *) &sd->func_cis_ptr[func]; - for (regaddr = SDIOD_FBR_CISPTR_0; regaddr <= SDIOD_FBR_CISPTR_2; regaddr++) { - if ((status = sdspi_card_regread (sd, 0, regaddr + fbraddr, 1, ®data)) - != SUCCESS) - return status; - - *ptr++ = (uint8) regdata; - } - - /* Only the lower 17-bits are valid */ - sd->func_cis_ptr[func] &= 0x0001FFFF; - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - sd_info(("%s: write ESCI bit\n", __FUNCTION__)); - /* Enable continuous SPI interrupt (ESCI bit) */ - sdspi_card_regwrite(sd, 0, SDIOD_CCCR_BICTRL, 1, 0x60); - - sd_info(("%s: enable f1\n", __FUNCTION__)); - /* Enable function 1 on the card */ - regdata = SDIO_FUNC_ENABLE_1; - if ((status = sdspi_card_regwrite(sd, 0, SDIOD_CCCR_IOEN, 1, regdata)) != SUCCESS) - return status; - - sd_info(("%s: done\n", __FUNCTION__)); - return SUCCESS; -} - -/* Read client card reg */ -static int -sdspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_READ); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, 0); - - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_52, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, rsp5, func)); - - *data = sd->card_rsp_data >> 24; - } else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - - sd->data_xfer_count = regsize; - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_53, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, rsp5, func)); - - *data = sd->card_rsp_data; - if (regsize == 2) { - *data &= 0xffff; - } - - sd_info(("%s: CMD53 func %d, addr 0x%x, size %d, data 0x%08x\n", - __FUNCTION__, func, regaddr, regsize, *data)); - - - } - - return SUCCESS; -} - -/* write a client register */ -static int -sdspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - int status; - uint32 cmd_arg, rsp5, flags; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, data & 0xff); - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_52, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - flags = GFIELD(rsp5, RSP5_FLAGS); - if (flags && (flags != 0x10)) - sd_err(("%s: rsp5.rsp5.flags = 0x%x, expecting 0x10\n", - __FUNCTION__, flags)); - } - else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = regsize; - sd->cmd53_wr_data = data; - - sd_info(("%s: CMD53 func %d, addr 0x%x, size %d, data 0x%08x\n", - __FUNCTION__, func, regaddr, regsize, data)); - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, sd->sd_use_dma, SDIOH_CMD_53, cmd_arg, NULL, 0)) - != SUCCESS) - return status; - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x00\n", - __FUNCTION__, rsp5)); - - } - return SUCCESS; -} - -void -sdspi_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count /* num 32 bit words */) -{ - *rsp_buffer = sd->card_response; -} - -int max_errors = 0; - -#define SPI_MAX_PKT_LEN 768 -uint8 spi_databuf[SPI_MAX_PKT_LEN]; -uint8 spi_rspbuf[SPI_MAX_PKT_LEN]; - -/* datalen is used for CMD53 length only (0 for sd->data_xfer_count) */ -static int -sdspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg, - uint32 *data, uint32 datalen) -{ - uint32 cmd_reg; - uint32 cmd_arg = arg; - uint8 cmd_crc = 0x95; /* correct CRC for CMD0 and don't care for others. */ - uint16 dat_crc; - uint8 cmd52data = 0; - uint32 i, j; - uint32 spi_datalen = 0; - uint32 spi_pre_cmd_pad = 0; - uint32 spi_max_response_pad = 128; - - cmd_reg = 0; - cmd_reg = SFIELD(cmd_reg, SPI_DIR, 1); - cmd_reg = SFIELD(cmd_reg, SPI_CMD_INDEX, cmd); - - if (GFIELD(cmd_arg, CMD52_RW_FLAG) == 1) { /* Same for CMD52 and CMD53 */ - cmd_reg = SFIELD(cmd_reg, SPI_RW, 1); - } - - switch (cmd) { - case SDIOH_CMD_59: /* CRC_ON_OFF (SPI Mode Only) - Response R1 */ - cmd52data = arg & 0x1; - case SDIOH_CMD_0: /* Set Card to Idle State - No Response */ - case SDIOH_CMD_5: /* Send Operation condition - Response R4 */ - sd_trace(("%s: CMD%d\n", __FUNCTION__, cmd)); - spi_datalen = 44; - spi_pre_cmd_pad = 12; - spi_max_response_pad = 28; - break; - - case SDIOH_CMD_3: /* Ask card to send RCA - Response R6 */ - case SDIOH_CMD_7: /* Select card - Response R1 */ - case SDIOH_CMD_15: /* Set card to inactive state - Response None */ - sd_err(("%s: CMD%d is invalid for SPI Mode.\n", __FUNCTION__, cmd)); - return ERROR; - break; - - case SDIOH_CMD_52: /* IO R/W Direct (single byte) - Response R5 */ - cmd52data = GFIELD(cmd_arg, CMD52_DATA); - cmd_arg = arg; - cmd_reg = SFIELD(cmd_reg, SPI_FUNC, GFIELD(cmd_arg, CMD52_FUNCTION)); - cmd_reg = SFIELD(cmd_reg, SPI_ADDR, GFIELD(cmd_arg, CMD52_REG_ADDR)); - /* Display trace for byte write */ - if (GFIELD(cmd_arg, CMD52_RW_FLAG) == 1) { - sd_trace(("%s: CMD52: Wr F:%d @0x%04x=%02x\n", - __FUNCTION__, - GFIELD(cmd_arg, CMD52_FUNCTION), - GFIELD(cmd_arg, CMD52_REG_ADDR), - cmd52data)); - } - - spi_datalen = 32; - spi_max_response_pad = 28; - - break; - case SDIOH_CMD_53: /* IO R/W Extended (multiple bytes/blocks) */ - cmd_arg = arg; - cmd_reg = SFIELD(cmd_reg, SPI_FUNC, GFIELD(cmd_arg, CMD53_FUNCTION)); - cmd_reg = SFIELD(cmd_reg, SPI_ADDR, GFIELD(cmd_arg, CMD53_REG_ADDR)); - cmd_reg = SFIELD(cmd_reg, SPI_BLKMODE, 0); - cmd_reg = SFIELD(cmd_reg, SPI_OPCODE, GFIELD(cmd_arg, CMD53_OP_CODE)); - cmd_reg = SFIELD(cmd_reg, SPI_STUFF0, (sd->data_xfer_count>>8)); - cmd52data = (uint8)sd->data_xfer_count; - - /* Set upper bit in byte count if necessary, but don't set it for 512 bytes. */ - if ((sd->data_xfer_count > 255) && (sd->data_xfer_count < 512)) { - cmd_reg |= 1; - } - - if (GFIELD(cmd_reg, SPI_RW) == 1) { /* Write */ - spi_max_response_pad = 32; - spi_datalen = (sd->data_xfer_count + spi_max_response_pad) & 0xFFFC; - } else { /* Read */ - - spi_max_response_pad = 32; - spi_datalen = (sd->data_xfer_count + spi_max_response_pad) & 0xFFFC; - } - sd_trace(("%s: CMD53: %s F:%d @0x%04x len=0x%02x\n", - __FUNCTION__, - (GFIELD(cmd_reg, SPI_RW) == 1 ? "Wr" : "Rd"), - GFIELD(cmd_arg, CMD53_FUNCTION), - GFIELD(cmd_arg, CMD53_REG_ADDR), - cmd52data)); - break; - - default: - sd_err(("%s: Unknown command %d\n", __FUNCTION__, cmd)); - return ERROR; - } - - /* Set up and issue the SDIO command */ - memset(spi_databuf, SDSPI_IDLE_PAD, spi_datalen); - spi_databuf[spi_pre_cmd_pad + 0] = (cmd_reg & 0xFF000000) >> 24; - spi_databuf[spi_pre_cmd_pad + 1] = (cmd_reg & 0x00FF0000) >> 16; - spi_databuf[spi_pre_cmd_pad + 2] = (cmd_reg & 0x0000FF00) >> 8; - spi_databuf[spi_pre_cmd_pad + 3] = (cmd_reg & 0x000000FF); - spi_databuf[spi_pre_cmd_pad + 4] = cmd52data; - - /* Generate CRC7 for command, if CRC is enabled, otherwise, a - * default CRC7 of 0x95, which is correct for CMD0, is used. - */ - if (sd_crc) { - cmd_crc = sdspi_crc7(&spi_databuf[spi_pre_cmd_pad], 5); - } - spi_databuf[spi_pre_cmd_pad + 5] = cmd_crc; -#define SPI_STOP_TRAN 0xFD - - /* for CMD53 Write, put the data into the output buffer */ - if ((cmd == SDIOH_CMD_53) && (GFIELD(cmd_arg, CMD53_RW_FLAG) == 1)) { - if (datalen != 0) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - - for (i = 0; i < sd->data_xfer_count; i++) { - spi_databuf[i + 11 + spi_pre_cmd_pad] = ((uint8 *)data)[i]; - } - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], i); - } else { - dat_crc = 0xAAAA; - } - spi_databuf[i + 11 + spi_pre_cmd_pad] = (dat_crc >> 8) & 0xFF; - spi_databuf[i + 12 + spi_pre_cmd_pad] = dat_crc & 0xFF; - } else if (sd->data_xfer_count == 2) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - spi_databuf[spi_pre_cmd_pad + 11] = sd->cmd53_wr_data & 0xFF; - spi_databuf[spi_pre_cmd_pad + 12] = (sd->cmd53_wr_data & 0x0000FF00) >> 8; - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], 2); - } else { - dat_crc = 0x22AA; - } - spi_databuf[spi_pre_cmd_pad + 13] = (dat_crc >> 8) & 0xFF; - spi_databuf[spi_pre_cmd_pad + 14] = (dat_crc & 0xFF); - } else if (sd->data_xfer_count == 4) { - spi_databuf[spi_pre_cmd_pad + 9] = SDSPI_IDLE_PAD; - spi_databuf[spi_pre_cmd_pad + 10] = SDSPI_START_BLOCK; - spi_databuf[spi_pre_cmd_pad + 11] = sd->cmd53_wr_data & 0xFF; - spi_databuf[spi_pre_cmd_pad + 12] = (sd->cmd53_wr_data & 0x0000FF00) >> 8; - spi_databuf[spi_pre_cmd_pad + 13] = (sd->cmd53_wr_data & 0x00FF0000) >> 16; - spi_databuf[spi_pre_cmd_pad + 14] = (sd->cmd53_wr_data & 0xFF000000) >> 24; - if (sd_crc) { - dat_crc = sdspi_crc16(&spi_databuf[spi_pre_cmd_pad+11], 4); - } else { - dat_crc = 0x44AA; - } - spi_databuf[spi_pre_cmd_pad + 15] = (dat_crc >> 8) & 0xFF; - spi_databuf[spi_pre_cmd_pad + 16] = (dat_crc & 0xFF); - } else { - printf("CMD53 Write: size %d unsupported\n", sd->data_xfer_count); - } - } - - spi_sendrecv(sd, spi_databuf, spi_rspbuf, spi_datalen); - - for (i = spi_pre_cmd_pad + SDSPI_COMMAND_LEN; i < spi_max_response_pad; i++) { - if ((spi_rspbuf[i] & SDSPI_START_BIT_MASK) == 0) { - break; - } - } - - if (i == spi_max_response_pad) { - sd_err(("%s: Did not get a response for CMD%d\n", __FUNCTION__, cmd)); - return ERROR; - } - - /* Extract the response. */ - sd->card_response = spi_rspbuf[i]; - - /* for CMD53 Read, find the start of the response data... */ - if ((cmd == SDIOH_CMD_53) && (GFIELD(cmd_arg, CMD52_RW_FLAG) == 0)) { - for (; i < spi_max_response_pad; i++) { - if (spi_rspbuf[i] == SDSPI_START_BLOCK) { - break; - } - } - - if (i == spi_max_response_pad) { - printf("Did not get a start of data phase for CMD%d\n", cmd); - max_errors++; - sdspi_abort(sd, GFIELD(cmd_arg, CMD53_FUNCTION)); - } - sd->card_rsp_data = spi_rspbuf[i+1]; - sd->card_rsp_data |= spi_rspbuf[i+2] << 8; - sd->card_rsp_data |= spi_rspbuf[i+3] << 16; - sd->card_rsp_data |= spi_rspbuf[i+4] << 24; - - if (datalen != 0) { - i++; - for (j = 0; j < sd->data_xfer_count; j++) { - ((uint8 *)data)[j] = spi_rspbuf[i+j]; - } - if (sd_crc) { - uint16 recv_crc; - - recv_crc = spi_rspbuf[i+j] << 8 | spi_rspbuf[i+j+1]; - dat_crc = sdspi_crc16((uint8 *)data, datalen); - if (dat_crc != recv_crc) { - sd_err(("%s: Incorrect data CRC: expected 0x%04x, " - "received 0x%04x\n", - __FUNCTION__, dat_crc, recv_crc)); - } - } - } - return SUCCESS; - } - - sd->card_rsp_data = spi_rspbuf[i+4]; - sd->card_rsp_data |= spi_rspbuf[i+3] << 8; - sd->card_rsp_data |= spi_rspbuf[i+2] << 16; - sd->card_rsp_data |= spi_rspbuf[i+1] << 24; - - /* Display trace for byte read */ - if ((cmd == SDIOH_CMD_52) && (GFIELD(cmd_arg, CMD52_RW_FLAG) == 0)) { - sd_trace(("%s: CMD52: Rd F:%d @0x%04x=%02x\n", - __FUNCTION__, - GFIELD(cmd_arg, CMD53_FUNCTION), - GFIELD(cmd_arg, CMD53_REG_ADDR), - sd->card_rsp_data >> 24)); - } - - return SUCCESS; -} - -/* - * On entry: if single-block or non-block, buffer size <= block size. - * If multi-block, buffer size is unlimited. - * Question is how to handle the left-overs in either single- or multi-block. - * I think the caller should break the buffer up so this routine will always - * use block size == buffer size to handle the end piece of the buffer - */ - -static int -sdspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int nbytes, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - int num_blocks, blocksize; - bool local_blockmode, local_dma; - bool read = rw == SDIOH_READ ? 1 : 0; - - ASSERT(nbytes); - - cmd_arg = 0; - sd_data(("%s: %s 53 func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", func, fifo ? "FIXED" : "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - - if (read) sd->r_cnt++; else sd->t_cnt++; - - local_blockmode = sd->sd_blockmode; - local_dma = sd->sd_use_dma; - - /* Don't bother with block mode on small xfers */ - if (nbytes < sd->client_block_size[func]) { - sd_info(("setting local blockmode to false: nbytes (%d) != block_size (%d)\n", - nbytes, sd->client_block_size[func])); - local_blockmode = FALSE; - local_dma = FALSE; - } - - if (local_blockmode) { - blocksize = MIN(sd->client_block_size[func], nbytes); - num_blocks = nbytes/blocksize; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, num_blocks); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 1); - } else { - num_blocks = 1; - blocksize = nbytes; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, nbytes); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - } - - if (fifo) - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 0); - else - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, addr); - if (read) - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - else - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = nbytes; - if ((func == 2) && (fifo == 1)) { - sd_data(("%s: %s 53 func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", func, fifo ? "FIXED" : "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - } - - /* sdspi_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdspi_cmd_issue(sd, local_dma, - SDIOH_CMD_53, cmd_arg, - data, nbytes)) != SUCCESS) { - sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, (read ? "read" : "write"))); - return status; - } - - sdspi_cmd_getrsp(sd, &rsp5, 1); - - if (rsp5 != 0x00) { - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x00\n", - __FUNCTION__, rsp5)); - return ERROR; - } - - return SUCCESS; -} - -static int -set_client_block_size(sdioh_info_t *sd, int func, int block_size) -{ - int base; - int err = 0; - - sd_err(("%s: Setting block size %d, func %d\n", __FUNCTION__, block_size, func)); - sd->client_block_size[func] = block_size; - - /* Set the block size in the SDIO Card register */ - base = func * SDIOD_FBR_SIZE; - err = sdspi_card_regwrite(sd, 0, base + SDIOD_CCCR_BLKSIZE_0, 1, block_size & 0xff); - if (!err) { - err = sdspi_card_regwrite(sd, 0, base + SDIOD_CCCR_BLKSIZE_1, 1, - (block_size >> 8) & 0xff); - } - - /* - * Do not set the block size in the SDIO Host register; that - * is func dependent and will get done on an individual - * transaction basis. - */ - - return (err ? BCME_SDIO_ERROR : 0); -} - -/* Reset and re-initialize the device */ -int -sdioh_sdio_reset(sdioh_info_t *si) -{ - si->card_init_done = FALSE; - return sdspi_client_init(si); -} - -#define CRC7_POLYNOM 0x09 -#define CRC7_CRCHIGHBIT 0x40 - -static uint8 sdspi_crc7(unsigned char* p, uint32 len) -{ - uint8 c, j, bit, crc = 0; - uint32 i; - - for (i = 0; i < len; i++) { - c = *p++; - for (j = 0x80; j; j >>= 1) { - bit = crc & CRC7_CRCHIGHBIT; - crc <<= 1; - if (c & j) bit ^= CRC7_CRCHIGHBIT; - if (bit) crc ^= CRC7_POLYNOM; - } - } - - /* Convert the CRC7 to an 8-bit SD CRC */ - crc = (crc << 1) | 1; - - return (crc); -} - -#define CRC16_POLYNOM 0x1021 -#define CRC16_CRCHIGHBIT 0x8000 - -static uint16 sdspi_crc16(unsigned char* p, uint32 len) -{ - uint32 i; - uint16 j, c, bit; - uint16 crc = 0; - - for (i = 0; i < len; i++) { - c = *p++; - for (j = 0x80; j; j >>= 1) { - bit = crc & CRC16_CRCHIGHBIT; - crc <<= 1; - if (c & j) bit ^= CRC16_CRCHIGHBIT; - if (bit) crc ^= CRC16_POLYNOM; - } - } - - return (crc); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdspi_linux.c b/drivers/net/wireless/bcm4329/bcmsdspi_linux.c deleted file mode 100644 index e2e0ca6abe46..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdspi_linux.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Broadcom SPI Host Controller Driver - Linux Per-port - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdspi_linux.c,v 1.7.2.1.4.3 2008/06/30 21:09:36 Exp $ - */ - -#include -#include -#include - -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq(), free_irq() */ - -#include -#include - -extern uint sd_crc; -module_param(sd_crc, uint, 0); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define KERNEL26 -#endif - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; - wait_queue_head_t intr_wait_queue; -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* Interrupt handler */ -static irqreturn_t -sdspi_isr(int irq, void *dev_id -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) -, struct pt_regs *ptregs -#endif -) -{ - sdioh_info_t *sd; - struct sdos_info *sdos; - bool ours; - - sd = (sdioh_info_t *)dev_id; - sd->local_intrcount++; - - if (!sd->card_init_done) { - sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq)); - return IRQ_RETVAL(FALSE); - } else { - ours = spi_check_client_intr(sd, NULL); - - /* For local interrupts, wake the waiting process */ - if (ours && sd->got_hcint) { - sdos = (struct sdos_info *)sd->sdos_info; - wake_up_interruptible(&sdos->intr_wait_queue); - } - - return IRQ_RETVAL(ours); - } -} - -/* Register with Linux for interrupts */ -int -spi_register_irq(sdioh_info_t *sd, uint irq) -{ - sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq)); - if (request_irq(irq, sdspi_isr, IRQF_SHARED, "bcmsdspi", sd) < 0) { - sd_err(("%s: request_irq() failed\n", __FUNCTION__)); - return ERROR; - } - return SUCCESS; -} - -/* Free Linux irq */ -void -spi_free_irq(uint irq, sdioh_info_t *sd) -{ - free_irq(irq, sd); -} - -/* Map Host controller registers */ - -uint32 * -spi_reg_map(osl_t *osh, uintptr addr, int size) -{ - return (uint32 *)REG_MAP(addr, size); -} - -void -spi_reg_unmap(osl_t *osh, uintptr addr, int size) -{ - REG_UNMAP((void*)(uintptr)addr); -} - -int -spi_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - init_waitqueue_head(&sdos->intr_wait_queue); - return BCME_OK; -} - -void -spi_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - if (!(sd->host_init_done && sd->card_init_done)) { - sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable && !sd->lockcount) - spi_devintr_on(sd); - else - spi_devintr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - -/* Protect against reentrancy (disable device interrupts while executing) */ -void -spi_lock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount)); - - spin_lock_irqsave(&sdos->lock, flags); - if (sd->lockcount) { - sd_err(("%s: Already locked!\n", __FUNCTION__)); - ASSERT(sd->lockcount == 0); - } - spi_devintr_off(sd); - sd->lockcount++; - spin_unlock_irqrestore(&sdos->lock, flags); -} - -/* Enable client interrupt */ -void -spi_unlock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled)); - ASSERT(sd->lockcount > 0); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - spin_lock_irqsave(&sdos->lock, flags); - if (--sd->lockcount == 0 && sd->client_intr_enabled) { - spi_devintr_on(sd); - } - spin_unlock_irqrestore(&sdos->lock, flags); -} - -void spi_waitbits(sdioh_info_t *sd, bool yield) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - -#ifndef BCMSDYIELD - ASSERT(!yield); -#endif - sd_trace(("%s: yield %d canblock %d\n", - __FUNCTION__, yield, BLOCKABLE())); - - /* Clear the "interrupt happened" flag and last intrstatus */ - sd->got_hcint = FALSE; - -#ifdef BCMSDYIELD - if (yield && BLOCKABLE()) { - /* Wait for the indication, the interrupt will be masked when the ISR fires. */ - wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint)); - } else -#endif /* BCMSDYIELD */ - { - spi_spinbits(sd); - } - -} diff --git a/drivers/net/wireless/bcm4329/bcmsdstd.c b/drivers/net/wireless/bcm4329/bcmsdstd.c deleted file mode 100644 index 0ca1f8ff8a24..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdstd.c +++ /dev/null @@ -1,3127 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $ - */ - -#include - -#include -#include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ -#include - - -#define SD_PAGE_BITS 12 -#define SD_PAGE (1 << SD_PAGE_BITS) - -#include - -/* Globals */ -uint sd_msglevel = SDH_ERROR_VAL; -uint sd_hiok = TRUE; /* Use hi-speed mode if available? */ -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 64; /* Default blocksize */ - -#ifdef BCMSDYIELD -bool sd_yieldcpu = TRUE; /* Allow CPU yielding for buffer requests */ -uint sd_minyield = 0; /* Minimum xfer size to allow CPU yield */ -bool sd_forcerb = FALSE; /* Force sync readback in intrs_on/off */ -#endif - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */ -uint8 sd_dma_mode = DMA_MODE_SDMA; /* Default to SDMA for now */ - -uint sd_toctl = 7; - -static bool trap_errs = FALSE; - -static const char *dma_mode_description[] = { "PIO", "SDMA", "ADMA1", "32b ADMA2", "64b ADMA2" }; - -/* Prototypes */ -static bool sdstd_start_clock(sdioh_info_t *sd, uint16 divisor); -static bool sdstd_start_power(sdioh_info_t *sd); -static bool sdstd_bus_width(sdioh_info_t *sd, int width); -static int sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode); -static int sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode); -static int sdstd_card_enablefuncs(sdioh_info_t *sd); -static void sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count); -static int sdstd_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg); -static int sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 *data); -static int sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 data); -static int sdstd_driver_init(sdioh_info_t *sd); -static bool sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset); -static int sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data); -static int sdstd_abort(sdioh_info_t *sd, uint func); -static int sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg); -static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize); -static void sd_map_dma(sdioh_info_t * sd); -static void sd_unmap_dma(sdioh_info_t * sd); -static void sd_clear_adma_dscr_buf(sdioh_info_t *sd); -static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data); -static void sd_create_adma_descriptor(sdioh_info_t *sd, - uint32 index, uint32 addr_phys, - uint16 length, uint16 flags); -static void sd_dump_adma_dscr(sdioh_info_t *sd); -static void sdstd_dumpregs(sdioh_info_t *sd); - - -/* - * Private register access routines. - */ - -/* 16 bit PCI regs */ - -extern uint16 sdstd_rreg16(sdioh_info_t *sd, uint reg); -uint16 -sdstd_rreg16(sdioh_info_t *sd, uint reg) -{ - - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} - -extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data); -void -sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data) -{ - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; - sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data)); -} - -static void -sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val) -{ - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val)); - data |= val; - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; - -} -static void -sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val) -{ - - volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg); - sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val)); - data &= ~mask; - data |= (val & mask); - *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data; -} - - -/* 32 bit PCI regs */ -static uint32 -sdstd_rreg(sdioh_info_t *sd, uint reg) -{ - volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg); - sd_ctrl(("32: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} -static inline void -sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data) -{ - *(volatile uint32 *)(sd->mem_space + reg) = (uint32)data; - sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data)); - -} - -/* 8 bit PCI regs */ -static inline void -sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data) -{ - *(volatile uint8 *)(sd->mem_space + reg) = (uint8)data; - sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data)); -} -static uint8 -sdstd_rreg8(sdioh_info_t *sd, uint reg) -{ - volatile uint8 data = *(volatile uint8 *)(sd->mem_space + reg); - sd_ctrl(("08: R Reg 0x%02x, Data 0x%x\n", reg, data)); - return data; -} - -/* - * Private work routines - */ - -sdioh_info_t *glob_sd; - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - - sd_trace(("%s\n", __FUNCTION__)); - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - glob_sd = sd; - sd->osh = osh; - if (sdstd_osinit(sd) != 0) { - sd_err(("%s:sdstd_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - sd->mem_space = (volatile char *)sdstd_reg_map(osh, (uintptr)bar0, SDIOH_REG_WINSZ); - sd_init_dma(sd); - sd->irq = irq; - if (sd->mem_space == NULL) { - sd_err(("%s:ioremap() failed\n", __FUNCTION__)); - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - sd_info(("%s:sd->mem_space = %p\n", __FUNCTION__, sd->mem_space)); - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - sd->intr_handler_valid = FALSE; - - /* Set defaults */ - sd->sd_blockmode = TRUE; - sd->use_client_ints = TRUE; - sd->sd_dma_mode = sd_dma_mode; - - if (!sd->sd_blockmode) - sd->sd_dma_mode = DMA_MODE_NONE; - - if (sdstd_driver_init(sd) != SUCCESS) { - /* If host CPU was reset without resetting SD bus or - SD device, the device will still have its RCA but - driver no longer knows what it is (since driver has been restarted). - go through once to clear the RCA and a gain reassign it. - */ - sd_info(("driver_init failed - Reset RCA and try again\n")); - if (sdstd_driver_init(sd) != SUCCESS) { - sd_err(("%s:driver_init() failed()\n", __FUNCTION__)); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - } - - OSL_DMADDRWIDTH(osh, 32); - - /* Always map DMA buffers, so we can switch between DMA modes. */ - sd_map_dma(sd); - - if (sdstd_register_irq(sd, irq) != SUCCESS) { - sd_err(("%s: sdstd_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); - sdstd_free_irq(sd->irq, sd); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - sd_trace(("%s: Done\n", __FUNCTION__)); - return sd; -} - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if (sd) { - sd_unmap_dma(sd); - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); - sd_trace(("%s: freeing irq %d\n", __FUNCTION__, sd->irq)); - sdstd_free_irq(sd->irq, sd); - if (sd->card_init_done) - sdstd_reset(sd, 1, 1); - if (sd->mem_space) { - sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - sdstd_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -/* Configure callback to client when we receive client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - uint16 intrstatus; - intrstatus = sdstd_rreg16(sd, SD_IntrStatus); - return !!(intrstatus & CLIENT_INTR); -} -#endif - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_YIELDCPU, - IOV_MINYIELD, - IOV_FORCERB, - IOV_CLOCK -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_UINT32, 0 }, -#ifdef BCMSDYIELD - {"sd_yieldcpu", IOV_YIELDCPU, 0, IOVT_BOOL, 0 }, - {"sd_minyield", IOV_MINYIELD, 0, IOVT_UINT32, 0 }, - {"sd_forcerb", IOV_FORCERB, 0, IOVT_BOOL, 0 }, -#endif - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool)int_val; - /* Haven't figured out how to make non-block mode with DMA */ - if (!si->sd_blockmode) - si->sd_dma_mode = DMA_MODE_NONE; - break; - -#ifdef BCMSDYIELD - case IOV_GVAL(IOV_YIELDCPU): - int_val = sd_yieldcpu; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_YIELDCPU): - sd_yieldcpu = (bool)int_val; - break; - - case IOV_GVAL(IOV_MINYIELD): - int_val = sd_minyield; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MINYIELD): - sd_minyield = (bool)int_val; - break; - - case IOV_GVAL(IOV_FORCERB): - int_val = sd_forcerb; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_FORCERB): - sd_forcerb = (bool)int_val; - break; -#endif /* BCMSDYIELD */ - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((uint32)int_val >> 16); - uint blksize = (uint16)int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - - switch (func) { - case 0: maxsize = 32; break; - case 1: maxsize = BLOCK_SIZE_4318; break; - case 2: maxsize = BLOCK_SIZE_4328; break; - default: maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = BCME_BADARG; - break; - } - if (!blksize) { - blksize = maxsize; - } - - /* Now set it */ - sdstd_lock(si); - bcmerror = set_client_block_size(si, func, blksize); - sdstd_unlock(si); - break; - } - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_dma_mode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_dma_mode = (char)int_val; - sdstd_set_dma_mode(si, si->sd_dma_mode); - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool)int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - if (!sdstd_start_clock(si, (uint16)sd_divisor)) { - sd_err(("set clock failed!\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - if (sd_power == 1) { - if (sdstd_driver_init(si) != SUCCESS) { - sd_err(("set SD Slot power failed!\n")); - bcmerror = BCME_ERROR; - } else { - sd_err(("SD Slot Powered ON.\n")); - } - } else { - uint8 pwr = 0; - - pwr = SFIELD(pwr, PWR_BUS_EN, 0); - sdstd_wreg8(si, SD_PwrCntrl, pwr); /* Set Voltage level */ - sd_err(("SD Slot Powered OFF.\n")); - } - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - if (sd_clock == 1) { - sd_info(("SD Clock turned ON.\n")); - if (!sdstd_start_clock(si, (uint16)sd_divisor)) { - sd_err(("sdstd_start_clock failed\n")); - bcmerror = BCME_ERROR; - } - } else { - /* turn off HC clock */ - sdstd_wreg16(si, SD_ClockCntrl, - sdstd_rreg16(si, SD_ClockCntrl) & ~((uint16)0x4)); - - sd_info(("SD Clock turned OFF.\n")); - } - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - - if (!sdstd_bus_width(si, sd_sdmode)) { - sd_err(("sdstd_bus_width failed\n")); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - bcmerror = sdstd_set_highspeed_mode(si, (bool)sd_hiok); - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)si->local_intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = sdstd_rreg8(si, sd_ptr->offset); - else if (sd_ptr->offset & 2) - int_val = sdstd_rreg16(si, sd_ptr->offset); - else - int_val = sdstd_rreg(si, sd_ptr->offset); - - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - - if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset)); - bcmerror = BCME_BADARG; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - sdstd_wreg8(si, sd_ptr->offset, (uint8)sd_ptr->value); - else if (sd_ptr->offset & 2) - sdstd_wreg16(si, sd_ptr->offset, (uint16)sd_ptr->value); - else - sdstd_wreg(si, sd_ptr->offset, (uint32)sd_ptr->value); - - break; - } - - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 foo; - uint8 *cis = cisd; - - sd_trace(("%s: Func = %d\n", __FUNCTION__, func)); - - if (!sd->func_cis_ptr[func]) { - bzero(cis, length); - return SDIOH_API_RC_FAIL; - } - - sdstd_lock(sd); - *cis = 0; - for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (sdstd_card_regread(sd, 0, offset, 1, &foo)) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - *cis = (uint8)(foo & 0xff); - cis++; - } - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - sdstd_lock(sd); - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte); - - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) != SUCCESS) { - sdstd_unlock(sd); - return status; - } - - sdstd_cmd_getrsp(sd, &rsp5, 1); - if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) { - sd_err(("%s: 1: ErrorintrStatus 0x%x\n", - __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus))); - } - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (rw == SDIOH_READ) - *byte = GFIELD(rsp5, RSP5_DATA); - - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int status; - bool swap = FALSE; - - sdstd_lock(sd); - - if (rw == SDIOH_READ) { - status = sdstd_card_regread(sd, func, addr, nbytes, word); - if (swap) - *word = BCMSWAP32(*word); - } else { - if (swap) - *word = BCMSWAP32(*word); - status = sdstd_card_regwrite(sd, func, addr, nbytes, *word); - } - - sdstd_unlock(sd); - return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - int len; - int buflen = (int)buflen_u; - bool fifo = (fix_inc == SDIOH_DATA_FIX); - uint8 *localbuf = NULL, *tmpbuf = NULL; - uint tmplen = 0; - bool local_blockmode = sd->sd_blockmode; - - sdstd_lock(sd); - - ASSERT(reg_width == 4); - ASSERT(buflen_u < (1 << 30)); - ASSERT(sd->client_block_size[func]); - - sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", - __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', - buflen_u, sd->r_cnt, sd->t_cnt, pkt)); - - /* Break buffer down into blocksize chunks: - * Bytemode: 1 block at a time. - * Blockmode: Multiples of blocksizes at a time w/ max of SD_PAGE. - * Both: leftovers are handled last (will be sent via bytemode). - */ - while (buflen > 0) { - if (local_blockmode) { - /* Max xfer is Page size */ - len = MIN(SD_PAGE, buflen); - - /* Round down to a block boundry */ - if (buflen > sd->client_block_size[func]) - len = (len/sd->client_block_size[func]) * - sd->client_block_size[func]; - if ((func == SDIO_FUNC_1) && ((len % 4) == 3) && (rw == SDIOH_WRITE)) { - tmplen = len; - sd_err(("%s: Rounding up buffer to mod4 length.\n", __FUNCTION__)); - len++; - tmpbuf = buffer; - if ((localbuf = (uint8 *)MALLOC(sd->osh, len)) == NULL) { - sd_err(("out of memory, malloced %d bytes\n", - MALLOCED(sd->osh))); - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - bcopy(buffer, localbuf, len); - buffer = localbuf; - } - } else { - /* Byte mode: One block at a time */ - len = MIN(sd->client_block_size[func], buflen); - } - - if (sdstd_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { - sdstd_unlock(sd); - return SDIOH_API_RC_FAIL; - } - - if (local_blockmode) { - if ((func == SDIO_FUNC_1) && ((tmplen % 4) == 3) && (rw == SDIOH_WRITE)) { - if (localbuf) - MFREE(sd->osh, localbuf, len); - len--; - buffer = tmpbuf; - sd_err(("%s: Restoring back buffer ptr and len.\n", __FUNCTION__)); - } - } - - buffer += len; - buflen -= len; - if (!fifo) - addr += len; - } - sdstd_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -static -int sdstd_abort(sdioh_info_t *sd, uint func) -{ - int err = 0; - int retries; - - uint16 cmd_reg; - uint32 cmd_arg; - uint32 rsp5; - uint8 rflags; - - uint16 int_reg = 0; - uint16 plain_intstatus; - - /* Argument is write to F0 (CCCR) IOAbort with function number */ - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, SDIO_FUNC_0); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, SDIOD_CCCR_IOABORT); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SD_IO_OP_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, func); - - /* Command is CMD52 write */ - cmd_reg = 0; - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48_BUSY); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_ABORT); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, SDIOH_CMD_52); - - if (sd->sd_mode == SDIOH_MODE_SPI) { - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - } - - /* Wait for CMD_INHIBIT to go away as per spec section 3.6.1.1 */ - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CMD_INHIBIT)) { - if (retries == RETRIES_SMALL) - sd_err(("%s: Waiting for Command Inhibit, state 0x%08x\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState))); - if (!--retries) { - sd_err(("%s: Command Inhibit timeout, state 0x%08x\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState))); - if (trap_errs) - ASSERT(0); - err = BCME_SDIO_ERROR; - goto done; - } - } - - /* Clear errors from any previous commands */ - if ((plain_intstatus = sdstd_rreg16(sd, SD_ErrorIntrStatus)) != 0) { - sd_err(("abort: clearing errstat 0x%04x\n", plain_intstatus)); - sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus); - } - plain_intstatus = sdstd_rreg16(sd, SD_IntrStatus); - if (plain_intstatus & ~(SFIELD(0, INTSTAT_CARD_INT, 1))) { - sd_err(("abort: intstatus 0x%04x\n", plain_intstatus)); - if (GFIELD(plain_intstatus, INTSTAT_CMD_COMPLETE)) { - sd_err(("SDSTD_ABORT: CMD COMPLETE SET BEFORE COMMAND GIVEN!!!\n")); - } - if (GFIELD(plain_intstatus, INTSTAT_CARD_REMOVAL)) { - sd_err(("SDSTD_ABORT: INTSTAT_CARD_REMOVAL\n")); - err = BCME_NODEVICE; - goto done; - } - } - - /* Issue the command */ - sdstd_wreg(sd, SD_Arg0, cmd_arg); - sdstd_wreg16(sd, SD_Command, cmd_reg); - - /* In interrupt mode return, expect later CMD_COMPLETE interrupt */ - if (!sd->polled_mode) - return err; - - /* Otherwise, wait for the command to complete */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && - (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) && - (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0)); - - /* If command completion fails, do a cmd reset and note the error */ - if (!retries) { - sd_err(("%s: CMD_COMPLETE timeout: intr 0x%04x err 0x%04x state 0x%08x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - - sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset), - SW_RESET_CMD)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - - err = BCME_SDIO_ERROR; - } - - /* Clear Command Complete interrupt */ - int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1); - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* Check for Errors */ - if ((plain_intstatus = sdstd_rreg16 (sd, SD_ErrorIntrStatus)) != 0) { - sd_err(("%s: ErrorintrStatus: 0x%x, " - "(intrstatus = 0x%x, present state 0x%x) clearing\n", - __FUNCTION__, plain_intstatus, - sdstd_rreg16(sd, SD_IntrStatus), - sdstd_rreg(sd, SD_PresentState))); - - sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus); - - sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for DAT line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset), - SW_RESET_DAT)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - - /* ABORT is dataless, only cmd errs count */ - if (plain_intstatus & ERRINT_CMD_ERRS) - err = BCME_SDIO_ERROR; - } - - /* If command failed don't bother looking at response */ - if (err) - goto done; - - /* Otherwise, check the response */ - sdstd_cmd_getrsp(sd, &rsp5, 1); - rflags = GFIELD(rsp5, RSP5_FLAGS); - - if (rflags & SD_RSP_R5_ERRBITS) { - sd_err(("%s: R5 flags include errbits: 0x%02x\n", __FUNCTION__, rflags)); - - /* The CRC error flag applies to the previous command */ - if (rflags & (SD_RSP_R5_ERRBITS & ~SD_RSP_R5_COM_CRC_ERROR)) { - err = BCME_SDIO_ERROR; - goto done; - } - } - - if (((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x10) && - ((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x20)) { - sd_err(("%s: R5 flags has bad state: 0x%02x\n", __FUNCTION__, rflags)); - err = BCME_SDIO_ERROR; - goto done; - } - - if (GFIELD(rsp5, RSP5_STUFF)) { - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - err = BCME_SDIO_ERROR; - goto done; - } - -done: - if (err == BCME_NODEVICE) - return err; - - sdstd_wreg8(sd, SD_SoftwareReset, - SFIELD(SFIELD(0, SW_RESET_DAT, 1), SW_RESET_CMD, 1)); - - retries = RETRIES_LARGE; - do { - rflags = sdstd_rreg8(sd, SD_SoftwareReset); - if (!GFIELD(rflags, SW_RESET_DAT) && !GFIELD(rflags, SW_RESET_CMD)) - break; - } while (--retries); - - if (!retries) { - sd_err(("%s: Timeout waiting for DAT/CMD reset: 0x%02x\n", - __FUNCTION__, rflags)); - err = BCME_SDIO_ERROR; - } - - return err; -} - -extern int -sdioh_abort(sdioh_info_t *sd, uint fnum) -{ - int ret; - - sdstd_lock(sd); - ret = sdstd_abort(sd, fnum); - sdstd_unlock(sd); - - return ret; -} - -int -sdioh_start(sdioh_info_t *sd, int stage) -{ - return SUCCESS; -} - -int -sdioh_stop(sdioh_info_t *sd) -{ - return SUCCESS; -} - -static int -sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg) -{ - uint16 regval; - uint retries; - uint function = 0; - - /* If no errors, we're done */ - if ((regval = sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)) == 0) - return SUCCESS; - - sd_info(("%s: ErrorIntrStatus 0x%04x (clearing), IntrStatus 0x%04x PresentState 0x%08x\n", - __FUNCTION__, regval, sdstd_rreg16(sdioh_info, SD_IntrStatus), - sdstd_rreg(sdioh_info, SD_PresentState))); - sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval); - - /* On command error, issue CMD reset */ - if (regval & ERRINT_CMD_ERRS) { - sd_trace(("%s: issuing CMD reset\n", __FUNCTION__)); - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - for (retries = RETRIES_LARGE; retries; retries--) - if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_CMD))) - break; - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - } - - /* On data error, issue DAT reset */ - if (regval & ERRINT_DATA_ERRS) { - sd_trace(("%s: issuing DAT reset\n", __FUNCTION__)); - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1)); - for (retries = RETRIES_LARGE; retries; retries--) - if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_DAT))) - break; - if (!retries) { - sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__)); - } - } - - /* For an IO command (CMD52 or CMD53) issue an abort to the appropriate function */ - if (cmd == SDIOH_CMD_53) - function = GFIELD(arg, CMD53_FUNCTION); - else if (cmd == SDIOH_CMD_52) - function = GFIELD(arg, CMD52_FUNCTION); - if (function) { - sd_trace(("%s: requesting abort for function %d after cmd %d\n", - __FUNCTION__, function, cmd)); - sdstd_abort(sdioh_info, function); - } - - if (trap_errs) - ASSERT(0); - - return ERROR; -} - - - -/* - * Private/Static work routines - */ -static bool -sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset) -{ - int retries = RETRIES_LARGE; - uchar regval; - - if (!sd) - return TRUE; - - sdstd_lock(sd); - /* Reset client card */ - if (client_reset && (sd->adapter_slot != -1)) { - if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS) - sd_err(("%s: Cannot write to card reg 0x%x\n", - __FUNCTION__, SDIOD_CCCR_IOABORT)); - else - sd->card_rca = 0; - } - - /* Reset host controller */ - if (host_reset) { - regval = SFIELD(0, SW_RESET_ALL, 1); - sdstd_wreg8(sd, SD_SoftwareReset, regval); - do { - sd_trace(("%s: waiting for reset\n", __FUNCTION__)); - } while ((sdstd_rreg8(sd, SD_SoftwareReset) & regval) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for host reset\n", __FUNCTION__)); - sdstd_unlock(sd); - return (FALSE); - } - - /* A reset should reset bus back to 1 bit mode */ - sd->sd_mode = SDIOH_MODE_SD1; - sdstd_set_dma_mode(sd, sd->sd_dma_mode); - } - sdstd_unlock(sd); - return TRUE; -} - -/* Disable device interrupt */ -void -sdstd_devintr_off(sdioh_info_t *sd) -{ - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - sd->intmask &= ~CLIENT_INTR; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ - } -} - -/* Enable device interrupt */ -void -sdstd_devintr_on(sdioh_info_t *sd) -{ - ASSERT(sd->lockcount == 0); - sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints)); - if (sd->use_client_ints) { - uint16 status = sdstd_rreg16(sd, SD_IntrStatusEnable); - sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(status, INTSTAT_CARD_INT, 0)); - sdstd_wreg16(sd, SD_IntrStatusEnable, status); - - sd->intmask |= CLIENT_INTR; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ - } -} - -#ifdef BCMSDYIELD -/* Enable/disable other interrupts */ -void -sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - if (err) { - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, err); - } - - sd->intmask |= norm; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - if (sd_forcerb) - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ -} - -void -sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - if (err) { - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0); - } - - sd->intmask &= ~norm; - sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask); - if (sd_forcerb) - sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */ -} -#endif /* BCMSDYIELD */ - -static int -sdstd_host_init(sdioh_info_t *sd) -{ - int num_slots, full_slot; - uint8 reg8; - - uint32 card_ins; - int slot, first_bar = 0; - bool detect_slots = FALSE; - uint bar; - - /* Check for Arasan ID */ - if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_SI_IMAGE) { - sd_info(("%s: Found Arasan Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_ARASAN_HDK; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_BROADCOM) { - sd_info(("%s: Found Broadcom 27xx Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_BCM27XX; - detect_slots = FALSE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_TI) { - sd_info(("%s: Found TI PCIxx21 Standard SDIO Host Controller\n", __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_TI_PCIXX21; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_RICOH) { - sd_info(("%s: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter\n", - __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_RICOH_R5C822; - detect_slots = TRUE; - } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JMICRON) { - sd_info(("%s: JMicron Standard SDIO Host Controller\n", - __FUNCTION__)); - sd->controller_type = SDIOH_TYPE_JMICRON; - detect_slots = TRUE; - } else { - return ERROR; - } - - /* - * Determine num of slots - * Search each slot - */ - - first_bar = OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0x7; - num_slots = (OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0xff) >> 4; - num_slots &= 7; - num_slots++; /* map bits to num slots according to spec */ - - if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) == - ((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) { - sd_err(("%s: Found Broadcom Standard SDIO Host Controller FPGA\n", __FUNCTION__)); - /* Set BAR0 Window to SDIOSTH core */ - OSL_PCI_WRITE_CONFIG(sd->osh, PCI_BAR0_WIN, 4, 0x18001000); - - /* Set defaults particular to this controller. */ - detect_slots = TRUE; - num_slots = 1; - first_bar = 0; - - /* Controller supports ADMA2, so turn it on here. */ - sd->sd_dma_mode = DMA_MODE_ADMA2; - } - - /* Map in each slot on the board and query it to see if a - * card is inserted. Use the first populated slot found. - */ - if (sd->mem_space) { - sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - - full_slot = -1; - - for (slot = 0; slot < num_slots; slot++) { - bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(slot + first_bar)), 4); - sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, - (uintptr)bar, SDIOH_REG_WINSZ); - - sd->adapter_slot = -1; - - if (detect_slots) { - card_ins = GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CARD_PRESENT); - } else { - card_ins = TRUE; - } - - if (card_ins) { - sd_info(("%s: SDIO slot %d: Full\n", __FUNCTION__, slot)); - if (full_slot < 0) - full_slot = slot; - } else { - sd_info(("%s: SDIO slot %d: Empty\n", __FUNCTION__, slot)); - } - - if (sd->mem_space) { - sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ); - sd->mem_space = NULL; - } - } - - if (full_slot < 0) { - sd_err(("No slots on SDIO controller are populated\n")); - return -1; - } - - bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4); - sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (uintptr)bar, SDIOH_REG_WINSZ); - - sd_err(("Using slot %d at BAR%d [0x%08x] mem_space 0x%p\n", - full_slot, - (full_slot + first_bar), - OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4), - sd->mem_space)); - - - sd->adapter_slot = full_slot; - - sd->version = sdstd_rreg16(sd, SD_HostControllerVersion) & 0xFF; - switch (sd->version) { - case 0: - sd_err(("Host Controller version 1.0, Vendor Revision: 0x%02x\n", - sdstd_rreg16(sd, SD_HostControllerVersion) >> 8)); - break; - case 1: - case 2: - sd_err(("Host Controller version 2.0, Vendor Revision: 0x%02x\n", - sdstd_rreg16(sd, SD_HostControllerVersion) >> 8)); - break; - default: - sd_err(("%s: Host Controller version 0x%02x not supported.\n", - __FUNCTION__, sd->version)); - break; - } - - sd->caps = sdstd_rreg(sd, SD_Capabilities); /* Cache this for later use */ - sd->curr_caps = sdstd_rreg(sd, SD_MaxCurCap); - - sdstd_set_dma_mode(sd, sd->sd_dma_mode); - - - sdstd_reset(sd, 1, 0); - - /* Read SD4/SD1 mode */ - if ((reg8 = sdstd_rreg8(sd, SD_HostCntrl))) { - if (reg8 & SD4_MODE) { - sd_err(("%s: Host cntrlr already in 4 bit mode: 0x%x\n", - __FUNCTION__, reg8)); - } - } - - /* Default power on mode is SD1 */ - sd->sd_mode = SDIOH_MODE_SD1; - sd->polled_mode = TRUE; - sd->host_init_done = TRUE; - sd->card_init_done = FALSE; - sd->adapter_slot = full_slot; - - return (SUCCESS); -} -#define CMD5_RETRIES 200 -static int -get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp) -{ - int retries, status; - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - retries = CMD5_RETRIES; - do { - *cmd_rsp = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_5, *cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD5 failed\n", __FUNCTION__)); - return status; - } - sdstd_cmd_getrsp(sd, cmd_rsp, 1); - if (!GFIELD(*cmd_rsp, RSP4_CARD_READY)) - sd_trace(("%s: Waiting for card to become ready\n", __FUNCTION__)); - } while ((!GFIELD(*cmd_rsp, RSP4_CARD_READY)) && --retries); - if (!retries) - return ERROR; - - return (SUCCESS); -} - -static int -sdstd_client_init(sdioh_info_t *sd) -{ - uint32 cmd_arg, cmd_rsp; - int status; - uint8 fn_ints; - - - sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); - - /* Clear any pending ints */ - sdstd_wreg16(sd, SD_IntrStatus, 0x1ff); - sdstd_wreg16(sd, SD_ErrorIntrStatus, 0x0fff); - - /* Enable both Normal and Error Status. This does not enable - * interrupts, it only enables the status bits to - * become 'live' - */ - sdstd_wreg16(sd, SD_IntrStatusEnable, 0x1ff); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, 0xffff); - - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); /* Disable ints for now. */ - - /* Start at ~400KHz clock rate for initialization */ - if (!sdstd_start_clock(sd, 128)) { - sd_err(("sdstd_start_clock failed\n")); - return ERROR; - } - if (!sdstd_start_power(sd)) { - sd_err(("sdstd_start_power failed\n")); - return ERROR; - } - - if (sd->num_funcs == 0) { - sd_err(("%s: No IO funcs!\n", __FUNCTION__)); - return ERROR; - } - - /* In SPI mode, issue CMD0 first */ - if (sd->sd_mode == SDIOH_MODE_SPI) { - cmd_arg = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_0, cmd_arg)) - != SUCCESS) { - sd_err(("BCMSDIOH: cardinit: CMD0 failed!\n")); - return status; - } - } - - if (sd->sd_mode != SDIOH_MODE_SPI) { - uint16 rsp6_status; - - /* Card is operational. Ask it to send an RCA */ - cmd_arg = 0; - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_3, cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD3 failed!\n", __FUNCTION__)); - return status; - } - - /* Verify the card status returned with the cmd response */ - sdstd_cmd_getrsp(sd, &cmd_rsp, 1); - rsp6_status = GFIELD(cmd_rsp, RSP6_STATUS); - if (GFIELD(rsp6_status, RSP6STAT_COM_CRC_ERROR) || - GFIELD(rsp6_status, RSP6STAT_ILLEGAL_CMD) || - GFIELD(rsp6_status, RSP6STAT_ERROR)) { - sd_err(("%s: CMD3 response error. Response = 0x%x!\n", - __FUNCTION__, rsp6_status)); - return ERROR; - } - - /* Save the Card's RCA */ - sd->card_rca = GFIELD(cmd_rsp, RSP6_IO_RCA); - sd_info(("RCA is 0x%x\n", sd->card_rca)); - - if (rsp6_status) - sd_err(("raw status is 0x%x\n", rsp6_status)); - - /* Select the card */ - cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca); - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg)) - != SUCCESS) { - sd_err(("%s: CMD7 failed!\n", __FUNCTION__)); - return status; - } - sdstd_cmd_getrsp(sd, &cmd_rsp, 1); - if (cmd_rsp != SDIOH_CMD7_EXP_STATUS) { - sd_err(("%s: CMD7 response error. Response = 0x%x!\n", - __FUNCTION__, cmd_rsp)); - return ERROR; - } - } - - sdstd_card_enablefuncs(sd); - - if (!sdstd_bus_width(sd, sd_sdmode)) { - sd_err(("sdstd_bus_width failed\n")); - return ERROR; - } - - set_client_block_size(sd, 1, BLOCK_SIZE_4318); - fn_ints = INTR_CTL_FUNC1_EN; - - if (sd->num_funcs >= 2) { - set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */); - fn_ints |= INTR_CTL_FUNC2_EN; - } - - /* Enable/Disable Client interrupts */ - /* Turn on here but disable at host controller? */ - if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1, - (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) { - sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__)); - return ERROR; - } - - /* Switch to High-speed clocking mode if both host and device support it */ - sdstd_set_highspeed_mode(sd, (bool)sd_hiok); - - /* After configuring for High-Speed mode, set the desired clock rate. */ - if (!sdstd_start_clock(sd, (uint16)sd_divisor)) { - sd_err(("sdstd_start_clock failed\n")); - return ERROR; - } - - sd->card_init_done = TRUE; - - return SUCCESS; -} - -static int -sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode) -{ - uint32 regdata; - int status; - uint8 reg8; - - reg8 = sdstd_rreg8(sd, SD_HostCntrl); - - - if (HSMode == TRUE) { - if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) { - sd_err(("Host Controller does not support hi-speed mode.\n")); - return BCME_ERROR; - } - - sd_info(("Attempting to enable High-Speed mode.\n")); - - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != SUCCESS) { - return BCME_SDIO_ERROR; - } - if (regdata & SDIO_SPEED_SHS) { - sd_info(("Device supports High-Speed mode.\n")); - - regdata |= SDIO_SPEED_EHS; - - sd_info(("Writing %08x to Card at %08x\n", - regdata, SDIOD_CCCR_SPEED_CONTROL)); - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return BCME_SDIO_ERROR; - } - - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != BCME_OK) { - return BCME_SDIO_ERROR; - } - - sd_info(("Read %08x to Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL)); - - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 1); - - sd_err(("High-speed clocking mode enabled.\n")); - } - else { - sd_err(("Device does not support High-Speed Mode.\n")); - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0); - } - } else { - /* Force off device bit */ - if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, ®data)) != BCME_OK) { - return status; - } - if (regdata & SDIO_SPEED_EHS) { - regdata &= ~SDIO_SPEED_EHS; - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL, - 1, regdata)) != BCME_OK) { - return status; - } - } - - sd_err(("High-speed clocking mode disabled.\n")); - reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0); - } - - sdstd_wreg8(sd, SD_HostCntrl, reg8); - - return BCME_OK; -} - -/* Select DMA Mode: - * If dma_mode == DMA_MODE_AUTO, pick the "best" mode. - * Otherwise, pick the selected mode if supported. - * If not supported, use PIO mode. - */ -static int -sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode) -{ - uint8 reg8, dma_sel_bits = SDIOH_SDMA_MODE; - int8 prev_dma_mode = sd->sd_dma_mode; - - switch (prev_dma_mode) { - case DMA_MODE_AUTO: - sd_dma(("%s: Selecting best DMA mode supported by controller.\n", - __FUNCTION__)); - if (GFIELD(sd->caps, CAP_ADMA2)) { - sd->sd_dma_mode = DMA_MODE_ADMA2; - dma_sel_bits = SDIOH_ADMA2_MODE; - } else if (GFIELD(sd->caps, CAP_ADMA1)) { - sd->sd_dma_mode = DMA_MODE_ADMA1; - dma_sel_bits = SDIOH_ADMA1_MODE; - } else if (GFIELD(sd->caps, CAP_DMA)) { - sd->sd_dma_mode = DMA_MODE_SDMA; - } else { - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_NONE: - sd->sd_dma_mode = DMA_MODE_NONE; - break; - case DMA_MODE_SDMA: - if (GFIELD(sd->caps, CAP_DMA)) { - sd->sd_dma_mode = DMA_MODE_SDMA; - } else { - sd_err(("%s: SDMA not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA1: - if (GFIELD(sd->caps, CAP_ADMA1)) { - sd->sd_dma_mode = DMA_MODE_ADMA1; - dma_sel_bits = SDIOH_ADMA1_MODE; - } else { - sd_err(("%s: ADMA1 not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA2: - if (GFIELD(sd->caps, CAP_ADMA2)) { - sd->sd_dma_mode = DMA_MODE_ADMA2; - dma_sel_bits = SDIOH_ADMA2_MODE; - } else { - sd_err(("%s: ADMA2 not supported by controller.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - } - break; - case DMA_MODE_ADMA2_64: - sd_err(("%s: 64b ADMA2 not supported by driver.\n", __FUNCTION__)); - sd->sd_dma_mode = DMA_MODE_NONE; - break; - default: - sd_err(("%s: Unsupported DMA Mode %d requested.\n", __FUNCTION__, - prev_dma_mode)); - sd->sd_dma_mode = DMA_MODE_NONE; - break; - } - - /* clear SysAddr, only used for SDMA */ - sdstd_wreg(sd, SD_SysAddr, 0); - - sd_err(("%s: %s mode selected.\n", __FUNCTION__, dma_mode_description[sd->sd_dma_mode])); - - reg8 = sdstd_rreg8(sd, SD_HostCntrl); - reg8 = SFIELD(reg8, HOST_DMA_SEL, dma_sel_bits); - sdstd_wreg8(sd, SD_HostCntrl, reg8); - sd_dma(("%s: SD_HostCntrl=0x%02x\n", __FUNCTION__, reg8)); - - return BCME_OK; -} - - -bool -sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor) -{ - uint rc, count; - uint16 divisor; - - /* turn off HC clock */ - sdstd_wreg16(sd, SD_ClockCntrl, - sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4)); /* Disable the HC clock */ - - /* Set divisor */ - - divisor = (new_sd_divisor >> 1) << 8; - - sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl))); - sdstd_mod_reg16(sd, SD_ClockCntrl, 0xff00, divisor); - sd_info(("%s: Using clock divisor of %d (regval 0x%04x)\n", __FUNCTION__, - new_sd_divisor, divisor)); - - sd_info(("Primary Clock Freq = %d MHz\n", GFIELD(sd->caps, CAP_TO_CLKFREQ))); - - if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 50) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((50 % new_sd_divisor) ? (50000 / new_sd_divisor) : (50 / new_sd_divisor)), - ((50 % new_sd_divisor) ? "KHz" : "MHz"))); - } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 48) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((48 % new_sd_divisor) ? (48000 / new_sd_divisor) : (48 / new_sd_divisor)), - ((48 % new_sd_divisor) ? "KHz" : "MHz"))); - } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 33) { - sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__, - ((33 % new_sd_divisor) ? (33000 / new_sd_divisor) : (33 / new_sd_divisor)), - ((33 % new_sd_divisor) ? "KHz" : "MHz"))); - - } else if (sd->controller_type == SDIOH_TYPE_BCM27XX) { - } else { - sd_err(("Need to determine divisor for %d MHz clocks\n", - GFIELD(sd->caps, CAP_TO_CLKFREQ))); - sd_err(("Consult SD Host Controller Spec: Clock Control Register\n")); - return (FALSE); - } - - sdstd_or_reg16(sd, SD_ClockCntrl, 0x1); /* Enable the clock */ - - /* Wait for clock to stabilize */ - rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2); - count = 0; - while (!rc) { - OSL_DELAY(1); - sd_info(("Waiting for clock to become stable 0x%x\n", rc)); - rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2); - count++; - if (count > 10000) { - sd_err(("%s:Clocks failed to stabilize after %u attempts", - __FUNCTION__, count)); - return (FALSE); - } - } - /* Turn on clock */ - sdstd_or_reg16(sd, SD_ClockCntrl, 0x4); - - /* Set timeout control (adjust default value based on divisor). - * Disabling timeout interrupts during setting is advised by host spec. - */ - { - uint16 regdata; - uint toval; - - toval = sd_toctl; - divisor = new_sd_divisor; - - while (toval && !(divisor & 1)) { - toval -= 1; - divisor >>= 1; - } - - regdata = sdstd_rreg16(sd, SD_ErrorIntrStatusEnable); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, (regdata & ~ERRINT_DATA_TIMEOUT_BIT)); - sdstd_wreg8(sd, SD_TimeoutCntrl, (uint8)toval); - sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, regdata); - } - - OSL_DELAY(2); - - sd_info(("Final Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl))); - - return TRUE; -} - -bool -sdstd_start_power(sdioh_info_t *sd) -{ - char *s; - uint32 cmd_arg; - uint32 cmd_rsp; - uint8 pwr = 0; - int volts; - - volts = 0; - s = NULL; - if (GFIELD(sd->caps, CAP_VOLT_1_8)) { - volts = 5; - s = "1.8"; - } - if (GFIELD(sd->caps, CAP_VOLT_3_0)) { - volts = 6; - s = "3.0"; - } - if (GFIELD(sd->caps, CAP_VOLT_3_3)) { - volts = 7; - s = "3.3"; - } - - pwr = SFIELD(pwr, PWR_VOLTS, volts); - pwr = SFIELD(pwr, PWR_BUS_EN, 1); - sdstd_wreg8(sd, SD_PwrCntrl, pwr); /* Set Voltage level */ - sd_info(("Setting Bus Power to %s Volts\n", s)); - - /* Wait for power to stabilize, Dongle takes longer than NIC. */ - OSL_DELAY(250000); - - /* Get the Card's Operation Condition. Occasionally the board - * takes a while to become ready - */ - cmd_arg = 0; - cmd_rsp = 0; - if (get_ocr(sd, &cmd_arg, &cmd_rsp) != SUCCESS) { - sd_err(("%s: Failed to get OCR bailing\n", __FUNCTION__)); - sdstd_reset(sd, 0, 1); - return FALSE; - } - - sd_info(("mem_present = %d\n", GFIELD(cmd_rsp, RSP4_MEM_PRESENT))); - sd_info(("num_funcs = %d\n", GFIELD(cmd_rsp, RSP4_NUM_FUNCS))); - sd_info(("card_ready = %d\n", GFIELD(cmd_rsp, RSP4_CARD_READY))); - sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - - /* Verify that the card supports I/O mode */ - if (GFIELD(cmd_rsp, RSP4_NUM_FUNCS) == 0) { - sd_err(("%s: Card does not support I/O\n", __FUNCTION__)); - return ERROR; - } - sd->num_funcs = GFIELD(cmd_rsp, RSP4_NUM_FUNCS); - - /* Examine voltage: Arasan only supports 3.3 volts, - * so look for 3.2-3.3 Volts and also 3.3-3.4 volts. - */ - - if ((GFIELD(cmd_rsp, RSP4_IO_OCR) & (0x3 << 20)) == 0) { - sd_err(("This client does not support 3.3 volts!\n")); - return ERROR; - } - sd_info(("Leaving bus power at 3.3 Volts\n")); - - cmd_arg = SFIELD(0, CMD5_OCR, 0xfff000); - cmd_rsp = 0; - get_ocr(sd, &cmd_arg, &cmd_rsp); - sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR))); - return TRUE; -} - -bool -sdstd_bus_width(sdioh_info_t *sd, int new_mode) -{ - uint32 regdata; - int status; - uint8 reg8; - - sd_trace(("%s\n", __FUNCTION__)); - if (sd->sd_mode == new_mode) { - sd_info(("%s: Already at width %d\n", __FUNCTION__, new_mode)); - /* Could exit, but continue just in case... */ - } - - /* Set client side via reg 0x7 in CCCR */ - if ((status = sdstd_card_regread (sd, 0, SDIOD_CCCR_BICTRL, 1, ®data)) != SUCCESS) - return (bool)status; - regdata &= ~BUS_SD_DATA_WIDTH_MASK; - if (new_mode == SDIOH_MODE_SD4) { - sd_info(("Changing to SD4 Mode\n")); - regdata |= SD4_MODE; - } else if (new_mode == SDIOH_MODE_SD1) { - sd_info(("Changing to SD1 Mode\n")); - } else { - sd_err(("SPI Mode not supported by Standard Host Controller\n")); - } - - if ((status = sdstd_card_regwrite (sd, 0, SDIOD_CCCR_BICTRL, 1, regdata)) != SUCCESS) - return (bool)status; - - /* Set host side via Host reg */ - reg8 = sdstd_rreg8(sd, SD_HostCntrl) & ~SD4_MODE; - if (new_mode == SDIOH_MODE_SD4) - reg8 |= SD4_MODE; - sdstd_wreg8(sd, SD_HostCntrl, reg8); - - sd->sd_mode = new_mode; - - return TRUE; -} - -static int -sdstd_driver_init(sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if ((sdstd_host_init(sd)) != SUCCESS) { - return ERROR; - } - - if (sdstd_client_init(sd) != SUCCESS) { - return ERROR; - } - - return SUCCESS; -} - -static int -sdstd_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i; - uint32 scratch, regdata; - uint8 *ptr = (uint8 *)&scratch; - for (i = 0; i < 3; i++) { - if ((sdstd_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) - sd_err(("%s: Can't read!\n", __FUNCTION__)); - - *ptr++ = (uint8) regdata; - regaddr++; - } - /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); - scratch &= 0x0001FFFF; - return (scratch); -} - -static int -sdstd_card_enablefuncs(sdioh_info_t *sd) -{ - int status; - uint32 regdata; - uint32 fbraddr; - uint8 func; - - sd_trace(("%s\n", __FUNCTION__)); - - /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdstd_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr)); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = sdstd_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", - __FUNCTION__, func, sd->func_cis_ptr[func])); - } - - /* Enable function 1 on the card */ - regdata = SDIO_FUNC_ENABLE_1; - if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOEN, 1, regdata)) != SUCCESS) - return status; - - return SUCCESS; -} - -/* Read client card reg */ -static int -sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_READ); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, 0); - - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - if (sdstd_rreg16(sd, SD_ErrorIntrStatus) != 0) { - sd_err(("%s: 1: ErrorintrStatus 0x%x\n", - __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus))); - } - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - *data = GFIELD(rsp5, RSP5_DATA); - } else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - - sd->data_xfer_count = regsize; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags is 0x%x\t %d\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func)); - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (sd->polled_mode) { - volatile uint16 int_reg; - int retries = RETRIES_LARGE; - - /* Wait for Read Buffer to become ready */ - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_BUF_READ_READY) == 0)); - - if (!retries) { - sd_err(("%s: Timeout on Buf_Read_Ready: " - "intStat: 0x%x errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - - /* Have Buffer Ready, so clear it and read the data */ - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_BUF_READ_READY, 1)); - if (regsize == 2) - *data = sdstd_rreg16(sd, SD_BufferDataPort0); - else - *data = sdstd_rreg(sd, SD_BufferDataPort0); - - /* Check Status. - * After the data is read, the Transfer Complete bit should be on - */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0)); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - if (!retries) { - sd_err(("%s: Timeout on xfer complete: " - "intr 0x%04x err 0x%04x state 0x%08x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - return (ERROR); - } - - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_XFER_COMPLETE, 1)); - } - } - if (sd->polled_mode) { - if (regsize == 2) - *data &= 0xffff; - } - return SUCCESS; -} - -bool -check_client_intr(sdioh_info_t *sd) -{ - uint16 raw_int, cur_int, old_int; - - raw_int = sdstd_rreg16(sd, SD_IntrStatus); - cur_int = raw_int & sd->intmask; - - if (!cur_int) { - /* Not an error -- might share interrupts... */ - return FALSE; - } - - if (GFIELD(cur_int, INTSTAT_CARD_INT)) { - old_int = sdstd_rreg16(sd, SD_IntrStatusEnable); - sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(old_int, INTSTAT_CARD_INT, 0)); - - if (sd->client_intr_enabled && sd->use_client_ints) { - sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); - (sd->intr_handler)(sd->intr_handler_arg); - } else { - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __FUNCTION__, sd->client_intr_enabled, sd->intr_handler)); - } - sdstd_wreg16(sd, SD_IntrStatusEnable, old_int); - } else { - /* Local interrupt: disable, set flag, and save intrstatus */ - sdstd_wreg16(sd, SD_IntrSignalEnable, 0); - sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0); - sd->local_intrcount++; - sd->got_hcint = TRUE; - sd->last_intrstatus = cur_int; - } - - return TRUE; -} - -void -sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err) -{ - uint16 int_reg, err_reg; - int retries = RETRIES_LARGE; - - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - err_reg = sdstd_rreg16(sd, SD_ErrorIntrStatus); - } while (--retries && !(int_reg & norm) && !(err_reg & err)); - - norm |= sd->intmask; - if (err_reg & err) - norm = SFIELD(norm, INTSTAT_ERROR_INT, 1); - sd->last_intrstatus = int_reg & norm; -} - -/* write a client register */ -static int -sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - int status; - uint32 cmd_arg, rsp5, flags; - - cmd_arg = 0; - - if ((func == 0) || (regsize == 1)) { - cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0); - cmd_arg = SFIELD(cmd_arg, CMD52_DATA, data & 0xff); - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - flags = GFIELD(rsp5, RSP5_FLAGS); - if (flags && (flags != 0x10)) - sd_err(("%s: rsp5.rsp5.flags = 0x%x, expecting 0x10\n", - __FUNCTION__, flags)); - } - else { - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize); - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = regsize; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg)) - != SUCCESS) - return status; - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10\n", - __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS))); - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - - if (sd->polled_mode) { - uint16 int_reg; - int retries = RETRIES_LARGE; - - /* Wait for Write Buffer to become ready */ - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_BUF_WRITE_READY) == 0)); - - if (!retries) { - sd_err(("%s: Timeout on Buf_Write_Ready: intStat: 0x%x " - "errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - /* Clear Write Buf Ready bit */ - int_reg = 0; - int_reg = SFIELD(int_reg, INTSTAT_BUF_WRITE_READY, 1); - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* At this point we have Buffer Ready, so write the data */ - if (regsize == 2) - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16) data); - else - sdstd_wreg(sd, SD_BufferDataPort0, data); - - /* Wait for Transfer Complete */ - retries = RETRIES_LARGE; - do { - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - } while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0)); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - if (retries == 0) { - sd_err(("%s: Timeout for xfer complete; State = 0x%x, " - "intr state=0x%x, Errintstatus 0x%x rcnt %d, tcnt %d\n", - __FUNCTION__, sdstd_rreg(sd, SD_PresentState), - int_reg, sdstd_rreg16(sd, SD_ErrorIntrStatus), - sd->r_cnt, sd->t_cnt)); - } - /* Clear the status bits */ - sdstd_wreg16(sd, SD_IntrStatus, SFIELD(int_reg, INTSTAT_CARD_INT, 0)); - } - } - return SUCCESS; -} - -void -sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count /* num 32 bit words */) -{ - int rsp_count; - int respaddr = SD_Response0; - - if (count > 4) - count = 4; - - for (rsp_count = 0; rsp_count < count; rsp_count++) { - *rsp_buffer++ = sdstd_rreg(sd, respaddr); - respaddr += 4; - } -} - -static int -sdstd_cmd_issue(sdioh_info_t *sdioh_info, bool use_dma, uint32 cmd, uint32 arg) -{ - uint16 cmd_reg; - int retries; - uint32 cmd_arg; - uint16 xfer_reg = 0; - - - if ((sdioh_info->sd_mode == SDIOH_MODE_SPI) && - ((cmd == SDIOH_CMD_3) || (cmd == SDIOH_CMD_7) || (cmd == SDIOH_CMD_15))) { - sd_err(("%s: Cmd %d is not for SPI\n", __FUNCTION__, cmd)); - return ERROR; - } - - retries = RETRIES_SMALL; - while ((GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), PRES_CMD_INHIBIT)) && --retries) { - if (retries == RETRIES_SMALL) - sd_err(("%s: Waiting for Command Inhibit cmd = %d 0x%x\n", - __FUNCTION__, cmd, sdstd_rreg(sdioh_info, SD_PresentState))); - } - if (!retries) { - sd_err(("%s: Command Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - - - cmd_reg = 0; - switch (cmd) { - case SDIOH_CMD_0: /* Set Card to Idle State - No Response */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_3: /* Ask card to send RCA - Response R6 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_5: /* Send Operation condition - Response R4 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_7: /* Select card - Response R1 */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_15: /* Set card to inactive state - Response None */ - sd_data(("%s: CMD%d\n", __FUNCTION__, cmd)); - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_52: /* IO R/W Direct (single byte) - Response R5 */ - - sd_data(("%s: CMD52 func(%d) addr(0x%x) %s data(0x%x)\n", - __FUNCTION__, - GFIELD(arg, CMD52_FUNCTION), - GFIELD(arg, CMD52_REG_ADDR), - GFIELD(arg, CMD52_RW_FLAG) ? "W" : "R", - GFIELD(arg, CMD52_DATA))); - - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - break; - - case SDIOH_CMD_53: /* IO R/W Extended (multiple bytes/blocks) */ - - sd_data(("%s: CMD53 func(%d) addr(0x%x) %s mode(%s) cnt(%d), %s\n", - __FUNCTION__, - GFIELD(arg, CMD53_FUNCTION), - GFIELD(arg, CMD53_REG_ADDR), - GFIELD(arg, CMD53_RW_FLAG) ? "W" : "R", - GFIELD(arg, CMD53_BLK_MODE) ? "Block" : "Byte", - GFIELD(arg, CMD53_BYTE_BLK_CNT), - GFIELD(arg, CMD53_OP_CODE) ? "Incrementing addr" : "Single addr")); - - cmd_arg = arg; - xfer_reg = 0; - - cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48); - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 1); - cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd); - - use_dma = USE_DMA(sdioh_info) && GFIELD(cmd_arg, CMD53_BLK_MODE); - - if (GFIELD(cmd_arg, CMD53_BLK_MODE)) { - uint16 blocksize; - uint16 blockcount; - int func; - - ASSERT(sdioh_info->sd_blockmode); - - func = GFIELD(cmd_arg, CMD53_FUNCTION); - blocksize = MIN((int)sdioh_info->data_xfer_count, - sdioh_info->client_block_size[func]); - blockcount = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT); - - /* data_xfer_cnt is already setup so that for multiblock mode, - * it is the entire buffer length. For non-block or single block, - * it is < 64 bytes - */ - if (use_dma) { - switch (sdioh_info->sd_dma_mode) { - case DMA_MODE_SDMA: - sd_dma(("%s: SDMA: SysAddr reg was 0x%x now 0x%x\n", - __FUNCTION__, sdstd_rreg(sdioh_info, SD_SysAddr), - (uint32)sdioh_info->dma_phys)); - sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys); - break; - case DMA_MODE_ADMA1: - case DMA_MODE_ADMA2: - sd_dma(("%s: ADMA: Using ADMA\n", __FUNCTION__)); - sd_create_adma_descriptor(sdioh_info, 0, - sdioh_info->dma_phys, blockcount*blocksize, - ADMA2_ATTRIBUTE_VALID | ADMA2_ATTRIBUTE_END | - ADMA2_ATTRIBUTE_INT | ADMA2_ATTRIBUTE_ACT_TRAN); - /* Dump descriptor if DMA debugging is enabled. */ - if (sd_msglevel & SDH_DMA_VAL) { - sd_dump_adma_dscr(sdioh_info); - } - - sdstd_wreg(sdioh_info, SD_ADMA_SysAddr, - sdioh_info->adma2_dscr_phys); - break; - default: - sd_err(("%s: unsupported DMA mode %d.\n", - __FUNCTION__, sdioh_info->sd_dma_mode)); - break; - } - } - - sd_trace(("%s: Setting block count %d, block size %d bytes\n", - __FUNCTION__, blockcount, blocksize)); - sdstd_wreg16(sdioh_info, SD_BlockSize, blocksize); - sdstd_wreg16(sdioh_info, SD_BlockCount, blockcount); - - xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, use_dma); - - if (sdioh_info->client_block_size[func] != blocksize) - set_client_block_size(sdioh_info, 1, blocksize); - - if (blockcount > 1) { - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 1); - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 1); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - } else { - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0); - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - } - - if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ) - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1); - else - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0); - - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), - PRES_DAT_INHIBIT) && --retries) - sd_err(("%s: Waiting for Data Inhibit cmd = %d\n", - __FUNCTION__, cmd)); - if (!retries) { - sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg); - - } else { /* Non block mode */ - uint16 bytes = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT); - /* The byte/block count field only has 9 bits, - * so, to do a 512-byte bytemode transfer, this - * field will contain 0, but we need to tell the - * controller we're transferring 512 bytes. - */ - if (bytes == 0) bytes = 512; - - if (use_dma) - sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys); - - /* PCI: Transfer Mode register 0x0c */ - xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, bytes <= 4 ? 0 : use_dma); - xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0); - if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ) - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1); - else - xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0); - /* See table 2-8 Host Controller spec ver 1.00 */ - xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0); /* Dont care */ - xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0); - - sdstd_wreg16(sdioh_info, SD_BlockSize, bytes); - - sdstd_wreg16(sdioh_info, SD_BlockCount, 1); - - retries = RETRIES_SMALL; - while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), - PRES_DAT_INHIBIT) && --retries) - sd_err(("%s: Waiting for Data Inhibit cmd = %d\n", - __FUNCTION__, cmd)); - if (!retries) { - sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg); - } - break; - - default: - sd_err(("%s: Unknown command\n", __FUNCTION__)); - return ERROR; - } - - if (sdioh_info->sd_mode == SDIOH_MODE_SPI) { - cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0); - cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0); - } - - /* Setup and issue the SDIO command */ - sdstd_wreg(sdioh_info, SD_Arg0, arg); - sdstd_wreg16(sdioh_info, SD_Command, cmd_reg); - - /* If we are in polled mode, wait for the command to complete. - * In interrupt mode, return immediately. The calling function will - * know that the command has completed when the CMDATDONE interrupt - * is asserted - */ - if (sdioh_info->polled_mode) { - uint16 int_reg = 0; - int retries = RETRIES_LARGE; - - do { - int_reg = sdstd_rreg16(sdioh_info, SD_IntrStatus); - } while (--retries && - (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) && - (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0)); - - if (!retries) { - sd_err(("%s: CMD_COMPLETE timeout: intrStatus: 0x%x " - "error stat 0x%x state 0x%x\n", - __FUNCTION__, int_reg, - sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus), - sdstd_rreg(sdioh_info, SD_PresentState))); - - /* Attempt to reset CMD line when we get a CMD timeout */ - sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1)); - retries = RETRIES_LARGE; - do { - sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__)); - } while ((GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), - SW_RESET_CMD)) && retries--); - - if (!retries) { - sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__)); - } - - if (trap_errs) - ASSERT(0); - return (ERROR); - } - - /* Clear Command Complete interrupt */ - int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1); - sdstd_wreg16(sdioh_info, SD_IntrStatus, int_reg); - - /* Check for Errors */ - if (sdstd_check_errs(sdioh_info, cmd, arg)) { - if (trap_errs) - ASSERT(0); - return ERROR; - } - } - return SUCCESS; -} - - -static int -sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int nbytes, uint32 *data) -{ - int status; - uint32 cmd_arg; - uint32 rsp5; - uint16 int_reg, int_bit; - uint flags; - int num_blocks, blocksize; - bool local_blockmode, local_dma; - bool read = rw == SDIOH_READ ? 1 : 0; - bool yield = FALSE; - - ASSERT(nbytes); - - cmd_arg = 0; - - sd_data(("%s: %s 53 addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, read ? "Rd" : "Wr", addr, nbytes, sd->r_cnt, sd->t_cnt)); - - if (read) sd->r_cnt++; else sd->t_cnt++; - - local_blockmode = sd->sd_blockmode; - local_dma = USE_DMA(sd); - - /* Don't bother with block mode on small xfers */ - if (nbytes < sd->client_block_size[func]) { - sd_data(("setting local blockmode to false: nbytes (%d) != block_size (%d)\n", - nbytes, sd->client_block_size[func])); - local_blockmode = FALSE; - local_dma = FALSE; - } - - if (local_blockmode) { - blocksize = MIN(sd->client_block_size[func], nbytes); - num_blocks = nbytes/blocksize; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, num_blocks); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 1); - } else { - num_blocks = 1; - blocksize = nbytes; - cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, nbytes); - cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0); - } - - if (local_dma && !read) { - bcopy(data, sd->dma_buf, nbytes); - sd_sync_dma(sd, read, nbytes); - } - - if (fifo) - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 0); - else - cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1); - - cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, addr); - if (read) - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ); - else - cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE); - - sd->data_xfer_count = nbytes; - - /* sdstd_cmd_issue() returns with the command complete bit - * in the ISR already cleared - */ - if ((status = sdstd_cmd_issue(sd, local_dma, SDIOH_CMD_53, cmd_arg)) != SUCCESS) { - sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, (read ? "read" : "write"))); - return status; - } - - sdstd_cmd_getrsp(sd, &rsp5, 1); - - if ((flags = GFIELD(rsp5, RSP5_FLAGS)) != 0x10) { - sd_err(("%s: Rsp5: nbytes %d, dma %d blockmode %d, read %d " - "numblocks %d, blocksize %d\n", - __FUNCTION__, nbytes, local_dma, local_dma, read, num_blocks, blocksize)); - - if (flags & 1) - sd_err(("%s: rsp5: Command not accepted: arg out of range 0x%x, " - "bytes %d dma %d\n", - __FUNCTION__, flags, GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT), - GFIELD(cmd_arg, CMD53_BLK_MODE))); - if (flags & 0x8) - sd_err(("%s: Rsp5: General Error\n", __FUNCTION__)); - - sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10 returning error\n", - __FUNCTION__, flags)); - if (trap_errs) - ASSERT(0); - return ERROR; - } - - if (GFIELD(rsp5, RSP5_STUFF)) - sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n", - __FUNCTION__, GFIELD(rsp5, RSP5_STUFF))); - -#ifdef BCMSDYIELD - yield = sd_yieldcpu && ((uint)nbytes >= sd_minyield); -#endif - - if (!local_dma) { - int bytes, i; - uint32 tmp; - for (i = 0; i < num_blocks; i++) { - int words; - - /* Decide which status bit we're waiting for */ - if (read) - int_bit = SFIELD(0, INTSTAT_BUF_READ_READY, 1); - else - int_bit = SFIELD(0, INTSTAT_BUF_WRITE_READY, 1); - - /* If not on, wait for it (or for xfer error) */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) - int_reg = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS, yield); - - /* Confirm we got the bit w/o error */ - if (!(int_reg & int_bit) || GFIELD(int_reg, INTSTAT_ERROR_INT)) { - sd_err(("%s: Error or timeout for Buf_%s_Ready: intStat: 0x%x " - "errint: 0x%x PresentState 0x%x\n", - __FUNCTION__, read ? "Read" : "Write", int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), - sdstd_rreg(sd, SD_PresentState))); - sdstd_dumpregs(sd); - sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg); - return (ERROR); - } - - /* Clear Buf Ready bit */ - sdstd_wreg16(sd, SD_IntrStatus, int_bit); - - /* At this point we have Buffer Ready, write the data 4 bytes at a time */ - for (words = blocksize/4; words; words--) { - if (read) - *data = sdstd_rreg(sd, SD_BufferDataPort0); - else - sdstd_wreg(sd, SD_BufferDataPort0, *data); - data++; - } - - bytes = blocksize % 4; - - /* If no leftover bytes, go to next block */ - if (!bytes) - continue; - - switch (bytes) { - case 1: - /* R/W 8 bits */ - if (read) - *(data++) = (uint32)(sdstd_rreg8(sd, SD_BufferDataPort0)); - else - sdstd_wreg8(sd, SD_BufferDataPort0, - (uint8)(*(data++) & 0xff)); - break; - case 2: - /* R/W 16 bits */ - if (read) - *(data++) = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0); - else - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)(*(data++))); - break; - case 3: - /* R/W 24 bits: - * SD_BufferDataPort0[0-15] | SD_BufferDataPort1[16-23] - */ - if (read) { - tmp = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0); - tmp |= ((uint32)(sdstd_rreg8(sd, - SD_BufferDataPort1)) << 16); - *(data++) = tmp; - } else { - tmp = *(data++); - sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)tmp & 0xffff); - sdstd_wreg8(sd, SD_BufferDataPort1, - (uint8)((tmp >> 16) & 0xff)); - } - break; - default: - sd_err(("%s: Unexpected bytes leftover %d\n", - __FUNCTION__, bytes)); - ASSERT(0); - break; - } - } - } /* End PIO processing */ - - /* Wait for Transfer Complete or Transfer Error */ - int_bit = SFIELD(0, INTSTAT_XFER_COMPLETE, 1); - - /* If not on, wait for it (or for xfer error) */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) - int_reg = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS, yield); - - /* Check for any errors from the data phase */ - if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) - return ERROR; - - /* May have gotten a software timeout if not blocking? */ - int_reg = sdstd_rreg16(sd, SD_IntrStatus); - if (!(int_reg & int_bit)) { - sd_err(("%s: Error or Timeout for xfer complete; %s, dma %d, State 0x%08x, " - "intr 0x%04x, Err 0x%04x, len = %d, rcnt %d, tcnt %d\n", - __FUNCTION__, read ? "R" : "W", local_dma, - sdstd_rreg(sd, SD_PresentState), int_reg, - sdstd_rreg16(sd, SD_ErrorIntrStatus), nbytes, - sd->r_cnt, sd->t_cnt)); - sdstd_dumpregs(sd); - return ERROR; - } - - /* Clear the status bits */ - int_reg = int_bit; - if (local_dma) { - /* DMA Complete */ - /* Reads in particular don't have DMA_COMPLETE set */ - int_reg = SFIELD(int_reg, INTSTAT_DMA_INT, 1); - } - sdstd_wreg16(sd, SD_IntrStatus, int_reg); - - /* Fetch data */ - if (local_dma && read) { - sd_sync_dma(sd, read, nbytes); - bcopy(sd->dma_buf, data, nbytes); - } - return SUCCESS; -} - -static int -set_client_block_size(sdioh_info_t *sd, int func, int block_size) -{ - int base; - int err = 0; - - - sd_err(("%s: Setting block size %d, func %d\n", __FUNCTION__, block_size, func)); - sd->client_block_size[func] = block_size; - - /* Set the block size in the SDIO Card register */ - base = func * SDIOD_FBR_SIZE; - err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_0, 1, block_size & 0xff); - if (!err) { - err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_1, 1, - (block_size >> 8) & 0xff); - } - - /* Do not set the block size in the SDIO Host register, that - * is func dependent and will get done on an individual - * transaction basis - */ - - return (err ? BCME_SDIO_ERROR : 0); -} - -/* Reset and re-initialize the device */ -int -sdioh_sdio_reset(sdioh_info_t *si) -{ - uint8 hreg; - - /* Reset the attached device (use slower clock for safety) */ - sdstd_start_clock(si, 128); - sdstd_reset(si, 0, 1); - - /* Reset portions of the host state accordingly */ - hreg = sdstd_rreg8(si, SD_HostCntrl); - hreg = SFIELD(hreg, HOST_HI_SPEED_EN, 0); - hreg = SFIELD(hreg, HOST_DATA_WIDTH, 0); - si->sd_mode = SDIOH_MODE_SD1; - - /* Reinitialize the card */ - si->card_init_done = FALSE; - return sdstd_client_init(si); -} - - -static void -sd_map_dma(sdioh_info_t * sd) -{ - - void *va; - - if ((va = DMA_ALLOC_CONSISTENT(sd->osh, SD_PAGE, - &sd->dma_start_phys, 0x12, 12)) == NULL) { - sd->sd_dma_mode = DMA_MODE_NONE; - sd->dma_start_buf = 0; - sd->dma_buf = (void *)0; - sd->dma_phys = 0; - sd->alloced_dma_size = SD_PAGE; - sd_err(("%s: DMA_ALLOC failed. Disabling DMA support.\n", __FUNCTION__)); - } else { - sd->dma_start_buf = va; - sd->dma_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE); - sd->dma_phys = ROUNDUP((sd->dma_start_phys), SD_PAGE); - sd->alloced_dma_size = SD_PAGE; - sd_err(("%s: Mapped DMA Buffer %dbytes @virt/phys: %p/0x%lx\n", - __FUNCTION__, sd->alloced_dma_size, sd->dma_buf, sd->dma_phys)); - sd_fill_dma_data_buf(sd, 0xA5); - } - - if ((va = DMA_ALLOC_CONSISTENT(sd->osh, SD_PAGE, - &sd->adma2_dscr_start_phys, 0x12, 12)) == NULL) { - sd->sd_dma_mode = DMA_MODE_NONE; - sd->adma2_dscr_start_buf = 0; - sd->adma2_dscr_buf = (void *)0; - sd->adma2_dscr_phys = 0; - sd->alloced_adma2_dscr_size = 0; - sd_err(("%s: DMA_ALLOC failed for descriptor buffer. " - "Disabling DMA support.\n", __FUNCTION__)); - } else { - sd->adma2_dscr_start_buf = va; - sd->adma2_dscr_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE); - sd->adma2_dscr_phys = ROUNDUP((sd->adma2_dscr_start_phys), SD_PAGE); - sd->alloced_adma2_dscr_size = SD_PAGE; - } - - sd_err(("%s: Mapped ADMA2 Descriptor Buffer %dbytes @virt/phys: %p/0x%lx\n", - __FUNCTION__, sd->alloced_adma2_dscr_size, sd->adma2_dscr_buf, - sd->adma2_dscr_phys)); - sd_clear_adma_dscr_buf(sd); -} - -static void -sd_unmap_dma(sdioh_info_t * sd) -{ - if (sd->dma_start_buf) { - DMA_FREE_CONSISTENT(sd->osh, sd->dma_start_buf, sd->alloced_dma_size, - sd->dma_start_phys, 0x12); - } - - if (sd->adma2_dscr_start_buf) { - DMA_FREE_CONSISTENT(sd->osh, sd->adma2_dscr_start_buf, sd->alloced_adma2_dscr_size, - sd->adma2_dscr_start_phys, 0x12); - } -} - -static void sd_clear_adma_dscr_buf(sdioh_info_t *sd) -{ - bzero((char *)sd->adma2_dscr_buf, SD_PAGE); - sd_dump_adma_dscr(sd); -} - -static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data) -{ - memset((char *)sd->dma_buf, data, SD_PAGE); -} - - -static void sd_create_adma_descriptor(sdioh_info_t *sd, uint32 index, - uint32 addr_phys, uint16 length, uint16 flags) -{ - adma2_dscr_32b_t *adma2_dscr_table; - adma1_dscr_t *adma1_dscr_table; - - adma2_dscr_table = sd->adma2_dscr_buf; - adma1_dscr_table = sd->adma2_dscr_buf; - - switch (sd->sd_dma_mode) { - case DMA_MODE_ADMA2: - sd_dma(("%s: creating ADMA2 descriptor for index %d\n", - __FUNCTION__, index)); - - adma2_dscr_table[index].phys_addr = addr_phys; - adma2_dscr_table[index].len_attr = length << 16; - adma2_dscr_table[index].len_attr |= flags; - break; - case DMA_MODE_ADMA1: - /* ADMA1 requires two descriptors, one for len - * and the other for data transfer - */ - index <<= 1; - - sd_dma(("%s: creating ADMA1 descriptor for index %d\n", - __FUNCTION__, index)); - - adma1_dscr_table[index].phys_addr_attr = length << 12; - adma1_dscr_table[index].phys_addr_attr |= (ADMA1_ATTRIBUTE_ACT_SET | - ADMA2_ATTRIBUTE_VALID); - adma1_dscr_table[index+1].phys_addr_attr = addr_phys & 0xFFFFF000; - adma1_dscr_table[index+1].phys_addr_attr |= (flags & 0x3f); - break; - default: - sd_err(("%s: cannot create ADMA descriptor for DMA mode %d\n", - __FUNCTION__, sd->sd_dma_mode)); - break; - } -} - - -static void sd_dump_adma_dscr(sdioh_info_t *sd) -{ - adma2_dscr_32b_t *adma2_dscr_table; - adma1_dscr_t *adma1_dscr_table; - uint32 i = 0; - uint16 flags; - char flags_str[32]; - - ASSERT(sd->adma2_dscr_buf != NULL); - - adma2_dscr_table = sd->adma2_dscr_buf; - adma1_dscr_table = sd->adma2_dscr_buf; - - switch (sd->sd_dma_mode) { - case DMA_MODE_ADMA2: - sd_err(("ADMA2 Descriptor Table (%dbytes) @virt/phys: %p/0x%lx\n", - SD_PAGE, sd->adma2_dscr_buf, sd->adma2_dscr_phys)); - sd_err((" #[Descr VA ] Buffer PA | Len | Flags (5:4 2 1 0)" - " |\n")); - while (adma2_dscr_table->len_attr & ADMA2_ATTRIBUTE_VALID) { - flags = adma2_dscr_table->len_attr & 0xFFFF; - sprintf(flags_str, "%s%s%s%s", - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP " : "RSV ", - (flags & ADMA2_ATTRIBUTE_INT ? "INT " : " "), - (flags & ADMA2_ATTRIBUTE_END ? "END " : " "), - (flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : "")); - sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | 0x%04x (%s) |\n", - i, adma2_dscr_table, adma2_dscr_table->phys_addr, - adma2_dscr_table->len_attr >> 16, flags, flags_str)); - i++; - - /* Follow LINK descriptors or skip to next. */ - if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) { - adma2_dscr_table = phys_to_virt( - adma2_dscr_table->phys_addr); - } else { - adma2_dscr_table++; - } - - } - break; - case DMA_MODE_ADMA1: - sd_err(("ADMA1 Descriptor Table (%dbytes) @virt/phys: %p/0x%lx\n", - SD_PAGE, sd->adma2_dscr_buf, sd->adma2_dscr_phys)); - sd_err((" #[Descr VA ] Buffer PA | Flags (5:4 2 1 0) |\n")); - - for (i = 0; adma1_dscr_table->phys_addr_attr & ADMA2_ATTRIBUTE_VALID; i++) { - flags = adma1_dscr_table->phys_addr_attr & 0x3F; - sprintf(flags_str, "%s%s%s%s", - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " : - ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP " : "SET ", - (flags & ADMA2_ATTRIBUTE_INT ? "INT " : " "), - (flags & ADMA2_ATTRIBUTE_END ? "END " : " "), - (flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : "")); - sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | (%s) |\n", - i, adma1_dscr_table, - adma1_dscr_table->phys_addr_attr & 0xFFFFF000, - flags, flags_str)); - - /* Follow LINK descriptors or skip to next. */ - if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) == - ADMA2_ATTRIBUTE_ACT_LINK) { - adma1_dscr_table = phys_to_virt( - adma1_dscr_table->phys_addr_attr & 0xFFFFF000); - } else { - adma1_dscr_table++; - } - } - break; - default: - sd_err(("Unknown DMA Descriptor Table Format.\n")); - break; - } -} - -static void sdstd_dumpregs(sdioh_info_t *sd) -{ - sd_err(("IntrStatus: 0x%04x ErrorIntrStatus 0x%04x\n", - sdstd_rreg16(sd, SD_IntrStatus), - sdstd_rreg16(sd, SD_ErrorIntrStatus))); - sd_err(("IntrStatusEnable: 0x%04x ErrorIntrStatusEnable 0x%04x\n", - sdstd_rreg16(sd, SD_IntrStatusEnable), - sdstd_rreg16(sd, SD_ErrorIntrStatusEnable))); - sd_err(("IntrSignalEnable: 0x%04x ErrorIntrSignalEnable 0x%04x\n", - sdstd_rreg16(sd, SD_IntrSignalEnable), - sdstd_rreg16(sd, SD_ErrorIntrSignalEnable))); -} diff --git a/drivers/net/wireless/bcm4329/bcmsdstd_linux.c b/drivers/net/wireless/bcm4329/bcmsdstd_linux.c deleted file mode 100644 index a8b98e2054a0..000000000000 --- a/drivers/net/wireless/bcm4329/bcmsdstd_linux.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - linux portion - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdstd_linux.c,v 1.11.18.2.16.1 2010/08/17 17:03:13 Exp $ - */ - -#include -#include -#include -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include /* request_irq() */ - -#include - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; - wait_queue_head_t intr_wait_queue; -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* Interrupt handler */ -static irqreturn_t -sdstd_isr(int irq, void *dev_id -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) -, struct pt_regs *ptregs -#endif -) -{ - sdioh_info_t *sd; - struct sdos_info *sdos; - bool ours; - - sd = (sdioh_info_t *)dev_id; - - if (!sd->card_init_done) { - sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq)); - return IRQ_RETVAL(FALSE); - } else { - ours = check_client_intr(sd); - - /* For local interrupts, wake the waiting process */ - if (ours && sd->got_hcint) { - sd_trace(("INTR->WAKE\n")); - sdos = (struct sdos_info *)sd->sdos_info; - wake_up_interruptible(&sdos->intr_wait_queue); - } - return IRQ_RETVAL(ours); - } -} - -/* Register with Linux for interrupts */ -int -sdstd_register_irq(sdioh_info_t *sd, uint irq) -{ - sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq)); - if (request_irq(irq, sdstd_isr, IRQF_SHARED, "bcmsdstd", sd) < 0) { - sd_err(("%s: request_irq() failed\n", __FUNCTION__)); - return ERROR; - } - return SUCCESS; -} - -/* Free Linux irq */ -void -sdstd_free_irq(uint irq, sdioh_info_t *sd) -{ - free_irq(irq, sd); -} - -/* Map Host controller registers */ - -uint32 * -sdstd_reg_map(osl_t *osh, int32 addr, int size) -{ - return (uint32 *)REG_MAP(addr, size); -} - -void -sdstd_reg_unmap(osl_t *osh, int32 addr, int size) -{ - REG_UNMAP((void*)(uintptr)addr); -} - -int -sdstd_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); - sd->sdos_info = (void*)sdos; - if (sdos == NULL) - return BCME_NOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - init_waitqueue_head(&sdos->intr_wait_queue); - return BCME_OK; -} - -void -sdstd_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC -sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - if (!(sd->host_init_done && sd->card_init_done)) { - sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); - return SDIOH_API_RC_FAIL; - } - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable && !sd->lockcount) - sdstd_devintr_on(sd); - else - sdstd_devintr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - -/* Protect against reentrancy (disable device interrupts while executing) */ -void -sdstd_lock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount)); - - spin_lock_irqsave(&sdos->lock, flags); - if (sd->lockcount) { - sd_err(("%s: Already locked! called from %p\n", - __FUNCTION__, - __builtin_return_address(0))); - ASSERT(sd->lockcount == 0); - } - sdstd_devintr_off(sd); - sd->lockcount++; - spin_unlock_irqrestore(&sdos->lock, flags); -} - -/* Enable client interrupt */ -void -sdstd_unlock(sdioh_info_t *sd) -{ - ulong flags; - struct sdos_info *sdos; - - sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled)); - ASSERT(sd->lockcount > 0); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - - spin_lock_irqsave(&sdos->lock, flags); - if (--sd->lockcount == 0 && sd->client_intr_enabled) { - sdstd_devintr_on(sd); - } - spin_unlock_irqrestore(&sdos->lock, flags); -} - -uint16 -sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - -#ifndef BCMSDYIELD - ASSERT(!yield); -#endif - sd_trace(("%s: int 0x%02x err 0x%02x yield %d canblock %d\n", - __FUNCTION__, norm, err, yield, BLOCKABLE())); - - /* Clear the "interrupt happened" flag and last intrstatus */ - sd->got_hcint = FALSE; - sd->last_intrstatus = 0; - -#ifdef BCMSDYIELD - if (yield && BLOCKABLE()) { - /* Enable interrupts, wait for the indication, then disable */ - sdstd_intrs_on(sd, norm, err); - wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint)); - sdstd_intrs_off(sd, norm, err); - } else -#endif /* BCMSDYIELD */ - { - sdstd_spinbits(sd, norm, err); - } - - sd_trace(("%s: last_intrstatus 0x%04x\n", __FUNCTION__, sd->last_intrstatus)); - - return sd->last_intrstatus; -} diff --git a/drivers/net/wireless/bcm4329/bcmspibrcm.c b/drivers/net/wireless/bcm4329/bcmspibrcm.c deleted file mode 100644 index 0f131a40f4b8..000000000000 --- a/drivers/net/wireless/bcm4329/bcmspibrcm.c +++ /dev/null @@ -1,1726 +0,0 @@ -/* - * Broadcom BCMSDH to gSPI Protocol Conversion Layer - * - * Copyright (C) 2010, Broadcom Corporation - * All Rights Reserved. - * - * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; - * the contents of this file may not be disclosed to third parties, copied - * or duplicated in any form, in whole or in part, without the prior - * written permission of Broadcom Corporation. - * - * $Id: bcmspibrcm.c,v 1.11.2.10.2.9.6.11 2009/05/21 13:21:57 Exp $ - */ - -#define HSMODE - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ -#include - -#include - - -#include -#include - -#define F0_RESPONSE_DELAY 16 -#define F1_RESPONSE_DELAY 16 -#define F2_RESPONSE_DELAY F0_RESPONSE_DELAY - -#define CMDLEN 4 - -#define DWORDMODE_ON (sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 2) && (sd->dwordmode == TRUE) - -/* Globals */ -uint sd_msglevel = 0; - -uint sd_hiok = FALSE; /* Use hi-speed mode if available? */ -uint sd_sdmode = SDIOH_MODE_SPI; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 64; /* Default blocksize */ - - -uint sd_divisor = 2; -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_crc = 0; /* Default to SPI CRC Check turned OFF */ - -uint8 spi_outbuf[SPI_MAX_PKT_LEN]; -uint8 spi_inbuf[SPI_MAX_PKT_LEN]; - -/* 128bytes buffer is enough to clear data-not-available and program response-delay F0 bits - * assuming we will not exceed F0 response delay > 100 bytes at 48MHz. - */ -#define BUF2_PKT_LEN 128 -uint8 spi_outbuf2[BUF2_PKT_LEN]; -uint8 spi_inbuf2[BUF2_PKT_LEN]; - -/* Prototypes */ -static bool bcmspi_test_card(sdioh_info_t *sd); -static bool bcmspi_host_device_init_adapt(sdioh_info_t *sd); -static int bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode); -static int bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg, - uint32 *data, uint32 datalen); -static int bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 *data); -static int bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, - int regsize, uint32 data); -static int bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, - uint8 *data); -static int bcmspi_driver_init(sdioh_info_t *sd); -static int bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data); -static int bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, - uint32 *data); -static void bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer); -static int bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg); - -/* - * Public entry points & extern's - */ -extern sdioh_info_t * -sdioh_attach(osl_t *osh, void *bar0, uint irq) -{ - sdioh_info_t *sd; - - sd_trace(("%s\n", __FUNCTION__)); - if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { - sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); - return NULL; - } - bzero((char *)sd, sizeof(sdioh_info_t)); - sd->osh = osh; - if (spi_osinit(sd) != 0) { - sd_err(("%s: spi_osinit() failed\n", __FUNCTION__)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; - } - - sd->bar0 = bar0; - sd->irq = irq; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - sd->intr_handler_valid = FALSE; - - /* Set defaults */ - sd->use_client_ints = TRUE; - sd->sd_use_dma = FALSE; /* DMA Not supported */ - - /* Spi device default is 16bit mode, change to 4 when device is changed to 32bit - * mode - */ - sd->wordlen = 2; - - if (!spi_hw_attach(sd)) { - sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__)); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - if (bcmspi_driver_init(sd) != SUCCESS) { - sd_err(("%s: bcmspi_driver_init() failed()\n", __FUNCTION__)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - if (spi_register_irq(sd, irq) != SUCCESS) { - sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return (NULL); - } - - sd_trace(("%s: Done\n", __FUNCTION__)); - - return sd; -} - -extern SDIOH_API_RC -sdioh_detach(osl_t *osh, sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if (sd) { - sd_err(("%s: detaching from hardware\n", __FUNCTION__)); - spi_free_irq(sd->irq, sd); - spi_hw_detach(sd); - spi_osfree(sd); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - } - return SDIOH_API_RC_SUCCESS; -} - -/* Configure callback to client when we recieve client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = TRUE; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_deregister(sdioh_info_t *sd) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - sd->intr_handler_valid = FALSE; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __FUNCTION__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool -sdioh_interrupt_pending(sdioh_info_t *sd) -{ - return 0; -} -#endif - -extern SDIOH_API_RC -sdioh_query_device(sdioh_info_t *sd) -{ - /* Return a BRCM ID appropriate to the dongle class */ - return (sd->num_funcs > 1) ? BCM4329_D11NDUAL_ID : BCM4318_D11G_ID; -} - -/* Provide dstatus bits of spi-transaction for dhd layers. */ -extern uint32 -sdioh_get_dstatus(sdioh_info_t *sd) -{ - return sd->card_dstatus; -} - -extern void -sdioh_chipinfo(sdioh_info_t *sd, uint32 chip, uint32 chiprev) -{ - sd->chip = chip; - sd->chiprev = chiprev; -} - -extern void -sdioh_dwordmode(sdioh_info_t *sd, bool set) -{ - uint8 reg = 0; - int status; - - if ((status = sdioh_request_byte(sd, SDIOH_READ, SPI_FUNC_0, SPID_STATUS_ENABLE, ®)) != - SUCCESS) { - sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__)); - return; - } - - if (set) { - reg |= DWORD_PKT_LEN_EN; - sd->dwordmode = TRUE; - sd->client_block_size[SPI_FUNC_2] = 4096; /* h2spi's limit is 4KB, we support 8KB */ - } else { - reg &= ~DWORD_PKT_LEN_EN; - sd->dwordmode = FALSE; - sd->client_block_size[SPI_FUNC_2] = 2048; - } - - if ((status = sdioh_request_byte(sd, SDIOH_WRITE, SPI_FUNC_0, SPID_STATUS_ENABLE, ®)) != - SUCCESS) { - sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__)); - return; - } -} - - -uint -sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} - -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, - IOV_BLOCKSIZE, - IOV_DMA, - IOV_USEINTS, - IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, - IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, - IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, - IOV_SPIERRSTATS, - IOV_RESP_DELAY_ALL -}; - -const bcm_iovar_t sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, - {"spi_errstats", IOV_SPIERRSTATS, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) }, - {"spi_respdelay", IOV_RESP_DELAY_ALL, 0, IOVT_BOOL, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - int32 int_val = 0; - bool bool_val; - uint32 actionid; -/* - sdioh_regs_t *regs; -*/ - - ASSERT(name); - ASSERT(len >= 0); - - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); - - sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); - - if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((uint32)int_val > si->num_funcs) { - bcmerror = BCME_BADARG; - break; - } - int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_DMA): - int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool)int_val; - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - break; - - case IOV_GVAL(IOV_DIVISOR): - int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - if (!spi_start_clock(si, (uint16)sd_divisor)) { - sd_err(("%s: set clock failed\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - } - break; - - case IOV_GVAL(IOV_POWER): - int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - - if (!bcmspi_set_highspeed_mode(si, (bool)sd_hiok)) { - sd_err(("%s: Failed changing highspeed mode to %d.\n", - __FUNCTION__, sd_hiok)); - bcmerror = BCME_ERROR; - return ERROR; - } - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (int32)si->local_intrcount; - bcopy(&int_val, arg, val_size); - break; - case IOV_GVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data; - - if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - - int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - sdreg_t *sd_ptr = (sdreg_t *)params; - uint8 data = (uint8)sd_ptr->value; - - if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - } - - - case IOV_GVAL(IOV_SPIERRSTATS): - { - bcopy(&si->spierrstats, arg, sizeof(struct spierrstats_t)); - break; - } - - case IOV_SVAL(IOV_SPIERRSTATS): - { - bzero(&si->spierrstats, sizeof(struct spierrstats_t)); - break; - } - - case IOV_GVAL(IOV_RESP_DELAY_ALL): - int_val = (int32)si->resp_delay_all; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_RESP_DELAY_ALL): - si->resp_delay_all = (bool)int_val; - int_val = STATUS_ENABLE|INTR_WITH_STATUS; - if (si->resp_delay_all) - int_val |= RESP_DELAY_ALL; - else { - if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_RESPONSE_DELAY, 1, - F1_RESPONSE_DELAY) != SUCCESS) { - sd_err(("%s: Unable to set response delay.\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - break; - } - } - - if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, int_val) - != SUCCESS) { - sd_err(("%s: Unable to set response delay.\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - break; - } - break; - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } -exit: - - return bcmerror; -} - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -{ - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - - if ((fnc_num == SPI_FUNC_1) && (addr == SBSDIO_FUNC1_FRAMECTRL)) { - uint8 dummy_data; - status = sdioh_cfg_read(sd, fnc_num, addr, &dummy_data); - if (status) { - sd_err(("sdioh_cfg_read() failed.\n")); - return status; - } - } - - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -{ - uint32 count; - int offset; - uint32 cis_byte; - uint16 *cis = (uint16 *)cisd; - uint bar0 = SI_ENUM_BASE; - int status; - uint8 data; - - sd_trace(("%s: Func %d\n", __FUNCTION__, func)); - - spi_lock(sd); - - /* Set sb window address to 0x18000000 */ - data = (bar0 >> 8) & SBSDIO_SBADDRLOW_MASK; - status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, &data); - if (status == SUCCESS) { - data = (bar0 >> 16) & SBSDIO_SBADDRMID_MASK; - status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, &data); - } else { - sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__)); - spi_unlock(sd); - return (BCME_ERROR); - } - if (status == SUCCESS) { - data = (bar0 >> 24) & SBSDIO_SBADDRHIGH_MASK; - status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, &data); - } else { - sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__)); - spi_unlock(sd); - return (BCME_ERROR); - } - - offset = CC_OTP; /* OTP offset in chipcommon. */ - for (count = 0; count < length/2; count++) { - if (bcmspi_card_regread (sd, SDIO_FUNC_1, offset, 2, &cis_byte) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); - spi_unlock(sd); - return (BCME_ERROR); - } - - *cis = (uint16)cis_byte; - cis++; - offset += 2; - } - - spi_unlock(sd); - - return (BCME_OK); -} - -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 dstatus; - uint32 data = (uint32)(*byte); - - spi_lock(sd); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, rw == SDIOH_READ ? 0 : 1); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, rw, func, - regaddr, data)); - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, - cmd_arg, &data, 1)) != SUCCESS) { - spi_unlock(sd); - return status; - } - - if (rw == SDIOH_READ) - *byte = (uint8)data; - - bcmspi_cmd_getdstatus(sd, &dstatus); - if (dstatus) - sd_trace(("dstatus =0x%x\n", dstatus)); - - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, - uint32 *word, uint nbytes) -{ - int status; - - spi_lock(sd); - - if (rw == SDIOH_READ) - status = bcmspi_card_regread(sd, func, addr, nbytes, word); - else - status = bcmspi_card_regwrite(sd, func, addr, nbytes, *word); - - spi_unlock(sd); - return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -} - -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -{ - int len; - int buflen = (int)buflen_u; - bool fifo = (fix_inc == SDIOH_DATA_FIX); - - spi_lock(sd); - - ASSERT(reg_width == 4); - ASSERT(buflen_u < (1 << 30)); - ASSERT(sd->client_block_size[func]); - - sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", - __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', - buflen_u, sd->r_cnt, sd->t_cnt, pkt)); - - /* Break buffer down into blocksize chunks. */ - while (buflen > 0) { - len = MIN(sd->client_block_size[func], buflen); - if (bcmspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { - sd_err(("%s: bcmspi_card_buf %s failed\n", - __FUNCTION__, rw == SDIOH_READ ? "Read" : "Write")); - spi_unlock(sd); - return SDIOH_API_RC_FAIL; - } - buffer += len; - buflen -= len; - if (!fifo) - addr += len; - } - spi_unlock(sd); - return SDIOH_API_RC_SUCCESS; -} - -/* This function allows write to gspi bus when another rd/wr function is deep down the call stack. - * Its main aim is to have simpler spi writes rather than recursive writes. - * e.g. When there is a need to program response delay on the fly after detecting the SPI-func - * this call will allow to program the response delay. - */ -static int -bcmspi_card_byterewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 byte) -{ - uint32 cmd_arg; - uint32 datalen = 1; - uint32 hostlen; - - cmd_arg = 0; - - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, datalen); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - - - /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen - * according to the wordlen mode(16/32bit) the device is in. - */ - ASSERT(sd->wordlen == 4 || sd->wordlen == 2); - datalen = ROUNDUP(datalen, sd->wordlen); - - /* Start by copying command in the spi-outbuffer */ - if (sd->wordlen == 4) { /* 32bit spid */ - *(uint32 *)spi_outbuf2 = bcmswap32(cmd_arg); - if (datalen & 0x3) - datalen += (4 - (datalen & 0x3)); - } else if (sd->wordlen == 2) { /* 16bit spid */ - *(uint16 *)spi_outbuf2 = bcmswap16(cmd_arg & 0xffff); - *(uint16 *)&spi_outbuf2[2] = bcmswap16((cmd_arg & 0xffff0000) >> 16); - if (datalen & 0x1) - datalen++; - } else { - sd_err(("%s: Host is %d bit spid, could not create SPI command.\n", - __FUNCTION__, 8 * sd->wordlen)); - return ERROR; - } - - /* for Write, put the data into the output buffer */ - if (datalen != 0) { - if (sd->wordlen == 4) { /* 32bit spid */ - *(uint32 *)&spi_outbuf2[CMDLEN] = bcmswap32(byte); - } else if (sd->wordlen == 2) { /* 16bit spid */ - *(uint16 *)&spi_outbuf2[CMDLEN] = bcmswap16(byte & 0xffff); - *(uint16 *)&spi_outbuf2[CMDLEN + 2] = - bcmswap16((byte & 0xffff0000) >> 16); - } - } - - /* +4 for cmd, +4 for dstatus */ - hostlen = datalen + 8; - hostlen += (4 - (hostlen & 0x3)); - spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, hostlen); - - /* Last 4bytes are dstatus. Device is configured to return status bits. */ - if (sd->wordlen == 4) { /* 32bit spid */ - sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); - } else if (sd->wordlen == 2) { /* 16bit spid */ - sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN ]) | - (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN + 2]) << 16)); - } else { - sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n", - __FUNCTION__, 8 * sd->wordlen)); - return ERROR; - } - - if (sd->card_dstatus) - sd_trace(("dstatus after byte rewrite = 0x%x\n", sd->card_dstatus)); - - return (BCME_OK); -} - -/* Program the response delay corresponding to the spi function */ -static int -bcmspi_prog_resp_delay(sdioh_info_t *sd, int func, uint8 resp_delay) -{ - if (sd->resp_delay_all == FALSE) - return (BCME_OK); - - if (sd->prev_fun == func) - return (BCME_OK); - - if (F0_RESPONSE_DELAY == F1_RESPONSE_DELAY) - return (BCME_OK); - - bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_RESPONSE_DELAY, resp_delay); - - /* Remember function for which to avoid reprogramming resp-delay in next iteration */ - sd->prev_fun = func; - - return (BCME_OK); - -} - -#define GSPI_RESYNC_PATTERN 0x0 - -/* A resync pattern is a 32bit MOSI line with all zeros. Its a special command in gSPI. - * It resets the spi-bkplane logic so that all F1 related ping-pong buffer logic is - * synchronised and all queued resuests are cancelled. - */ -static int -bcmspi_resync_f1(sdioh_info_t *sd) -{ - uint32 cmd_arg = GSPI_RESYNC_PATTERN, data = 0, datalen = 0; - - - /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen - * according to the wordlen mode(16/32bit) the device is in. - */ - ASSERT(sd->wordlen == 4 || sd->wordlen == 2); - datalen = ROUNDUP(datalen, sd->wordlen); - - /* Start by copying command in the spi-outbuffer */ - *(uint32 *)spi_outbuf2 = cmd_arg; - - /* for Write, put the data into the output buffer */ - *(uint32 *)&spi_outbuf2[CMDLEN] = data; - - /* +4 for cmd, +4 for dstatus */ - spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, datalen + 8); - - /* Last 4bytes are dstatus. Device is configured to return status bits. */ - if (sd->wordlen == 4) { /* 32bit spid */ - sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); - } else if (sd->wordlen == 2) { /* 16bit spid */ - sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN ]) | - (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN + 2]) << 16)); - } else { - sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n", - __FUNCTION__, 8 * sd->wordlen)); - return ERROR; - } - - if (sd->card_dstatus) - sd_trace(("dstatus after resync pattern write = 0x%x\n", sd->card_dstatus)); - - return (BCME_OK); -} - -uint32 dstatus_count = 0; - -static int -bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg) -{ - uint32 dstatus = sd->card_dstatus; - struct spierrstats_t *spierrstats = &sd->spierrstats; - int err = SUCCESS; - - sd_trace(("cmd = 0x%x, dstatus = 0x%x\n", cmd_arg, dstatus)); - - /* Store dstatus of last few gSPI transactions */ - spierrstats->dstatus[dstatus_count % NUM_PREV_TRANSACTIONS] = dstatus; - spierrstats->spicmd[dstatus_count % NUM_PREV_TRANSACTIONS] = cmd_arg; - dstatus_count++; - - if (sd->card_init_done == FALSE) - return err; - - if (dstatus & STATUS_DATA_NOT_AVAILABLE) { - spierrstats->dna++; - sd_trace(("Read data not available on F1 addr = 0x%x\n", - GFIELD(cmd_arg, SPI_REG_ADDR))); - /* Clear dna bit */ - bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, DATA_UNAVAILABLE); - } - - if (dstatus & STATUS_UNDERFLOW) { - spierrstats->rdunderflow++; - sd_err(("FIFO underflow happened due to current F2 read command.\n")); - } - - if (dstatus & STATUS_OVERFLOW) { - spierrstats->wroverflow++; - sd_err(("FIFO overflow happened due to current (F1/F2) write command.\n")); - if ((sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 0)) { - bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, F1_OVERFLOW); - bcmspi_resync_f1(sd); - sd_err(("Recovering from F1 FIFO overflow.\n")); - } else { - err = ERROR_OF; - } - } - - if (dstatus & STATUS_F2_INTR) { - spierrstats->f2interrupt++; - sd_trace(("Interrupt from F2. SW should clear corresponding IntStatus bits\n")); - } - - if (dstatus & STATUS_F3_INTR) { - spierrstats->f3interrupt++; - sd_err(("Interrupt from F3. SW should clear corresponding IntStatus bits\n")); - } - - if (dstatus & STATUS_HOST_CMD_DATA_ERR) { - spierrstats->hostcmddataerr++; - sd_err(("Error in CMD or Host data, detected by CRC/Checksum (optional)\n")); - } - - if (dstatus & STATUS_F2_PKT_AVAILABLE) { - spierrstats->f2pktavailable++; - sd_trace(("Packet is available/ready in F2 TX FIFO\n")); - sd_trace(("Packet length = %d\n", sd->dwordmode ? - ((dstatus & STATUS_F2_PKT_LEN_MASK) >> (STATUS_F2_PKT_LEN_SHIFT - 2)) : - ((dstatus & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT))); - } - - if (dstatus & STATUS_F3_PKT_AVAILABLE) { - spierrstats->f3pktavailable++; - sd_err(("Packet is available/ready in F3 TX FIFO\n")); - sd_err(("Packet length = %d\n", - (dstatus & STATUS_F3_PKT_LEN_MASK) >> STATUS_F3_PKT_LEN_SHIFT)); - } - - return err; -} - -extern int -sdioh_abort(sdioh_info_t *sd, uint func) -{ - return 0; -} - -int -sdioh_start(sdioh_info_t *sd, int stage) -{ - return SUCCESS; -} - -int -sdioh_stop(sdioh_info_t *sd) -{ - return SUCCESS; -} - - - -/* - * Private/Static work routines - */ -static int -bcmspi_host_init(sdioh_info_t *sd) -{ - - /* Default power on mode */ - sd->sd_mode = SDIOH_MODE_SPI; - sd->polled_mode = TRUE; - sd->host_init_done = TRUE; - sd->card_init_done = FALSE; - sd->adapter_slot = 1; - - return (SUCCESS); -} - -static int -get_client_blocksize(sdioh_info_t *sd) -{ - uint32 regdata[2]; - int status; - - /* Find F1/F2/F3 max packet size */ - if ((status = bcmspi_card_regread(sd, 0, SPID_F1_INFO_REG, - 8, regdata)) != SUCCESS) { - return status; - } - - sd_trace(("pkt_size regdata[0] = 0x%x, regdata[1] = 0x%x\n", - regdata[0], regdata[1])); - - sd->client_block_size[1] = (regdata[0] & F1_MAX_PKT_SIZE) >> 2; - sd_trace(("Func1 blocksize = %d\n", sd->client_block_size[1])); - ASSERT(sd->client_block_size[1] == BLOCK_SIZE_F1); - - sd->client_block_size[2] = ((regdata[0] >> 16) & F2_MAX_PKT_SIZE) >> 2; - sd_trace(("Func2 blocksize = %d\n", sd->client_block_size[2])); - ASSERT(sd->client_block_size[2] == BLOCK_SIZE_F2); - - sd->client_block_size[3] = (regdata[1] & F3_MAX_PKT_SIZE) >> 2; - sd_trace(("Func3 blocksize = %d\n", sd->client_block_size[3])); - ASSERT(sd->client_block_size[3] == BLOCK_SIZE_F3); - - return 0; -} - -static int -bcmspi_client_init(sdioh_info_t *sd) -{ - uint32 status_en_reg = 0; - sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); - -#ifdef HSMODE - if (!spi_start_clock(sd, (uint16)sd_divisor)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } -#else - /* Start at ~400KHz clock rate for initialization */ - if (!spi_start_clock(sd, 128)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } -#endif /* HSMODE */ - - if (!bcmspi_host_device_init_adapt(sd)) { - sd_err(("bcmspi_host_device_init_adapt failed\n")); - return ERROR; - } - - if (!bcmspi_test_card(sd)) { - sd_err(("bcmspi_test_card failed\n")); - return ERROR; - } - - sd->num_funcs = SPI_MAX_IOFUNCS; - - get_client_blocksize(sd); - - /* Apply resync pattern cmd with all zeros to reset spi-bkplane F1 logic */ - bcmspi_resync_f1(sd); - - sd->dwordmode = FALSE; - - bcmspi_card_regread(sd, 0, SPID_STATUS_ENABLE, 1, &status_en_reg); - - sd_trace(("%s: Enabling interrupt with dstatus \n", __FUNCTION__)); - status_en_reg |= INTR_WITH_STATUS; - - - if (bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, - status_en_reg & 0xff) != SUCCESS) { - sd_err(("%s: Unable to set response delay for all fun's.\n", __FUNCTION__)); - return ERROR; - } - - -#ifndef HSMODE - /* After configuring for High-Speed mode, set the desired clock rate. */ - if (!spi_start_clock(sd, 4)) { - sd_err(("spi_start_clock failed\n")); - return ERROR; - } -#endif /* HSMODE */ - - sd->card_init_done = TRUE; - - - return SUCCESS; -} - -static int -bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode) -{ - uint32 regdata; - int status; - - if ((status = bcmspi_card_regread(sd, 0, SPID_CONFIG, - 4, ®data)) != SUCCESS) - return status; - - sd_trace(("In %s spih-ctrl = 0x%x \n", __FUNCTION__, regdata)); - - - if (hsmode == TRUE) { - sd_trace(("Attempting to enable High-Speed mode.\n")); - - if (regdata & HIGH_SPEED_MODE) { - sd_trace(("Device is already in High-Speed mode.\n")); - return status; - } else { - regdata |= HIGH_SPEED_MODE; - sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG)); - if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG, - 4, regdata)) != SUCCESS) { - return status; - } - } - } else { - sd_trace(("Attempting to disable High-Speed mode.\n")); - - if (regdata & HIGH_SPEED_MODE) { - regdata &= ~HIGH_SPEED_MODE; - sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG)); - if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG, - 4, regdata)) != SUCCESS) - return status; - } - else { - sd_trace(("Device is already in Low-Speed mode.\n")); - return status; - } - } - - spi_controller_highspeed_mode(sd, hsmode); - - return TRUE; -} - -#define bcmspi_find_curr_mode(sd) { \ - sd->wordlen = 2; \ - status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, ®data); \ - regdata &= 0xff; \ - if ((regdata == 0xad) || (regdata == 0x5b) || \ - (regdata == 0x5d) || (regdata == 0x5a)) \ - break; \ - sd->wordlen = 4; \ - status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, ®data); \ - regdata &= 0xff; \ - if ((regdata == 0xad) || (regdata == 0x5b) || \ - (regdata == 0x5d) || (regdata == 0x5a)) \ - break; \ - sd_trace(("Silicon testability issue: regdata = 0x%x." \ - " Expected 0xad, 0x5a, 0x5b or 0x5d.\n", regdata)); \ - OSL_DELAY(100000); \ -} - -#define INIT_ADAPT_LOOP 100 - -/* Adapt clock-phase-speed-bitwidth between host and device */ -static bool -bcmspi_host_device_init_adapt(sdioh_info_t *sd) -{ - uint32 wrregdata, regdata = 0; - int status; - int i; - - /* Due to a silicon testability issue, the first command from the Host - * to the device will get corrupted (first bit will be lost). So the - * Host should poll the device with a safe read request. ie: The Host - * should try to read F0 addr 0x14 using the Fixed address mode - * (This will prevent a unintended write command to be detected by device) - */ - for (i = 0; i < INIT_ADAPT_LOOP; i++) { - /* If device was not power-cycled it will stay in 32bit mode with - * response-delay-all bit set. Alternate the iteration so that - * read either with or without response-delay for F0 to succeed. - */ - bcmspi_find_curr_mode(sd); - sd->resp_delay_all = (i & 0x1) ? TRUE : FALSE; - - bcmspi_find_curr_mode(sd); - sd->dwordmode = TRUE; - - bcmspi_find_curr_mode(sd); - sd->dwordmode = FALSE; - } - - /* Bail out, device not detected */ - if (i == INIT_ADAPT_LOOP) - return FALSE; - - /* Softreset the spid logic */ - if ((sd->dwordmode) || (sd->wordlen == 4)) { - bcmspi_card_regwrite(sd, 0, SPID_RESET_BP, 1, RESET_ON_WLAN_BP_RESET|RESET_SPI); - bcmspi_card_regread(sd, 0, SPID_RESET_BP, 1, ®data); - sd_trace(("reset reg read = 0x%x\n", regdata)); - sd_trace(("dwordmode = %d, wordlen = %d, resp_delay_all = %d\n", sd->dwordmode, - sd->wordlen, sd->resp_delay_all)); - /* Restore default state after softreset */ - sd->wordlen = 2; - sd->dwordmode = FALSE; - } - - if (sd->wordlen == 4) { - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != - SUCCESS) - return FALSE; - if (regdata == TEST_RO_DATA_32BIT_LE) { - sd_trace(("Spid is already in 32bit LE mode. Value read = 0x%x\n", - regdata)); - sd_trace(("Spid power was left on.\n")); - } else { - sd_err(("Spid power was left on but signature read failed." - " Value read = 0x%x\n", regdata)); - return FALSE; - } - } else { - sd->wordlen = 2; - -#define CTRL_REG_DEFAULT 0x00010430 /* according to the host m/c */ - - wrregdata = (CTRL_REG_DEFAULT); - sd->resp_delay_all = TRUE; - if (sd->resp_delay_all == TRUE) { - /* Enable response delay for all */ - wrregdata |= (RESP_DELAY_ALL << 16); - /* Program response delay value */ - wrregdata &= 0xffff00ff; - wrregdata |= (F1_RESPONSE_DELAY << 8); - sd->prev_fun = SPI_FUNC_1; - bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata); - } - - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) - return FALSE; - sd_trace(("(we are still in 16bit mode) 32bit READ LE regdata = 0x%x\n", regdata)); - -#ifndef HSMODE - wrregdata |= (CLOCK_PHASE | CLOCK_POLARITY); - wrregdata &= ~HIGH_SPEED_MODE; - bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata); -#endif /* HSMODE */ - - for (i = 0; i < INIT_ADAPT_LOOP; i++) { - if ((regdata == 0xfdda7d5b) || (regdata == 0xfdda7d5a)) { - sd_trace(("0xfeedbead was leftshifted by 1-bit.\n")); - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, - ®data)) != SUCCESS) - return FALSE; - } - OSL_DELAY(1000); - } - - - /* Change to host controller intr-polarity of active-low */ - wrregdata &= ~INTR_POLARITY; - sd_trace(("(we are still in 16bit mode) 32bit Write LE reg-ctrl-data = 0x%x\n", - wrregdata)); - /* Change to 32bit mode */ - wrregdata |= WORD_LENGTH_32; - bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata); - - /* Change command/data packaging in 32bit LE mode */ - sd->wordlen = 4; - - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) - return FALSE; - - if (regdata == TEST_RO_DATA_32BIT_LE) { - sd_trace(("Read spid passed. Value read = 0x%x\n", regdata)); - sd_trace(("Spid had power-on cycle OR spi was soft-resetted \n")); - } else { - sd_err(("Stale spid reg values read as it was kept powered. Value read =" - "0x%x\n", regdata)); - return FALSE; - } - } - - - return TRUE; -} - -static bool -bcmspi_test_card(sdioh_info_t *sd) -{ - uint32 regdata; - int status; - - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) - return FALSE; - - if (regdata == (TEST_RO_DATA_32BIT_LE)) - sd_trace(("32bit LE regdata = 0x%x\n", regdata)); - else { - sd_trace(("Incorrect 32bit LE regdata = 0x%x\n", regdata)); - return FALSE; - } - - -#define RW_PATTERN1 0xA0A1A2A3 -#define RW_PATTERN2 0x4B5B6B7B - - regdata = RW_PATTERN1; - if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS) - return FALSE; - regdata = 0; - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, ®data)) != SUCCESS) - return FALSE; - if (regdata != RW_PATTERN1) { - sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n", - RW_PATTERN1, regdata)); - return FALSE; - } else - sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata)); - - regdata = RW_PATTERN2; - if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS) - return FALSE; - regdata = 0; - if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, ®data)) != SUCCESS) - return FALSE; - if (regdata != RW_PATTERN2) { - sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n", - RW_PATTERN2, regdata)); - return FALSE; - } else - sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata)); - - return TRUE; -} - -static int -bcmspi_driver_init(sdioh_info_t *sd) -{ - sd_trace(("%s\n", __FUNCTION__)); - if ((bcmspi_host_init(sd)) != SUCCESS) { - return ERROR; - } - - if (bcmspi_client_init(sd) != SUCCESS) { - return ERROR; - } - - return SUCCESS; -} - -/* Read device reg */ -static int -bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - int status; - uint32 cmd_arg, dstatus; - - ASSERT(regsize); - - if (func == 2) - sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n")); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 0, func, - regaddr, *data)); - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) - != SUCCESS) - return status; - - bcmspi_cmd_getdstatus(sd, &dstatus); - if (dstatus) - sd_trace(("dstatus =0x%x\n", dstatus)); - - return SUCCESS; -} - -static int -bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -{ - - int status; - uint32 cmd_arg; - uint32 dstatus; - - ASSERT(regsize); - - if (func == 2) - sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n")); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0); /* Fixed access */ - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) - != SUCCESS) - return status; - - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 0, func, - regaddr, *data)); - - bcmspi_cmd_getdstatus(sd, &dstatus); - sd_trace(("dstatus =0x%x\n", dstatus)); - return SUCCESS; -} - -/* write a device register */ -static int -bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -{ - int status; - uint32 cmd_arg, dstatus; - - ASSERT(regsize); - - cmd_arg = 0; - - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 1, func, - regaddr, data)); - - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, regsize)) - != SUCCESS) - return status; - - bcmspi_cmd_getdstatus(sd, &dstatus); - if (dstatus) - sd_trace(("dstatus =0x%x\n", dstatus)); - - return SUCCESS; -} - -/* write a device register - 1 byte */ -static int -bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 *byte) -{ - int status; - uint32 cmd_arg; - uint32 dstatus; - uint32 data = (uint32)(*byte); - - cmd_arg = 0; - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1); - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - sd_trace(("%s: func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, func, - regaddr, data)); - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, - cmd_arg, &data, 1)) != SUCCESS) { - return status; - } - - bcmspi_cmd_getdstatus(sd, &dstatus); - if (dstatus) - sd_trace(("dstatus =0x%x\n", dstatus)); - - return SUCCESS; -} - -void -bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer) -{ - *dstatus_buffer = sd->card_dstatus; -} - -/* 'data' is of type uint32 whereas other buffers are of type uint8 */ -static int -bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg, - uint32 *data, uint32 datalen) -{ - uint32 i, j; - uint8 resp_delay = 0; - int err = SUCCESS; - uint32 hostlen; - uint32 spilen = 0; - uint32 dstatus_idx = 0; - uint16 templen, buslen, len, *ptr = NULL; - - sd_trace(("spi cmd = 0x%x\n", cmd_arg)); - - if (DWORDMODE_ON) { - spilen = GFIELD(cmd_arg, SPI_LEN); - if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_0) || - (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_1)) - dstatus_idx = spilen * 3; - - if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) && - (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) { - spilen = spilen << 2; - dstatus_idx = (spilen % 16) ? (16 - (spilen % 16)) : 0; - /* convert len to mod16 size */ - spilen = ROUNDUP(spilen, 16); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2)); - } - } - - /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen - * according to the wordlen mode(16/32bit) the device is in. - */ - if (sd->wordlen == 4) { /* 32bit spid */ - *(uint32 *)spi_outbuf = bcmswap32(cmd_arg); - if (datalen & 0x3) - datalen += (4 - (datalen & 0x3)); - } else if (sd->wordlen == 2) { /* 16bit spid */ - *(uint16 *)spi_outbuf = bcmswap16(cmd_arg & 0xffff); - *(uint16 *)&spi_outbuf[2] = bcmswap16((cmd_arg & 0xffff0000) >> 16); - if (datalen & 0x1) - datalen++; - if (datalen < 4) - datalen = ROUNDUP(datalen, 4); - } else { - sd_err(("Host is %d bit spid, could not create SPI command.\n", - 8 * sd->wordlen)); - return ERROR; - } - - /* for Write, put the data into the output buffer */ - if (GFIELD(cmd_arg, SPI_RW_FLAG) == 1) { - /* We send len field of hw-header always a mod16 size, both from host and dongle */ - if (DWORDMODE_ON) { - if (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) { - ptr = (uint16 *)&data[0]; - templen = *ptr; - /* ASSERT(*ptr == ~*(ptr + 1)); */ - templen = ROUNDUP(templen, 16); - *ptr = templen; - sd_trace(("actual tx len = %d\n", (uint16)(~*(ptr+1)))); - } - } - - if (datalen != 0) { - for (i = 0; i < datalen/4; i++) { - if (sd->wordlen == 4) { /* 32bit spid */ - *(uint32 *)&spi_outbuf[i * 4 + CMDLEN] = - bcmswap32(data[i]); - } else if (sd->wordlen == 2) { /* 16bit spid */ - *(uint16 *)&spi_outbuf[i * 4 + CMDLEN] = - bcmswap16(data[i] & 0xffff); - *(uint16 *)&spi_outbuf[i * 4 + CMDLEN + 2] = - bcmswap16((data[i] & 0xffff0000) >> 16); - } - } - } - } - - /* Append resp-delay number of bytes and clock them out for F0/1/2 reads. */ - if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) { - int func = GFIELD(cmd_arg, SPI_FUNCTION); - switch (func) { - case 0: - resp_delay = sd->resp_delay_all ? F0_RESPONSE_DELAY : 0; - break; - case 1: - resp_delay = F1_RESPONSE_DELAY; - break; - case 2: - resp_delay = sd->resp_delay_all ? F2_RESPONSE_DELAY : 0; - break; - default: - ASSERT(0); - break; - } - /* Program response delay */ - bcmspi_prog_resp_delay(sd, func, resp_delay); - } - - /* +4 for cmd and +4 for dstatus */ - hostlen = datalen + 8 + resp_delay; - hostlen += dstatus_idx; - hostlen += (4 - (hostlen & 0x3)); - spi_sendrecv(sd, spi_outbuf, spi_inbuf, hostlen); - - /* for Read, get the data into the input buffer */ - if (datalen != 0) { - if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) { /* if read cmd */ - for (j = 0; j < datalen/4; j++) { - if (sd->wordlen == 4) { /* 32bit spid */ - data[j] = bcmswap32(*(uint32 *)&spi_inbuf[j * 4 + - CMDLEN + resp_delay]); - } else if (sd->wordlen == 2) { /* 16bit spid */ - data[j] = (bcmswap16(*(uint16 *)&spi_inbuf[j * 4 + - CMDLEN + resp_delay])) | - ((bcmswap16(*(uint16 *)&spi_inbuf[j * 4 + - CMDLEN + resp_delay + 2])) << 16); - } - } - - if ((DWORDMODE_ON) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) { - ptr = (uint16 *)&data[0]; - templen = *ptr; - buslen = len = ~(*(ptr + 1)); - buslen = ROUNDUP(buslen, 16); - /* populate actual len in hw-header */ - if (templen == buslen) - *ptr = len; - } - } - } - - /* Restore back the len field of the hw header */ - if (DWORDMODE_ON) { - if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) && - (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) { - ptr = (uint16 *)&data[0]; - *ptr = (uint16)(~*(ptr+1)); - } - } - - dstatus_idx += (datalen + CMDLEN + resp_delay); - /* Last 4bytes are dstatus. Device is configured to return status bits. */ - if (sd->wordlen == 4) { /* 32bit spid */ - sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf[dstatus_idx]); - } else if (sd->wordlen == 2) { /* 16bit spid */ - sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf[dstatus_idx]) | - (bcmswap16(*(uint16 *)&spi_inbuf[dstatus_idx + 2]) << 16)); - } else { - sd_err(("Host is %d bit machine, could not read SPI dstatus.\n", - 8 * sd->wordlen)); - return ERROR; - } - if (sd->card_dstatus == 0xffffffff) { - sd_err(("looks like not a GSPI device or device is not powered.\n")); - } - - err = bcmspi_update_stats(sd, cmd_arg); - - return err; - -} - -static int -bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, - uint32 addr, int nbytes, uint32 *data) -{ - int status; - uint32 cmd_arg; - bool write = rw == SDIOH_READ ? 0 : 1; - uint retries = 0; - - bool enable; - uint32 spilen; - - cmd_arg = 0; - - ASSERT(nbytes); - ASSERT(nbytes <= sd->client_block_size[func]); - - if (write) sd->t_cnt++; else sd->r_cnt++; - - if (func == 2) { - /* Frame len check limited by gSPI. */ - if ((nbytes > 2000) && write) { - sd_trace((">2KB write: F2 wr of %d bytes\n", nbytes)); - } - /* ASSERT(nbytes <= 2048); Fix bigger len gspi issue and uncomment. */ - /* If F2 fifo on device is not ready to receive data, don't do F2 transfer */ - if (write) { - uint32 dstatus; - /* check F2 ready with cached one */ - bcmspi_cmd_getdstatus(sd, &dstatus); - if ((dstatus & STATUS_F2_RX_READY) == 0) { - retries = WAIT_F2RXFIFORDY; - enable = 0; - while (retries-- && !enable) { - OSL_DELAY(WAIT_F2RXFIFORDY_DELAY * 1000); - bcmspi_card_regread(sd, SPI_FUNC_0, SPID_STATUS_REG, 4, - &dstatus); - if (dstatus & STATUS_F2_RX_READY) - enable = TRUE; - } - if (!enable) { - struct spierrstats_t *spierrstats = &sd->spierrstats; - spierrstats->f2rxnotready++; - sd_err(("F2 FIFO is not ready to receive data.\n")); - return ERROR; - } - sd_trace(("No of retries on F2 ready %d\n", - (WAIT_F2RXFIFORDY - retries))); - } - } - } - - /* F2 transfers happen on 0 addr */ - addr = (func == 2) ? 0 : addr; - - /* In pio mode buffer is read using fixed address fifo in func 1 */ - if ((func == 1) && (fifo)) - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0); - else - cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); - - cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); - cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, addr); - cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, write); - spilen = sd->data_xfer_count = MIN(sd->client_block_size[func], nbytes); - if ((sd->dwordmode == TRUE) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) { - /* convert len to mod4 size */ - spilen = spilen + ((spilen & 0x3) ? (4 - (spilen & 0x3)): 0); - cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2)); - } else - cmd_arg = SFIELD(cmd_arg, SPI_LEN, spilen); - - if ((func == 2) && (fifo == 1)) { - sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, write ? "Wr" : "Rd", func, "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - } - - sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); - sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", - __FUNCTION__, write ? "Wd" : "Rd", func, "INCR", - addr, nbytes, sd->r_cnt, sd->t_cnt)); - - - if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, - data, nbytes)) != SUCCESS) { - sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, - (write ? "write" : "read"))); - return status; - } - - /* gSPI expects that hw-header-len is equal to spi-command-len */ - if ((func == 2) && (rw == SDIOH_WRITE) && (sd->dwordmode == FALSE)) { - ASSERT((uint16)sd->data_xfer_count == (uint16)(*data & 0xffff)); - ASSERT((uint16)sd->data_xfer_count == (uint16)(~((*data & 0xffff0000) >> 16))); - } - - if ((nbytes > 2000) && !write) { - sd_trace((">2KB read: F2 rd of %d bytes\n", nbytes)); - } - - return SUCCESS; -} - -/* Reset and re-initialize the device */ -int -sdioh_sdio_reset(sdioh_info_t *si) -{ - si->card_init_done = FALSE; - return bcmspi_client_init(si); -} diff --git a/drivers/net/wireless/bcm4329/bcmutils.c b/drivers/net/wireless/bcm4329/bcmutils.c deleted file mode 100644 index 43c04ee92f38..000000000000 --- a/drivers/net/wireless/bcm4329/bcmutils.c +++ /dev/null @@ -1,1838 +0,0 @@ -/* - * Driver O/S-independent utility routines - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: bcmutils.c,v 1.210.4.5.2.4.6.19 2010/04/26 06:05:25 Exp $ - */ - -#include -#include -#include -#include -#ifdef BCMDRIVER -#include -#include -#else -#include -#include -/* This case for external supplicant use */ -#if defined(BCMEXTSUP) -#include -#endif - -#endif /* BCMDRIVER */ -#include -#include -#include -#include -#include -#include -#include - - -#ifdef BCMDRIVER - - -/* copy a pkt buffer chain into a buffer */ -uint -pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - if (len < 0) - len = 4096; /* "infinite" */ - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(PKTDATA(osh, p) + offset, buf, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - -/* copy a buffer into a pkt buffer chain */ -uint -pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(osh, p)) { - if (offset < (uint)PKTLEN(osh, p)) - break; - offset -= PKTLEN(osh, p); - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = PKTNEXT(osh, p)) { - n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); - bcopy(buf, PKTDATA(osh, p) + offset, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - - - -/* return total length of buffer chain */ -uint -pkttotlen(osl_t *osh, void *p) -{ - uint total; - - total = 0; - for (; p; p = PKTNEXT(osh, p)) - total += PKTLEN(osh, p); - return (total); -} - -/* return the last buffer of chained pkt */ -void * -pktlast(osl_t *osh, void *p) -{ - for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) - ; - - return (p); -} - -/* count segments of a chained packet */ -uint -pktsegcnt(osl_t *osh, void *p) -{ - uint cnt; - - for (cnt = 0; p; p = PKTNEXT(osh, p)) - cnt++; - - return cnt; -} - - -/* - * osl multiple-precedence packet queue - * hi_prec is always >= the number of the highest non-empty precedence - */ -void * -pktq_penq(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head) - PKTSETLINK(q->tail, p); - else - q->head = p; - - q->tail = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * -pktq_penq_head(struct pktq *pq, int prec, void *p) -{ - struct pktq_prec *q; - - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); - - q = &pq->q[prec]; - - if (q->head == NULL) - q->tail = p; - - PKTSETLINK(p, q->head); - q->head = p; - q->len++; - - pq->len++; - - if (pq->hi_prec < prec) - pq->hi_prec = (uint8)prec; - - return p; -} - -void * -pktq_pdeq(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_pdeq_tail(struct pktq *pq, int prec) -{ - struct pktq_prec *q; - void *p, *prev; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - return p; -} - -void -pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) -{ - struct pktq_prec *q; - void *p; - - q = &pq->q[prec]; - p = q->head; - while (p) { - q->head = PKTLINK(p); - PKTSETLINK(p, NULL); - PKTFREE(osh, p, dir); - q->len--; - pq->len--; - p = q->head; - } - ASSERT(q->len == 0); - q->tail = NULL; -} - -bool -pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -{ - struct pktq_prec *q; - void *p; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - if (!pktbuf) - return FALSE; - - q = &pq->q[prec]; - - if (q->head == pktbuf) { - if ((q->head = PKTLINK(pktbuf)) == NULL) - q->tail = NULL; - } else { - for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) - ; - if (p == NULL) - return FALSE; - - PKTSETLINK(p, PKTLINK(pktbuf)); - if (q->tail == pktbuf) - q->tail = p; - } - - q->len--; - pq->len--; - PKTSETLINK(pktbuf, NULL); - return TRUE; -} - -void -pktq_init(struct pktq *pq, int num_prec, int max_len) -{ - int prec; - - ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); - - /* pq is variable size; only zero out what's requested */ - bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); - - pq->num_prec = (uint16)num_prec; - - pq->max = (uint16)max_len; - - for (prec = 0; prec < num_prec; prec++) - pq->q[prec].max = pq->max; -} - -void * -pktq_deq(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_deq_tail(struct pktq *pq, int *prec_out) -{ - struct pktq_prec *q; - void *p, *prev; - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - for (prev = NULL; p != q->tail; p = PKTLINK(p)) - prev = p; - - if (prev) - PKTSETLINK(prev, NULL); - else - q->head = NULL; - - q->tail = prev; - q->len--; - - pq->len--; - - if (prec_out) - *prec_out = prec; - - PKTSETLINK(p, NULL); - - return p; -} - -void * -pktq_peek(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].head); -} - -void * -pktq_peek_tail(struct pktq *pq, int *prec_out) -{ - int prec; - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - if (pq->q[prec].head) - break; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].tail); -} - -void -pktq_flush(osl_t *osh, struct pktq *pq, bool dir) -{ - int prec; - for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(osh, pq, prec, dir); - ASSERT(pq->len == 0); -} - -/* Return sum of lengths of a specific set of precedences */ -int -pktq_mlen(struct pktq *pq, uint prec_bmp) -{ - int prec, len; - - len = 0; - - for (prec = 0; prec <= pq->hi_prec; prec++) - if (prec_bmp & (1 << prec)) - len += pq->q[prec].len; - - return len; -} - -/* Priority dequeue from a specific set of precedences */ -void * -pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -{ - struct pktq_prec *q; - void *p; - int prec; - - if (pq->len == 0) - return NULL; - - while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) - pq->hi_prec--; - - while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) - if (prec-- == 0) - return NULL; - - q = &pq->q[prec]; - - if ((p = q->head) == NULL) - return NULL; - - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - - q->len--; - - if (prec_out) - *prec_out = prec; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} -#endif /* BCMDRIVER */ - - - -const unsigned char bcm_ctype[] = { - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ - _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, - _BCM_C, /* 8-15 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ - _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ - _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ - _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, - _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ - _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, - _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ - _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ -}; - -ulong -bcm_strtoul(char *cp, char **endp, uint base) -{ - ulong result, last_result = 0, value; - bool minus; - - minus = FALSE; - - while (bcm_isspace(*cp)) - cp++; - - if (cp[0] == '+') - cp++; - else if (cp[0] == '-') { - minus = TRUE; - cp++; - } - - if (base == 0) { - if (cp[0] == '0') { - if ((cp[1] == 'x') || (cp[1] == 'X')) { - base = 16; - cp = &cp[2]; - } else { - base = 8; - cp = &cp[1]; - } - } else - base = 10; - } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { - cp = &cp[2]; - } - - result = 0; - - while (bcm_isxdigit(*cp) && - (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { - result = result*base + value; - /* Detected overflow */ - if (result < last_result && !minus) - return (ulong)-1; - last_result = result; - cp++; - } - - if (minus) - result = (ulong)(-(long)result); - - if (endp) - *endp = (char *)cp; - - return (result); -} - -int -bcm_atoi(char *s) -{ - return (int)bcm_strtoul(s, NULL, 10); -} - -/* return pointer to location of substring 'needle' in 'haystack' */ -char* -bcmstrstr(char *haystack, char *needle) -{ - int len, nlen; - int i; - - if ((haystack == NULL) || (needle == NULL)) - return (haystack); - - nlen = strlen(needle); - len = strlen(haystack) - nlen + 1; - - for (i = 0; i < len; i++) - if (memcmp(needle, &haystack[i], nlen) == 0) - return (&haystack[i]); - return (NULL); -} - -char* -bcmstrcat(char *dest, const char *src) -{ - char *p; - - p = dest + strlen(dest); - - while ((*p++ = *src++) != '\0') - ; - - return (dest); -} - -char* -bcmstrncat(char *dest, const char *src, uint size) -{ - char *endp; - char *p; - - p = dest + strlen(dest); - endp = p + size; - - while (p != endp && (*p++ = *src++) != '\0') - ; - - return (dest); -} - - -/**************************************************************************** -* Function: bcmstrtok -* -* Purpose: -* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), -* but allows strToken() to be used by different strings or callers at the same -* time. Each call modifies '*string' by substituting a NULL character for the -* first delimiter that is encountered, and updates 'string' to point to the char -* after the delimiter. Leading delimiters are skipped. -* -* Parameters: -* string (mod) Ptr to string ptr, updated by token. -* delimiters (in) Set of delimiter characters. -* tokdelim (out) Character that delimits the returned token. (May -* be set to NULL if token delimiter is not required). -* -* Returns: Pointer to the next token found. NULL when no more tokens are found. -***************************************************************************** -*/ -char * -bcmstrtok(char **string, const char *delimiters, char *tokdelim) -{ - unsigned char *str; - unsigned long map[8]; - int count; - char *nextoken; - - if (tokdelim != NULL) { - /* Prime the token delimiter */ - *tokdelim = '\0'; - } - - /* Clear control map */ - for (count = 0; count < 8; count++) { - map[count] = 0; - } - - /* Set bits in delimiter table */ - do { - map[*delimiters >> 5] |= (1 << (*delimiters & 31)); - } - while (*delimiters++); - - str = (unsigned char*)*string; - - /* Find beginning of token (skip over leading delimiters). Note that - * there is no token iff this loop sets str to point to the terminal - * null (*str == '\0') - */ - while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { - str++; - } - - nextoken = (char*)str; - - /* Find the end of the token. If it is not the end of the string, - * put a null there. - */ - for (; *str; str++) { - if (map[*str >> 5] & (1 << (*str & 31))) { - if (tokdelim != NULL) { - *tokdelim = *str; - } - - *str++ = '\0'; - break; - } - } - - *string = (char*)str; - - /* Determine if a token has been found. */ - if (nextoken == (char *) str) { - return NULL; - } - else { - return nextoken; - } -} - - -#define xToLower(C) \ - ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) - - -/**************************************************************************** -* Function: bcmstricmp -* -* Purpose: Compare to strings case insensitively. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstricmp(const char *s1, const char *s2) -{ - char dc, sc; - - while (*s2 && *s1) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - } - - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - - -/**************************************************************************** -* Function: bcmstrnicmp -* -* Purpose: Compare to strings case insensitively, upto a max of 'cnt' -* characters. -* -* Parameters: s1 (in) First string to compare. -* s2 (in) Second string to compare. -* cnt (in) Max characters to compare. -* -* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -* t1 > t2, when ignoring case sensitivity. -***************************************************************************** -*/ -int -bcmstrnicmp(const char* s1, const char* s2, int cnt) -{ - char dc, sc; - - while (*s2 && *s1 && cnt) { - dc = xToLower(*s1); - sc = xToLower(*s2); - if (dc < sc) return -1; - if (dc > sc) return 1; - s1++; - s2++; - cnt--; - } - - if (!cnt) return 0; - if (*s1 && !*s2) return 1; - if (!*s1 && *s2) return -1; - return 0; -} - -/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int -bcm_ether_atoe(char *p, struct ether_addr *ea) -{ - int i = 0; - - for (;;) { - ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); - if (!*p++ || i == 6) - break; - } - - return (i == 6); -} - - -#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -/* registry routine buffer preparation utility functions: - * parameter order is like strncpy, but returns count - * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) - */ -ulong -wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) -{ - ulong copyct = 1; - ushort i; - - if (abuflen == 0) - return 0; - - /* wbuflen is in bytes */ - wbuflen /= sizeof(ushort); - - for (i = 0; i < wbuflen; ++i) { - if (--abuflen == 0) - break; - *abuf++ = (char) *wbuf++; - ++copyct; - } - *abuf = '\0'; - - return copyct; -} -#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ - -char * -bcm_ether_ntoa(const struct ether_addr *ea, char *buf) -{ - static const char template[] = "%02x:%02x:%02x:%02x:%02x:%02x"; - snprintf(buf, 18, template, - ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, - ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); - return (buf); -} - -char * -bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) -{ - snprintf(buf, 16, "%d.%d.%d.%d", - ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); - return (buf); -} - -#ifdef BCMDRIVER - -void -bcm_mdelay(uint ms) -{ - uint i; - - for (i = 0; i < ms; i++) { - OSL_DELAY(1000); - } -} - - - - - - -#if defined(DHD_DEBUG) -/* pretty hex print a pkt buffer chain */ -void -prpkt(const char *msg, osl_t *osh, void *p0) -{ - void *p; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - for (p = p0; p; p = PKTNEXT(osh, p)) - prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); -} -#endif - -/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. - * Also updates the inplace vlan tag if requested. - * For debugging, it returns an indication of what it did. - */ -uint -pktsetprio(void *pkt, bool update_vtag) -{ - struct ether_header *eh; - struct ethervlan_header *evh; - uint8 *pktdata; - int priority = 0; - int rc = 0; - - pktdata = (uint8 *) PKTDATA(NULL, pkt); - ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); - - eh = (struct ether_header *) pktdata; - - if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { - uint16 vlan_tag; - int vlan_prio, dscp_prio = 0; - - evh = (struct ethervlan_header *)eh; - - vlan_tag = ntoh16(evh->vlan_tag); - vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; - - if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); - uint8 tos_tc = IP_TOS(ip_body); - dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - } - - /* DSCP priority gets precedence over 802.1P (vlan tag) */ - if (dscp_prio != 0) { - priority = dscp_prio; - rc |= PKTPRIO_VDSCP; - } else { - priority = vlan_prio; - rc |= PKTPRIO_VLAN; - } - /* - * If the DSCP priority is not the same as the VLAN priority, - * then overwrite the priority field in the vlan tag, with the - * DSCP priority value. This is required for Linux APs because - * the VLAN driver on Linux, overwrites the skb->priority field - * with the priority value in the vlan tag - */ - if (update_vtag && (priority != vlan_prio)) { - vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); - vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; - evh->vlan_tag = hton16(vlan_tag); - rc |= PKTPRIO_UPD; - } - } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { - uint8 *ip_body = pktdata + sizeof(struct ether_header); - uint8 tos_tc = IP_TOS(ip_body); - priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - rc |= PKTPRIO_DSCP; - } - - ASSERT(priority >= 0 && priority <= MAXPRIO); - PKTSETPRIO(pkt, priority); - return (rc | priority); -} - -static char bcm_undeferrstr[BCME_STRLEN]; - -static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; - -/* Convert the error codes into related error strings */ -const char * -bcmerrorstr(int bcmerror) -{ - /* check if someone added a bcmerror code but forgot to add errorstring */ - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); - - if (bcmerror > 0 || bcmerror < BCME_LAST) { - snprintf(bcm_undeferrstr, BCME_STRLEN, "Undefined error %d", bcmerror); - return bcm_undeferrstr; - } - - ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); - - return bcmerrorstrtable[-bcmerror]; -} - - - -/* iovar table lookup */ -const bcm_iovar_t* -bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -int -bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -{ - int bcmerror = 0; - - /* length check on io buf */ - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - /* all integers are int32 sized args at the ioctl interface */ - if (len < (int)sizeof(int)) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_BUFFER: - /* buffer must meet minimum length requirement */ - if (len < vi->minlen) { - bcmerror = BCME_BUFTOOSHORT; - } - break; - - case IOVT_VOID: - if (!set) { - /* Cannot return nil... */ - bcmerror = BCME_UNSUPPORTED; - } else if (len) { - /* Set is an action w/o parameters */ - bcmerror = BCME_BUFTOOLONG; - } - break; - - default: - /* unknown type for length check in iovar info */ - ASSERT(0); - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - -#endif /* BCMDRIVER */ - -/******************************************************************************* - * crc8 - * - * Computes a crc8 over the input data using the polynomial: - * - * x^8 + x^7 +x^6 + x^4 + x^2 + 1 - * - * The caller provides the initial value (either CRC8_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC8_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -STATIC const uint8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -}; - -#define CRC_INNER_LOOP(n, c, x) \ - (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] - -uint8 -hndcrc8( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -) -{ - /* hard code the crc loop instead of using CRC_INNER_LOOP macro - * to avoid the undefined and unnecessary (uint8 >> 8) operation. - */ - while (nbytes-- > 0) - crc = crc8_table[(crc ^ *pdata++) & 0xff]; - - return crc; -} - -/******************************************************************************* - * crc16 - * - * Computes a crc16 over the input data using the polynomial: - * - * x^16 + x^12 +x^5 + 1 - * - * The caller provides the initial value (either CRC16_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC16_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const uint16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -}; - -uint16 -hndcrc16( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -) -{ - while (nbytes-- > 0) - CRC_INNER_LOOP(16, crc, *pdata++); - return crc; -} - -STATIC const uint32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -uint32 -hndcrc32( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint32 crc /* either CRC32_INIT_VALUE or previous return value */ -) -{ - uint8 *pend; -#ifdef __mips__ - uint8 tmp[4]; - ulong *tptr = (ulong *)tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = *(ulong *)pdata; - pdata += sizeof(ulong *); - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else - pend = pdata + nbytes; - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#endif /* __mips__ */ - - return crc; -} - -#ifdef notdef -#define CLEN 1499 /* CRC Length */ -#define CBUFSIZ (CLEN+4) -#define CNBUFS 5 /* # of bufs */ - -void testcrc32(void) -{ - uint j, k, l; - uint8 *buf; - uint len[CNBUFS]; - uint32 crcr; - uint32 crc32tv[CNBUFS] = - {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; - - ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); - - /* step through all possible alignments */ - for (l = 0; l <= 4; l++) { - for (j = 0; j < CNBUFS; j++) { - len[j] = CLEN; - for (k = 0; k < len[j]; k++) - *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; - } - - for (j = 0; j < CNBUFS; j++) { - crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); - ASSERT(crcr == crc32tv[j]); - } - } - - MFREE(buf, CBUFSIZ*CNBUFS); - return; -} -#endif /* notdef */ - -/* - * Advance from the current 1-byte tag/1-byte length/variable-length value - * triple, to the next, returning a pointer to the next. - * If the current or next TLV is invalid (does not fit in given buffer length), - * NULL is returned. - * *buflen is not modified if the TLV elt parameter is invalid, or is decremented - * by the TLV parameter's length if it is valid. - */ -bcm_tlv_t * -bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -{ - int len; - - /* validate current elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - /* advance to next elt */ - len = elt->len; - elt = (bcm_tlv_t*)(elt->data + len); - *buflen -= (2 + len); - - /* validate next elt */ - if (!bcm_valid_tlv(elt, *buflen)) - return NULL; - - return elt; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag - */ -bcm_tlv_t * -bcm_parse_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - int len = elt->len; - - /* validate remaining totlen */ - if ((elt->id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - - return NULL; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag. Stop parsing when we see an element whose ID is greater - * than the target key. - */ -bcm_tlv_t * -bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - uint id = elt->id; - int len = elt->len; - - /* Punt if we start seeing IDs > than target key */ - if (id > key) - return (NULL); - - /* validate remaining totlen */ - if ((id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - return NULL; -} - -#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ - defined(DHD_DEBUG) -int -bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) -{ - int i; - char* p = buf; - char hexstr[16]; - int slen = 0; - uint32 bit; - const char* name; - - if (len < 2 || !buf) - return 0; - - buf[0] = '\0'; - len -= 1; - - for (i = 0; flags != 0; i++) { - bit = bd[i].bit; - name = bd[i].name; - if (bit == 0 && flags) { - /* print any unnamed bits */ - sprintf(hexstr, "0x%X", flags); - name = hexstr; - flags = 0; /* exit loop */ - } else if ((flags & bit) == 0) - continue; - slen += strlen(name); - if (len < slen) - break; - if (p != buf) p += sprintf(p, " "); /* btwn flag space */ - strcat(p, name); - p += strlen(name); - flags &= ~bit; - len -= slen; - slen = 1; /* account for btwn flag space */ - } - - /* indicate the str was too short */ - if (flags != 0) { - if (len == 0) - p--; /* overwrite last char */ - p += sprintf(p, ">"); - } - - return (int)(p - buf); -} - -/* print bytes formatted as hex to a string. return the resulting string length */ -int -bcm_format_hex(char *str, const void *bytes, int len) -{ - int i; - char *p = str; - const uint8 *src = (const uint8*)bytes; - - for (i = 0; i < len; i++) { - p += sprintf(p, "%02X", *src); - src++; - } - return (int)(p - str); -} - -/* pretty hex print a contiguous buffer */ -void -prhex(const char *msg, uchar *buf, uint nbytes) -{ - char line[128], *p; - uint i; - - if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - p += sprintf(p, " %04d: ", i); /* line prefix */ - } - p += sprintf(p, "%02x ", buf[i]); - if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ - p = line; - } - } - - /* flush last partial line */ - if (p != line) - printf("%s\n", line); -} -#endif - - -/* Produce a human-readable string for boardrev */ -char * -bcm_brev_str(uint32 brev, char *buf) -{ - if (brev < 0x100) - snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); - else - snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); - - return (buf); -} - -#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ - -/* dump large strings to console */ -void -printbig(char *buf) -{ - uint len, max_len; - char c; - - len = strlen(buf); - - max_len = BUFSIZE_TODUMP_ATONCE; - - while (len > max_len) { - c = buf[max_len]; - buf[max_len] = '\0'; - printf("%s", buf); - buf[max_len] = c; - - buf += max_len; - len -= max_len; - } - /* print the remaining string */ - printf("%s\n", buf); - return; -} - -/* routine to dump fields in a fileddesc structure */ -uint -bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, - char *buf, uint32 bufsize) -{ - uint filled_len; - int len; - struct fielddesc *cur_ptr; - - filled_len = 0; - cur_ptr = fielddesc_array; - - while (bufsize > 1) { - if (cur_ptr->nameandfmt == NULL) - break; - len = snprintf(buf, bufsize, cur_ptr->nameandfmt, - read_rtn(arg0, arg1, cur_ptr->offset)); - /* check for snprintf overflow or error */ - if (len < 0 || (uint32)len >= bufsize) - len = bufsize - 1; - buf += len; - bufsize -= len; - filled_len += len; - cur_ptr++; - } - return filled_len; -} - -uint -bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -{ - uint len; - - len = strlen(name) + 1; - - if ((len + datalen) > buflen) - return 0; - - strncpy(buf, name, buflen); - - /* append data onto the end of the name string */ - memcpy(&buf[len], data, datalen); - len += datalen; - - return len; -} - -/* Quarter dBm units to mW - * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 - * Table is offset so the last entry is largest mW value that fits in - * a uint16. - */ - -#define QDBM_OFFSET 153 /* Offset for first entry */ -#define QDBM_TABLE_LEN 40 /* Table size */ - -/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. - * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 - */ -#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ - -/* Largest mW value that will round down to the last table entry, - * QDBM_OFFSET + QDBM_TABLE_LEN-1. - * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. - */ -#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ - -static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -}; - -uint16 -bcm_qdbm_to_mw(uint8 qdbm) -{ - uint factor = 1; - int idx = qdbm - QDBM_OFFSET; - - if (idx >= QDBM_TABLE_LEN) { - /* clamp to max uint16 mW value */ - return 0xFFFF; - } - - /* scale the qdBm index up to the range of the table 0-40 - * where an offset of 40 qdBm equals a factor of 10 mW. - */ - while (idx < 0) { - idx += 40; - factor *= 10; - } - - /* return the mW value scaled down to the correct factor of 10, - * adding in factor/2 to get proper rounding. - */ - return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -} - -uint8 -bcm_mw_to_qdbm(uint16 mw) -{ - uint8 qdbm; - int offset; - uint mw_uint = mw; - uint boundary; - - /* handle boundary case */ - if (mw_uint <= 1) - return 0; - - offset = QDBM_OFFSET; - - /* move mw into the range of the table */ - while (mw_uint < QDBM_TABLE_LOW_BOUND) { - mw_uint *= 10; - offset -= 40; - } - - for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { - boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - - nqdBm_to_mW_map[qdbm])/2; - if (mw_uint < boundary) break; - } - - qdbm += (uint8)offset; - - return (qdbm); -} - - -uint -bcm_bitcount(uint8 *bitmap, uint length) -{ - uint bitcount = 0, i; - uint8 tmp; - for (i = 0; i < length; i++) { - tmp = bitmap[i]; - while (tmp) { - bitcount++; - tmp &= (tmp - 1); - } - } - return bitcount; -} - -#ifdef BCMDRIVER - -/* Initialization of bcmstrbuf structure */ -void -bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -{ - b->origsize = b->size = size; - b->origbuf = b->buf = buf; -} - -/* Buffer sprintf wrapper to guard against buffer overflow */ -int -bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -{ - va_list ap; - int r; - - va_start(ap, fmt); - r = vsnprintf(b->buf, b->size, fmt, ap); - - /* Non Ansi C99 compliant returns -1, - * Ansi compliant return r >= b->size, - * bcmstdlib returns 0, handle all - */ - if ((r == -1) || (r >= (int)b->size) || (r == 0)) { - b->size = 0; - } else { - b->size -= r; - b->buf += r; - } - - va_end(ap); - - return r; -} - -void -bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) -{ - int i; - - for (i = 0; i < num_bytes; i++) { - num[i] += amount; - if (num[i] >= amount) - break; - amount = 1; - } -} - -int -bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes) -{ - int i; - - for (i = nbytes - 1; i >= 0; i--) { - if (arg1[i] != arg2[i]) - return (arg1[i] - arg2[i]); - } - return 0; -} - -void -bcm_print_bytes(char *name, const uchar *data, int len) -{ - int i; - int per_line = 0; - - printf("%s: %d \n", name ? name : "", len); - for (i = 0; i < len; i++) { - printf("%02x ", *data++); - per_line++; - if (per_line == 16) { - per_line = 0; - printf("\n"); - } - } - printf("\n"); -} - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ - -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -int -bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (bcm_isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif - -#endif /* BCMDRIVER */ diff --git a/drivers/net/wireless/bcm4329/bcmwifi.c b/drivers/net/wireless/bcm4329/bcmwifi.c deleted file mode 100644 index 803acf842a29..000000000000 --- a/drivers/net/wireless/bcm4329/bcmwifi.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Misc utility routines used by kernel or app-level. - * Contents are wifi-specific, used by any kernel or app-level - * software that might want wifi things as it grows. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: bcmwifi.c,v 1.18.24.2.4.1 2009/09/25 00:32:01 Exp $ - */ - - -#include - -#ifdef BCMDRIVER -#include -#include -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#else -#include -#include -#include -#endif -#include - -#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) -#include -#endif - - - - - -char * -wf_chspec_ntoa(chanspec_t chspec, char *buf) -{ - const char *band, *bw, *sb; - uint channel; - - band = ""; - bw = ""; - sb = ""; - channel = CHSPEC_CHANNEL(chspec); - - if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) || - (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL)) - band = (CHSPEC_IS2G(chspec)) ? "b" : "a"; - if (CHSPEC_IS40(chspec)) { - if (CHSPEC_SB_UPPER(chspec)) { - sb = "u"; - channel += CH_10MHZ_APART; - } else { - sb = "l"; - channel -= CH_10MHZ_APART; - } - } else if (CHSPEC_IS10(chspec)) { - bw = "n"; - } - - - snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb); - return (buf); -} - - -chanspec_t -wf_chspec_aton(char *a) -{ - char *endp = NULL; - uint channel, band, bw, ctl_sb; - char c; - - channel = strtoul(a, &endp, 10); - - - if (endp == a) - return 0; - - if (channel > MAXCHANNEL) - return 0; - - band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); - bw = WL_CHANSPEC_BW_20; - ctl_sb = WL_CHANSPEC_CTL_SB_NONE; - - a = endp; - - c = tolower(a[0]); - if (c == '\0') - goto done; - - - if (c == 'a' || c == 'b') { - band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G; - a++; - c = tolower(a[0]); - if (c == '\0') - goto done; - } - - - if (c == 'n') { - bw = WL_CHANSPEC_BW_10; - } else if (c == 'l') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_LOWER; - - if (channel <= (MAXCHANNEL - CH_20MHZ_APART)) - channel += CH_10MHZ_APART; - else - return 0; - } else if (c == 'u') { - bw = WL_CHANSPEC_BW_40; - ctl_sb = WL_CHANSPEC_CTL_SB_UPPER; - - if (channel > CH_20MHZ_APART) - channel -= CH_10MHZ_APART; - else - return 0; - } else { - return 0; - } - -done: - return (channel | band | bw | ctl_sb); -} - - -int -wf_mhz2channel(uint freq, uint start_factor) -{ - int ch = -1; - uint base; - int offset; - - - if (start_factor == 0) { - if (freq >= 2400 && freq <= 2500) - start_factor = WF_CHAN_FACTOR_2_4_G; - else if (freq >= 5000 && freq <= 6000) - start_factor = WF_CHAN_FACTOR_5_G; - } - - if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) - return 14; - - base = start_factor / 2; - - - if ((freq < base) || (freq > base + 1000)) - return -1; - - offset = freq - base; - ch = offset / 5; - - - if (offset != (ch * 5)) - return -1; - - - if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13)) - return -1; - - return ch; -} - - -int -wf_channel2mhz(uint ch, uint start_factor) -{ - int freq; - - if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || - (ch <= 200)) - freq = -1; - if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) - freq = 2484; - else - freq = ch * 5 + start_factor / 2; - - return freq; -} diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h deleted file mode 100644 index 573f425527ff..000000000000 --- a/drivers/net/wireless/bcm4329/dhd.h +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.9 2011/01/14 22:40:45 Exp $ - */ - -/**************** - * Common types * - */ - -#ifndef _dhd_h_ -#define _dhd_h_ - -#if defined(LINUX) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* The kernel threading is sdio-specific */ -#else /* LINUX */ -#define ENOMEM 1 -#define EFAULT 2 -#define EINVAL 3 -#define EIO 4 -#define ETIMEDOUT 5 -#define ERESTARTSYS 6 -#endif /* LINUX */ - -#include - -#ifdef DHD_DEBUG -#ifndef DHD_DEBUG_TRAP -#define DHD_DEBUG_TRAP -#endif -#endif - -/* Forward decls */ -struct dhd_bus; -struct dhd_prot; -struct dhd_info; - -/* The level of bus communication with the dongle */ -enum dhd_bus_state { - DHD_BUS_DOWN, /* Not ready for frame transfers */ - DHD_BUS_LOAD, /* Download access only (CPU reset) */ - DHD_BUS_DATA /* Ready for frame transfers */ -}; - -enum dhd_bus_wake_state { - WAKE_LOCK_OFF, - WAKE_LOCK_PRIV, - WAKE_LOCK_DPC, - WAKE_LOCK_IOCTL, - WAKE_LOCK_DOWNLOAD, - WAKE_LOCK_TMOUT, - WAKE_LOCK_WATCHDOG, - WAKE_LOCK_LINK_DOWN_TMOUT, - WAKE_LOCK_PNO_FIND_TMOUT, - WAKE_LOCK_SOFTAP_SET, - WAKE_LOCK_SOFTAP_STOP, - WAKE_LOCK_SOFTAP_START, - WAKE_LOCK_SOFTAP_THREAD, - WAKE_LOCK_MAX -}; -enum dhd_prealloc_index { - DHD_PREALLOC_PROT = 0, - DHD_PREALLOC_RXBUF, - DHD_PREALLOC_DATABUF, - DHD_PREALLOC_OSL_BUF -}; -#ifdef DHD_USE_STATIC_BUF -extern void * dhd_os_prealloc(int section, unsigned long size); -#endif -/* Common structure for module and instance linkage */ -typedef struct dhd_pub { - /* Linkage ponters */ - osl_t *osh; /* OSL handle */ - struct dhd_bus *bus; /* Bus module handle */ - struct dhd_prot *prot; /* Protocol module handle */ - struct dhd_info *info; /* Info module handle */ - - /* Internal dhd items */ - bool up; /* Driver up/down (to OS) */ - bool txoff; /* Transmit flow-controlled */ - bool dongle_reset; /* TRUE = DEVRESET put dongle into reset */ - enum dhd_bus_state busstate; - uint hdrlen; /* Total DHD header length (proto + bus) */ - uint maxctl; /* Max size rxctl request from proto to bus */ - uint rxsz; /* Rx buffer size bus module should use */ - uint8 wme_dp; /* wme discard priority */ - - /* Dongle media info */ - bool iswl; /* Dongle-resident driver is wl */ - ulong drv_version; /* Version of dongle-resident driver */ - struct ether_addr mac; /* MAC address obtained from dongle */ - dngl_stats_t dstats; /* Stats for dongle-based data */ - - /* Additional stats for the bus level */ - ulong tx_packets; /* Data packets sent to dongle */ - ulong tx_multicast; /* Multicast data packets sent to dongle */ - ulong tx_errors; /* Errors in sending data to dongle */ - ulong tx_ctlpkts; /* Control packets sent to dongle */ - ulong tx_ctlerrs; /* Errors sending control frames to dongle */ - ulong rx_packets; /* Packets sent up the network interface */ - ulong rx_multicast; /* Multicast packets sent up the network interface */ - ulong rx_errors; /* Errors processing rx data packets */ - ulong rx_ctlpkts; /* Control frames processed from dongle */ - ulong rx_ctlerrs; /* Errors in processing rx control frames */ - ulong rx_dropped; /* Packets dropped locally (no memory) */ - ulong rx_flushed; /* Packets flushed due to unscheduled sendup thread */ - ulong wd_dpc_sched; /* Number of times dhd dpc scheduled by watchdog timer */ - - ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */ - ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */ - ulong fc_packets; /* Number of flow control pkts recvd */ - - /* Last error return */ - int bcmerror; - uint tickcnt; - - /* Last error from dongle */ - int dongle_error; - - /* Suspend disable flag and "in suspend" flag */ - int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ - int in_suspend; /* flag set to 1 when early suspend called */ -#ifdef PNO_SUPPORT - int pno_enable; /* pno status : "1" is pno enable */ -#endif /* PNO_SUPPORT */ - int dtim_skip; /* dtim skip , default 0 means wake each dtim */ - - /* Pkt filter defination */ - char * pktfilter[100]; - int pktfilter_count; - - wl_country_t dhd_cspec; /* Current Locale info */ - char eventmask[WL_EVENTING_MASK_LEN]; - -} dhd_pub_t; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - - #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define _DHD_PM_RESUME_WAIT(a, b) do { \ - int retry = 0; \ - smp_mb(); \ - while (dhd_mmc_suspend && retry++ != b) { \ - wait_event_interruptible_timeout(a, FALSE, HZ/100); \ - } \ - } while (0) - #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) - #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) - #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) - #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) - - #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9999; \ - while ((exp) && (countdown >= 10000)) { \ - wait_event_interruptible_timeout(a, FALSE, HZ/100); \ - countdown -= 10000; \ - } \ - } while (0) - -#else - - #define DHD_PM_RESUME_WAIT_INIT(a) - #define DHD_PM_RESUME_WAIT(a) - #define DHD_PM_RESUME_WAIT_FOREVER(a) - #define DHD_PM_RESUME_RETURN_ERROR(a) - #define DHD_PM_RESUME_RETURN - - #define DHD_SPINWAIT_SLEEP_INIT(a) - #define SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) { \ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ - } while (0) - -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ - -inline static void NETIF_ADDR_LOCK(struct net_device *dev) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) - netif_addr_lock_bh(dev); -#endif -} - -inline static void NETIF_ADDR_UNLOCK(struct net_device *dev) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) - netif_addr_unlock_bh(dev); -#endif -} - -/* Wakelock Functions */ -extern int dhd_os_wake_lock(dhd_pub_t *pub); -extern int dhd_os_wake_unlock(dhd_pub_t *pub); -extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); -extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub); - -extern void dhd_os_start_lock(dhd_pub_t *pub); -extern void dhd_os_start_unlock(dhd_pub_t *pub); -extern unsigned long dhd_os_spin_lock(dhd_pub_t *pub); -extern void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags); - -typedef struct dhd_if_event { - uint8 ifidx; - uint8 action; - uint8 flags; - uint8 bssidx; -} dhd_if_event_t; - -/* - * Exported from dhd OS modules (dhd_linux/dhd_ndis) - */ - -/* To allow osl_attach/detach calls from os-independent modules */ -osl_t *dhd_osl_attach(void *pdev, uint bustype); -void dhd_osl_detach(osl_t *osh); - -/* Indication from bus module regarding presence/insertion of dongle. - * Return dhd_pub_t pointer, used as handle to OS module in later calls. - * Returned structure should have bus and prot pointers filled in. - * bus_hdrlen specifies required headroom for bus module header. - */ -extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen); -extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); - -/* Indication from bus module regarding removal/absence of dongle */ -extern void dhd_detach(dhd_pub_t *dhdp); - -/* Indication from bus module to change flow-control state */ -extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); - -extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); - -/* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt); - -/* Return pointer to interface name */ -extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); - -/* Request scheduling of the bus dpc */ -extern void dhd_sched_dpc(dhd_pub_t *dhdp); - -/* Notify tx completion */ -extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); - -/* Query ioctl */ -extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -/* OS independent layer functions */ -extern int dhd_os_proto_block(dhd_pub_t * pub); -extern int dhd_os_proto_unblock(dhd_pub_t * pub); -extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending); -extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub); -extern unsigned int dhd_os_get_ioctl_resp_timeout(void); -extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -extern void * dhd_os_open_image(char * filename); -extern int dhd_os_get_image_block(char * buf, int len, void * image); -extern void dhd_os_close_image(void * image); -extern void dhd_os_wd_timer(void *bus, uint wdtick); -extern void dhd_os_sdlock(dhd_pub_t * pub); -extern void dhd_os_sdunlock(dhd_pub_t * pub); -extern void dhd_os_sdlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_txq(dhd_pub_t * pub); -extern void dhd_os_sdlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern int dhd_custom_get_mac_address(unsigned char *buf); -extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); -extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); -extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); -#ifdef DHD_DEBUG -extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); -#endif /* DHD_DEBUG */ -#if defined(OOB_INTR_ONLY) -extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr); -#endif /* defined(OOB_INTR_ONLY) */ -extern void dhd_os_sdtxlock(dhd_pub_t * pub); -extern void dhd_os_sdtxunlock(dhd_pub_t * pub); - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param); - -typedef struct { - uint32 limit; /* Expiration time (usec) */ - uint32 increment; /* Current expiration increment (usec) */ - uint32 elapsed; /* Current elapsed time (usec) */ - uint32 tick; /* O/S tick time (usec) */ -} dhd_timeout_t; - -extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec); -extern int dhd_timeout_expired(dhd_timeout_t *tmo); - -extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); -extern uint8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx); -extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata, - wl_event_msg_t *, void **data_ptr); -extern void wl_event_to_host_order(wl_event_msg_t * evt); - -extern void dhd_common_init(void); - -extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, - char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx); -extern void dhd_del_if(struct dhd_info *dhd, int ifidx); - -extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name); -extern void dhd_vif_del(struct dhd_info *dhd, int ifidx); - -extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx); -extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len); - - -/* Send packet to dongle via data channel */ -extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt); - -/* Send event to host */ -extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag); -extern uint dhd_bus_status(dhd_pub_t *dhdp); -extern int dhd_bus_start(dhd_pub_t *dhdp); - -extern void print_buf(void *pbuf, int len, int bytes_per_line); - - -typedef enum cust_gpio_modes { - WLAN_RESET_ON, - WLAN_RESET_OFF, - WLAN_POWER_ON, - WLAN_POWER_OFF -} cust_gpio_modes_t; - -extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -extern int wl_iw_send_priv_event(struct net_device *dev, char *flag); -extern int net_os_send_hang_message(struct net_device *dev); - -/* - * Insmod parameters for debug/test - */ - -/* Watchdog timer interval */ -extern uint dhd_watchdog_ms; - -#if defined(DHD_DEBUG) -/* Console output poll interval */ -extern uint dhd_console_ms; -#endif /* defined(DHD_DEBUG) */ - -/* Use interrupts */ -extern uint dhd_intr; - -/* Use polling */ -extern uint dhd_poll; - -/* ARP offload agent mode */ -extern uint dhd_arp_mode; - -/* ARP offload enable */ -extern uint dhd_arp_enable; - -/* Pkt filte enable control */ -extern uint dhd_pkt_filter_enable; - -/* Pkt filter init setup */ -extern uint dhd_pkt_filter_init; - -/* Pkt filter mode control */ -extern uint dhd_master_mode; - -/* Roaming mode control */ -extern uint dhd_roam; - -/* Roaming mode control */ -extern uint dhd_radio_up; - -/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -extern int dhd_idletime; -#define DHD_IDLETIME_TICKS 1 - -/* SDIO Drive Strength */ -extern uint dhd_sdiod_drive_strength; - -/* Override to force tx queueing all the time */ -extern uint dhd_force_tx_queueing; - -/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */ -#define KEEP_ALIVE_PERIOD 55000 -#define NULL_PKT_STR "null_pkt" - -#ifdef SDTEST -/* Echo packet generator (SDIO), pkts/s */ -extern uint dhd_pktgen; - -/* Echo packet len (0 => sawtooth, max 1800) */ -extern uint dhd_pktgen_len; -#define MAX_PKTGEN_LEN 1800 -#endif - - -/* optionally set by a module_param_string() */ -#define MOD_PARAM_PATHLEN 2048 -extern char fw_path[MOD_PARAM_PATHLEN]; -extern char nv_path[MOD_PARAM_PATHLEN]; - -/* For supporting multiple interfaces */ -#define DHD_MAX_IFS 16 -#define DHD_DEL_IF -0xe -#define DHD_BAD_IF -0xf - - -extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar); -extern void dhd_wait_event_wakeup(dhd_pub_t*dhd); - -/* dhd_commn arp offload wrapers */ -extern void dhd_arp_cleanup(dhd_pub_t *dhd); -int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen); -void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr); - -#endif /* _dhd_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_bus.h b/drivers/net/wireless/bcm4329/dhd_bus.h deleted file mode 100644 index 97af41b313d0..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_bus.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_bus.h,v 1.4.6.3.2.3.6.7 2010/08/13 01:35:24 Exp $ - */ - -#ifndef _dhd_bus_h_ -#define _dhd_bus_h_ - -/* - * Exported from dhd bus module (dhd_usb, dhd_sdio) - */ - -/* Indicate (dis)interest in finding dongles. */ -extern int dhd_bus_register(void); -extern void dhd_bus_unregister(void); - -/* Download firmware image and nvram image */ -extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *fw_path, char *nv_path); - -/* Stop bus module: clear pending frames, disable data flow */ -extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); - -/* Initialize bus module: prepare for communication w/dongle */ -extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); - -/* Send a data frame to the dongle. Callee disposes of txp. */ -extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp); - -/* Send/receive a control message to/from the dongle. - * Expects caller to enforce a single outstanding transaction. - */ -extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen); -extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen); - -/* Watchdog timer function */ -extern bool dhd_bus_watchdog(dhd_pub_t *dhd); - -#ifdef DHD_DEBUG -/* Device console input function */ -extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen); -#endif /* DHD_DEBUG */ - -/* Deferred processing for the bus, return TRUE requests reschedule */ -extern bool dhd_bus_dpc(struct dhd_bus *bus); -extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg); - - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add bus dump output to a buffer */ -extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Clear any bus counters */ -extern void dhd_bus_clearcounts(dhd_pub_t *dhdp); - -/* return the dongle chipid */ -extern uint dhd_bus_chip(struct dhd_bus *bus); - -/* Set user-specified nvram parameters. */ -extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params); - -extern void *dhd_bus_pub(struct dhd_bus *bus); -extern void *dhd_bus_txq(struct dhd_bus *bus); -extern uint dhd_bus_hdrlen(struct dhd_bus *bus); - -#endif /* _dhd_bus_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_cdc.c b/drivers/net/wireless/bcm4329/dhd_cdc.c deleted file mode 100644 index 61f6a6f393a9..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_cdc.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * DHD Protocol Module for CDC and BDC. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_cdc.c,v 1.22.4.2.4.7.2.41 2010/06/23 19:58:18 Exp $ - * - * BDC is like CDC, except it includes a header for data packets to convey - * packet priority over the bus, and flags (e.g. to indicate checksum status - * for dongle offload). - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#define RETRIES 2 /* # of retries to retrieve matching ioctl response */ -#define BUS_HEADER_LEN (16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE - * defined in dhd_sdio.c (amount of header tha might be added) - * plus any space that might be needed for alignment padding. - */ -#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for - * round off at the end of buffer - */ - -typedef struct dhd_prot { - uint16 reqid; - uint8 pending; - uint32 lastcmd; - uint8 bus_header[BUS_HEADER_LEN]; - cdc_ioctl_t msg; - unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; -} dhd_prot_t; - -static int -dhdcdc_msg(dhd_pub_t *dhd) -{ - dhd_prot_t *prot = dhd->prot; - int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t); - int ret; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_wake_lock(dhd); - - /* NOTE : cdc->msg.len holds the desired length of the buffer to be - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area - * is actually sent to the dongle - */ - if (len > CDC_MAX_MSG_SIZE) - len = CDC_MAX_MSG_SIZE; - - /* Send request */ - ret = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len); - dhd_os_wake_unlock(dhd); - return ret; -} - -static int -dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len) -{ - int ret; - dhd_prot_t *prot = dhd->prot; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - do { - ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, len+sizeof(cdc_ioctl_t)); - if (ret < 0) - break; - } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); - - return ret; -} - -int -dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - void *info; - int ret = 0, retries = 0; - uint32 id, flags = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - - /* Respond "bcmerror" and "bcmerrorstr" with local cache */ - if (cmd == WLC_GET_VAR && buf) - { - if (!strcmp((char *)buf, "bcmerrorstr")) - { - strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN); - goto done; - } - else if (!strcmp((char *)buf, "bcmerror")) - { - *(int *)buf = dhd->dongle_error; - goto done; - } - } - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); - CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) { - DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret)); - goto done; - } - -retry: - /* wait for interrupt and get first fragment */ - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if ((id < prot->reqid) && (++retries < RETRIES)) - goto retry; - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check info buffer */ - info = (void*)&msg[1]; - - /* Copy info buffer */ - if (buf) - { - if (ret < (int)len) - len = ret; - memcpy(buf, info, len); - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - -int -dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) -{ - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; - int ret = 0; - uint32 flags, id; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len)); - - memset(msg, 0, sizeof(cdc_ioctl_t)); - - msg->cmd = htol32(cmd); - msg->len = htol32(len); - msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET; - CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); - - if (buf) - memcpy(prot->buf, buf, len); - - if ((ret = dhdcdc_msg(dhd)) < 0) - goto done; - - if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) - goto done; - - flags = ltoh32(msg->flags); - id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; - - if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid)); - ret = -EINVAL; - goto done; - } - - /* Check the ERROR flag */ - if (flags & CDCF_IOC_ERROR) - { - ret = ltoh32(msg->status); - /* Cache error from dongle */ - dhd->dongle_error = ret; - } - -done: - return ret; -} - -extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void* arg2); -int -dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len) -{ - dhd_prot_t *prot = dhd->prot; - int ret = -1; - - if (dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return ret; - } - dhd_os_proto_block(dhd); - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(len <= WLC_IOCTL_MAXLEN); - - if (len > WLC_IOCTL_MAXLEN) - goto done; - - if (prot->pending == TRUE) { - DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", - ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, - (unsigned long)prot->lastcmd)); - if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) { - DHD_TRACE(("iovar cmd=%s\n", (char*)buf)); - } - goto done; - } - - prot->pending = TRUE; - prot->lastcmd = ioc->cmd; - if (ioc->set) - ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len); - else { - ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len); - if (ret > 0) - ioc->used = ret - sizeof(cdc_ioctl_t); - } - - /* Too many programs assume ioctl() returns 0 on success */ - if (ret >= 0) - ret = 0; - else { - cdc_ioctl_t *msg = &prot->msg; - ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */ - } - - /* Intercept the wme_dp ioctl here */ - if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) { - int slen, val = 0; - - slen = strlen("wme_dp") + 1; - if (len >= (int)(slen + sizeof(int))) - bcopy(((char *)buf + slen), &val, sizeof(int)); - dhd->wme_dp = (uint8) ltoh32(val); - } - - prot->pending = FALSE; - -done: - dhd_os_proto_unblock(dhd); - - return ret; -} - -int -dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - return BCME_UNSUPPORTED; -} - -void -dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -} - - -void -dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif /* BDC */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Push BDC header used to convey priority for buses that don't */ - - - PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN); - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(pktbuf)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - - h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->rssi = 0; -#endif /* BDC */ - BDC_SET_IF_IDX(h, ifidx); -} - - -bool -dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, uint8 *fcbits) -{ -#ifdef BDC - struct bdc_header *h; - - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", - __FUNCTION__, PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - *fcbits = h->priority >> BDC_PRIORITY_FC_SHIFT; - if ((h->flags2 & BDC_FLAG2_FC_FLAG) == BDC_FLAG2_FC_FLAG) - return TRUE; -#endif - return FALSE; -} - - -int -dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef BDC - /* Pop BDC header used to convey priority for buses that don't */ - - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); - - if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { - DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", - __FUNCTION__, *ifidx)); - return BCME_ERROR; - } - - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - return BCME_ERROR; - } - - if (h->flags & BDC_FLAG_SUM_GOOD) { - DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - PKTSETSUMGOOD(pktbuf, TRUE); - } - - PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); - - PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -#endif /* BDC */ - - return 0; -} - -int -dhd_prot_attach(dhd_pub_t *dhd) -{ - dhd_prot_t *cdc; - -#ifndef DHD_USE_STATIC_BUF - if (!(cdc = (dhd_prot_t *)MALLOC(dhd->osh, sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } -#else - if (!(cdc = (dhd_prot_t *)dhd_os_prealloc(DHD_PREALLOC_PROT, sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } -#endif /* DHD_USE_STATIC_BUF */ - memset(cdc, 0, sizeof(dhd_prot_t)); - - /* ensure that the msg buf directly follows the cdc msg struct */ - if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { - DHD_ERROR(("dhd_prot_t is not correctly defined\n")); - goto fail; - } - - dhd->prot = cdc; -#ifdef BDC - dhd->hdrlen += BDC_HEADER_LEN; -#endif - dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; - return 0; - -fail: -#ifndef DHD_USE_STATIC_BUF - if (cdc != NULL) - MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); -#endif - return BCME_NOMEM; -} - -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void -dhd_prot_detach(dhd_pub_t *dhd) -{ -#ifndef DHD_USE_STATIC_BUF - MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); -#endif - dhd->prot = NULL; -} - -void -dhd_prot_dstats(dhd_pub_t *dhd) -{ - /* No stats from dongle added yet, copy bus stats */ - dhd->dstats.tx_packets = dhd->tx_packets; - dhd->dstats.tx_errors = dhd->tx_errors; - dhd->dstats.rx_packets = dhd->rx_packets; - dhd->dstats.rx_errors = dhd->rx_errors; - dhd->dstats.rx_dropped = dhd->rx_dropped; - dhd->dstats.multicast = dhd->rx_multicast; - return; -} - -int -dhd_prot_init(dhd_pub_t *dhd) -{ - int ret = 0; - char buf[128]; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_proto_block(dhd); - - /* Get the device MAC address */ - strcpy(buf, "cur_etheraddr"); - ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); - if (ret < 0) { - dhd_os_proto_unblock(dhd); - return ret; - } - memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); - - dhd_os_proto_unblock(dhd); - -#ifdef EMBEDDED_PLATFORM - ret = dhd_preinit_ioctls(dhd); -#endif /* EMBEDDED_PLATFORM */ - - /* Always assumes wl for now */ - dhd->iswl = TRUE; - - return ret; -} - -void -dhd_prot_stop(dhd_pub_t *dhd) -{ - /* Nothing to do for CDC */ -} diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c deleted file mode 100644 index e50da1414c9e..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_common.c +++ /dev/null @@ -1,2426 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), common DHD core. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.25 2011-02-11 21:16:02 Exp $ - */ -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef SET_RANDOM_MAC_SOFTAP -#include -#include -#endif - -#ifdef GET_CUSTOM_MAC_ENABLE -int wifi_get_mac_addr(unsigned char *buf); -#endif /* GET_CUSTOM_MAC_ENABLE */ - -int dhd_msg_level; - -#include - -char fw_path[MOD_PARAM_PATHLEN]; -char nv_path[MOD_PARAM_PATHLEN]; - -/* Last connection success/failure status */ -uint32 dhd_conn_event; -uint32 dhd_conn_status; -uint32 dhd_conn_reason; - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i - -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); -extern void dhd_ind_scan_confirm(void *h, bool status); -extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen); -void dhd_iscan_lock(void); -void dhd_iscan_unlock(void); - -#if defined(SOFTAP) -extern bool ap_fw_loaded; -#endif -#if defined(KEEP_ALIVE) -int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on); -#endif /* KEEP_ALIVE */ - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#ifdef DHD_DEBUG -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " - __DATE__ " at " __TIME__; -#else -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR; -#endif - -void dhd_set_timer(void *bus, uint wdtick); - -/* IOVar table */ -enum { - IOV_VERSION = 1, - IOV_MSGLEVEL, - IOV_BCMERRORSTR, - IOV_BCMERROR, - IOV_WDTICK, - IOV_DUMP, -#ifdef DHD_DEBUG - IOV_CONS, - IOV_DCONSOLE_POLL, -#endif - IOV_CLEARCOUNTS, - IOV_LOGDUMP, - IOV_LOGCAL, - IOV_LOGSTAMP, - IOV_GPIOOB, - IOV_IOCTLTIMEOUT, - IOV_LAST -}; - -const bcm_iovar_t dhd_iovars[] = { - {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) }, -#ifdef DHD_DEBUG - {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, -#endif /* DHD_DEBUG */ - {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN }, - {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 }, - {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 }, - {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, -#ifdef DHD_DEBUG - {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 }, - {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 }, -#endif - {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, - {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, - {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, - {NULL, 0, 0, 0, 0 } -}; - -void -dhd_common_init(void) -{ - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behaviour since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - dhd_msg_level = DHD_ERROR_VAL; -#ifdef CONFIG_BCM4329_FW_PATH - strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN-1); -#else - fw_path[0] = '\0'; -#endif -#ifdef CONFIG_BCM4329_NVRAM_PATH - strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN-1); -#else - nv_path[0] = '\0'; -#endif -} - -static int -dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) -{ - char eabuf[ETHER_ADDR_STR_LEN]; - - struct bcmstrbuf b; - struct bcmstrbuf *strbuf = &b; - - bcm_binit(strbuf, buf, buflen); - - /* Base DHD info */ - bcm_bprintf(strbuf, "%s\n", dhd_version); - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", - dhdp->up, dhdp->txoff, dhdp->busstate); - bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", - dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); - bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n", - dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf)); - bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt); - - bcm_bprintf(strbuf, "dongle stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", - dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, - dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); - bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", - dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, - dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); - bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); - - bcm_bprintf(strbuf, "bus stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", - dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); - bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", - dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); - bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n", - dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); - bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n", - dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped, dhdp->rx_flushed); - bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n", - dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets); - bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched); - bcm_bprintf(strbuf, "\n"); - - /* Add any prot info */ - dhd_prot_dump(dhdp, strbuf); - bcm_bprintf(strbuf, "\n"); - - /* Add any bus info */ - dhd_bus_dump(dhdp, strbuf); - - return (!strbuf->size ? BCME_BUFTOOSHORT : 0); -} - -static int -dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - switch (actionid) { - case IOV_GVAL(IOV_VERSION): - /* Need to have checked buffer length */ - strncpy((char*)arg, dhd_version, len); - break; - - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (int32)dhd_msg_level; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - dhd_msg_level = int_val; - break; - - case IOV_GVAL(IOV_BCMERRORSTR): - strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); - ((char *)arg)[BCME_STRLEN - 1] = 0x00; - break; - - case IOV_GVAL(IOV_BCMERROR): - int_val = (int32)dhd_pub->bcmerror; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_WDTICK): - int_val = (int32)dhd_watchdog_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_WDTICK): - if (!dhd_pub->up) { - bcmerror = BCME_NOTUP; - break; - } - dhd_os_wd_timer(dhd_pub, (uint)int_val); - break; - - case IOV_GVAL(IOV_DUMP): - bcmerror = dhd_dump(dhd_pub, arg, len); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_DCONSOLE_POLL): - int_val = (int32)dhd_console_ms; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_DCONSOLE_POLL): - dhd_console_ms = (uint)int_val; - break; - - case IOV_SVAL(IOV_CONS): - if (len > 0) - bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1); - break; -#endif - - case IOV_SVAL(IOV_CLEARCOUNTS): - dhd_pub->tx_packets = dhd_pub->rx_packets = 0; - dhd_pub->tx_errors = dhd_pub->rx_errors = 0; - dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0; - dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0; - dhd_pub->rx_dropped = 0; - dhd_pub->rx_readahead_cnt = 0; - dhd_pub->tx_realloc = 0; - dhd_pub->wd_dpc_sched = 0; - memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats)); - dhd_bus_clearcounts(dhd_pub); - break; - - - case IOV_GVAL(IOV_IOCTLTIMEOUT): { - int_val = (int32)dhd_os_get_ioctl_resp_timeout(); - bcopy(&int_val, arg, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_IOCTLTIMEOUT): { - if (int_val <= 0) - bcmerror = BCME_BADARG; - else - dhd_os_set_ioctl_resp_timeout((unsigned int)int_val); - break; - } - - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - return bcmerror; -} - -/* Store the status of a connection attempt for later retrieval by an iovar */ -void -dhd_store_conn_status(uint32 event, uint32 status, uint32 reason) -{ - /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID - * because an encryption/rsn mismatch results in both events, and - * the important information is in the WLC_E_PRUNE. - */ - if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL && - dhd_conn_event == WLC_E_PRUNE)) { - dhd_conn_event = event; - dhd_conn_status = status; - dhd_conn_reason = reason; - } -} - -bool -dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) -{ - void *p; - int eprec = -1; /* precedence to evict from */ - bool discard_oldest; - - /* Fast case, precedence queue is not full and we are also not - * exceeding total queue length - */ - if (!pktq_pfull(q, prec) && !pktq_full(q)) { - pktq_penq(q, prec, pkt); - return TRUE; - } - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p); - if (eprec > prec) - return FALSE; - } - - /* Evict if needed */ - if (eprec >= 0) { - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); - if (eprec == prec && !discard_oldest) - return FALSE; /* refuse newer (incoming) packet */ - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec); - if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed, oldest %d.", - __FUNCTION__, discard_oldest)); - ASSERT(p); - } - - PKTFREE(dhdp->osh, p, TRUE); - } - - /* Enqueue */ - p = pktq_penq(q, prec, pkt); - if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed.", __FUNCTION__)); - ASSERT(p); - } - - return TRUE; -} - -static int -dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - int bcmerror = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) { - bcmerror = BCME_UNSUPPORTED; - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -int -dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) -{ - int bcmerror = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!buf) return BCME_BADARG; - - switch (ioc->cmd) { - case DHD_GET_MAGIC: - if (buflen < sizeof(int)) - bcmerror = BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_MAGIC; - break; - - case DHD_GET_VERSION: - if (buflen < sizeof(int)) - bcmerror = -BCME_BUFTOOSHORT; - else - *(int*)buf = DHD_IOCTL_VERSION; - break; - - case DHD_GET_VAR: - case DHD_SET_VAR: { - char *arg; - uint arglen; - - /* scan past the name to any arguments */ - for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--); - - if (*arg) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* account for the NUL terminator */ - arg++, arglen--; - - /* call with the appropriate arguments */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen, - buf, buflen, IOV_GET); - else - bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* not in generic table, try protocol module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg, - arglen, buf, buflen, IOV_GET); - else - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) - break; - - /* if still not found, try bus module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - arg, arglen, buf, buflen, IOV_GET); - else - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - NULL, 0, arg, arglen, IOV_SET); - - break; - } - - default: - bcmerror = BCME_UNSUPPORTED; - } - - return bcmerror; -} - - -#ifdef SHOW_EVENTS -static void -wl_show_host_event(wl_event_msg_t *event, void *event_data) -{ - uint i, status, reason; - bool group = FALSE, flush_txq = FALSE, link = FALSE; - char *auth_str, *event_name; - uchar *buf; - char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; - static struct {uint event; char *event_name;} event_names[] = { - {WLC_E_SET_SSID, "SET_SSID"}, - {WLC_E_JOIN, "JOIN"}, - {WLC_E_START, "START"}, - {WLC_E_AUTH, "AUTH"}, - {WLC_E_AUTH_IND, "AUTH_IND"}, - {WLC_E_DEAUTH, "DEAUTH"}, - {WLC_E_DEAUTH_IND, "DEAUTH_IND"}, - {WLC_E_ASSOC, "ASSOC"}, - {WLC_E_ASSOC_IND, "ASSOC_IND"}, - {WLC_E_REASSOC, "REASSOC"}, - {WLC_E_REASSOC_IND, "REASSOC_IND"}, - {WLC_E_DISASSOC, "DISASSOC"}, - {WLC_E_DISASSOC_IND, "DISASSOC_IND"}, - {WLC_E_QUIET_START, "START_QUIET"}, - {WLC_E_QUIET_END, "END_QUIET"}, - {WLC_E_BEACON_RX, "BEACON_RX"}, - {WLC_E_LINK, "LINK"}, - {WLC_E_MIC_ERROR, "MIC_ERROR"}, - {WLC_E_NDIS_LINK, "NDIS_LINK"}, - {WLC_E_ROAM, "ROAM"}, - {WLC_E_TXFAIL, "TXFAIL"}, - {WLC_E_PMKID_CACHE, "PMKID_CACHE"}, - {WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, - {WLC_E_PRUNE, "PRUNE"}, - {WLC_E_AUTOAUTH, "AUTOAUTH"}, - {WLC_E_EAPOL_MSG, "EAPOL_MSG"}, - {WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, - {WLC_E_ADDTS_IND, "ADDTS_IND"}, - {WLC_E_DELTS_IND, "DELTS_IND"}, - {WLC_E_BCNSENT_IND, "BCNSENT_IND"}, - {WLC_E_BCNRX_MSG, "BCNRX_MSG"}, - {WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, - {WLC_E_ROAM_PREP, "ROAM_PREP"}, - {WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, - {WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, - {WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, - {WLC_E_JOIN_START, "JOIN_START"}, - {WLC_E_ROAM_START, "ROAM_START"}, - {WLC_E_ASSOC_START, "ASSOC_START"}, - {WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, - {WLC_E_RADIO, "RADIO"}, - {WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, - {WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, - {WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, - {WLC_E_PSK_SUP, "PSK_SUP"}, - {WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, - {WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, - {WLC_E_ICV_ERROR, "ICV_ERROR"}, - {WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, - {WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, - {WLC_E_TRACE, "TRACE"}, - {WLC_E_ACTION_FRAME, "ACTION FRAME"}, - {WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, - {WLC_E_IF, "IF"}, - {WLC_E_RSSI, "RSSI"}, - {WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} - }; - uint event_type, flags, auth_type, datalen; - event_type = ntoh32(event->event_type); - flags = ntoh16(event->flags); - status = ntoh32(event->status); - reason = ntoh32(event->reason); - auth_type = ntoh32(event->auth_type); - datalen = ntoh32(event->datalen); - /* debug dump of event messages */ - sprintf(eabuf, "%02x:%02x:%02x:%02x:%02x:%02x", - (uchar)event->addr.octet[0]&0xff, - (uchar)event->addr.octet[1]&0xff, - (uchar)event->addr.octet[2]&0xff, - (uchar)event->addr.octet[3]&0xff, - (uchar)event->addr.octet[4]&0xff, - (uchar)event->addr.octet[5]&0xff); - - event_name = "UNKNOWN"; - for (i = 0; i < ARRAYSIZE(event_names); i++) { - if (event_names[i].event == event_type) - event_name = event_names[i].event_name; - } - - DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); - - if (flags & WLC_EVENT_MSG_LINK) - link = TRUE; - if (flags & WLC_EVENT_MSG_GROUP) - group = TRUE; - if (flags & WLC_EVENT_MSG_FLUSHTXQ) - flush_txq = TRUE; - - switch (event_type) { - case WLC_E_START: - case WLC_E_DEAUTH: - case WLC_E_DISASSOC: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - break; - - case WLC_E_ASSOC: - case WLC_E_REASSOC: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", - event_name, eabuf, (int)reason)); - } else { - DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status %d\n", - event_name, eabuf, (int)status)); - } - break; - - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason)); - break; - - case WLC_E_AUTH: - case WLC_E_AUTH_IND: - if (auth_type == DOT11_OPEN_SYSTEM) - auth_str = "Open System"; - else if (auth_type == DOT11_SHARED_KEY) - auth_str = "Shared Key"; - else { - sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); - auth_str = err_msg; - } - if (event_type == WLC_E_AUTH_IND) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", - event_name, eabuf, auth_str, (int)reason)); - } - - break; - - case WLC_E_JOIN: - case WLC_E_ROAM: - case WLC_E_SET_SSID: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, failed\n", event_name)); - } else if (status == WLC_E_STATUS_NO_NETWORKS) { - DHD_EVENT(("MACEVENT: %s, no networks found\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, unexpected status %d\n", - event_name, (int)status)); - } - break; - - case WLC_E_BEACON_RX: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name)); - } else { - DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, status)); - } - break; - - case WLC_E_LINK: - DHD_EVENT(("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN")); - break; - - case WLC_E_MIC_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", - event_name, eabuf, group, flush_txq)); - break; - - case WLC_E_ICV_ERROR: - case WLC_E_UNICAST_DECODE_ERROR: - case WLC_E_MULTICAST_DECODE_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", - event_name, eabuf)); - break; - - case WLC_E_TXFAIL: - DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); - break; - - case WLC_E_SCAN_COMPLETE: - case WLC_E_PMKID_CACHE: - DHD_EVENT(("MACEVENT: %s\n", event_name)); - break; - - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - case WLC_E_PFN_SCAN_COMPLETE: - DHD_EVENT(("PNOEVENT: %s\n", event_name)); - break; - - case WLC_E_PSK_SUP: - case WLC_E_PRUNE: - DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n", - event_name, (int)status, (int)reason)); - break; - - case WLC_E_TRACE: - { - static uint32 seqnum_prev = 0; - msgtrace_hdr_t hdr; - uint32 nblost; - char *s, *p; - - buf = (uchar *) event_data; - memcpy(&hdr, buf, MSGTRACE_HDRLEN); - - if (hdr.version != MSGTRACE_VERSION) { - printf("\nMACEVENT: %s [unsupported version --> " - "dhd version:%d dongle version:%d]\n", - event_name, MSGTRACE_VERSION, hdr.version); - /* Reset datalen to avoid display below */ - datalen = 0; - break; - } - - /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; - - if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { - printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" - "discarded_bytes %d discarded_printf %d]\n", - ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); - } - - nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; - if (nblost > 0) { - printf("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); - } - seqnum_prev = ntoh32(hdr.seqnum); - - /* Display the trace buffer. Advance from \n to \n to avoid display big - * printf (issue with Linux printk ) - */ - p = (char *)&buf[MSGTRACE_HDRLEN]; - while ((s = strstr(p, "\n")) != NULL) { - *s = '\0'; - printf("%s\n", p); - p = s + 1; - } - printf("%s\n", p); - - /* Reset datalen to avoid display below */ - datalen = 0; - } - break; - - - case WLC_E_RSSI: - DHD_EVENT(("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data)))); - break; - - default: - DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", - event_name, event_type, eabuf, (int)status, (int)reason, - (int)auth_type)); - break; - } - - /* show any appended data */ - if (datalen) { - buf = (uchar *) event_data; - DHD_EVENT((" data (%d) : ", datalen)); - for (i = 0; i < datalen; i++) - DHD_EVENT((" 0x%02x ", *buf++)); - DHD_EVENT(("\n")); - } -} -#endif /* SHOW_EVENTS */ - -int -wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data_ptr) -{ - /* check whether packet is a BRCM event pkt */ - bcm_event_t *pvt_data = (bcm_event_t *)pktdata; - char *event_data; - uint32 type, status; - uint16 flags; - int evlen; - - if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { - DHD_ERROR(("%s: mismatched OUI, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ - if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { - DHD_ERROR(("%s: mismatched subtype, bailing\n", __FUNCTION__)); - return (BCME_ERROR); - } - - *data_ptr = &pvt_data[1]; - event_data = *data_ptr; - - /* memcpy since BRCM event pkt may be unaligned. */ - memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); - - type = ntoh32_ua((void *)&event->event_type); - flags = ntoh16_ua((void *)&event->flags); - status = ntoh32_ua((void *)&event->status); - evlen = ntoh32_ua((void *)&event->datalen) + sizeof(bcm_event_t); - - switch (type) { - case WLC_E_IF: - { - dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; - DHD_TRACE(("%s: if event\n", __FUNCTION__)); - - if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) - { - if (ifevent->action == WLC_E_IF_ADD) - dhd_add_if(dhd, ifevent->ifidx, - NULL, event->ifname, - pvt_data->eth.ether_dhost, - ifevent->flags, ifevent->bssidx); - else - dhd_del_if(dhd, ifevent->ifidx); - } else { - DHD_ERROR(("%s: Invalid ifidx %d for %s\n", - __FUNCTION__, ifevent->ifidx, event->ifname)); - } - } - /* send up the if event: btamp user needs it */ - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); - break; - - -#ifdef P2P - case WLC_E_NDIS_LINK: - break; -#endif - /* fall through */ - /* These are what external supplicant/authenticator wants */ - case WLC_E_LINK: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - case WLC_E_DISASSOC_IND: - case WLC_E_MIC_ERROR: - default: - /* Fall through: this should get _everything_ */ - - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); - DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", - __FUNCTION__, type, flags, status)); - - /* put it back to WLC_E_NDIS_LINK */ - if (type == WLC_E_NDIS_LINK) { - uint32 temp; - - temp = ntoh32_ua((void *)&event->event_type); - DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); - - temp = ntoh32(WLC_E_NDIS_LINK); - memcpy((void *)(&pvt_data->event.event_type), &temp, - sizeof(pvt_data->event.event_type)); - } - break; - } - -#ifdef SHOW_EVENTS - wl_show_host_event(event, event_data); -#endif /* SHOW_EVENTS */ - - return (BCME_OK); -} - - -void -wl_event_to_host_order(wl_event_msg_t *evt) -{ - /* Event struct members passed from dongle to host are stored in network - * byte order. Convert all members to host-order. - */ - evt->event_type = ntoh32(evt->event_type); - evt->flags = ntoh16(evt->flags); - evt->status = ntoh32(evt->status); - evt->reason = ntoh32(evt->reason); - evt->auth_type = ntoh32(evt->auth_type); - evt->datalen = ntoh32(evt->datalen); - evt->version = ntoh16(evt->version); -} - -void print_buf(void *pbuf, int len, int bytes_per_line) -{ - int i, j = 0; - unsigned char *buf = pbuf; - - if (bytes_per_line == 0) { - bytes_per_line = len; - } - - for (i = 0; i < len; i++) { - printf("%2.2x", *buf++); - j++; - if (j == bytes_per_line) { - printf("\n"); - j = 0; - } else { - printf(":"); - } - } - printf("\n"); -} - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -#ifdef PKT_FILTER_SUPPORT -/* Convert user's input in hex pattern to byte-size mask */ -static int -wl_pattern_atoh(char *src, char *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && - strncmp(src, "0X", 2) != 0) { - DHD_ERROR(("Mask invalid format. Needs to start with 0x\n")); - return -1; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - DHD_ERROR(("Mask invalid format. Needs to be of even length\n")); - return -1; - } - for (i = 0; *src != '\0'; i++) { - char num[3]; - strncpy(num, src, 2); - num[2] = '\0'; - dst[i] = (uint8)strtoul(num, NULL, 16); - src += 2; - } - return i; -} - -void -dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode) -{ - char *argv[8]; - int i = 0; - const char *str; - int buf_len; - int str_len; - char *arg_save = 0, *arg_org = 0; - int rc; - char buf[128]; - wl_pkt_filter_enable_t enable_parm; - wl_pkt_filter_enable_t * pkt_filterp; - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - arg_org = arg_save; - memcpy(arg_save, arg, strlen(arg) + 1); - - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_enable"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1); - - /* Parse packet filter id. */ - enable_parm.id = htod32(strtoul(argv[i], NULL, 0)); - - /* Parse enable/disable value. */ - enable_parm.enable = htod32(enable); - - buf_len += sizeof(enable_parm); - memcpy((char *)pkt_filterp, - &enable_parm, - sizeof(enable_parm)); - - /* Enable/disable the specified filter. */ - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - - /* Contorl the master mode */ - bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf)); - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - rc = rc >= 0 ? 0 : rc; - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); -} - -void -dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg) -{ - const char *str; - wl_pkt_filter_t pkt_filter; - wl_pkt_filter_t *pkt_filterp; - int buf_len; - int str_len; - int rc; - uint32 mask_size; - uint32 pattern_size; - char *argv[8], * buf = 0; - int i = 0; - char *arg_save = 0, *arg_org = 0; -#define BUF_SIZE 2048 - - if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - arg_org = arg_save; - - if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } - - memcpy(arg_save, arg, strlen(arg) + 1); - - if (strlen(arg) > BUF_SIZE) { - DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf))); - goto fail; - } - - argv[i] = bcmstrtok(&arg_save, " ", 0); - while (argv[i++]) - argv[i] = bcmstrtok(&arg_save, " ", 0); - - i = 0; - if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); - goto fail; - } - - str = "pkt_filter_add"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[ str_len ] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); - - /* Parse packet filter id. */ - pkt_filter.id = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Polarity not provided\n")); - goto fail; - } - - /* Parse filter polarity. */ - pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Filter type not provided\n")); - goto fail; - } - - /* Parse filter type. */ - pkt_filter.type = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Offset not provided\n")); - goto fail; - } - - /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Bitmask not provided\n")); - goto fail; - } - - /* Parse pattern filter mask. */ - mask_size = - htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern)); - - if (NULL == argv[++i]) { - DHD_ERROR(("Pattern not provided\n")); - goto fail; - } - - /* Parse pattern filter pattern. */ - pattern_size = - htod32(wl_pattern_atoh(argv[i], - (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size])); - - if (mask_size != pattern_size) { - DHD_ERROR(("Mask and pattern not the same size\n")); - goto fail; - } - - pkt_filter.u.pattern.size_bytes = mask_size; - buf_len += WL_PKT_FILTER_FIXED_LEN; - buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); - - /* Keep-alive attributes are set in local variable (keep_alive_pkt), and - ** then memcpy'ed into buffer (keep_alive_pktp) since there is no - ** guarantee that the buffer is properly aligned. - */ - memcpy((char *)pkt_filterp, - &pkt_filter, - WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); - - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - rc = rc >= 0 ? 0 : rc; - - if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __FUNCTION__, arg, rc)); - else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __FUNCTION__, arg)); - -fail: - if (arg_org) - MFREE(dhd->osh, arg_org, strlen(arg) + 1); - - if (buf) - MFREE(dhd->osh, buf, BUF_SIZE); -} -#endif - -#ifdef ARP_OFFLOAD_SUPPORT -void -dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n", - __FUNCTION__, arp_mode, retcode)); - else - DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", - __FUNCTION__, arp_mode)); -} - -void -dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable) -{ - char iovbuf[32]; - int retcode; - - bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - retcode = retcode >= 0 ? 0 : retcode; - if (retcode) - DHD_TRACE(("%s: failed to enabe ARP offload to %d, retcode = %d\n", - __FUNCTION__, arp_enable, retcode)); - else - DHD_TRACE(("%s: successfully enabed ARP offload to %d\n", - __FUNCTION__, arp_enable)); -} -#endif - - -void dhd_arp_cleanup(dhd_pub_t *dhd) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int ret = 0; - int iov_len = 0; - char iovbuf[128]; - - if (dhd == NULL) return; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - dhd_os_proto_unblock(dhd); - -#endif /* ARP_OFFLOAD_SUPPORT */ -} - -void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int iov_len = 0; - char iovbuf[32]; - int retcode; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len); - - dhd_os_proto_unblock(dhd); - - if (retcode) - DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n", - __FUNCTION__, retcode)); - else - DHD_TRACE(("%s: ARP ipaddr entry added\n", - __FUNCTION__)); -#endif /* ARP_OFFLOAD_SUPPORT */ -} - - -int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) -{ -#ifdef ARP_OFFLOAD_SUPPORT - int retcode; - int iov_len = 0; - - if (!buf) - return -1; - - dhd_os_proto_block(dhd); - - iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); - retcode = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, buflen); - - dhd_os_proto_unblock(dhd); - - if (retcode) { - DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", - __FUNCTION__, retcode)); - - return -1; - } -#endif /* ARP_OFFLOAD_SUPPORT */ - return 0; -} - - -int -dhd_preinit_ioctls(dhd_pub_t *dhd) -{ - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ - uint up = 0; - char buf[128], *ptr; - uint power_mode = PM_FAST; - uint32 dongle_align = DHD_SDALIGN; - uint32 glom = 0; - uint bcn_timeout = 4; - int scan_assoc_time = 40; - int scan_unassoc_time = 40; - uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ -#if defined(SOFTAP) - uint dtim = 1; -#endif - int ret = 0; -#ifdef GET_CUSTOM_MAC_ENABLE - struct ether_addr ea_addr; -#endif /* GET_CUSTOM_MAC_ENABLE */ - - dhd_os_proto_block(dhd); - -#ifdef GET_CUSTOM_MAC_ENABLE - /* - ** Read MAC address from external customer place - ** NOTE that default mac address has to be present in otp or nvram file - ** to bring up firmware but unique per board mac address maybe provided - ** by customer code - */ - ret = dhd_custom_get_mac_address(ea_addr.octet); - if (!ret) { - bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - } else - memcpy(dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN); - } -#endif /* GET_CUSTOM_MAC_ENABLE */ - -#ifdef SET_RANDOM_MAC_SOFTAP - if (strstr(fw_path, "apsta") != NULL) { - uint rand_mac; - - srandom32((uint)jiffies); - rand_mac = random32(); - iovbuf[0] = 0x02; /* locally administered bit */ - iovbuf[1] = 0x1A; - iovbuf[2] = 0x11; - iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0; - iovbuf[4] = (unsigned char)(rand_mac >> 8); - iovbuf[5] = (unsigned char)(rand_mac >> 16); - - printk("Broadcom Dongle Host Driver mac=%02x:%02x:%02x:%02x:%02x:%02x\n", - iovbuf[0], iovbuf[1], iovbuf[2], iovbuf[3], iovbuf[4], iovbuf[5]); - - bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - } else - memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN); - } -#endif /* SET_RANDOM_MAC_SOFTAP */ - - /* Set Country code */ - if (dhd->dhd_cspec.ccode[0] != 0) { - bcm_mkiovar("country", (char *)&dhd->dhd_cspec, \ - sizeof(wl_country_t), iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); - } - } - - /* Set Listen Interval */ - bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) - DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret)); - - /* query for 'ver' to get version info from firmware */ - memset(buf, 0, sizeof(buf)); - ptr = buf; - bcm_mkiovar("ver", 0, 0, buf, sizeof(buf)); - dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); - bcmstrtok(&ptr, "\n", 0); - /* Print fw version info */ - DHD_ERROR(("Firmware version = %s\n", buf)); - - /* Set PowerSave mode */ - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode)); - - /* Match Host and Dongle rx alignment */ - bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* disable glom option per default */ - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */ - bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - -#if defined(SOFTAP) - if (ap_fw_loaded == TRUE) { - dhdcdc_set_ioctl(dhd, 0, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim)); - } -#endif - - if (dhd_roam == 0) - { - /* set internal roaming roaming parameters */ - int roam_scan_period = 30; /* in sec */ - int roam_fullscan_period = 120; /* in sec */ - int roam_trigger = -85; - int roam_delta = 15; - int band; - int band_temp_set = WLC_BAND_2G; - - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_SCAN_PERIOD, \ - (char *)&roam_scan_period, sizeof(roam_scan_period)) < 0) - DHD_ERROR(("%s: roam scan setup failed\n", __FUNCTION__)); - - bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, \ - 4, iovbuf, sizeof(iovbuf)); - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, \ - iovbuf, sizeof(iovbuf)) < 0) - DHD_ERROR(("%s: roam fullscan setup failed\n", __FUNCTION__)); - - if (dhdcdc_query_ioctl(dhd, 0, WLC_GET_BAND, \ - (char *)&band, sizeof(band)) < 0) - DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__)); - else { - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_ALL)) - { - /* temp set band to insert new roams values */ - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \ - (char *)&band_temp_set, sizeof(band_temp_set)) < 0) - DHD_ERROR(("%s: local band seting failed\n", __FUNCTION__)); - } - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_DELTA, \ - (char *)&roam_delta, sizeof(roam_delta)) < 0) - DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__)); - - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_TRIGGER, \ - (char *)&roam_trigger, sizeof(roam_trigger)) < 0) - DHD_ERROR(("%s: roam trigger setting failed\n", __FUNCTION__)); - - /* Restore original band settinngs */ - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \ - (char *)&band, sizeof(band)) < 0) - DHD_ERROR(("%s: Original band restore failed\n", __FUNCTION__)); - } - } - - /* Force STA UP */ - if (dhd_radio_up) - dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up)); - - /* Setup event_msgs */ - bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, - sizeof(scan_assoc_time)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, - sizeof(scan_unassoc_time)); - -#ifdef ARP_OFFLOAD_SUPPORT - /* Set and enable ARP offload feature */ - if (dhd_arp_enable) - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, dhd_arp_enable); -#endif /* ARP_OFFLOAD_SUPPORT */ - -#ifdef PKT_FILTER_SUPPORT - { - int i; - /* Set up pkt filter */ - if (dhd_pkt_filter_enable) { - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - dhd_pkt_filter_init, dhd_master_mode); - } - } - } -#endif /* PKT_FILTER_SUPPORT */ - -#if defined(KEEP_ALIVE) - { - /* Set Keep Alive : be sure to use FW with -keepalive */ - int res; - - if (ap_fw_loaded == FALSE) { - if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0) - DHD_ERROR(("%s set keeplive failed %d\n", \ - __FUNCTION__, res)); - } - } -#endif - - dhd_os_proto_unblock(dhd); - - return 0; -} - -#ifdef SIMPLE_ISCAN - -uint iscan_thread_id; -iscan_buf_t * iscan_chain = 0; - -iscan_buf_t * -dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf) -{ - iscan_buf_t *iscanbuf_alloc = 0; - iscan_buf_t *iscanbuf_head; - - dhd_iscan_lock(); - - iscanbuf_alloc = (iscan_buf_t*)MALLOC(dhd->osh, sizeof(iscan_buf_t)); - if (iscanbuf_alloc == NULL) - goto fail; - - iscanbuf_alloc->next = NULL; - iscanbuf_head = *iscanbuf; - - DHD_ISCAN(("%s: addr of allocated node = 0x%X" - "addr of iscanbuf_head = 0x%X dhd = 0x%X\n", - __FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd)); - - if (iscanbuf_head == NULL) { - *iscanbuf = iscanbuf_alloc; - DHD_ISCAN(("%s: Head is allocated\n", __FUNCTION__)); - goto fail; - } - - while (iscanbuf_head->next) - iscanbuf_head = iscanbuf_head->next; - - iscanbuf_head->next = iscanbuf_alloc; - -fail: - dhd_iscan_unlock(); - return iscanbuf_alloc; -} - -void -dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete) -{ - iscan_buf_t *iscanbuf_free = 0; - iscan_buf_t *iscanbuf_prv = 0; - iscan_buf_t *iscanbuf_cur = iscan_chain; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - - dhd_iscan_lock(); - /* If iscan_delete is null then delete the entire - * chain or else delete specific one provided - */ - if (!iscan_delete) { - while (iscanbuf_cur) { - iscanbuf_free = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - iscanbuf_free->next = 0; - MFREE(dhd->osh, iscanbuf_free, sizeof(iscan_buf_t)); - } - iscan_chain = 0; - } else { - while (iscanbuf_cur) { - if (iscanbuf_cur == iscan_delete) - break; - iscanbuf_prv = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - } - if (iscanbuf_prv) - iscanbuf_prv->next = iscan_delete->next; - - iscan_delete->next = 0; - MFREE(dhd->osh, iscan_delete, sizeof(iscan_buf_t)); - - if (!iscanbuf_prv) - iscan_chain = 0; - } - dhd_iscan_unlock(); -} - -iscan_buf_t * -dhd_iscan_result_buf(void) -{ - return iscan_chain; -} - - - -/* -* print scan cache -* print partial iscan_skip list differently -*/ -int -dhd_iscan_print_cache(iscan_buf_t *iscan_skip) -{ - int i = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi; - - dhd_iscan_lock(); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ISCAN(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", - iscan_cur != iscan_skip?"BSS":"bss", l, i, - bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], bi->BSSID.octet[5])); - - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -/* -* delete disappeared AP from specific scan cache but skip partial list in iscan_skip -*/ -int -dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) -{ - int i = 0, j = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - uchar *s_addr = addr; - - dhd_iscan_lock(); - DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, s_addr[0], s_addr[1], s_addr[2], - s_addr[3], s_addr[4], s_addr[5])); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - if (iscan_cur != iscan_skip) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - if (!memcmp(bi->BSSID.octet, addr, ETHER_ADDR_LEN)) { - DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, l, i, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_new = bi; - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); -/* - if(bi && bi_new) { - bcopy(bi, bi_new, results->buflen - - dtoh32(bi_new->length)); - results->buflen -= dtoh32(bi_new->length); - } -*/ - results->buflen -= dtoh32(bi_new->length); - results->count--; - - for (j = i; j < results->count; j++) { - if (bi && bi_new) { - DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" - "%X:%X:%X:%X:%X:%X\n", - __FUNCTION__, l, j, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_next = (wl_bss_info_t *)((uintptr)bi + - dtoh32(bi->length)); - bcopy(bi, bi_new, dtoh32(bi->length)); - bi_new = (wl_bss_info_t *)((uintptr)bi_new + - dtoh32(bi_new->length)); - bi = bi_next; - } - } - - if (results->count == 0) { - /* Prune now empty partial scan list */ - dhd_iscan_free_buf(dhdp, iscan_cur); - goto done; - } - break; - } - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -int -dhd_iscan_remove_duplicates(void * dhdp, iscan_buf_t *iscan_cur) -{ - int i = 0; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - dhd_iscan_lock(); - - DHD_ISCAN(("%s: Scan cache before delete\n", - __FUNCTION__)); - dhd_iscan_print_cache(iscan_cur); - - if (!iscan_cur) - goto done; - - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - goto done; - - results = (wl_scan_results_t *)&list->results; - if (!results) - goto done; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n", - __FUNCTION__, i, bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], bi->BSSID.octet[5])); - - dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur); - - bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)); - } - -done: - DHD_ISCAN(("%s: Scan cache after delete\n", __FUNCTION__)); - dhd_iscan_print_cache(iscan_cur); - dhd_iscan_unlock(); - return 0; -} - -void -dhd_iscan_ind_scan_confirm(void *dhdp, bool status) -{ - - dhd_ind_scan_confirm(dhdp, status); -} - -int -dhd_iscan_request(void * dhdp, uint16 action) -{ - int rc; - wl_iscan_params_t params; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - char buf[WLC_IOCTL_SMLEN]; - - - memset(¶ms, 0, sizeof(wl_iscan_params_t)); - memcpy(¶ms.params.bssid, ðer_bcast, ETHER_ADDR_LEN); - - params.params.bss_type = DOT11_BSSTYPE_ANY; - params.params.scan_type = DOT11_SCANTYPE_ACTIVE; - - params.params.nprobes = htod32(-1); - params.params.active_time = htod32(-1); - params.params.passive_time = htod32(-1); - params.params.home_time = htod32(-1); - params.params.channel_num = htod32(0); - - params.version = htod32(ISCAN_REQ_VERSION); - params.action = htod16(action); - params.scan_duration = htod16(0); - - bcm_mkiovar("iscan", (char *)¶ms, sizeof(wl_iscan_params_t), buf, WLC_IOCTL_SMLEN); - rc = dhd_wl_ioctl(dhdp, WLC_SET_VAR, buf, WLC_IOCTL_SMLEN); - - return rc; -} - -static int -dhd_iscan_get_partial_result(void *dhdp, uint *scan_count) -{ - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - iscan_buf_t *iscan_cur; - int status = -1; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - int rc; - - - iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain); - if (!iscan_cur) { - DHD_ERROR(("%s: Failed to allocate node\n", __FUNCTION__)); - dhd_iscan_free_buf(dhdp, 0); - dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT); - goto fail; - } - - dhd_iscan_lock(); - - memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)iscan_cur->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE, - iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - *scan_count = results->count = dtoh32(results->count); - status = dtoh32(list_buf->status); - - dhd_iscan_unlock(); - - if (!(*scan_count)) - dhd_iscan_free_buf(dhdp, iscan_cur); - else - dhd_iscan_remove_duplicates(dhdp, iscan_cur); - - -fail: - return status; -} - -#endif - -/* Function to estimate possible DTIM_SKIP value */ -int dhd_get_dtim_skip(dhd_pub_t *dhd) -{ - int bcn_li_dtim; - char buf[128]; - int ret; - int dtim_assoc = 0; - - if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1)) - bcn_li_dtim = 3; - else - bcn_li_dtim = dhd->dtim_skip; - - /* Read DTIM value if associated */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf)); - if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf))) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - bcn_li_dtim = 1; - goto exit; - } - else - dtim_assoc = dtoh32(*(int *)buf); - - DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", \ - __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL)); - - /* if not assocated just eixt */ - if (dtim_assoc == 0) { - goto exit; - } - - /* check if sta listen interval fits into AP dtim */ - if (dtim_assoc > LISTEN_INTERVAL) { - /* AP DTIM to big for our Listen Interval : no dtim skiping */ - bcn_li_dtim = 1; - DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", \ - __FUNCTION__, dtim_assoc, LISTEN_INTERVAL)); - goto exit; - } - - if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) { - /* Round up dtim_skip to fit into STAs Listen Interval */ - bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc); - DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim)); - } - -exit: - return bcn_li_dtim; -} - -#ifdef PNO_SUPPORT -int dhd_pno_clean(dhd_pub_t *dhd) -{ - char iovbuf[128]; - int pfn_enabled = 0; - int iov_len = 0; - int ret; - - /* Disable pfn */ - iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) >= 0) { - /* clear pfn */ - iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); - if (iov_len) { - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, iov_len)) < 0) { - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - } - } - else { - ret = -1; - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, iov_len)); - } - } - else - DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); - - return ret; -} - -int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) -{ - char iovbuf[128]; - uint8 bssid[6]; - int ret = -1; - - if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - return ret; - } - - memset(iovbuf, 0, sizeof(iovbuf)); - - /* Check if disassoc to enable pno */ - if ((pfn_enabled) && \ - ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, \ - (char *)&bssid, ETHER_ADDR_LEN)) == BCME_NOTASSOCIATED)) { - DHD_TRACE(("%s pno enable called in disassoc mode\n", __FUNCTION__)); - } - else if (pfn_enabled) { - DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \ - __FUNCTION__, ret)); - return ret; - } - - /* Enable/disable PNO */ - if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { - if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s failed for error=%d\n", __FUNCTION__, ret)); - return ret; - } - else { - dhd->pno_enable = pfn_enabled; - DHD_TRACE(("%s set pno as %d\n", __FUNCTION__, dhd->pno_enable)); - } - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, ret)); - - return ret; -} - -/* Function to execute combined scan */ -int -dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, \ - int pno_repeat, int pno_freq_expo_max) -{ - int err = -1; - char iovbuf[128]; - int k, i; - wl_pfn_param_t pfn_param; - wl_pfn_t pfn_element; - - DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr)); - - if ((!dhd) && (!ssids_local)) { - DHD_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - } - - /* Check for broadcast ssid */ - for (k = 0; k < nssid; k++) { - if (!ssids_local[k].SSID_len) { - DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k)); - return err; - } - } -/* #define PNO_DUMP 1 */ -#ifdef PNO_DUMP - { - int j; - for (j = 0; j < nssid; j++) { - DHD_ERROR(("%d: scan for %s size =%d\n", j, - ssids_local[j].SSID, ssids_local[j].SSID_len)); - } - } -#endif /* PNO_DUMP */ - - /* clean up everything */ - if ((err = dhd_pno_clean(dhd)) < 0) { - DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err)); - return err; - } - memset(&pfn_param, 0, sizeof(pfn_param)); - memset(&pfn_element, 0, sizeof(pfn_element)); - - /* set pfn parameters */ - pfn_param.version = htod32(PFN_VERSION); - pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); - - /* check and set extra pno params */ - if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { - pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); - pfn_param.repeat_scan = htod32(pno_repeat); - pfn_param.max_freq_adjust = htod32(pno_freq_expo_max); - } - - /* set up pno scan fr */ - if (scan_fr != 0) - pfn_param.scan_freq = htod32(scan_fr); - - if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { - DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); - return err; - } - if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { - DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); - return err; - } - - bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* set all pfn ssid */ - for (i = 0; i < nssid; i++) { - - pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); - pfn_element.auth = (DOT11_OPEN_SYSTEM); - pfn_element.infra = htod32(1); - - memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); - pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; - - if ((err = - bcm_mkiovar("pfn_add", (char *)&pfn_element, - sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { - if ((err = - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0) { - DHD_ERROR(("%s failed for i=%d error=%d\n", - __FUNCTION__, i, err)); - return err; - } - else - DHD_ERROR(("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", \ - __FUNCTION__, pfn_param.scan_freq, \ - pfn_param.repeat_scan, pfn_param.max_freq_adjust)); - } - else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err)); - } - - /* Enable PNO */ - /* dhd_pno_enable(dhd, 1); */ - return err; -} - -int dhd_pno_get_status(dhd_pub_t *dhd) -{ - int ret = -1; - - if (!dhd) - return ret; - else - return (dhd->pno_enable); -} - -#endif /* PNO_SUPPORT */ - -#if defined(KEEP_ALIVE) -int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on) -{ - char buf[256]; - char *buf_ptr = buf; - wl_keep_alive_pkt_t keep_alive_pkt; - char * str; - int str_len, buf_len; - int res = 0; - int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */ - - DHD_TRACE(("%s: ka:%d\n", __FUNCTION__, ka_on)); - - if (ka_on) { /* on suspend */ - keep_alive_pkt.period_msec = keep_alive_period; - - } else { - /* on resume, turn off keep_alive packets */ - keep_alive_pkt.period_msec = 0; - } - - /* IOC var name */ - str = "keep_alive"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - /* set ptr to IOCTL payload after the var name */ - buf_ptr += buf_len; /* include term Z */ - - /* copy Keep-alive attributes from local var keep_alive_pkt */ - str = NULL_PKT_STR; - keep_alive_pkt.len_bytes = strlen(str); - - memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN); - buf_ptr += WL_KEEP_ALIVE_FIXED_LEN; - - /* copy packet data */ - memcpy(buf_ptr, str, keep_alive_pkt.len_bytes); - buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes); - - res = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); - return res; -} -#endif /* defined(KEEP_ALIVE) */ - -#if defined(CSCAN) - -/* Androd ComboSCAN support */ -/* - * data parsing from ComboScan tlv list -*/ -int -wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token, - int input_size, int *bytes_left) -{ - char* str = *list_str; - uint16 short_temp; - uint32 int_temp; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - /* Clean all dest bytes */ - memset(dst, 0, dst_size); - while (*bytes_left > 0) { - - if (str[0] != token) { - DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n", - __FUNCTION__, token, str[0], *bytes_left)); - return -1; - } - - *bytes_left -= 1; - str += 1; - - if (input_size == 1) { - memcpy(dst, str, input_size); - } - else if (input_size == 2) { - memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)), - input_size); - } - else if (input_size == 4) { - memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)), - input_size); - } - - *bytes_left -= input_size; - str += input_size; - *list_str = str; - return 1; - } - return 1; -} - -/* - * channel list parsing from cscan tlv list -*/ -int -wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, - int channel_num, int *bytes_left) -{ - char* str = *list_str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) { - *list_str = str; - DHD_TRACE(("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - /* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* All channels */ - channel_list[idx] = 0x0; - } - else { - channel_list[idx] = (uint16)str[0]; - DHD_TRACE(("%s channel=%d \n", __FUNCTION__, channel_list[idx])); - } - *bytes_left -= 1; - str += 1; - - if (idx++ > 255) { - DHD_ERROR(("%s Too many channels \n", __FUNCTION__)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* - * SSIDs list parsing from cscan tlv list - */ -int -wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) -{ - char* str = *list_str; - int idx = 0; - - if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { - DHD_ERROR(("%s error paramters\n", __FUNCTION__)); - return -1; - } - - while (*bytes_left > 0) { - - if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { - *list_str = str; - DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0])); - return idx; - } - - /* Get proper CSCAN_TLV_TYPE_SSID_IE */ - *bytes_left -= 1; - str += 1; - - if (str[0] == 0) { - /* Broadcast SSID */ - ssid[idx].SSID_len = 0; - memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN); - *bytes_left -= 1; - str += 1; - - DHD_TRACE(("BROADCAST SCAN left=%d\n", *bytes_left)); - } - else if (str[0] <= DOT11_MAX_SSID_LEN) { - /* Get proper SSID size */ - ssid[idx].SSID_len = str[0]; - *bytes_left -= 1; - str += 1; - - /* Get SSID */ - if (ssid[idx].SSID_len > *bytes_left) { - DHD_ERROR(("%s out of memory range len=%d but left=%d\n", - __FUNCTION__, ssid[idx].SSID_len, *bytes_left)); - return -1; - } - - memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len); - - *bytes_left -= ssid[idx].SSID_len; - str += ssid[idx].SSID_len; - - DHD_TRACE(("%s :size=%d left=%d\n", - (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left)); - } - else { - DHD_ERROR(("### SSID size more that %d\n", str[0])); - return -1; - } - - if (idx++ > max) { - DHD_ERROR(("%s number of SSIDs more that %d\n", __FUNCTION__, idx)); - return -1; - } - } - - *list_str = str; - return idx; -} - -/* Parse a comma-separated list from list_str into ssid array, starting - * at index idx. Max specifies size of the ssid array. Parses ssids - * and returns updated idx; if idx >= max not all fit, the excess have - * not been copied. Returns -1 on empty string, or on ssid too long. - */ -int -wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max) -{ - char* str, *ptr; - - if ((list_str == NULL) || (*list_str == NULL)) - return -1; - - for (str = *list_str; str != NULL; str = ptr) { - - /* check for next TAG */ - if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) { - *list_str = str + strlen(GET_CHANNEL); - return idx; - } - - if ((ptr = strchr(str, ',')) != NULL) { - *ptr++ = '\0'; - } - - if (strlen(str) > DOT11_MAX_SSID_LEN) { - DHD_ERROR(("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN)); - return -1; - } - - if (strlen(str) == 0) - ssid[idx].SSID_len = 0; - - if (idx < max) { - strcpy((char*)ssid[idx].SSID, str); - ssid[idx].SSID_len = strlen(str); - } - idx++; - } - return idx; -} - -/* - * Parse channel list from iwpriv CSCAN - */ -int -wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num) -{ - int num; - int val; - char* str; - char* endptr = NULL; - - if ((list_str == NULL)||(*list_str == NULL)) - return -1; - - str = *list_str; - num = 0; - while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) { - val = (int)strtoul(str, &endptr, 0); - if (endptr == str) { - printf("could not parse channel number starting at" - " substring \"%s\" in list:\n%s\n", - str, *list_str); - return -1; - } - str = endptr + strspn(endptr, " ,"); - - if (num == channel_num) { - DHD_ERROR(("too many channels (more than %d) in channel list:\n%s\n", - channel_num, *list_str)); - return -1; - } - - channel_list[num++] = (uint16)val; - } - *list_str = str; - return num; -} - -#endif diff --git a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c deleted file mode 100644 index 4d32863e2982..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -* Customer code to add GPIO control during WLAN start/stop -* Copyright (C) 1999-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 (the "GPL"), -* available at http://www.broadcom.com/licenses/GPLv2.php, with the -* following added to such license: -* -* As a special exception, the copyright holders of this software give you -* permission to link this software with independent modules, and to copy and -* distribute the resulting executable under terms of your choice, provided that -* you also meet, for each linked independent module, the terms and conditions of -* the license of that module. An independent module is a module which is not -* derived from this software. The special exception does not apply to any -* modifications of the software. -* -* 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. -* -* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.4 2011/01/20 20:23:09 Exp $ -*/ - - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define WL_ERROR(x) printf x -#define WL_TRACE(x) - -#ifdef CUSTOMER_HW -extern void bcm_wlan_power_off(int); -extern void bcm_wlan_power_on(int); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 -int wifi_set_carddetect(int on); -int wifi_set_power(int on, unsigned long msec); -int wifi_get_irq_number(unsigned long *irq_flags_ptr); -int wifi_get_mac_addr(unsigned char *buf); -void *wifi_get_country_code(char *ccode); -#endif - -#if defined(OOB_INTR_ONLY) - -#if defined(BCMLXSDMMC) -extern int sdioh_mmc_irq(int irq); -#endif /* (BCMLXSDMMC) */ - -#ifdef CUSTOMER_HW3 -#include -#endif - -/* Customer specific Host GPIO defintion */ -static int dhd_oob_gpio_num = -1; /* GG 19 */ - -module_param(dhd_oob_gpio_num, int, 0644); -MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); - -int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) -{ - int host_oob_irq = 0; - -#ifdef CUSTOMER_HW2 - host_oob_irq = wifi_get_irq_number(irq_flags_ptr); - -#else /* for NOT CUSTOMER_HW2 */ -#if defined(CUSTOM_OOB_GPIO_NUM) - if (dhd_oob_gpio_num < 0) { - dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; - } -#endif - - if (dhd_oob_gpio_num < 0) { - WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n", - __FUNCTION__)); - return (dhd_oob_gpio_num); - } - - WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", - __FUNCTION__, dhd_oob_gpio_num)); - -#if defined CUSTOMER_HW - host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); -#elif defined CUSTOMER_HW3 - gpio_request(dhd_oob_gpio_num, "oob irq"); - host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); - gpio_direction_input(dhd_oob_gpio_num); -#endif /* CUSTOMER_HW */ -#endif /* CUSTOMER_HW2 */ - - return (host_oob_irq); -} -#endif /* defined(OOB_INTR_ONLY) */ - -/* Customer function to control hw specific wlan gpios */ -void -dhd_customer_gpio_wlan_ctrl(int onoff) -{ - switch (onoff) { - case WLAN_RESET_OFF: - WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(0, 0); -#endif - WL_ERROR(("=========== WLAN placed in RESET ========\n")); - break; - - case WLAN_RESET_ON: - WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(1, 0); -#endif - WL_ERROR(("=========== WLAN going back to live ========\n")); - break; - - case WLAN_POWER_OFF: - WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(1); -#endif /* CUSTOMER_HW */ - break; - - case WLAN_POWER_ON: - WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", - __FUNCTION__)); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(1); - /* Lets customer power to get stable */ - OSL_DELAY(50); -#endif /* CUSTOMER_HW */ - break; - } -} - -#ifdef GET_CUSTOM_MAC_ENABLE -/* Function to get custom MAC address */ -int -dhd_custom_get_mac_address(unsigned char *buf) -{ - int ret = 0; - - WL_TRACE(("%s Enter\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - - /* Customer access to MAC address stored outside of DHD driver */ -#ifdef CUSTOMER_HW2 - ret = wifi_get_mac_addr(buf); -#endif - -#ifdef EXAMPLE_GET_MAC - /* EXAMPLE code */ - { - struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}}; - bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); - } -#endif /* EXAMPLE_GET_MAC */ - - return ret; -} -#endif /* GET_CUSTOM_MAC_ENABLE */ - -/* Customized Locale table : OPTIONAL feature */ -const struct cntry_locales_custom translate_custom_table[] = { -/* Table should be filled out based on custom platform regulatory requirement */ -#ifdef EXAMPLE_TABLE - {"", "XY", 4}, /* universal */ - {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ - {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ - {"EU", "EU", 5}, /* European union countries */ - {"AT", "EU", 5}, - {"BE", "EU", 5}, - {"BG", "EU", 5}, - {"CY", "EU", 5}, - {"CZ", "EU", 5}, - {"DK", "EU", 5}, - {"EE", "EU", 5}, - {"FI", "EU", 5}, - {"FR", "EU", 5}, - {"DE", "EU", 5}, - {"GR", "EU", 5}, - {"HU", "EU", 5}, - {"IE", "EU", 5}, - {"IT", "EU", 5}, - {"LV", "EU", 5}, - {"LI", "EU", 5}, - {"LT", "EU", 5}, - {"LU", "EU", 5}, - {"MT", "EU", 5}, - {"NL", "EU", 5}, - {"PL", "EU", 5}, - {"PT", "EU", 5}, - {"RO", "EU", 5}, - {"SK", "EU", 5}, - {"SI", "EU", 5}, - {"ES", "EU", 5}, - {"SE", "EU", 5}, - {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */ - {"IL", "IL", 0}, - {"CH", "CH", 0}, - {"TR", "TR", 0}, - {"NO", "NO", 0}, - {"KR", "XY", 3}, - {"AU", "XY", 3}, - {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ - {"TW", "XY", 3}, - {"AR", "XY", 3}, - {"MX", "XY", 3} -#endif /* EXAMPLE_TABLE */ -}; - - -/* Customized Locale convertor -* input : ISO 3166-1 country abbreviation -* output: customized cspec -*/ -void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) -{ -#ifdef CUSTOMER_HW2 - struct cntry_locales_custom *cloc_ptr; - - if (!cspec) - return; - - cloc_ptr = wifi_get_country_code(country_iso_code); - if (cloc_ptr) { - strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = cloc_ptr->custom_locale_rev; - } - return; -#else - int size, i; - - size = ARRAYSIZE(translate_custom_table); - - if (cspec == 0) - return; - - if (size == 0) - return; - - for (i = 0; i < size; i++) { - if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { - memcpy(cspec->ccode, translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[i].custom_locale_rev; - return; - } - } - memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); - cspec->rev = translate_custom_table[0].custom_locale_rev; - return; -#endif -} diff --git a/drivers/net/wireless/bcm4329/dhd_dbg.h b/drivers/net/wireless/bcm4329/dhd_dbg.h deleted file mode 100644 index b48c1d70f144..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_dbg.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Debug/trace/assert driver definitions for Dongle Host Driver. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_dbg.h,v 1.5.6.2.4.2.14.10 2010/05/21 21:49:38 Exp $ - */ - -#ifndef _dhd_dbg_ -#define _dhd_dbg_ - -#ifdef DHD_DEBUG - -#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \ - printf args;} while (0) -#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0) -#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0) -#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0) -#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) printf args;} while (0) -#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) printf args;} while (0) -#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0) -#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0) -#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) printf args;} while (0) -#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0) -#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0) -#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0) -#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0) - -#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) -#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) -#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL) -#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL) -#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL) -#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL) -#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL) -#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL) -#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL) -#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL) -#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL) -#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) -#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) - -#else /* DHD_DEBUG */ - -#define DHD_ERROR(args) do {if (net_ratelimit()) printf args;} while (0) -#define DHD_TRACE(args) -#define DHD_INFO(args) -#define DHD_DATA(args) -#define DHD_CTL(args) -#define DHD_TIMER(args) -#define DHD_HDRS(args) -#define DHD_BYTES(args) -#define DHD_INTR(args) -#define DHD_GLOM(args) -#define DHD_EVENT(args) -#define DHD_BTA(args) -#define DHD_ISCAN(args) - -#define DHD_ERROR_ON() 0 -#define DHD_TRACE_ON() 0 -#define DHD_INFO_ON() 0 -#define DHD_DATA_ON() 0 -#define DHD_CTL_ON() 0 -#define DHD_TIMER_ON() 0 -#define DHD_HDRS_ON() 0 -#define DHD_BYTES_ON() 0 -#define DHD_INTR_ON() 0 -#define DHD_GLOM_ON() 0 -#define DHD_EVENT_ON() 0 -#define DHD_BTA_ON() 0 -#define DHD_ISCAN_ON() 0 -#endif /* DHD_DEBUG */ - -#define DHD_LOG(args) - -#define DHD_NONE(args) -extern int dhd_msg_level; - -/* Defines msg bits */ -#include - -#endif /* _dhd_dbg_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c deleted file mode 100644 index 3b21e41dd54b..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_linux.c +++ /dev/null @@ -1,3390 +0,0 @@ -/* - * Broadcom Dongle Host Driver (DHD), Linux-specific network interface - * Basically selected code segments from usb-cdc.c and usb-rndis.c - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.40 2011/02/03 19:55:18 Exp $ - */ - -#ifdef CONFIG_WIFI_CONTROL_FUNC -#include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) -#include - -struct semaphore wifi_control_sem; - -struct dhd_bus *g_bus; - -static struct wifi_platform_data *wifi_control_data = NULL; -static struct resource *wifi_irqres = NULL; - -int wifi_get_irq_number(unsigned long *irq_flags_ptr) -{ - if (wifi_irqres) { - *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; - return (int)wifi_irqres->start; - } -#ifdef CUSTOM_OOB_GPIO_NUM - return CUSTOM_OOB_GPIO_NUM; -#else - return -1; -#endif -} - -int wifi_set_carddetect(int on) -{ - printk("%s = %d\n", __FUNCTION__, on); - if (wifi_control_data && wifi_control_data->set_carddetect) { - wifi_control_data->set_carddetect(on); - } - return 0; -} - -int wifi_set_power(int on, unsigned long msec) -{ - printk("%s = %d\n", __FUNCTION__, on); - if (wifi_control_data && wifi_control_data->set_power) { - wifi_control_data->set_power(on); - } - if (msec) - mdelay(msec); - return 0; -} - -int wifi_set_reset(int on, unsigned long msec) -{ - DHD_TRACE(("%s = %d\n", __FUNCTION__, on)); - if (wifi_control_data && wifi_control_data->set_reset) { - wifi_control_data->set_reset(on); - } - if (msec) - mdelay(msec); - return 0; -} - -int wifi_get_mac_addr(unsigned char *buf) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - if (wifi_control_data && wifi_control_data->get_mac_addr) { - return wifi_control_data->get_mac_addr(buf); - } - return -EOPNOTSUPP; -} - -void *wifi_get_country_code(char *ccode) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!ccode) - return NULL; - if (wifi_control_data && wifi_control_data->get_country_code) { - return wifi_control_data->get_country_code(ccode); - } - return NULL; -} - -static int wifi_probe(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_TRACE(("## %s\n", __FUNCTION__)); - wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq"); - wifi_control_data = wifi_ctrl; - - wifi_set_power(1, 0); /* Power On */ - wifi_set_carddetect(1); /* CardDetect (0->1) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_remove(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_TRACE(("## %s\n", __FUNCTION__)); - wifi_control_data = wifi_ctrl; - - wifi_set_power(0, 0); /* Power Off */ - wifi_set_carddetect(0); /* CardDetect (1->0) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(0); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} -static int wifi_resume(struct platform_device *pdev) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} - -static struct platform_driver wifi_device = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcm4329_wlan", - } -}; - -int wifi_add_dev(void) -{ - DHD_TRACE(("## Calling platform_driver_register\n")); - return platform_driver_register(&wifi_device); -} - -void wifi_del_dev(void) -{ - DHD_TRACE(("## Unregister platform_driver_register\n")); - platform_driver_unregister(&wifi_device); -} -#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - -static int dhd_device_event(struct notifier_block *this, unsigned long event, - void *ptr); - -static struct notifier_block dhd_notifier = { - .notifier_call = dhd_device_event -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -#include -volatile bool dhd_mmc_suspend = FALSE; -DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#if defined(OOB_INTR_ONLY) -extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -MODULE_LICENSE("GPL v2"); -#endif /* LinuxVer */ - -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) -const char * -print_tainted() -{ - return ""; -} -#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */ - -/* Linux wireless extension support */ -#if defined(CONFIG_WIRELESS_EXT) -#include -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -#if defined(CONFIG_HAS_EARLYSUSPEND) -#include -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -#ifdef PKT_FILTER_SUPPORT -extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg); -extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -#endif - -/* Interface control information */ -typedef struct dhd_if { - struct dhd_info *info; /* back pointer to dhd_info */ - /* OS/stack specifics */ - struct net_device *net; - struct net_device_stats stats; - int idx; /* iface idx in dongle */ - int state; /* interface state */ - uint subunit; /* subunit */ - uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */ - bool attached; /* Delayed attachment when unset */ - bool txflowcontrol; /* Per interface flow control indicator */ - char name[IFNAMSIZ+1]; /* linux interface name */ -} dhd_if_t; - -/* Local private structure (extension of pub) */ -typedef struct dhd_info { -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - dhd_pub_t pub; - - /* OS/stack specifics */ - dhd_if_t *iflist[DHD_MAX_IFS]; - - struct semaphore proto_sem; - wait_queue_head_t ioctl_resp_wait; - struct timer_list timer; - bool wd_timer_valid; - struct tasklet_struct tasklet; - spinlock_t sdlock; - spinlock_t txqlock; - spinlock_t dhd_lock; - - /* Thread based operation */ - bool threads_only; - struct semaphore sdsem; - long watchdog_pid; - struct semaphore watchdog_sem; - struct completion watchdog_exited; - long dpc_pid; - struct semaphore dpc_sem; - struct completion dpc_exited; - - /* Wakelocks */ -#ifdef CONFIG_HAS_WAKELOCK - struct wake_lock wl_wifi; /* Wifi wakelock */ - struct wake_lock wl_rxwake; /* Wifi rx wakelock */ -#endif - spinlock_t wl_lock; - int wl_count; - int wl_packet; - - int hang_was_sent; /* flag that message was send at least once */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */ -#endif - /* Thread to issue ioctl for multicast */ - long sysioc_pid; - struct semaphore sysioc_sem; - struct completion sysioc_exited; - bool set_multicast; - bool set_macaddress; - struct ether_addr macvalue; - wait_queue_head_t ctrl_wait; - atomic_t pend_8021x_cnt; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif /* CONFIG_HAS_EARLYSUSPEND */ -} dhd_info_t; - -/* Definitions to provide path to the firmware and nvram - * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt" - */ -char firmware_path[MOD_PARAM_PATHLEN]; -char nvram_path[MOD_PARAM_PATHLEN]; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -struct semaphore dhd_registration_sem; -#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -/* load firmware and/or nvram values from the filesystem */ -module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0); -module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); - -/* Error bits */ -module_param(dhd_msg_level, int, 0); - -/* Spawn a thread for system ioctls (set mac, set mcast) */ -uint dhd_sysioc = TRUE; -module_param(dhd_sysioc, uint, 0); - -/* Watchdog interval */ -uint dhd_watchdog_ms = 10; -module_param(dhd_watchdog_ms, uint, 0); - -#ifdef DHD_DEBUG -/* Console poll interval */ -uint dhd_console_ms = 0; -module_param(dhd_console_ms, uint, 0); -#endif /* DHD_DEBUG */ - -/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ -uint dhd_arp_mode = 0xb; -module_param(dhd_arp_mode, uint, 0); - -/* ARP offload enable */ -uint dhd_arp_enable = TRUE; -module_param(dhd_arp_enable, uint, 0); - -/* Global Pkt filter enable control */ -uint dhd_pkt_filter_enable = TRUE; -module_param(dhd_pkt_filter_enable, uint, 0); - -/* Pkt filter init setup */ -uint dhd_pkt_filter_init = 0; -module_param(dhd_pkt_filter_init, uint, 0); - -/* Pkt filter mode control */ -uint dhd_master_mode = TRUE; -module_param(dhd_master_mode, uint, 1); - -/* Watchdog thread priority, -1 to use kernel timer */ -int dhd_watchdog_prio = 97; -module_param(dhd_watchdog_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -int dhd_dpc_prio = 98; -module_param(dhd_dpc_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -extern int dhd_dongle_memsize; -module_param(dhd_dongle_memsize, int, 0); - -/* Control fw roaming */ -#ifdef CUSTOMER_HW2 -uint dhd_roam = 0; -#else -uint dhd_roam = 1; -#endif - -/* Control radio state */ -uint dhd_radio_up = 1; - -/* Network inteface name */ -char iface_name[IFNAMSIZ]; -module_param_string(iface_name, iface_name, IFNAMSIZ, 0); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else /* Linux 2.4 (w/o preemption patch) */ -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif /* LINUX_VERSION_CODE */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - -/* The following are specific to the SDIO dongle */ - -/* IOCTL response timeout */ -int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; - -/* Idle timeout for backplane clock */ -int dhd_idletime = DHD_IDLETIME_TICKS; -module_param(dhd_idletime, int, 0); - -/* Use polling */ -uint dhd_poll = FALSE; -module_param(dhd_poll, uint, 0); - -/* Use interrupts */ -uint dhd_intr = TRUE; -module_param(dhd_intr, uint, 0); - -/* SDIO Drive Strength (in milliamps) */ -uint dhd_sdiod_drive_strength = 6; -module_param(dhd_sdiod_drive_strength, uint, 0); - -/* Tx/Rx bounds */ -extern uint dhd_txbound; -extern uint dhd_rxbound; -module_param(dhd_txbound, uint, 0); -module_param(dhd_rxbound, uint, 0); - -/* Deferred transmits */ -extern uint dhd_deferred_tx; -module_param(dhd_deferred_tx, uint, 0); - - - -#ifdef SDTEST -/* Echo packet generator (pkts/s) */ -uint dhd_pktgen = 0; -module_param(dhd_pktgen, uint, 0); - -/* Echo packet len (0 => sawtooth, max 2040) */ -uint dhd_pktgen_len = 0; -module_param(dhd_pktgen_len, uint, 0); -#endif - -/* Version string to report */ -#ifdef DHD_DEBUG -#ifndef SRCBASE -#define SRCBASE "drivers/net/wireless/bcm4329" -#endif -#define DHD_COMPILED "\nCompiled in " SRCBASE -#else -#define DHD_COMPILED -#endif - -static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR -#ifdef DHD_DEBUG -"\nCompiled in " SRCBASE " on " __DATE__ " at " __TIME__ -#endif -; - - -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -static void dhd_dpc(ulong data); -/* forward decl */ -extern int dhd_wait_pend8021x(struct net_device *dev); - -#ifdef TOE -#ifndef BDC -#error TOE requires BDC -#endif /* !BDC */ -static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol); -static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); -#endif /* TOE */ - -static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event_ptr, void **data_ptr); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) -{ - int ret = NOTIFY_DONE; - - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - dhd_mmc_suspend = TRUE; - ret = NOTIFY_OK; - break; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - dhd_mmc_suspend = FALSE; - ret = NOTIFY_OK; - break; - } - smp_mb(); - return ret; -} - -static struct notifier_block dhd_sleep_pm_notifier = { - .notifier_call = dhd_sleep_pm_callback, - .priority = 0 -}; -extern int register_pm_notifier(struct notifier_block *nb); -extern int unregister_pm_notifier(struct notifier_block *nb); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -static void dhd_set_packet_filter(int value, dhd_pub_t *dhd) -{ -#ifdef PKT_FILTER_SUPPORT - DHD_TRACE(("%s: %d\n", __FUNCTION__, value)); - /* 1 - Enable packet filter, only allow unicast packet to send up */ - /* 0 - Disable packet filter */ - if (dhd_pkt_filter_enable) { - int i; - - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - value, dhd_master_mode); - } - } -#endif -} - - - -#if defined(CONFIG_HAS_EARLYSUSPEND) -static int dhd_set_suspend(int value, dhd_pub_t *dhd) -{ - int power_mode = PM_MAX; - /* wl_pkt_filter_enable_t enable_parm; */ - char iovbuf[32]; - int bcn_li_dtim = 3; -#ifdef CUSTOMER_HW2 - uint roamvar = 1; -#endif /* CUSTOMER_HW2 */ - - DHD_TRACE(("%s: enter, value = %d in_suspend = %d\n", - __FUNCTION__, value, dhd->in_suspend)); - - if (dhd && dhd->up) { - if (value && dhd->in_suspend) { - - /* Kernel suspended */ - DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, - (char *)&power_mode, sizeof(power_mode)); - - /* Enable packet filter, only allow unicast packet to send up */ - dhd_set_packet_filter(1, dhd); - - /* if dtim skip setup as default force it to wake each thrid dtim - * for better power saving. - * Note that side effect is chance to miss BC/MC packet - */ - bcn_li_dtim = dhd_get_dtim_skip(dhd); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - /* Disable build-in roaming during suspend */ - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - - } else { - - /* Kernel resumed */ - DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__)); - - power_mode = PM_FAST; - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, - sizeof(power_mode)); - - /* disable pkt filter */ - dhd_set_packet_filter(0, dhd); - - /* restore pre-suspend setting for dtim_skip */ - bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip, - 4, iovbuf, sizeof(iovbuf)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - roamvar = dhd_roam; - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - } - } - - return 0; -} - -static void dhd_suspend_resume_helper(struct dhd_info *dhd, int val) -{ - dhd_pub_t *dhdp = &dhd->pub; - - dhd_os_wake_lock(dhdp); - dhd_os_proto_block(dhdp); - /* Set flag when early suspend was called */ - dhdp->in_suspend = val; - if (!dhdp->suspend_disable_flag) - dhd_set_suspend(val, dhdp); - dhd_os_proto_unblock(dhdp); - dhd_os_wake_unlock(dhdp); -} - -static void dhd_early_suspend(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 1); -} - -static void dhd_late_resume(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __FUNCTION__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 0); -} -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -/* - * Generalized timeout mechanism. Uses spin sleep with exponential back-off until - * the sleep time reaches one jiffy, then switches over to task delay. Usage: - * - * dhd_timeout_start(&tmo, usec); - * while (!dhd_timeout_expired(&tmo)) - * if (poll_something()) - * break; - * if (dhd_timeout_expired(&tmo)) - * fatal(); - */ - -void -dhd_timeout_start(dhd_timeout_t *tmo, uint usec) -{ - tmo->limit = usec; - tmo->increment = 0; - tmo->elapsed = 0; - tmo->tick = 1000000 / HZ; -} - -int -dhd_timeout_expired(dhd_timeout_t *tmo) -{ - /* Does nothing the first call */ - if (tmo->increment == 0) { - tmo->increment = 1; - return 0; - } - - if (tmo->elapsed >= tmo->limit) - return 1; - - /* Add the delay that's about to take place */ - tmo->elapsed += tmo->increment; - - if (tmo->increment < tmo->tick) { - OSL_DELAY(tmo->increment); - tmo->increment *= 2; - if (tmo->increment > tmo->tick) - tmo->increment = tmo->tick; - } else { - wait_queue_head_t delay_wait; - DECLARE_WAITQUEUE(wait, current); - int pending; - init_waitqueue_head(&delay_wait); - add_wait_queue(&delay_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - pending = signal_pending(current); - remove_wait_queue(&delay_wait, &wait); - set_current_state(TASK_RUNNING); - if (pending) - return 1; /* Interrupted */ - } - - return 0; -} - -static int -dhd_net2idx(dhd_info_t *dhd, struct net_device *net) -{ - int i = 0; - - ASSERT(dhd); - while (i < DHD_MAX_IFS) { - if (dhd->iflist[i] && (dhd->iflist[i]->net == net)) - return i; - i++; - } - - return DHD_BAD_IF; -} - -int -dhd_ifname2idx(dhd_info_t *dhd, char *name) -{ - int i = DHD_MAX_IFS; - - ASSERT(dhd); - - if (name == NULL || *name == '\0') - return 0; - - while (--i > 0) - if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ)) - break; - - DHD_TRACE(("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name)); - - return i; /* default - the primary interface */ -} - -char * -dhd_ifname(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - ASSERT(dhd); - - if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { - DHD_ERROR(("%s: ifidx %d out of range\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx] == NULL) { - DHD_ERROR(("%s: null i/f %d\n", __FUNCTION__, ifidx)); - return ""; - } - - if (dhd->iflist[ifidx]->net) - return dhd->iflist[ifidx]->net->name; - - return ""; -} - -static void -_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) -{ - struct net_device *dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - struct netdev_hw_addr *ha; -#else - struct dev_mc_list *mclist; -#endif - uint32 allmulti, cnt; - - wl_ioctl_t ioc; - char *buf, *bufp; - uint buflen; - int ret; - - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; - - NETIF_ADDR_LOCK(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - cnt = netdev_mc_count(dev); -#else - cnt = dev->mc_count; -#endif - NETIF_ADDR_UNLOCK(dev); - - /* Determine initial value of allmulti flag */ - allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; - - /* Send down the multicast list first. */ - buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN); - if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - return; - } - - strcpy(bufp, "mcast_list"); - bufp += strlen("mcast_list") + 1; - - cnt = htol32(cnt); - memcpy(bufp, &cnt, sizeof(cnt)); - bufp += sizeof(cnt); - - NETIF_ADDR_LOCK(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - netdev_for_each_mc_addr(ha, dev) { - if (!cnt) - break; - memcpy(bufp, ha->addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - cnt--; - } -#else - for (mclist = dev->mc_list; (mclist && (cnt > 0)); cnt--, mclist = mclist->next) { - memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - } -#endif - NETIF_ADDR_UNLOCK(dev); - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set mcast_list failed, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); - allmulti = cnt ? TRUE : allmulti; - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Now send the allmulti setting. This is based on the setting in the - * net_device flags, but might be modified above to be turned on if we - * were trying to set some addresses and dongle rejected it... - */ - - buflen = sizeof("allmulti") + sizeof(allmulti); - if (!(buf = MALLOC(dhd->pub.osh, buflen))) { - DHD_ERROR(("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx))); - return; - } - allmulti = htol32(allmulti); - - if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) { - DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d buflen %u\n", - dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen)); - MFREE(dhd->pub.osh, buf, buflen); - return; - } - - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = buflen; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set allmulti %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } - - MFREE(dhd->pub.osh, buf, buflen); - - /* Finally, pick up the PROMISC flag as well, like the NIC driver does */ - - allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE; - allmulti = htol32(allmulti); - - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_PROMISC; - ioc.buf = &allmulti; - ioc.len = sizeof(allmulti); - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set promisc %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); - } -} - -static int -_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) -{ - char buf[32]; - wl_ioctl_t ioc; - int ret; - - DHD_TRACE(("%s enter\n", __FUNCTION__)); - if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) { - DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx))); - return -1; - } - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = 32; - ioc.set = TRUE; - - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx))); - } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); - } - - return ret; -} - -#ifdef SOFTAP -extern struct net_device *ap_net_dev; -/* semaphore that the soft AP CODE waits on */ -extern struct semaphore ap_eth_sema; -#endif - -static void -dhd_op_if(dhd_if_t *ifp) -{ - dhd_info_t *dhd; - int ret = 0, err = 0; -#ifdef SOFTAP - unsigned long flags; -#endif - - ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */ - - dhd = ifp->info; - - DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state)); - - switch (ifp->state) { - case WLC_E_IF_ADD: - /* - * Delete the existing interface before overwriting it - * in case we missed the WLC_E_IF_DEL event. - */ - if (ifp->net != NULL) { - DHD_ERROR(("%s: ERROR: netdev:%s already exists, try free & unregister \n", - __FUNCTION__, ifp->net->name)); - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - free_netdev(ifp->net); - } - /* Allocate etherdev, including space for private structure */ - if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - ret = -ENOMEM; - } - if (ret == 0) { - strcpy(ifp->net->name, ifp->name); - memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd)); - if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) { - DHD_ERROR(("%s: dhd_net_attach failed, err %d\n", - __FUNCTION__, err)); - ret = -EOPNOTSUPP; - } else { -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - /* save ptr to wl0.1 netdev for use in wl_iw.c */ - ap_net_dev = ifp->net; - /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */ - up(&ap_eth_sema); - dhd_os_spin_unlock(&dhd->pub, flags); -#endif - DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n", - current->pid, ifp->net->name)); - ifp->state = 0; - } - } - break; - case WLC_E_IF_DEL: - if (ifp->net != NULL) { - DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", __FUNCTION__)); - netif_stop_queue(ifp->net); - unregister_netdev(ifp->net); - ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */ - } - break; - default: - DHD_ERROR(("%s: bad op %d\n", __FUNCTION__, ifp->state)); - ASSERT(!ifp->state); - break; - } - - if (ret < 0) { - if (ifp->net) { - free_netdev(ifp->net); - } - dhd->iflist[ifp->idx] = NULL; - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - if (ifp->net == ap_net_dev) - ap_net_dev = NULL; /* NULL SOFTAP global as well */ - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - } -} - -static int -_dhd_sysioc_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - int i; -#ifdef SOFTAP - bool in_ap = FALSE; - unsigned long flags; -#endif - - DAEMONIZE("dhd_sysioc"); - - while (down_interruptible(&dhd->sysioc_sem) == 0) { - dhd_os_start_lock(&dhd->pub); - dhd_os_wake_lock(&dhd->pub); - for (i = 0; i < DHD_MAX_IFS; i++) { - if (dhd->iflist[i]) { - DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i)); -#ifdef SOFTAP - flags = dhd_os_spin_lock(&dhd->pub); - in_ap = (ap_net_dev != NULL); - dhd_os_spin_unlock(&dhd->pub, flags); -#endif /* SOFTAP */ - if (dhd->iflist[i]->state) - dhd_op_if(dhd->iflist[i]); -#ifdef SOFTAP - if (dhd->iflist[i] == NULL) { - DHD_TRACE(("%s: interface %d just been removed!\n\n", __FUNCTION__, i)); - continue; - } - - if (in_ap && dhd->set_macaddress) { - DHD_TRACE(("attempt to set MAC for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); - dhd->set_macaddress = FALSE; - continue; - } - - if (in_ap && dhd->set_multicast) { - DHD_TRACE(("attempt to set MULTICAST list for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); - dhd->set_multicast = FALSE; - continue; - } -#endif /* SOFTAP */ - if (dhd->set_multicast) { - dhd->set_multicast = FALSE; - _dhd_set_multicast_list(dhd, i); - } - if (dhd->set_macaddress) { - dhd->set_macaddress = FALSE; - _dhd_set_mac_address(dhd, i, &dhd->macvalue); - } - } - } - dhd_os_wake_unlock(&dhd->pub); - dhd_os_start_unlock(&dhd->pub); - } - DHD_TRACE(("%s: stopped\n",__FUNCTION__)); - complete_and_exit(&dhd->sysioc_exited, 0); -} - -static int -dhd_set_mac_address(struct net_device *dev, void *addr) -{ - int ret = 0; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - struct sockaddr *sa = (struct sockaddr *)addr; - int ifidx; - - DHD_TRACE(("%s: Enter\n",__FUNCTION__)); - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return -1; - - ASSERT(dhd->sysioc_pid >= 0); - memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); - dhd->set_macaddress = TRUE; - up(&dhd->sysioc_sem); - - return ret; -} - -static void -dhd_set_multicast_list(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ifidx; - - DHD_TRACE(("%s: Enter\n",__FUNCTION__)); - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) - return; - - ASSERT(dhd->sysioc_pid >= 0); - dhd->set_multicast = TRUE; - up(&dhd->sysioc_sem); -} - -int -dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) -{ - int ret; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - - /* Reject if down */ - if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) { - return -ENODEV; - } - - /* Update multicast statistic */ - if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_ADDR_LEN) { - uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf); - struct ether_header *eh = (struct ether_header *)pktdata; - - if (ETHER_ISMULTI(eh->ether_dhost)) - dhdp->tx_multicast++; - if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) - atomic_inc(&dhd->pend_8021x_cnt); - } - - /* Look into the packet and update the packet priority */ - if ((PKTPRIO(pktbuf) == 0)) - pktsetprio(pktbuf, FALSE); - - /* If the protocol uses a data header, apply it */ - dhd_prot_hdrpush(dhdp, ifidx, pktbuf); - - /* Use bus module to send data frame */ -#ifdef BCMDBUS - ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */); -#else - ret = dhd_bus_txdata(dhdp->bus, pktbuf); -#endif /* BCMDBUS */ - - return ret; -} - -static int -dhd_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - int ret; - void *pktbuf; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - int ifidx; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_os_wake_lock(&dhd->pub); - - /* Reject if down */ - if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) { - DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", - __FUNCTION__, dhd->pub.up, dhd->pub.busstate)); - netif_stop_queue(net); - /* Send Event when bus down detected during data session */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s: Event HANG send up\n", __FUNCTION__)); - net_os_send_hang_message(net); - } - dhd_os_wake_unlock(&dhd->pub); - return -ENODEV; - } - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx)); - netif_stop_queue(net); - dhd_os_wake_unlock(&dhd->pub); - return -ENODEV; - } - - /* Make sure there's enough room for any header */ - if (skb_headroom(skb) < dhd->pub.hdrlen) { - struct sk_buff *skb2; - - DHD_INFO(("%s: insufficient headroom\n", - dhd_ifname(&dhd->pub, ifidx))); - dhd->pub.tx_realloc++; - skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen); - dev_kfree_skb(skb); - if ((skb = skb2) == NULL) { - DHD_ERROR(("%s: skb_realloc_headroom failed\n", - dhd_ifname(&dhd->pub, ifidx))); - ret = -ENOMEM; - goto done; - } - } - - /* Convert to packet */ - if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) { - DHD_ERROR(("%s: PKTFRMNATIVE failed\n", - dhd_ifname(&dhd->pub, ifidx))); - dev_kfree_skb_any(skb); - ret = -ENOMEM; - goto done; - } - - ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); - -done: - if (ret) - dhd->pub.dstats.tx_dropped++; - else - dhd->pub.tx_packets++; - - dhd_os_wake_unlock(&dhd->pub); - - /* Return ok: we always eat the packet */ - return 0; -} - -void -dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) -{ - struct net_device *net; - dhd_info_t *dhd = dhdp->info; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhdp->txoff = state; - ASSERT(dhd && dhd->iflist[ifidx]); - net = dhd->iflist[ifidx]->net; - if (state == ON) - netif_stop_queue(net); - else - netif_wake_queue(net); -} - -void -dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct sk_buff *skb; - uchar *eth; - uint len; - void * data, *pnext, *save_pktbuf; - int i; - dhd_if_t *ifp; - wl_event_msg_t event; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - save_pktbuf = pktbuf; - - for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { - - pnext = PKTNEXT(dhdp->osh, pktbuf); - PKTSETNEXT(wl->sh.osh, pktbuf, NULL); - - - skb = PKTTONATIVE(dhdp->osh, pktbuf); - - /* Get the protocol, maintain skb around eth_type_trans() - * The main reason for this hack is for the limitation of - * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len' - * to perform skb_pull inside vs ETH_HLEN. Since to avoid - * coping of the packet coming from the network stack to add - * BDC, Hardware header etc, during network interface registration - * we set the 'net->hard_header_len' to ETH_HLEN + extra space required - * for BDC, Hardware header etc. and not just the ETH_HLEN - */ - eth = skb->data; - len = skb->len; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) - ifp = dhd->iflist[0]; - - ASSERT(ifp); - skb->dev = ifp->net; - skb->protocol = eth_type_trans(skb, skb->dev); - - if (skb->pkt_type == PACKET_MULTICAST) { - dhd->pub.rx_multicast++; - } - - skb->data = eth; - skb->len = len; - - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - - /* Process special event packets and then discard them */ - if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) - dhd_wl_host_event(dhd, &ifidx, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) - skb->mac_header, -#else - skb->mac.raw, -#endif - &event, - &data); - - ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); - if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) - ifp = dhd->iflist[ifidx]; - - if (ifp->net) - ifp->net->last_rx = jiffies; - - dhdp->dstats.rx_bytes += skb->len; - dhdp->rx_packets++; /* Local count */ - - if (in_interrupt()) { - netif_rx(skb); - } else { - /* If the receive is not processed inside an ISR, - * the softirqd must be woken explicitly to service - * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled - * by netif_rx_ni(), but in earlier kernels, we need - * to do it manually. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - netif_rx_ni(skb); -#else - ulong flags; - netif_rx(skb); - local_irq_save(flags); - RAISE_RX_SOFTIRQ(); - local_irq_restore(flags); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ - } - } - dhd_os_wake_lock_timeout_enable(dhdp); -} - -void -dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) -{ - /* Linux version has nothing to do */ - return; -} - -void -dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) -{ - uint ifidx; - dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); - struct ether_header *eh; - uint16 type; - - dhd_prot_hdrpull(dhdp, &ifidx, txp); - - eh = (struct ether_header *)PKTDATA(dhdp->osh, txp); - type = ntoh16(eh->ether_type); - - if (type == ETHER_TYPE_802_1X) - atomic_dec(&dhd->pend_8021x_cnt); - -} - -static struct net_device_stats * -dhd_get_stats(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_if_t *ifp; - int ifidx; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) - return NULL; - - ifp = dhd->iflist[ifidx]; - ASSERT(dhd && ifp); - - if (dhd->pub.up) { - /* Use the protocol to get dongle stats */ - dhd_prot_dstats(&dhd->pub); - } - - /* Copy dongle stats to net device stats */ - ifp->stats.rx_packets = dhd->pub.dstats.rx_packets; - ifp->stats.tx_packets = dhd->pub.dstats.tx_packets; - ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes; - ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes; - ifp->stats.rx_errors = dhd->pub.dstats.rx_errors; - ifp->stats.tx_errors = dhd->pub.dstats.tx_errors; - ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped; - ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped; - ifp->stats.multicast = dhd->pub.dstats.multicast; - - return &ifp->stats; -} - -static int -dhd_watchdog_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_watchdog_prio > 0) { - struct sched_param param; - param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)? - dhd_watchdog_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - DAEMONIZE("dhd_watchdog"); - - /* Run until signal received */ - while (1) { - if (down_interruptible (&dhd->watchdog_sem) == 0) { - dhd_os_sdlock(&dhd->pub); - if (dhd->pub.dongle_reset == FALSE) { - DHD_TIMER(("%s:\n", __FUNCTION__)); - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - } - dhd_os_sdunlock(&dhd->pub); - dhd_os_wake_unlock(&dhd->pub); - } else { - break; - } - } - - complete_and_exit(&dhd->watchdog_exited, 0); -} - -static void -dhd_watchdog(ulong data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - dhd_os_wake_lock(&dhd->pub); - if (dhd->pub.dongle_reset) { - dhd_os_wake_unlock(&dhd->pub); - return; - } - - if (dhd->watchdog_pid >= 0) { - up(&dhd->watchdog_sem); - return; - } - - dhd_os_sdlock(&dhd->pub); - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - dhd_os_sdunlock(&dhd->pub); - dhd_os_wake_unlock(&dhd->pub); -} - -static int -dhd_dpc_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *)data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_dpc_prio > 0) - { - struct sched_param param; - param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - DAEMONIZE("dhd_dpc"); - - /* Run until signal received */ - while (1) { - if (down_interruptible(&dhd->dpc_sem) == 0) { - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) { - up(&dhd->dpc_sem); - } - else { - dhd_os_wake_unlock(&dhd->pub); - } - } else { - dhd_bus_stop(dhd->pub.bus, TRUE); - dhd_os_wake_unlock(&dhd->pub); - } - } - else - break; - } - - complete_and_exit(&dhd->dpc_exited, 0); -} - -static void -dhd_dpc(ulong data) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)data; - - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) - tasklet_schedule(&dhd->tasklet); - } else { - dhd_bus_stop(dhd->pub.bus, TRUE); - } -} - -void -dhd_sched_dpc(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - dhd_os_wake_lock(dhdp); - if (dhd->dpc_pid >= 0) { - up(&dhd->dpc_sem); - return; - } - - tasklet_schedule(&dhd->tasklet); -} - -#ifdef TOE -/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -static int -dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_GET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = FALSE; - - strcpy(buf, "toe_ol"); - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - /* Check for older dongle image that doesn't support toe_ol */ - if (ret == -EIO) { - DHD_ERROR(("%s: toe not supported by device\n", - dhd_ifname(&dhd->pub, ifidx))); - return -EOPNOTSUPP; - } - - DHD_INFO(("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - memcpy(toe_ol, buf, sizeof(uint32)); - return 0; -} - -/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */ -static int -dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int toe, ret; - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = WLC_SET_VAR; - ioc.buf = buf; - ioc.len = (uint)sizeof(buf); - ioc.set = TRUE; - - /* Set toe_ol as requested */ - - strcpy(buf, "toe_ol"); - memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32)); - - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe_ol: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - /* Enable toe globally only if any components are enabled. */ - - toe = (toe_ol != 0); - - strcpy(buf, "toe"); - memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32)); - - if ((ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { - DHD_ERROR(("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret)); - return ret; - } - - return 0; -} -#endif /* TOE */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -static void dhd_ethtool_get_drvinfo(struct net_device *net, - struct ethtool_drvinfo *info) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - - sprintf(info->driver, "wl"); - sprintf(info->version, "%lu", dhd->pub.drv_version); -} - -struct ethtool_ops dhd_ethtool_ops = { - .get_drvinfo = dhd_ethtool_get_drvinfo -}; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) -static int -dhd_ethtool(dhd_info_t *dhd, void *uaddr) -{ - struct ethtool_drvinfo info; - char drvname[sizeof(info.driver)]; - uint32 cmd; -#ifdef TOE - struct ethtool_value edata; - uint32 toe_cmpnt, csum_dir; - int ret; -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* all ethtool calls start with a cmd word */ - if (copy_from_user(&cmd, uaddr, sizeof (uint32))) - return -EFAULT; - - switch (cmd) { - case ETHTOOL_GDRVINFO: - /* Copy out any request driver name */ - if (copy_from_user(&info, uaddr, sizeof(info))) - return -EFAULT; - strncpy(drvname, info.driver, sizeof(info.driver)); - drvname[sizeof(info.driver)-1] = '\0'; - - /* clear struct for return */ - memset(&info, 0, sizeof(info)); - info.cmd = cmd; - - /* if dhd requested, identify ourselves */ - if (strcmp(drvname, "?dhd") == 0) { - sprintf(info.driver, "dhd"); - strcpy(info.version, EPI_VERSION_STR); - } - - /* otherwise, require dongle to be up */ - else if (!dhd->pub.up) { - DHD_ERROR(("%s: dongle is not up\n", __FUNCTION__)); - return -ENODEV; - } - - /* finally, report dongle driver type */ - else if (dhd->pub.iswl) - sprintf(info.driver, "wl"); - else - sprintf(info.driver, "xx"); - - sprintf(info.version, "%lu", dhd->pub.drv_version); - if (copy_to_user(uaddr, &info, sizeof(info))) - return -EFAULT; - DHD_CTL(("%s: given %*s, returning %s\n", __FUNCTION__, - (int)sizeof(drvname), drvname, info.driver)); - break; - -#ifdef TOE - /* Get toe offload components from dongle */ - case ETHTOOL_GRXCSUM: - case ETHTOOL_GTXCSUM: - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - edata.cmd = cmd; - edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; - - if (copy_to_user(uaddr, &edata, sizeof(edata))) - return -EFAULT; - break; - - /* Set toe offload components in dongle */ - case ETHTOOL_SRXCSUM: - case ETHTOOL_STXCSUM: - if (copy_from_user(&edata, uaddr, sizeof(edata))) - return -EFAULT; - - /* Read the current settings, update and write back */ - if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) - return ret; - - csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - if (edata.data != 0) - toe_cmpnt |= csum_dir; - else - toe_cmpnt &= ~csum_dir; - - if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0) - return ret; - - /* If setting TX checksum mode, tell Linux the new mode */ - if (cmd == ETHTOOL_STXCSUM) { - if (edata.data) - dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM; - } - - break; -#endif /* TOE */ - - default: - return -EOPNOTSUPP; - } - - return 0; -} -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - -static int -dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_ioctl_t ioc; - int bcmerror = 0; - int buflen = 0; - void *buf = NULL; - uint driver = 0; - int ifidx; - bool is_set_key_cmd; - int ret; - - dhd_os_wake_lock(&dhd->pub); - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd)); - - if (ifidx == DHD_BAD_IF) { - dhd_os_wake_unlock(&dhd->pub); - return -1; - } - -#if defined(CONFIG_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - ret = wl_iw_ioctl(net, ifr, cmd); - dhd_os_wake_unlock(&dhd->pub); - return ret; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) - if (cmd == SIOCETHTOOL) { - ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); - dhd_os_wake_unlock(&dhd->pub); - return ret; - } -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - - if (cmd != SIOCDEVPRIVATE) { - dhd_os_wake_unlock(&dhd->pub); - return -EOPNOTSUPP; - } - - memset(&ioc, 0, sizeof(ioc)); - - /* Copy the ioc control structure part of ioctl request */ - if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { - bcmerror = -BCME_BADADDR; - goto done; - } - - /* Copy out any buffer passed */ - if (ioc.buf) { - buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); - /* optimization for direct ioctl calls from kernel */ - /* - if (segment_eq(get_fs(), KERNEL_DS)) { - buf = ioc.buf; - } else { - */ - { - if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) { - bcmerror = -BCME_NOMEM; - goto done; - } - if (copy_from_user(buf, ioc.buf, buflen)) { - bcmerror = -BCME_BADADDR; - goto done; - } - } - } - - /* To differentiate between wl and dhd read 4 more byes */ - if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), - sizeof(uint)) != 0)) { - bcmerror = -BCME_BADADDR; - goto done; - } - - if (!capable(CAP_NET_ADMIN)) { - bcmerror = -BCME_EPERM; - goto done; - } - - /* check for local dhd ioctl and handle it */ - if (driver == DHD_IOCTL_MAGIC) { - bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); - if (bcmerror) - dhd->pub.bcmerror = bcmerror; - goto done; - } - - /* send to dongle (must be up, and wl) */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - DHD_ERROR(("%s DONGLE_DOWN\n", __FUNCTION__)); - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - if (!dhd->pub.iswl) { - bcmerror = BCME_DONGLE_DOWN; - goto done; - } - - /* Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to - * prevent M4 encryption. - */ - is_set_key_cmd = ((ioc.cmd == WLC_SET_KEY) || - ((ioc.cmd == WLC_SET_VAR) && - !(strncmp("wsec_key", ioc.buf, 9))) || - ((ioc.cmd == WLC_SET_VAR) && - !(strncmp("bsscfg:wsec_key", ioc.buf, 15)))); - if (is_set_key_cmd) { - dhd_wait_pend8021x(net); - } - - bcmerror = dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); - -done: - if ((bcmerror == -ETIMEDOUT) || ((dhd->pub.busstate == DHD_BUS_DOWN) && - (!dhd->pub.dongle_reset))) { - DHD_ERROR(("%s: Event HANG send up\n", __FUNCTION__)); - net_os_send_hang_message(net); - } - - if (!bcmerror && buf && ioc.buf) { - if (copy_to_user(ioc.buf, buf, buflen)) - bcmerror = -EFAULT; - } - - if (buf) - MFREE(dhd->pub.osh, buf, buflen); - - dhd_os_wake_unlock(&dhd->pub); - - return OSL_ERROR(bcmerror); -} - -static int -dhd_stop(struct net_device *net) -{ -#if !defined(IGNORE_ETH0_DOWN) - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - - DHD_TRACE(("%s: Enter %s\n", __FUNCTION__, net->name)); - if (dhd->pub.up == 0) { - return 0; - } - - /* Set state and stop OS transmissions */ - dhd->pub.up = 0; - netif_stop_queue(net); -#else - DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation ...\n", __FUNCTION__)); -#endif /* !defined(IGNORE_ETH0_DOWN) */ - - OLD_MOD_DEC_USE_COUNT; - return 0; -} - -static int -dhd_open(struct net_device *net) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -#ifdef TOE - uint32 toe_ol; -#endif - int ifidx; - - /* Force start if ifconfig_up gets called before START command */ - wl_control_wl_start(net); - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - if ((dhd->iflist[ifidx]) && (dhd->iflist[ifidx]->state == WLC_E_IF_DEL)) { - DHD_ERROR(("%s: Error: called when IF already deleted\n", __FUNCTION__)); - return -1; - } - - if (ifidx == 0) { /* do it only for primary eth0 */ - - atomic_set(&dhd->pend_8021x_cnt, 0); - - memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); - -#ifdef TOE - /* Get current TOE mode from dongle */ - if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM; - else - dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM; -#endif - } - /* Allow transmit calls */ - netif_start_queue(net); - dhd->pub.up = 1; - - OLD_MOD_INC_USE_COUNT; - return 0; -} - -osl_t * -dhd_osl_attach(void *pdev, uint bustype) -{ - return osl_attach(pdev, bustype, TRUE); -} - -void -dhd_osl_detach(osl_t *osh) -{ - if (MALLOCED(osh)) { - DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh))); - } - osl_detach(osh); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1 - up(&dhd_registration_sem); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -} - -int -dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, - uint8 *mac_addr, uint32 flags, uint8 bssidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d, handle->%p\n", __FUNCTION__, ifidx, handle)); - - ASSERT(dhd && (ifidx < DHD_MAX_IFS)); - - ifp = dhd->iflist[ifidx]; - if (!ifp && !(ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t)))) { - DHD_ERROR(("%s: OOM - dhd_if_t\n", __FUNCTION__)); - return -ENOMEM; - } - - memset(ifp, 0, sizeof(dhd_if_t)); - ifp->info = dhd; - dhd->iflist[ifidx] = ifp; - strncpy(ifp->name, name, IFNAMSIZ); - ifp->name[IFNAMSIZ] = '\0'; - if (mac_addr != NULL) - memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); - - if (handle == NULL) { - ifp->state = WLC_E_IF_ADD; - ifp->idx = ifidx; - ASSERT(dhd->sysioc_pid >= 0); - up(&dhd->sysioc_sem); - } else - ifp->net = (struct net_device *)handle; - - return 0; -} - -void -dhd_del_if(dhd_info_t *dhd, int ifidx) -{ - dhd_if_t *ifp; - - DHD_TRACE(("%s: idx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS)); - ifp = dhd->iflist[ifidx]; - if (!ifp) { - DHD_ERROR(("%s: Null interface\n", __FUNCTION__)); - return; - } - - ifp->state = WLC_E_IF_DEL; - ifp->idx = ifidx; - ASSERT(dhd->sysioc_pid >= 0); - up(&dhd->sysioc_sem); -} - - -dhd_pub_t * -dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) -{ - dhd_info_t *dhd = NULL; - struct net_device *net; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - /* updates firmware nvram path if it was provided as module paramters */ - if ((firmware_path != NULL) && (firmware_path[0] != '\0')) - strcpy(fw_path, firmware_path); - if ((nvram_path != NULL) && (nvram_path[0] != '\0')) - strcpy(nv_path, nvram_path); - - /* Allocate etherdev, including space for private structure */ - if (!(net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - goto fail; - } - - /* Allocate primary dhd_info */ - if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) { - DHD_ERROR(("%s: OOM - alloc dhd_info\n", __FUNCTION__)); - goto fail; - } - - memset(dhd, 0, sizeof(dhd_info_t)); - - /* - * Save the dhd_info into the priv - */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - dhd->pub.osh = osh; - - /* Set network interface name if it was provided as module parameter */ - if (iface_name[0]) { - int len; - char ch; - strncpy(net->name, iface_name, IFNAMSIZ); - net->name[IFNAMSIZ - 1] = 0; - len = strlen(net->name); - ch = net->name[len - 1]; - if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) - strcat(net->name, "%d"); - } - - if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF) - goto fail; - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - - init_MUTEX(&dhd->proto_sem); - /* Initialize other structure content */ - init_waitqueue_head(&dhd->ioctl_resp_wait); - init_waitqueue_head(&dhd->ctrl_wait); - - /* Initialize the spinlocks */ - spin_lock_init(&dhd->sdlock); - spin_lock_init(&dhd->txqlock); - spin_lock_init(&dhd->dhd_lock); - - /* Initialize Wakelock stuff */ - spin_lock_init(&dhd->wl_lock); - dhd->wl_count = 0; - dhd->wl_packet = 0; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); - wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_init(&dhd->wl_start_lock); -#endif - /* Link to info module */ - dhd->pub.info = dhd; - - /* Link to bus module */ - dhd->pub.bus = bus; - dhd->pub.hdrlen = bus_hdrlen; - - /* Attach and link in the protocol */ - if (dhd_prot_attach(&dhd->pub) != 0) { - DHD_ERROR(("dhd_prot_attach failed\n")); - goto fail; - } -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - /* Set up the watchdog timer */ - init_timer(&dhd->timer); - dhd->timer.data = (ulong)dhd; - dhd->timer.function = dhd_watchdog; - - /* Initialize thread based operation and lock */ - init_MUTEX(&dhd->sdsem); - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) { - dhd->threads_only = TRUE; - } - else { - dhd->threads_only = FALSE; - } - - if (dhd_dpc_prio >= 0) { - /* Initialize watchdog thread */ - sema_init(&dhd->watchdog_sem, 0); - init_completion(&dhd->watchdog_exited); - dhd->watchdog_pid = kernel_thread(dhd_watchdog_thread, dhd, 0); - } else { - dhd->watchdog_pid = -1; - } - - /* Set up the bottom half handler */ - if (dhd_dpc_prio >= 0) { - /* Initialize DPC thread */ - sema_init(&dhd->dpc_sem, 0); - init_completion(&dhd->dpc_exited); - dhd->dpc_pid = kernel_thread(dhd_dpc_thread, dhd, 0); - } else { - tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); - dhd->dpc_pid = -1; - } - - if (dhd_sysioc) { - sema_init(&dhd->sysioc_sem, 0); - init_completion(&dhd->sysioc_exited); - dhd->sysioc_pid = kernel_thread(_dhd_sysioc_thread, dhd, 0); - } else { - dhd->sysioc_pid = -1; - } - - /* - * Save the dhd_info into the priv - */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - g_bus = bus; -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - register_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - -#ifdef CONFIG_HAS_EARLYSUSPEND - dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; - dhd->early_suspend.suspend = dhd_early_suspend; - dhd->early_suspend.resume = dhd_late_resume; - register_early_suspend(&dhd->early_suspend); -#endif - - register_inetaddr_notifier(&dhd_notifier); - - return &dhd->pub; - -fail: - if (net) - free_netdev(net); - if (dhd) - dhd_detach(&dhd->pub); - - return NULL; -} - - -int -dhd_bus_start(dhd_pub_t *dhdp) -{ - int ret = -1; - dhd_info_t *dhd = (dhd_info_t*)dhdp->info; -#ifdef EMBEDDED_PLATFORM - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -#endif /* EMBEDDED_PLATFORM */ - - ASSERT(dhd); - - DHD_TRACE(("%s: \n", __FUNCTION__)); - - dhd_os_sdlock(dhdp); - - /* try to download image and nvram to the dongle */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, - fw_path, nv_path))) { - DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n", - __FUNCTION__, fw_path, nv_path)); - dhd_os_sdunlock(dhdp); - return -1; - } - } - - /* Start the watchdog timer */ - dhd->pub.tickcnt = 0; - dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); - - /* Bring up the bus */ - if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) { - DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret)); - dhd_os_sdunlock(dhdp); - return ret; - } -#if defined(OOB_INTR_ONLY) - /* Host registration for OOB interrupt */ - if (bcmsdh_register_oob_intr(dhdp)) { - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__)); - dhd_os_sdunlock(dhdp); - return -ENODEV; - } - - /* Enable oob at firmware */ - dhd_enable_oob_intr(dhd->pub.bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - - /* If bus is not ready, can't come up */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__)); - dhd_os_sdunlock(dhdp); - return -ENODEV; - } - - dhd_os_sdunlock(dhdp); - -#ifdef EMBEDDED_PLATFORM - bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, dhdp->eventmask, WL_EVENTING_MASK_LEN); - - setbit(dhdp->eventmask, WLC_E_SET_SSID); - setbit(dhdp->eventmask, WLC_E_PRUNE); - setbit(dhdp->eventmask, WLC_E_AUTH); - setbit(dhdp->eventmask, WLC_E_REASSOC); - setbit(dhdp->eventmask, WLC_E_REASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DEAUTH_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC); - setbit(dhdp->eventmask, WLC_E_JOIN); - setbit(dhdp->eventmask, WLC_E_ASSOC_IND); - setbit(dhdp->eventmask, WLC_E_PSK_SUP); - setbit(dhdp->eventmask, WLC_E_LINK); - setbit(dhdp->eventmask, WLC_E_NDIS_LINK); - setbit(dhdp->eventmask, WLC_E_MIC_ERROR); - setbit(dhdp->eventmask, WLC_E_PMKID_CACHE); - setbit(dhdp->eventmask, WLC_E_TXFAIL); - setbit(dhdp->eventmask, WLC_E_JOIN_START); - setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE); - setbit(dhdp->eventmask, WLC_E_RELOAD); -#ifdef PNO_SUPPORT - setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND); -#endif /* PNO_SUPPORT */ - -/* enable dongle roaming event */ - setbit(dhdp->eventmask, WLC_E_ROAM); - - dhdp->pktfilter_count = 1; - /* Setup filter to allow only unicast */ - dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00"; -#endif /* EMBEDDED_PLATFORM */ - - /* Bus is ready, do any protocol initialization */ - if ((ret = dhd_prot_init(&dhd->pub)) < 0) - return ret; - - return 0; -} - -int -dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set) -{ - char buf[strlen(name) + 1 + cmd_len]; - int len = sizeof(buf); - wl_ioctl_t ioc; - int ret; - - len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len); - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR; - ioc.buf = buf; - ioc.len = len; - ioc.set = set; - - ret = dhd_prot_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); - if (!set && ret >= 0) - memcpy(cmd_buf, buf, cmd_len); - - return ret; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) -static struct net_device_ops dhd_ops_pri = { - .ndo_open = dhd_open, - .ndo_stop = dhd_stop, - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; - -static struct net_device_ops dhd_ops_virt = { - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list, -}; -#endif - -static int dhd_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; - dhd_info_t *dhd; - dhd_pub_t *dhd_pub; - - if (!ifa) - return NOTIFY_DONE; - - dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev); - dhd_pub = &dhd->pub; - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) - if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) { -#else - if (ifa->ifa_dev->dev->open == &dhd_open) { -#endif - switch (event) { - case NETDEV_UP: - DHD_TRACE(("%s: [%s] Up IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - - dhd_arp_cleanup(dhd_pub); - break; - - case NETDEV_DOWN: - DHD_TRACE(("%s: [%s] Down IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - - dhd_arp_cleanup(dhd_pub); - break; - - default: - DHD_TRACE(("%s: [%s] Event: %lu\n", - __FUNCTION__, ifa->ifa_label, event)); - break; - } - } - return NOTIFY_DONE; -} - -int -dhd_net_attach(dhd_pub_t *dhdp, int ifidx) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - struct net_device *net; - uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 }; - - DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); - - ASSERT(dhd && dhd->iflist[ifidx]); - net = dhd->iflist[ifidx]->net; - - ASSERT(net); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - ASSERT(!net->open); - net->get_stats = dhd_get_stats; - net->do_ioctl = dhd_ioctl_entry; - net->hard_start_xmit = dhd_start_xmit; - net->set_mac_address = dhd_set_mac_address; - net->set_multicast_list = dhd_set_multicast_list; - net->open = net->stop = NULL; -#else - ASSERT(!net->netdev_ops); - net->netdev_ops = &dhd_ops_virt; -#endif - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = dhd_open; - net->stop = dhd_stop; -#else - net->netdev_ops = &dhd_ops_pri; -#endif - - /* - * We have to use the primary MAC for virtual interfaces - */ - if (ifidx != 0) { - /* for virtual interfaces use the primary MAC */ - memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); - } - - if (ifidx == 1) { - DHD_TRACE(("%s ACCESS POINT MAC: \n", __FUNCTION__)); - /* ACCESSPOINT INTERFACE CASE */ - temp_addr[0] |= 0x02; /* set bit 2 , - Locally Administered address */ - } - net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) - net->ethtool_ops = &dhd_ethtool_ops; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ - -#if defined(CONFIG_WIRELESS_EXT) -#if WIRELESS_EXT < 19 - net->get_wireless_stats = dhd_get_wireless_stats; -#endif /* WIRELESS_EXT < 19 */ -#if WIRELESS_EXT > 12 - net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def; -#endif /* WIRELESS_EXT > 12 */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen; - - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - - if (register_netdev(net) != 0) { - DHD_ERROR(("%s: couldn't register the net device\n", __FUNCTION__)); - goto fail; - } - - printf("%s: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", net->name, - dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2], - dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]); - - -#if defined(CONFIG_WIRELESS_EXT) -#if defined(CONFIG_FIRST_SCAN) -#ifdef SOFTAP - if (ifidx == 0) - /* Don't call for SOFTAP Interface in SOFTAP MODE */ - wl_iw_iscan_set_scan_broadcast_prep(net, 1); -#else - wl_iw_iscan_set_scan_broadcast_prep(net, 1); -#endif /* SOFTAP */ -#endif /* CONFIG_FIRST_SCAN */ -#endif /* CONFIG_WIRELESS_EXT */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - up(&dhd_registration_sem); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - return 0; - -fail: -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - return BCME_ERROR; -} - -void -dhd_bus_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) { - /* Stop the protocol module */ - dhd_prot_stop(&dhd->pub); - - /* Stop the bus module */ - dhd_bus_stop(dhd->pub.bus, TRUE); -#if defined(OOB_INTR_ONLY) - bcmsdh_unregister_oob_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - - /* Clear the watchdog timer */ - dhd->wd_timer_valid = FALSE; - del_timer_sync(&dhd->timer); - } - } -} - -void -dhd_detach(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhdp) { - dhd = (dhd_info_t *)dhdp->info; - if (dhd) { - dhd_if_t *ifp; - int i; - - unregister_inetaddr_notifier(&dhd_notifier); - -#if defined(CONFIG_HAS_EARLYSUSPEND) - if (dhd->early_suspend.suspend) - unregister_early_suspend(&dhd->early_suspend); -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - wl_iw_detach(); -#endif - if (dhd->sysioc_pid >= 0) { - KILL_PROC(dhd->sysioc_pid, SIGTERM); - wait_for_completion(&dhd->sysioc_exited); - } - - for (i = 1; i < DHD_MAX_IFS; i++) - if (dhd->iflist[i]) { - dhd->iflist[i]->state = WLC_E_IF_DEL; - dhd->iflist[i]->idx = i; - dhd_op_if(dhd->iflist[i]); - } - - ifp = dhd->iflist[0]; - ASSERT(ifp); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - if (ifp->net->open) { -#else - if (ifp->net->netdev_ops == &dhd_ops_pri) { -#endif - dhd_stop(ifp->net); - unregister_netdev(ifp->net); - } - - if (dhd->watchdog_pid >= 0) - { - KILL_PROC(dhd->watchdog_pid, SIGTERM); - wait_for_completion(&dhd->watchdog_exited); - } - - if (dhd->dpc_pid >= 0) - { - KILL_PROC(dhd->dpc_pid, SIGTERM); - wait_for_completion(&dhd->dpc_exited); - } - else - tasklet_kill(&dhd->tasklet); - - dhd_bus_detach(dhdp); - - if (dhdp->prot) - dhd_prot_detach(dhdp); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) - unregister_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ - free_netdev(ifp->net); -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_destroy(&dhd->wl_wifi); - wake_lock_destroy(&dhd->wl_rxwake); -#endif - MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); - MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); - } - } -} - -static void __exit -dhd_module_cleanup(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - dhd_bus_unregister(); -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - wifi_del_dev(); -#endif - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -} - -static int __init -dhd_module_init(void) -{ - int error; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Sanity check on the module parameters */ - do { - /* Both watchdog and DPC as tasklets are ok */ - if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0)) - break; - - /* If both watchdog and DPC are threads, TX must be deferred */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) && dhd_deferred_tx) - break; - - DHD_ERROR(("Invalid module parameters.\n")); - return -EINVAL; - } while (0); - - /* Call customer gpio to turn on power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); - -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - sema_init(&wifi_control_sem, 0); - - error = wifi_add_dev(); - if (error) { - DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); - goto fail_0; - } - - /* Waiting callback after platform_driver_register is done or exit with error */ - if (down_timeout(&wifi_control_sem, msecs_to_jiffies(5000)) != 0) { - error = -EINVAL; - DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); - goto fail_1; - } -#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - sema_init(&dhd_registration_sem, 0); -#endif - - error = dhd_bus_register(); - - if (!error) - printf("\n%s\n", dhd_version); - else { - DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__)); - goto fail_1; - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* - * Wait till MMC sdio_register_driver callback called and made driver attach. - * It's needed to make sync up exit from dhd insmod and - * Kernel MMC sdio device callback registration - */ - if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) { - error = -EINVAL; - DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__)); - goto fail_2; - } -#endif - return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -fail_2: - dhd_bus_unregister(); -#endif -fail_1: -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - wifi_del_dev(); -fail_0: -#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); - - return error; -} - -module_init(dhd_module_init); -module_exit(dhd_module_cleanup); - -/* - * OS specific functions required to implement DHD driver in OS independent way - */ -int -dhd_os_proto_block(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - down(&dhd->proto_sem); - return 1; - } - - return 0; -} - -int -dhd_os_proto_unblock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) { - up(&dhd->proto_sem); - return 1; - } - - return 0; -} - -unsigned int -dhd_os_get_ioctl_resp_timeout(void) -{ - return ((unsigned int)dhd_ioctl_timeout_msec); -} - -void -dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec) -{ - dhd_ioctl_timeout_msec = (int)timeout_msec; -} - -int -dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - DECLARE_WAITQUEUE(wait, current); - int timeout = dhd_ioctl_timeout_msec; - - /* Convert timeout in millsecond to jiffies */ - /* timeout = timeout * HZ / 1000; */ - timeout = msecs_to_jiffies(timeout); - - /* Wait until control frame is available */ - add_wait_queue(&dhd->ioctl_resp_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - smp_mb(); - while (!(*condition) && (!signal_pending(current) && timeout)) { - timeout = schedule_timeout(timeout); - smp_mb(); - } - - if (signal_pending(current)) - *pending = TRUE; - - set_current_state(TASK_RUNNING); - remove_wait_queue(&dhd->ioctl_resp_wait, &wait); - - return timeout; -} - -int -dhd_os_ioctl_resp_wake(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (waitqueue_active(&dhd->ioctl_resp_wait)) { - wake_up_interruptible(&dhd->ioctl_resp_wait); - } - - return 0; -} - -void -dhd_os_wd_timer(void *bus, uint wdtick) -{ - dhd_pub_t *pub = bus; - dhd_info_t *dhd = (dhd_info_t *)pub->info; - unsigned long flags; - int del_timer_flag = FALSE; - - flags = dhd_os_spin_lock(pub); - - /* don't start the wd until fw is loaded */ - if (pub->busstate != DHD_BUS_DOWN) { - if (wdtick) { - dhd_watchdog_ms = (uint)wdtick; - dhd->wd_timer_valid = TRUE; - /* Re arm the timer, at last watchdog period */ - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); - } else if (dhd->wd_timer_valid == TRUE) { - /* Totally stop the timer */ - dhd->wd_timer_valid = FALSE; - del_timer_flag = TRUE; - } - } - dhd_os_spin_unlock(pub, flags); - if (del_timer_flag) { - del_timer_sync(&dhd->timer); - } -} - -void * -dhd_os_open_image(char *filename) -{ - struct file *fp; - - fp = filp_open(filename, O_RDONLY, 0); - /* - * 2.6.11 (FC4) supports filp_open() but later revs don't? - * Alternative: - * fp = open_namei(AT_FDCWD, filename, O_RD, 0); - * ??? - */ - if (IS_ERR(fp)) - fp = NULL; - - return fp; -} - -int -dhd_os_get_image_block(char *buf, int len, void *image) -{ - struct file *fp = (struct file *)image; - int rdlen; - - if (!image) - return 0; - - rdlen = kernel_read(fp, fp->f_pos, buf, len); - if (rdlen > 0) - fp->f_pos += rdlen; - - return rdlen; -} - -void -dhd_os_close_image(void *image) -{ - if (image) - filp_close((struct file *)image, NULL); -} - - -void -dhd_os_sdlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - - if (dhd->threads_only) - down(&dhd->sdsem); - else - spin_lock_bh(&dhd->sdlock); -} - -void -dhd_os_sdunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - - if (dhd->threads_only) - up(&dhd->sdsem); - else - spin_unlock_bh(&dhd->sdlock); -} - -void -dhd_os_sdlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_lock_bh(&dhd->txqlock); -} - -void -dhd_os_sdunlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_unlock_bh(&dhd->txqlock); -} -void -dhd_os_sdlock_rxq(dhd_pub_t *pub) -{ -} -void -dhd_os_sdunlock_rxq(dhd_pub_t *pub) -{ -} - -void -dhd_os_sdtxlock(dhd_pub_t *pub) -{ - dhd_os_sdlock(pub); -} - -void -dhd_os_sdtxunlock(dhd_pub_t *pub) -{ - dhd_os_sdunlock(pub); -} - -#ifdef DHD_USE_STATIC_BUF -void * dhd_os_prealloc(int section, unsigned long size) -{ -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - void *alloc_ptr = NULL; - if (wifi_control_data && wifi_control_data->mem_prealloc) - { - alloc_ptr = wifi_control_data->mem_prealloc(section, size); - if (alloc_ptr) - { - DHD_INFO(("success alloc section %d\n", section)); - bzero(alloc_ptr, size); - return alloc_ptr; - } - } - - DHD_ERROR(("can't alloc section %d\n", section)); - return 0; -#else -return MALLOC(0, size); -#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ -} -#endif /* DHD_USE_STATIC_BUF */ -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics * -dhd_get_wireless_stats(struct net_device *dev) -{ - int res = 0; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats); - - if (res == 0) - return &dhd->iw.wstats; - else - return NULL; -} -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -static int -dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data) -{ - int bcmerror = 0; - - ASSERT(dhd != NULL); - - bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data); - if (bcmerror != BCME_OK) - return (bcmerror); - -#if defined(CONFIG_WIRELESS_EXT) - ASSERT(dhd->iflist[*ifidx] != NULL); - - if (ntoh32(event->event_type) == WLC_E_IF) { - DHD_INFO(("<0> interface:%d OP:%d don't pass to wext," - "net_device might not be created yet\n", - *ifidx, ntoh32(event->event_type))); - return bcmerror; - } - - ASSERT(dhd->iflist[*ifidx]->net != NULL); - - if (dhd->iflist[*ifidx]->net) - wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - return (bcmerror); -} - -/* send up locally generated event */ -void -dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -{ - switch (ntoh32(event->event_type)) { - default: - break; - } -} - -void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - dhd_os_sdunlock(dhd); - wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2); - dhd_os_sdlock(dhd); -#endif - return; -} - -void dhd_wait_event_wakeup(dhd_pub_t *dhd) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - struct dhd_info *dhdinfo = dhd->info; - if (waitqueue_active(&dhdinfo->ctrl_wait)) - wake_up_interruptible(&dhdinfo->ctrl_wait); -#endif - return; -} - -int -dhd_dev_reset(struct net_device *dev, uint8 flag) -{ - int ret; - - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - ret = dhd_bus_devreset(&dhd->pub, flag); - if (ret) { - DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret)); - return ret; - } - DHD_ERROR(("%s: WLAN %s DONE\n", __FUNCTION__, flag ? "OFF" : "ON")); - - return ret; -} - -int net_os_set_suspend_disable(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - ret = dhd->pub.suspend_disable_flag; - dhd->pub.suspend_disable_flag = val; - } - return ret; -} - -int net_os_set_suspend(struct net_device *dev, int val) -{ - int ret = 0; -#if defined(CONFIG_HAS_EARLYSUSPEND) - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) { - dhd_os_proto_block(&dhd->pub); - ret = dhd_set_suspend(val, &dhd->pub); - dhd_os_proto_unblock(&dhd->pub); - } -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - return ret; -} - -int net_os_set_dtim_skip(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) - dhd->pub.dtim_skip = val; - - return 0; -} - -int net_os_set_packet_filter(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - /* Packet filtering is set only if we still in early-suspend and - * we need either to turn it ON or turn it OFF - * We can always turn it OFF in case of early-suspend, but we turn it - * back ON only if suspend_disable_flag was not set - */ - if (dhd && dhd->pub.up) { - dhd_os_proto_block(&dhd->pub); - if (dhd->pub.in_suspend) { - if (!val || (val && !dhd->pub.suspend_disable_flag)) - dhd_set_packet_filter(val, &dhd->pub); - } - dhd_os_proto_unblock(&dhd->pub); - } - return ret; -} - - -void -dhd_dev_init_ioctl(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - dhd_preinit_ioctls(&dhd->pub); -} - -#ifdef PNO_SUPPORT -/* Linux wrapper to call common dhd_pno_clean */ -int -dhd_dev_pno_reset(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_clean(&dhd->pub)); -} - - -/* Linux wrapper to call common dhd_pno_enable */ -int -dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_enable(&dhd->pub, pfn_enabled)); -} - - -/* Linux wrapper to call common dhd_pno_set */ -int -dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); -} - -/* Linux wrapper to get pno status */ -int -dhd_dev_get_pno_status(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_get_status(&dhd->pub)); -} - -#endif /* PNO_SUPPORT */ - -int net_os_send_hang_message(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - if (!dhd->hang_was_sent) { - dhd->hang_was_sent = 1; - ret = wl_iw_send_priv_event(dev, "HANG"); - } - } - return ret; -} - -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && dhd->pub.up) - memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); -} - -char *dhd_bus_country_get(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd && (dhd->pub.dhd_cspec.ccode[0] != 0)) - return dhd->pub.dhd_cspec.ccode; - return NULL; -} - -void dhd_os_start_lock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - mutex_lock(&dhd->wl_start_lock); -#endif -} - -void dhd_os_start_unlock(dhd_pub_t *pub) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - mutex_unlock(&dhd->wl_start_lock); -#endif -} - -static int -dhd_get_pend_8021x_cnt(dhd_info_t *dhd) -{ - return (atomic_read(&dhd->pend_8021x_cnt)); -} - -#define MAX_WAIT_FOR_8021X_TX 10 - -int -dhd_wait_pend8021x(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int timeout = 10 * HZ / 1000; - int ntimes = MAX_WAIT_FOR_8021X_TX; - int pend = dhd_get_pend_8021x_cnt(dhd); - - while (ntimes && pend) { - if (pend) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); - set_current_state(TASK_RUNNING); - ntimes--; - } - pend = dhd_get_pend_8021x_cnt(dhd); - } - return pend; -} - -#ifdef DHD_DEBUG -int -write_to_file(dhd_pub_t *dhd, uint8 *buf, int size) -{ - int ret = 0; - struct file *fp; - mm_segment_t old_fs; - loff_t pos = 0; - - /* change to KERNEL_DS address limit */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - - /* open file to write */ - fp = filp_open("/tmp/mem_dump", O_WRONLY|O_CREAT, 0640); - if (!fp) { - printf("%s: open file error\n", __FUNCTION__); - ret = -1; - goto exit; - } - - /* Write buf to file */ - fp->f_op->write(fp, buf, size, &pos); - -exit: - /* free buf before return */ - MFREE(dhd->osh, buf, size); - /* close file before return */ - if (fp) - filp_close(fp, current->files); - /* restore previous address limit */ - set_fs(old_fs); - - return ret; -} -#endif /* DHD_DEBUG */ - -int dhd_os_wake_lock_timeout(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - ret = dhd->wl_packet; -#ifdef CONFIG_HAS_WAKELOCK - if (dhd->wl_packet) - wake_lock_timeout(&dhd->wl_rxwake, HZ); -#endif - dhd->wl_packet = 0; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_lock_timeout(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_timeout(&dhd->pub); - return ret; -} - -int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - dhd->wl_packet = 1; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s\n",__func__); */ - return 0; -} - -int net_os_wake_lock_timeout_enable(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock_timeout_enable(&dhd->pub); - return ret; -} - -int dhd_os_wake_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wl_count) - wake_lock(&dhd->wl_wifi); -#endif - dhd->wl_count++; - ret = dhd->wl_count; - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_lock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_lock(&dhd->pub); - return ret; -} - -int dhd_os_wake_unlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - int ret = 0; - - dhd_os_wake_lock_timeout(pub); - if (dhd) { - spin_lock_irqsave(&dhd->wl_lock, flags); - if (dhd->wl_count) { - dhd->wl_count--; -#ifdef CONFIG_HAS_WAKELOCK - if (!dhd->wl_count) - wake_unlock(&dhd->wl_wifi); -#endif - ret = dhd->wl_count; - } - spin_unlock_irqrestore(&dhd->wl_lock, flags); - } - /* printk("%s: %d\n", __FUNCTION__, ret); */ - return ret; -} - -int net_os_wake_unlock(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) - ret = dhd_os_wake_unlock(&dhd->pub); - return ret; -} - -unsigned long dhd_os_spin_lock(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags = 0; - - if (dhd) - spin_lock_irqsave(&dhd->dhd_lock, flags); - - return flags; -} - -void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - - if (dhd) - spin_unlock_irqrestore(&dhd->dhd_lock, flags); -} diff --git a/drivers/net/wireless/bcm4329/dhd_linux_sched.c b/drivers/net/wireless/bcm4329/dhd_linux_sched.c deleted file mode 100644 index 480b416657ee..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_linux_sched.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Expose some of the kernel scheduler routines - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_linux_sched.c,v 1.1.34.1.6.1 2009/01/16 01:17:40 Exp $ - */ -#include -#include -#include -#include - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param) -{ - int rc = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) - rc = sched_setscheduler(p, policy, param); -#endif /* LinuxVer */ - return rc; -} diff --git a/drivers/net/wireless/bcm4329/dhd_proto.h b/drivers/net/wireless/bcm4329/dhd_proto.h deleted file mode 100644 index 7ef6929a5bf7..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_proto.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Header file describing the internal (inter-module) DHD interfaces. - * - * Provides type definitions and function prototypes used to link the - * DHD OS, bus, and protocol modules. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_proto.h,v 1.2.82.1.4.1.16.7 2010/05/10 12:54:59 Exp $ - */ - -#ifndef _dhd_proto_h_ -#define _dhd_proto_h_ - -#include -#include - -#ifndef IOCTL_RESP_TIMEOUT -#define IOCTL_RESP_TIMEOUT 3000 /* In milli second */ -#endif - -#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT -#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */ -#endif - -/* - * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) - */ - -/* Linkage, sets prot link and updates hdrlen in pub */ -extern int dhd_prot_attach(dhd_pub_t *dhdp); - -/* Unlink, frees allocated protocol memory (including dhd_prot) */ -extern void dhd_prot_detach(dhd_pub_t *dhdp); - -/* Initialize protocol: sync w/dongle state. - * Sets dongle media info (iswl, drv_version, mac address). - */ -extern int dhd_prot_init(dhd_pub_t *dhdp); - -/* Stop protocol: sync w/dongle state. */ -extern void dhd_prot_stop(dhd_pub_t *dhdp); - -extern bool dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, uint8 *fcbits); - -/* Add any protocol-specific data header. - * Caller must reserve prot_hdrlen prepend space. - */ -extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); - -/* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp); - -/* Use protocol to issue ioctl to dongle */ -extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len); - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Add prot dump output to a buffer */ -extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); - -/* Update local copy of dongle statistics */ -extern void dhd_prot_dstats(dhd_pub_t *dhdp); - -extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen); - -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); - -/******************************** - * For version-string expansion * - */ -#if defined(BDC) -#define DHD_PROTOCOL "bdc" -#elif defined(CDC) -#define DHD_PROTOCOL "cdc" -#elif defined(RNDIS) -#define DHD_PROTOCOL "rndis" -#else -#define DHD_PROTOCOL "unknown" -#endif /* proto */ - -#endif /* _dhd_proto_h_ */ diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c deleted file mode 100644 index 1380dd389cf6..000000000000 --- a/drivers/net/wireless/bcm4329/dhd_sdio.c +++ /dev/null @@ -1,5823 +0,0 @@ -/* - * DHD Bus Module for SDIO - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.129.4.1 2010/09/02 23:13:16 Exp $ - */ - -#include -#include -#include - -#ifdef BCMEMBEDIMAGE -#include BCMEMBEDIMAGE -#endif /* BCMEMBEDIMAGE */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DHD_DEBUG -#include -#endif /* DHD_DEBUG */ -#ifdef DHD_DEBUG_TRAP -#include -#endif /* DHD_DEBUG_TRAP */ - -#define QLEN 256 /* bulk rx and tx queue lengths */ -#define FCHI (QLEN - 10) -#define FCLOW (FCHI / 2) -#define PRIOMASK 7 - -#define TXRETRIES 2 /* # of retries for tx frames */ - -#if defined(CONFIG_MACH_SANDGATE2G) -#define DHD_RXBOUND 250 /* Default for max rx frames in one scheduling */ -#else -#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */ -#endif /* defined(CONFIG_MACH_SANDGATE2G) */ - -#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */ - -#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ - -#define MEMBLOCK 2048 /* Block size used for downloading of dongle image */ -#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ - -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#ifndef DHD_FIRSTREAD -#define DHD_FIRSTREAD 32 -#endif -#if !ISPOWEROF2(DHD_FIRSTREAD) -#error DHD_FIRSTREAD is not a power of 2! -#endif - -/* Total length of frame header for dongle protocol */ -#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -#ifdef SDTEST -#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN) -#else -#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN) -#endif - -/* Space for header read, limit for data packets */ -#ifndef MAX_HDR_READ -#define MAX_HDR_READ 32 -#endif -#if !ISPOWEROF2(MAX_HDR_READ) -#error MAX_HDR_READ is not a power of 2! -#endif - -#define MAX_RX_DATASZ 2048 - -/* Maximum milliseconds to wait for F2 to come up */ -#define DHD_WAIT_F2RDY 3000 - -/* Bump up limit on waiting for HT to account for first startup; - * if the image is doing a CRC calculation before programming the PMU - * for HT availability, it could take a couple hundred ms more, so - * max out at a 1 second (1000000us). - */ -#if (PMU_MAX_TRANSITION_DLY < 1000000) -#undef PMU_MAX_TRANSITION_DLY -#define PMU_MAX_TRANSITION_DLY 1000000 -#endif - -/* Value for ChipClockCSR during initial setup */ -#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ) -#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP) - -/* Flags for SDH calls */ -#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) - -/* Packet free applicable unconditionally for sdio and sdspi. Conditional if - * bufpool was present for gspi bus. - */ -#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - PKTFREE(bus->dhd->osh, pkt, FALSE); -DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); - -extern void bcmsdh_set_irq(int flag); - -#ifdef DHD_DEBUG -/* Device console log buffer state */ -typedef struct dhd_console { - uint count; /* Poll interval msec counter */ - uint log_addr; /* Log struct address (fixed) */ - hndrte_log_t log; /* Log struct (host copy) */ - uint bufsize; /* Size of log buffer */ - uint8 *buf; /* Log buffer (host copy) */ - uint last; /* Last buffer read index */ -} dhd_console_t; -#endif /* DHD_DEBUG */ - -/* Private data for SDIO bus interaction */ -typedef struct dhd_bus { - dhd_pub_t *dhd; - - bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ - si_t *sih; /* Handle for SI calls */ - char *vars; /* Variables (from CIS and/or other) */ - uint varsz; /* Size of variables buffer */ - uint32 sbaddr; /* Current SB window pointer (-1, invalid) */ - - sdpcmd_regs_t *regs; /* Registers for SDIO core */ - uint sdpcmrev; /* SDIO core revision */ - uint armrev; /* CPU core revision */ - uint ramrev; /* SOCRAM core revision */ - uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */ - uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ - - uint32 bus; /* gSPI or SDIO bus */ - uint32 hostintmask; /* Copy of Host Interrupt Mask */ - uint32 intstatus; /* Intstatus bits (events) pending */ - bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ - bool fcstate; /* State of dongle flow-control */ - - uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ - char *fw_path; /* module_param: path to firmware image */ - char *nv_path; /* module_param: path to nvram vars file */ - const char *nvram_params; /* user specified nvram params. */ - - uint blocksize; /* Block size of SDIO transfers */ - uint roundup; /* Max roundup limit */ - - struct pktq txq; /* Queue length used for flow-control */ - uint8 flowcontrol; /* per prio flow control bitmask */ - uint8 tx_seq; /* Transmit sequence number (next) */ - uint8 tx_max; /* Maximum transmit sequence allowed */ - - uint8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN]; - uint8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ - uint16 nextlen; /* Next Read Len from last header */ - uint8 rx_seq; /* Receive sequence number (expected) */ - bool rxskip; /* Skip receive (awaiting NAK ACK) */ - - void *glomd; /* Packet containing glomming descriptor */ - void *glom; /* Packet chain for glommed superframe */ - uint glomerr; /* Glom packet read errors */ - - uint8 *rxbuf; /* Buffer for receiving control packets */ - uint rxblen; /* Allocated length of rxbuf */ - uint8 *rxctl; /* Aligned pointer into rxbuf */ - uint8 *databuf; /* Buffer for receiving big glom packet */ - uint8 *dataptr; /* Aligned pointer into databuf */ - uint rxlen; /* Length of valid data in buffer */ - - uint8 sdpcm_ver; /* Bus protocol reported by dongle */ - - bool intr; /* Use interrupts */ - bool poll; /* Use polling */ - bool ipend; /* Device interrupt is pending */ - bool intdis; /* Interrupts disabled by isr */ - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ - uint spurious; /* Count of spurious interrupts */ - uint pollrate; /* Ticks between device polls */ - uint polltick; /* Tick counter */ - uint pollcnt; /* Count of active polls */ - -#ifdef DHD_DEBUG - dhd_console_t console; /* Console output polling support */ - uint console_addr; /* Console address from shared struct */ -#endif /* DHD_DEBUG */ - - uint regfails; /* Count of R_REG/W_REG failures */ - - uint clkstate; /* State of sd and backplane clock(s) */ - bool activity; /* Activity flag for clock down */ - int32 idletime; /* Control for activity timeout */ - int32 idlecount; /* Activity timeout counter */ - int32 idleclock; /* How to set bus driver when idle */ - int32 sd_divisor; /* Speed control to bus driver */ - int32 sd_mode; /* Mode control to bus driver */ - int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ - bool use_rxchain; /* If dhd should use PKT chains */ - bool sleeping; /* Is SDIO bus sleeping? */ - bool rxflow_mode; /* Rx flow control mode */ - bool rxflow; /* Is rx flow control on */ - uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */ - bool alp_only; /* Don't use HT clock (ALP only) */ - /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ - bool usebufpool; - -#ifdef SDTEST - /* external loopback */ - bool ext_loop; - uint8 loopid; - - /* pktgen configuration */ - uint pktgen_freq; /* Ticks between bursts */ - uint pktgen_count; /* Packets to send each burst */ - uint pktgen_print; /* Bursts between count displays */ - uint pktgen_total; /* Stop after this many */ - uint pktgen_minlen; /* Minimum packet data len */ - uint pktgen_maxlen; /* Maximum packet data len */ - uint pktgen_mode; /* Configured mode: tx, rx, or echo */ - uint pktgen_stop; /* Number of tx failures causing stop */ - - /* active pktgen fields */ - uint pktgen_tick; /* Tick counter for bursts */ - uint pktgen_ptick; /* Burst counter for printing */ - uint pktgen_sent; /* Number of test packets generated */ - uint pktgen_rcvd; /* Number of test packets received */ - uint pktgen_fail; /* Number of failed send attempts */ - uint16 pktgen_len; /* Length of next packet to send */ -#endif /* SDTEST */ - - /* Some additional counters */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - - uint8 *ctrl_frame_buf; - uint32 ctrl_frame_len; - bool ctrl_frame_stat; -} dhd_bus_t; - -/* clkstate */ -#define CLK_NONE 0 -#define CLK_SDONLY 1 -#define CLK_PENDING 2 /* Not used yet */ -#define CLK_AVAIL 3 - -#define DHD_NOPMU(dhd) (FALSE) - -#ifdef DHD_DEBUG -static int qcount[NUMPRIO]; -static int tx_packets[NUMPRIO]; -#endif /* DHD_DEBUG */ - -/* Deferred transmit */ -const uint dhd_deferred_tx = 1; - -extern uint dhd_watchdog_ms; -extern void dhd_os_wd_timer(void *bus, uint wdtick); - -/* Tx/Rx bounds */ -uint dhd_txbound; -uint dhd_rxbound; -uint dhd_txminmax; - -/* override the RAM size if possible */ -#define DONGLE_MIN_MEMSIZE (128 *1024) -int dhd_dongle_memsize; - -static bool dhd_doflow; -static bool dhd_alignctl; - -static bool sd1idle; - -static bool retrydata; -#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) - -static const uint watermark = 8; -static const uint firstread = DHD_FIRSTREAD; - -#define HDATLEN (firstread - (SDPCM_HDRLEN)) - -/* Retry count for register access failures */ -static const uint retry_limit = 2; - -/* Force even SD lengths (some host controllers mess up on odd bytes) */ -static bool forcealign; - -#define ALIGNMENT 4 - -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); -#endif - -#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) -#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD -#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -#define PKTALIGN(osh, p, len, align) \ - do { \ - uint datalign; \ - datalign = (uintptr)PKTDATA((osh), (p)); \ - datalign = ROUNDUP(datalign, (align)) - datalign; \ - ASSERT(datalign < (align)); \ - ASSERT(PKTLEN((osh), (p)) >= ((len) + datalign)); \ - if (datalign) \ - PKTPULL((osh), (p), datalign); \ - PKTSETLEN((osh), (p), (len)); \ - } while (0) - -/* Limit on rounding up frames */ -static const uint max_roundup = 512; - -/* Try doing readahead */ -static bool dhd_readahead; - - -/* To check if there's window offered */ -#define DATAOK(bus) \ - (((uint8)(bus->tx_max - bus->tx_seq) != 0) && \ - (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) - -/* Macros to get register read/write status */ -/* NOTE: these assume a local dhdsdio_bus_t *bus! */ -#define R_SDREG(regvar, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - regvar = R_REG(bus->dhd->osh, regaddr); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) { \ - DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - regvar = 0; \ - } \ - } \ -} while (0) - -#define W_SDREG(regval, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - W_REG(bus->dhd->osh, regaddr, regval); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) \ - DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \ - __FUNCTION__, __LINE__)); \ - } \ -} while (0) - - -#define DHD_BUS SDIO_BUS - -#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) - -#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) - -#define GSPI_PR55150_BAILOUT - - -#ifdef SDTEST -static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); -static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start); -#endif - -#ifdef DHD_DEBUG_TRAP -static int dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size); -#endif /* DHD_DEBUG_TRAP */ -static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); - -static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_disconnect(void *ptr); -static bool dhdsdio_chipmatch(uint16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh, - void * regsva, uint16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag); - -static uint process_nvram_vars(char *varbuf, uint len); - -static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); - -static bool dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh); -static int _dhdsdio_download_firmware(struct dhd_bus *bus); - -static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path); -static int dhdsdio_download_nvram(struct dhd_bus *bus); -#ifdef BCMEMBEDIMAGE -static int dhdsdio_download_code_array(struct dhd_bus *bus); -#endif - - -static void -dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) -{ - int32 min_size = DONGLE_MIN_MEMSIZE; - /* Restrict the memsize to user specified limit */ - DHD_ERROR(("user: Restrict the dongle ram size to %d, min accepted %d\n", - dhd_dongle_memsize, min_size)); - if ((dhd_dongle_memsize > min_size) && - (dhd_dongle_memsize < (int32)bus->orig_ramsize)) - bus->ramsize = dhd_dongle_memsize; -} - -static int -dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address) -{ - int err = 0; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); - return err; -} - - -/* Turn backplane clock on or off */ -static int -dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) -{ - int err; - uint8 clkctl, clkreq, devctl; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#if defined(OOB_INTR_ONLY) - pendok = FALSE; -#endif - clkctl = 0; - sdh = bus->sdh; - - - if (on) { - /* Request HT Avail */ - clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - - if ((bus->sih->chip == BCM4329_CHIP_ID) && (bus->sih->chiprev == 0)) - clkreq |= SBSDIO_FORCE_ALP; - - - - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - - if (pendok && - ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) { - uint32 dummy, retries; - R_SDREG(dummy, &bus->regs->clockctlstatus, retries); - } - - /* Check current status */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: HT Avail read error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - - /* Go to pending and await interrupt if appropriate */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { - /* Allow only clock-available interrupt */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: Devctl access error setting CA: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - DHD_INFO(("CLKCTL: set PENDING\n")); - bus->clkstate = CLK_PENDING; - return BCME_OK; - } else if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - /* Otherwise, wait here (polling) for HT Avail */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - ((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, &err)), - !SBSDIO_CLKAV(clkctl, bus->alp_only)), PMU_MAX_TRANSITION_DLY); - } - if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); - return BCME_ERROR; - } - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n", - __FUNCTION__, PMU_MAX_TRANSITION_DLY, clkctl)); - return BCME_ERROR; - } - - - /* Mark clock available */ - bus->clkstate = CLK_AVAIL; - DHD_INFO(("CLKCTL: turned ON\n")); - -#if defined(DHD_DEBUG) - if (bus->alp_only == TRUE) { -#if !defined(BCMLXSDMMC) - if (!SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock, when ALP Only\n", __FUNCTION__)); - } -#endif /* !defined(BCMLXSDMMC) */ - } else { - if (SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock should be on.\n", __FUNCTION__)); - } - } -#endif /* defined (DHD_DEBUG) */ - - bus->activity = TRUE; - } else { - clkreq = 0; - - if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } - - bus->clkstate = CLK_SDONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - DHD_INFO(("CLKCTL: turned OFF\n")); - if (err) { - DHD_ERROR(("%s: Failed access turning clock off: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - return BCME_OK; -} - -/* Change idle/active SD state */ -static int -dhdsdio_sdclk(dhd_bus_t *bus, bool on) -{ - int err; - int32 iovalue; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (on) { - if (bus->idleclock == DHD_IDLE_STOP) { - /* Turn on clock and restore mode */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error enabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - - iovalue = bus->sd_mode; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_mode: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Restore clock speed */ - iovalue = bus->sd_divisor; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error restoring sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_SDONLY; - } else { - /* Stop or slow the SD clock itself */ - if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { - DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n", - __FUNCTION__, bus->sd_divisor, bus->sd_mode)); - return BCME_ERROR; - } - if (bus->idleclock == DHD_IDLE_STOP) { - if (sd1idle) { - /* Change to SD1 mode and turn off clock */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - - iovalue = 0; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error disabling sd_clock: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Set divisor to idle value */ - iovalue = bus->idleclock; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), TRUE); - if (err) { - DHD_ERROR(("%s: error changing sd_divisor: %d\n", - __FUNCTION__, err)); - return BCME_ERROR; - } - } - bus->clkstate = CLK_NONE; - } - - return BCME_OK; -} - -/* Transition SD and backplane clock readiness */ -static int -dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) -{ - int ret = BCME_OK; -#ifdef DHD_DEBUG - uint oldstate = bus->clkstate; -#endif /* DHD_DEBUG */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Early exit if we're already there */ - if (bus->clkstate == target) { - if (target == CLK_AVAIL) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - return ret; - } - - switch (target) { - case CLK_AVAIL: - /* Make sure SD clock is available */ - if (bus->clkstate == CLK_NONE) - dhdsdio_sdclk(bus, TRUE); - /* Now request HT Avail on the backplane */ - ret = dhdsdio_htclk(bus, TRUE, pendok); - if (ret == BCME_OK) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; - } - break; - - case CLK_SDONLY: - /* Remove HT request, or bring up SD clock */ - if (bus->clkstate == CLK_NONE) - ret = dhdsdio_sdclk(bus, TRUE); - else if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - else - DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n", - bus->clkstate, target)); - if (ret == BCME_OK) - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - break; - - case CLK_NONE: - /* Make sure to remove HT request */ - if (bus->clkstate == CLK_AVAIL) - ret = dhdsdio_htclk(bus, FALSE, FALSE); - /* Now remove the SD clock */ - ret = dhdsdio_sdclk(bus, FALSE); - dhd_os_wd_timer(bus->dhd, 0); - break; - } -#ifdef DHD_DEBUG - DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate)); -#endif /* DHD_DEBUG */ - - return ret; -} - -int -dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n", - (sleep ? "SLEEP" : "WAKE"), - (bus->sleeping ? "SLEEP" : "WAKE"))); - - /* Done if we're already in the requested state */ - if (sleep == bus->sleeping) - return BCME_OK; - - /* Going to sleep: set the alarm and turn off the lights... */ - if (sleep) { - /* Don't sleep if something is pending */ - if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) - return BCME_BUSY; - - - /* Disable SDIO interrupts (no longer interested) */ - bcmsdh_intr_disable(bus->sdh); - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); - - /* Isolate the bus */ - if (bus->sih->chip != BCM4329_CHIP_ID && bus->sih->chip != BCM4319_CHIP_ID) { - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); - } - - /* Change state */ - bus->sleeping = TRUE; - - } else { - /* Waking up: bus power up is ok, set local state */ - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); - - /* Force pad isolation off if possible (in case power never toggled) */ - if ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev >= 10)) - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); - - - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); - - /* Make sure we have SD bus access */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Change state */ - bus->sleeping = FALSE; - - /* Enable interrupts again */ - if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { - bus->intdis = FALSE; - bcmsdh_intr_enable(bus->sdh); - } - } - - return BCME_OK; -} -#if defined(OOB_INTR_ONLY) -void -dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) -{ -#if defined(HW_OOB) - bcmsdh_enable_hw_oob_intr(bus->sdh, enable); -#else - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (enable == TRUE) { - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - } else { - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - } - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -#endif /* !defined(HW_OOB) */ -} -#endif /* defined(OOB_INTR_ONLY) */ - -#define BUS_WAKE(bus) \ - do { \ - if ((bus)->sleeping) \ - dhdsdio_bussleep((bus), FALSE); \ - } while (0); - - -/* Writes a HW/SW header into the packet and sends it. */ -/* Assumes: (a) header space already there, (b) caller holds lock */ -static int -dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) -{ - int ret; - osl_t *osh; - uint8 *frame; - uint16 len, pad = 0; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh; - void *new; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - sdh = bus->sdh; - osh = bus->dhd->osh; - - if (bus->dhd->dongle_reset) { - ret = BCME_NOTREADY; - goto done; - } - - frame = (uint8*)PKTDATA(osh, pkt); - - /* Add alignment padding, allocate new packet if needed */ - if ((pad = ((uintptr)frame % DHD_SDALIGN))) { - if (PKTHEADROOM(osh, pkt) < pad) { - DHD_INFO(("%s: insufficient headroom %d for %d pad\n", - __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad)); - bus->dhd->tx_realloc++; - new = PKTGET(osh, (PKTLEN(osh, pkt) + DHD_SDALIGN), TRUE); - if (!new) { - DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", - __FUNCTION__, PKTLEN(osh, pkt) + DHD_SDALIGN)); - ret = BCME_NOMEM; - goto done; - } - - PKTALIGN(osh, new, PKTLEN(osh, pkt), DHD_SDALIGN); - bcopy(PKTDATA(osh, pkt), PKTDATA(osh, new), PKTLEN(osh, pkt)); - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - /* free the pkt if canned one is not used */ - free_pkt = TRUE; - pkt = new; - frame = (uint8*)PKTDATA(osh, pkt); - ASSERT(((uintptr)frame % DHD_SDALIGN) == 0); - pad = 0; - } else { - PKTPUSH(osh, pkt, pad); - frame = (uint8*)PKTDATA(osh, pkt); - - ASSERT((pad + SDPCM_HDRLEN) <= (int) PKTLEN(osh, pkt)); - bzero(frame, pad + SDPCM_HDRLEN); - } - } - ASSERT(pad < DHD_SDALIGN); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - len = (uint16)PKTLEN(osh, pkt); - *(uint16*)frame = htol16(len); - *(((uint16*)frame) + 1) = htol16(~len); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | - (((pad + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - -#ifdef DHD_DEBUG - tx_packets[PKTPRIO(pkt)]++; - if (DHD_BYTES_ON() && - (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - /* Raise len to next SDIO block to eliminate tail command */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) -#ifdef NOTUSED - if (pad <= PKTTAILROOM(osh, pkt)) -#endif /* NOTUSED */ - len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Some controllers have trouble with odd bytes -- round to even */ - if (forcealign && (len & (ALIGNMENT - 1))) { -#ifdef NOTUSED - if (PKTTAILROOM(osh, pkt)) -#endif - len = ROUNDUP(len, ALIGNMENT); -#ifdef NOTUSED - else - DHD_ERROR(("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len)); -#endif - } - - do { - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, pkt, NULL, NULL); - bus->f2txdata++; - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retrydata && retries++ < TXRETRIES); - -done: - /* restore pkt buffer pointer before calling tx complete routine */ - PKTPULL(osh, pkt, SDPCM_HDRLEN + pad); - dhd_os_sdunlock(bus->dhd); - dhd_txcomplete(bus->dhd, pkt, ret != 0); - dhd_os_sdlock(bus->dhd); - - if (free_pkt) - PKTFREE(osh, pkt, TRUE); - - return ret; -} - -int -dhd_bus_txdata(struct dhd_bus *bus, void *pkt) -{ - int ret = BCME_ERROR; - osl_t *osh; - uint datalen, prec; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - osh = bus->dhd->osh; - datalen = PKTLEN(osh, pkt); - -#ifdef SDTEST - /* Push the test header if doing loopback */ - if (bus->ext_loop) { - uint8* data; - PKTPUSH(osh, pkt, SDPCM_TEST_HDRLEN); - data = PKTDATA(osh, pkt); - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->loopid++; - *data++ = (datalen >> 0); - *data++ = (datalen >> 8); - datalen += SDPCM_TEST_HDRLEN; - } -#endif /* SDTEST */ - - /* Add space for the header */ - PKTPUSH(osh, pkt, SDPCM_HDRLEN); - ASSERT(ISALIGNED((uintptr)PKTDATA(osh, pkt), 2)); - - prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); - - - /* Check for existing queue, current flow-control, pending event, or pending clock */ - if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched || - (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || - (bus->clkstate != CLK_AVAIL)) { - DHD_TRACE(("%s: deferring pktq len %d\n", __FUNCTION__, - pktq_len(&bus->txq))); - bus->fcqueued++; - - /* Priority based enq */ - dhd_os_sdlock_txq(bus->dhd); - if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == FALSE) { - PKTPULL(osh, pkt, SDPCM_HDRLEN); - dhd_txcomplete(bus->dhd, pkt, FALSE); - PKTFREE(osh, pkt, TRUE); - DHD_ERROR(("%s: out of bus->txq !!!\n", __FUNCTION__)); - ret = BCME_NORESOURCE; - } else { - ret = BCME_OK; - } - dhd_os_sdunlock_txq(bus->dhd); - - if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) - dhd_txflowcontrol(bus->dhd, 0, ON); - -#ifdef DHD_DEBUG - if (pktq_plen(&bus->txq, prec) > qcount[prec]) - qcount[prec] = pktq_plen(&bus->txq, prec); -#endif - /* Schedule DPC if needed to send queued packet(s) */ - if (dhd_deferred_tx && !bus->dpc_sched) { - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - } - } else { - /* Lock: we're about to use shared data/code (and SDIO) */ - dhd_os_sdlock(bus->dhd); - - /* Otherwise, send it now */ - BUS_WAKE(bus); - /* Make sure back plane ht clk is on, no pending allowed */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); - -#ifndef SDTEST - DHD_TRACE(("%s: calling txpkt\n", __FUNCTION__)); - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - } - - - return ret; -} - -static uint -dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) -{ - void *pkt; - uint32 intstatus = 0; - uint retries = 0; - int ret = 0, prec_out; - uint cnt = 0; - uint datalen; - uint8 tx_prec_map; - - dhd_pub_t *dhd = bus->dhd; - sdpcmd_regs_t *regs = bus->regs; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - tx_prec_map = ~bus->flowcontrol; - - /* Send frames until the limit or some other event */ - for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { - dhd_os_sdlock_txq(bus->dhd); - if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { - dhd_os_sdunlock_txq(bus->dhd); - break; - } - dhd_os_sdunlock_txq(bus->dhd); - datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN; - -#ifndef SDTEST - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE); -#else - ret = dhdsdio_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE); -#endif - if (ret) - bus->dhd->tx_errors++; - else - bus->dhd->dstats.tx_bytes += datalen; - - /* In poll mode, need to check for other events */ - if (!bus->intr && cnt) - { - /* Check device status, signal pending interrupt */ - R_SDREG(intstatus, ®s->intstatus, retries); - bus->f2txdata++; - if (bcmsdh_regfail(bus->sdh)) - break; - if (intstatus & bus->hostintmask) - bus->ipend = TRUE; - } - } - - /* Deflow-control stack if needed */ - if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) - dhd_txflowcontrol(dhd, 0, OFF); - - return cnt; -} - -int -dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - uint8 *frame; - uint16 len; - uint32 swheader; - uint retries = 0; - bcmsdh_info_t *sdh = bus->sdh; - uint8 doff = 0; - int ret = -1; - int i; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Back the pointer to make a room for bus header */ - frame = msg - SDPCM_HDRLEN; - len = (msglen += SDPCM_HDRLEN); - - /* Add alignment padding (optional for ctl frames) */ - if (dhd_alignctl) { - if ((doff = ((uintptr)frame % DHD_SDALIGN))) { - frame -= doff; - len += doff; - msglen += doff; - bzero(frame, doff + SDPCM_HDRLEN); - } - ASSERT(doff < DHD_SDALIGN); - } - doff += SDPCM_HDRLEN; - - /* Round send length to next SDIO block */ - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - uint16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) - len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (len & (ALIGNMENT - 1))) - len = ROUNDUP(len, ALIGNMENT); - - ASSERT(ISALIGNED((uintptr)frame, 2)); - - - /* Need to lock here to protect txseq and SDIO tx calls */ - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - *(uint16*)frame = htol16((uint16)msglen); - *(((uint16*)frame) + 1) = htol16(~msglen); - - /* Software tag: channel, sequence number, data offset */ - swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) - | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); - - if (!DATAOK(bus)) { - DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", - __FUNCTION__, bus->tx_max, bus->tx_seq)); - bus->ctrl_frame_stat = TRUE; - /* Send from dpc */ - bus->ctrl_frame_buf = frame; - bus->ctrl_frame_len = len; - - dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); - - if (bus->ctrl_frame_stat == FALSE) { - DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__)); - ret = 0; - } else { - DHD_INFO(("%s: ctrl_frame_stat == TRUE\n", __FUNCTION__)); - ret = -1; - } - } - - if (ret == -1) { -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("Tx Frame", frame, len); - } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, MIN(len, 16)); - } -#endif - - do { - bus->ctrl_frame_stat = FALSE; - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - frame, len, NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - } while ((ret < 0) && retries++ < TXRETRIES); - } - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (ret) - bus->dhd->tx_ctlerrs++; - else - bus->dhd->tx_ctlpkts++; - - return ret ? -EIO : 0; -} - -int -dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) -{ - int timeleft; - uint rxlen = 0; - bool pending; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) - return -EIO; - - /* Wait until control frame is available */ - timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending); - - dhd_os_sdlock(bus->dhd); - rxlen = bus->rxlen; - bcopy(bus->rxctl, msg, MIN(msglen, rxlen)); - bus->rxlen = 0; - dhd_os_sdunlock(bus->dhd); - - if (rxlen) { - DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __FUNCTION__, rxlen, msglen)); - } else if (timeleft == 0) { - DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); -#ifdef DHD_DEBUG_TRAP - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG_TRAP */ - } else if (pending == TRUE) { - DHD_CTL(("%s: cancelled\n", __FUNCTION__)); - return -ERESTARTSYS; - } else { - DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__)); -#ifdef DHD_DEBUG_TRAP - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG_TRAP */ - } - - if (rxlen) - bus->dhd->rx_ctlpkts++; - else - bus->dhd->rx_ctlerrs++; - - return rxlen ? (int)rxlen : -ETIMEDOUT; -} - -/* IOVar table */ -enum { - IOV_INTR = 1, - IOV_POLLRATE, - IOV_SDREG, - IOV_SBREG, - IOV_SDCIS, - IOV_MEMBYTES, - IOV_MEMSIZE, -#ifdef DHD_DEBUG_TRAP - IOV_CHECKDIED, -#endif - IOV_DOWNLOAD, - IOV_FORCEEVEN, - IOV_SDIOD_DRIVE, - IOV_READAHEAD, - IOV_SDRXCHAIN, - IOV_ALIGNCTL, - IOV_SDALIGN, - IOV_DEVRESET, - IOV_CPU, -#ifdef SDTEST - IOV_PKTGEN, - IOV_EXTLOOP, -#endif /* SDTEST */ - IOV_SPROM, - IOV_TXBOUND, - IOV_RXBOUND, - IOV_TXMINMAX, - IOV_IDLETIME, - IOV_IDLECLOCK, - IOV_SD1IDLE, - IOV_SLEEP, - IOV_VARS -}; - -const bcm_iovar_t dhdsdio_iovars[] = { - {"intr", IOV_INTR, 0, IOVT_BOOL, 0 }, - {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0 }, - {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0 }, - {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0 }, - {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 }, - {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, - {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, - {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 }, - {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0 }, - {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 }, - {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 }, - {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0 }, - {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0 }, - {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0 }, - {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0 }, - {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0 }, -#ifdef DHD_DEBUG - {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, - {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, - {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0 }, - {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0 }, - {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 }, - {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 }, - {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 }, -#endif /* DHD_DEBUG */ -#ifdef DHD_DEBUG_TRAP - {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 }, -#endif /* DHD_DEBUG_TRAP */ -#ifdef SDTEST - {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, - {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, -#endif /* SDTEST */ - - {NULL, 0, 0, 0, 0 } -}; - -static void -dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div) -{ - uint q1, q2; - - if (!div) { - bcm_bprintf(strbuf, "%s N/A", desc); - } else { - q1 = num / div; - q2 = (100 * (num - (q1 * div))) / div; - bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); - } -} - -void -dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - dhd_bus_t *bus = dhdp->bus; - - bcm_bprintf(strbuf, "Bus SDIO structure:\n"); - bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", - bus->hostintmask, bus->intstatus, bus->sdpcm_ver); - bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", - bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, - bus->rxlen, bus->rx_seq); - bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", - bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); - bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", - bus->pollrate, bus->pollcnt, bus->regfails); - - bcm_bprintf(strbuf, "\nAdditional counters:\n"); - bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", - bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, - bus->rxc_errors); - bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", - bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); - bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", - bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); - bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", - bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); - bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", - (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata, - bus->f2txdata, bus->f1regdata); - { - dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets, - (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), - bus->dhd->rx_packets); - dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, bus->f2txdata); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets, - (bus->f2txdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); - - dhd_dump_pct(strbuf, "Total: pkts/f2rw", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), - (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", - (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->intrcount); - bcm_bprintf(strbuf, "\n\n"); - } - -#ifdef SDTEST - if (bus->pktgen_count) { - bcm_bprintf(strbuf, "pktgen config and count:\n"); - bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", - bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, - bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); - bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", - bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); - } -#endif /* SDTEST */ -#ifdef DHD_DEBUG - bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", - bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); - bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); -#endif /* DHD_DEBUG */ - bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", - bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); -} - -void -dhd_bus_clearcounts(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; - - bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; - bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; - bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0; - bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0; - bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0; - bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; -} - -#ifdef SDTEST -static int -dhdsdio_pktgen_get(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - - pktgen.version = DHD_PKTGEN_VERSION; - pktgen.freq = bus->pktgen_freq; - pktgen.count = bus->pktgen_count; - pktgen.print = bus->pktgen_print; - pktgen.total = bus->pktgen_total; - pktgen.minlen = bus->pktgen_minlen; - pktgen.maxlen = bus->pktgen_maxlen; - pktgen.numsent = bus->pktgen_sent; - pktgen.numrcvd = bus->pktgen_rcvd; - pktgen.numfail = bus->pktgen_fail; - pktgen.mode = bus->pktgen_mode; - pktgen.stop = bus->pktgen_stop; - - bcopy(&pktgen, arg, sizeof(pktgen)); - - return 0; -} - -static int -dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg) -{ - dhd_pktgen_t pktgen; - uint oldcnt, oldmode; - - bcopy(arg, &pktgen, sizeof(pktgen)); - if (pktgen.version != DHD_PKTGEN_VERSION) - return BCME_BADARG; - - oldcnt = bus->pktgen_count; - oldmode = bus->pktgen_mode; - - bus->pktgen_freq = pktgen.freq; - bus->pktgen_count = pktgen.count; - bus->pktgen_print = pktgen.print; - bus->pktgen_total = pktgen.total; - bus->pktgen_minlen = pktgen.minlen; - bus->pktgen_maxlen = pktgen.maxlen; - bus->pktgen_mode = pktgen.mode; - bus->pktgen_stop = pktgen.stop; - - bus->pktgen_tick = bus->pktgen_ptick = 0; - bus->pktgen_len = MAX(bus->pktgen_len, bus->pktgen_minlen); - bus->pktgen_len = MIN(bus->pktgen_len, bus->pktgen_maxlen); - - /* Clear counts for a new pktgen (mode change, or was stopped) */ - if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) - bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0; - - return 0; -} -#endif /* SDTEST */ - -static int -dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size) -{ - int bcmerror = 0; - uint32 sdaddr; - uint dsize; - - /* Determine initial transfer parameters */ - sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; - if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) - dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); - else - dsize = size; - - /* Set the backplane window to include the start address */ - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - goto xfer_done; - } - - /* Do the transfer(s) */ - while (size) { - DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n", - __FUNCTION__, (write ? "write" : "read"), dsize, sdaddr, - (address & SBSDIO_SBWINDOW_MASK))); - if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) { - DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__)); - break; - } - - /* Adjust for next transfer (if any) */ - if ((size -= dsize)) { - data += dsize; - address += dsize; - if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { - DHD_ERROR(("%s: window change failed\n", __FUNCTION__)); - break; - } - sdaddr = 0; - dsize = MIN(SBSDIO_SB_OFT_ADDR_LIMIT, size); - } - } - -xfer_done: - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) { - DHD_ERROR(("%s: FAILED to set window back to 0x%x\n", __FUNCTION__, - bcmsdh_cur_sbwad(bus->sdh))); - } - - return bcmerror; -} - -#ifdef DHD_DEBUG_TRAP -static int -dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) -{ - uint32 addr; - int rv; - - /* Read last word in memory to determine address of sdpcm_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, bus->ramsize - 4, (uint8 *)&addr, 4)) < 0) - return rv; - - addr = ltoh32(addr); - - DHD_INFO(("sdpcm_shared address 0x%08X\n", addr)); - - /* - * Check if addr is valid. - * NVRAM length at the end of memory should have been overwritten. - */ - if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { - DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", __FUNCTION__, addr)); - return BCME_ERROR; - } - - /* Read hndrte_shared structure */ - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0) - return rv; - - /* Endianness */ - sh->flags = ltoh32(sh->flags); - sh->trap_addr = ltoh32(sh->trap_addr); - sh->assert_exp_addr = ltoh32(sh->assert_exp_addr); - sh->assert_file_addr = ltoh32(sh->assert_file_addr); - sh->assert_line = ltoh32(sh->assert_line); - sh->console_addr = ltoh32(sh->console_addr); - sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); - - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - DHD_ERROR(("%s: sdpcm_shared version %d in dhd " - "is different than sdpcm_shared version %d in dongle\n", - __FUNCTION__, SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK)); - return BCME_ERROR; - } - - return BCME_OK; -} - -static int -dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size) -{ - int bcmerror = 0; - uint msize = 512; - char *mbuffer = NULL; - uint maxstrlen = 256; - char *str = NULL; - trap_t tr; - sdpcm_shared_t sdpcm_shared; - struct bcmstrbuf strbuf; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (data == NULL) { - /* - * Called after a rx ctrl timeout. "data" is NULL. - * allocate memory to trace the trap or assert. - */ - size = msize; - mbuffer = data = MALLOC(bus->dhd->osh, msize); - if (mbuffer == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, msize)); - bcmerror = BCME_NOMEM; - goto done; - } - } - - if ((str = MALLOC(bus->dhd->osh, maxstrlen)) == NULL) { - DHD_ERROR(("%s: MALLOC(%d) failed \n", __FUNCTION__, maxstrlen)); - bcmerror = BCME_NOMEM; - goto done; - } - - if ((bcmerror = dhdsdio_readshared(bus, &sdpcm_shared)) < 0) - goto done; - - bcm_binit(&strbuf, data, size); - - bcm_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", - sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); - - if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "Assrt not built in dongle\n"); - } - - if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT|SDPCM_SHARED_TRAP)) == 0) { - /* NOTE: Misspelled assert is intentional - DO NOT FIX. - * (Avoids conflict with real asserts for programmatic parsing of output.) - */ - bcm_bprintf(&strbuf, "No trap%s in dongle", - (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) - ?"/assrt" :""); - } else { - if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { - /* Download assert */ - bcm_bprintf(&strbuf, "Dongle assert"); - if (sdpcm_shared.assert_exp_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_exp_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " expr \"%s\"", str); - } - - if (sdpcm_shared.assert_file_addr != 0) { - str[0] = '\0'; - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.assert_file_addr, - (uint8 *)str, maxstrlen)) < 0) - goto done; - - str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " file \"%s\"", str); - } - - bcm_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line); - } - - if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { - if ((bcmerror = dhdsdio_membytes(bus, FALSE, - sdpcm_shared.trap_addr, - (uint8*)&tr, sizeof(trap_t))) < 0) - goto done; - - bcm_bprintf(&strbuf, - "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," - "lp 0x%x, rpc 0x%x Trap offset 0x%x, " - "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n", - tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13, tr.r14, tr.pc, - sdpcm_shared.trap_addr, - tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5, tr.r6, tr.r7); - } - } - - if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) { - DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf)); - } - -done: - if (mbuffer) - MFREE(bus->dhd->osh, mbuffer, msize); - if (str) - MFREE(bus->dhd->osh, str, maxstrlen); - - return bcmerror; -} -#endif /* DHD_DEBUG_TRAP */ - -#ifdef DHD_DEBUG -#define CONSOLE_LINE_MAX 192 - -static int -dhdsdio_readconsole(dhd_bus_t *bus) -{ - dhd_console_t *c = &bus->console; - uint8 line[CONSOLE_LINE_MAX], ch; - uint32 n, idx, addr; - int rv; - - /* Don't do anything until FWREADY updates console address */ - if (bus->console_addr == 0) - return 0; - - /* Read console log struct */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0) - return rv; - - /* Allocate console buffer (one time only) */ - if (c->buf == NULL) { - c->bufsize = ltoh32(c->log.buf_size); - if ((c->buf = MALLOC(bus->dhd->osh, c->bufsize)) == NULL) - return BCME_NOMEM; - } - - idx = ltoh32(c->log.idx); - - /* Protect against corrupt value */ - if (idx > c->bufsize) - return BCME_ERROR; - - /* Skip reading the console buffer if the index pointer has not moved */ - if (idx == c->last) - return BCME_OK; - - /* Read the console buffer */ - addr = ltoh32(c->log.buf); - if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0) - return rv; - - while (c->last != idx) { - for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { - if (c->last == idx) { - /* This would output a partial line. Instead, back up - * the buffer pointer and output this line next time around. - */ - if (c->last >= n) - c->last -= n; - else - c->last = c->bufsize - n; - goto break2; - } - ch = c->buf[c->last]; - c->last = (c->last + 1) % c->bufsize; - if (ch == '\n') - break; - line[n] = ch; - } - - if (n > 0) { - if (line[n - 1] == '\r') - n--; - line[n] = 0; - printf("CONSOLE: %s\n", line); - } - } -break2: - - return BCME_OK; -} -#endif /* DHD_DEBUG */ - -int -dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) -{ - int bcmerror = BCME_OK; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Basic sanity checks */ - if (bus->dhd->up) { - bcmerror = BCME_NOTDOWN; - goto err; - } - if (!len) { - bcmerror = BCME_BUFTOOSHORT; - goto err; - } - - /* Free the old ones and replace with passed variables */ - if (bus->vars) - MFREE(bus->dhd->osh, bus->vars, bus->varsz); - - bus->vars = MALLOC(bus->dhd->osh, len); - bus->varsz = bus->vars ? len : 0; - if (bus->vars == NULL) { - bcmerror = BCME_NOMEM; - goto err; - } - - /* Copy the passed variables, which should include the terminating double-null */ - bcopy(arg, bus->vars, bus->varsz); -err: - return bcmerror; -} - -static int -dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, - void *params, int plen, void *arg, int len, int val_size) -{ - int bcmerror = 0; - int32 int_val = 0; - bool bool_val = 0; - - DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", - __FUNCTION__, actionid, name, params, plen, arg, len, val_size)); - - if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) - goto exit; - - if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - bool_val = (int_val != 0) ? TRUE : FALSE; - - - /* Some ioctls use the bus */ - dhd_os_sdlock(bus->dhd); - - /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ - if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || - actionid == IOV_GVAL(IOV_DEVRESET))) { - bcmerror = BCME_NOTREADY; - goto exit; - } - - /* Handle sleep stuff before any clock mucking */ - if (vi->varid == IOV_SLEEP) { - if (IOV_ISSET(actionid)) { - bcmerror = dhdsdio_bussleep(bus, bool_val); - } else { - int_val = (int32)bus->sleeping; - bcopy(&int_val, arg, val_size); - } - goto exit; - } - - /* Request clock to allow SDIO accesses */ - if (!bus->dhd->dongle_reset) { - BUS_WAKE(bus); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - } - - switch (actionid) { - case IOV_GVAL(IOV_INTR): - int_val = (int32)bus->intr; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_INTR): - bus->intr = bool_val; - bus->intdis = FALSE; - if (bus->dhd->up) { - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - } - break; - - case IOV_GVAL(IOV_POLLRATE): - int_val = (int32)bus->pollrate; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_POLLRATE): - bus->pollrate = (uint)int_val; - bus->poll = (bus->pollrate != 0); - break; - - case IOV_GVAL(IOV_IDLETIME): - int_val = bus->idletime; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLETIME): - if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) { - bcmerror = BCME_BADARG; - } else { - bus->idletime = int_val; - } - break; - - case IOV_GVAL(IOV_IDLECLOCK): - int_val = (int32)bus->idleclock; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_IDLECLOCK): - bus->idleclock = int_val; - break; - - case IOV_GVAL(IOV_SD1IDLE): - int_val = (int32)sd1idle; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SD1IDLE): - sd1idle = bool_val; - break; - - - case IOV_SVAL(IOV_MEMBYTES): - case IOV_GVAL(IOV_MEMBYTES): - { - uint32 address; - uint size, dsize; - uint8 *data; - - bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); - - ASSERT(plen >= 2*sizeof(int)); - - address = (uint32)int_val; - bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val)); - size = (uint)int_val; - - /* Do some validation */ - dsize = set ? plen - (2 * sizeof(int)) : len; - if (dsize < size) { - DHD_ERROR(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n", - __FUNCTION__, (set ? "set" : "get"), address, size, dsize)); - bcmerror = BCME_BADARG; - break; - } - - DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, - (set ? "write" : "read"), size, address)); - - /* If we know about SOCRAM, check for a fit */ - if ((bus->orig_ramsize) && - ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) { - DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", - __FUNCTION__, bus->orig_ramsize, size, address)); - bcmerror = BCME_BADARG; - break; - } - - /* Generate the actual data pointer */ - data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; - - /* Call to do the transfer */ - bcmerror = dhdsdio_membytes(bus, set, address, data, size); - - break; - } - - case IOV_GVAL(IOV_MEMSIZE): - int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); - break; - - case IOV_GVAL(IOV_SDIOD_DRIVE): - int_val = (int32)dhd_sdiod_drive_strength; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDIOD_DRIVE): - dhd_sdiod_drive_strength = int_val; - si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength); - break; - - case IOV_SVAL(IOV_DOWNLOAD): - bcmerror = dhdsdio_download_state(bus, bool_val); - break; - - case IOV_SVAL(IOV_VARS): - bcmerror = dhdsdio_downloadvars(bus, arg, len); - break; - - case IOV_GVAL(IOV_READAHEAD): - int_val = (int32)dhd_readahead; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_READAHEAD): - if (bool_val && !dhd_readahead) - bus->nextlen = 0; - dhd_readahead = bool_val; - break; - - case IOV_GVAL(IOV_SDRXCHAIN): - int_val = (int32)bus->use_rxchain; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_SDRXCHAIN): - if (bool_val && !bus->sd_rxchain) - bcmerror = BCME_UNSUPPORTED; - else - bus->use_rxchain = bool_val; - break; - case IOV_GVAL(IOV_ALIGNCTL): - int_val = (int32)dhd_alignctl; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_ALIGNCTL): - dhd_alignctl = bool_val; - break; - - case IOV_GVAL(IOV_SDALIGN): - int_val = DHD_SDALIGN; - bcopy(&int_val, arg, val_size); - break; - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_VARS): - if (bus->varsz < (uint)len) - bcopy(bus->vars, arg, bus->varsz); - else - bcmerror = BCME_BUFTOOSHORT; - break; -#endif /* DHD_DEBUG */ - -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SDREG): - { - sdreg_t *sd_ptr; - uint32 addr, size; - - sd_ptr = (sdreg_t *)params; - - addr = (uintptr)bus->regs + sd_ptr->offset; - size = sd_ptr->func; - bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - /* Same as above, but offset is not backplane (not SDIO core) */ - case IOV_GVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(int32)); - break; - } - - case IOV_SVAL(IOV_SBREG): - { - sdreg_t sdreg; - uint32 addr, size; - - bcopy(params, &sdreg, sizeof(sdreg)); - - addr = SI_ENUM_BASE + sdreg.offset; - size = sdreg.func; - bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); - if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; - break; - } - - case IOV_GVAL(IOV_SDCIS): - { - *(char *)arg = 0; - - bcmstrcat(arg, "\nFunc 0\n"); - bcmsdh_cis_read(bus->sdh, 0x10, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 1\n"); - bcmsdh_cis_read(bus->sdh, 0x11, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - bcmstrcat(arg, "\nFunc 2\n"); - bcmsdh_cis_read(bus->sdh, 0x12, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); - break; - } - - case IOV_GVAL(IOV_FORCEEVEN): - int_val = (int32)forcealign; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_FORCEEVEN): - forcealign = bool_val; - break; - - case IOV_GVAL(IOV_TXBOUND): - int_val = (int32)dhd_txbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXBOUND): - dhd_txbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_RXBOUND): - int_val = (int32)dhd_rxbound; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_RXBOUND): - dhd_rxbound = (uint)int_val; - break; - - case IOV_GVAL(IOV_TXMINMAX): - int_val = (int32)dhd_txminmax; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_TXMINMAX): - dhd_txminmax = (uint)int_val; - break; - - - -#endif /* DHD_DEBUG */ - - -#ifdef SDTEST - case IOV_GVAL(IOV_EXTLOOP): - int_val = (int32)bus->ext_loop; - bcopy(&int_val, arg, val_size); - break; - - case IOV_SVAL(IOV_EXTLOOP): - bus->ext_loop = bool_val; - break; - - case IOV_GVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_get(bus, arg); - break; - - case IOV_SVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_set(bus, arg); - break; -#endif /* SDTEST */ - - - case IOV_SVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n", - __FUNCTION__, bool_val, bus->dhd->dongle_reset, - bus->dhd->busstate)); - - ASSERT(bus->dhd->osh); - /* ASSERT(bus->cl_devid); */ - - dhd_bus_devreset(bus->dhd, (uint8)bool_val); - - break; - - case IOV_GVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __FUNCTION__)); - - /* Get its status */ - int_val = (bool) bus->dhd->dongle_reset; - bcopy(&int_val, arg, val_size); - - break; - - default: - bcmerror = BCME_UNSUPPORTED; - break; - } - -exit: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == FALSE) - dhd_preinit_ioctls((dhd_pub_t *) bus->dhd); - - return bcmerror; -} - -static int -dhdsdio_write_vars(dhd_bus_t *bus) -{ - int bcmerror = 0; - uint32 varsize; - uint32 varaddr; - uint8 *vbuffer; - uint32 varsizew; -#ifdef DHD_DEBUG - char *nvram_ularray; -#endif /* DHD_DEBUG */ - - /* Even if there are no vars are to be written, we still need to set the ramsize. */ - varsize = bus->varsz ? ROUNDUP(bus->varsz, 4) : 0; - varaddr = (bus->ramsize - 4) - varsize; - - if (bus->vars) { - vbuffer = (uint8 *)MALLOC(bus->dhd->osh, varsize); - if (!vbuffer) - return BCME_NOMEM; - - bzero(vbuffer, varsize); - bcopy(bus->vars, vbuffer, bus->varsz); - - /* Write the vars list */ - bcmerror = dhdsdio_membytes(bus, TRUE, varaddr, vbuffer, varsize); -#ifdef DHD_DEBUG - /* Verify NVRAM bytes */ - DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); - nvram_ularray = (char*)MALLOC(bus->dhd->osh, varsize); - if (!nvram_ularray) - return BCME_NOMEM; - - /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, varsize); - - /* Read the vars list to temp buffer for comparison */ - bcmerror = dhdsdio_membytes(bus, FALSE, varaddr, nvram_ularray, varsize); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d nvram bytes at 0x%08x\n", - __FUNCTION__, bcmerror, varsize, varaddr)); - } - /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(vbuffer, nvram_ularray, varsize)) { - DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n", __FUNCTION__)); - } else - DHD_ERROR(("%s: Download, Upload and compare of NVRAM succeeded.\n", - __FUNCTION__)); - - MFREE(bus->dhd->osh, nvram_ularray, varsize); -#endif /* DHD_DEBUG */ - - MFREE(bus->dhd->osh, vbuffer, varsize); - } - - /* adjust to the user specified RAM */ - DHD_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); - DHD_INFO(("Vars are at %d, orig varsize is %d\n", - varaddr, varsize)); - varsize = ((bus->orig_ramsize - 4) - varaddr); - - /* - * Determine the length token: - * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits. - */ - if (bcmerror) { - varsizew = 0; - } else { - varsizew = varsize / 4; - varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); - varsizew = htol32(varsizew); - } - - DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, varsizew)); - - /* Write the length token to the last word */ - bcmerror = dhdsdio_membytes(bus, TRUE, (bus->orig_ramsize - 4), - (uint8*)&varsizew, 4); - - return bcmerror; -} - -static int -dhdsdio_download_state(dhd_bus_t *bus, bool enter) -{ - uint retries; - int bcmerror = 0; - - /* To enter download state, disable ARM and reset SOCRAM. - * To exit download state, simply reset ARM (default is RAM boot). - */ - if (enter) { - - bus->alp_only = TRUE; - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_disable(bus->sih, 0); - if (bcmsdh_regfail(bus->sdh)) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Clear the top bit of memory */ - if (bus->ramsize) { - uint32 zeros = 0; - dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4); - } - } else { - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if (!si_iscoreup(bus->sih)) { - DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if ((bcmerror = dhdsdio_write_vars(bus))) { - DHD_ERROR(("%s: no vars written to RAM\n", __FUNCTION__)); - bcmerror = 0; - } - - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && - !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { - DHD_ERROR(("%s: Can't change back to SDIO core?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); - - - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying to reset ARM core?\n", __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - /* Allow HT Clock now that the ARM is running. */ - bus->alp_only = FALSE; - - bus->dhd->busstate = DHD_BUS_LOAD; - } - -fail: - /* Always return to SDIOD core */ - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) - si_setcore(bus->sih, SDIOD_CORE_ID, 0); - - return bcmerror; -} - -int -dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - dhd_bus_t *bus = dhdp->bus; - const bcm_iovar_t *vi = NULL; - int bcmerror = 0; - int val_size; - uint32 actionid; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(name); - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); - - /* Look up var locally; if not found pass to host driver */ - if ((vi = bcm_iovar_lookup(dhdsdio_iovars, name)) == NULL) { - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Turn on clock in case SD command needs backplane */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - bcmerror = bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, set); - - /* Check for bus configuration changes of interest */ - - /* If it was divisor change, read the new one */ - if (set && strcmp(name, "sd_divisor") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_divisor = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_divisor)); - } - } - /* If it was a mode change, read the new one */ - if (set && strcmp(name, "sd_mode") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_mode = -1; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, name, bus->sd_mode)); - } - } - /* Similar check for blocksize change */ - if (set && strcmp(name, "sd_blocksize") == 0) { - int32 fnum = 2; - if (bcmsdh_iovar_op(bus->sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - goto exit; - } - - DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__, - name, (set ? "set" : "get"), len, plen)); - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, val_size); - -exit: - return bcmerror; -} - -void -dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) -{ - osl_t *osh = bus->dhd->osh; - uint32 local_hostintmask; - uint8 saveclk; - uint retries; - int err; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - BUS_WAKE(bus); - - /* Change our idea of bus state */ - bus->dhd->busstate = DHD_BUS_DOWN; - - /* Enable clock for device interrupts */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Disable and clear interrupts at the chip level also */ - W_SDREG(0, &bus->regs->hostintmask, retries); - local_hostintmask = bus->hostintmask; - bus->hostintmask = 0; - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - } - - /* Turn off the bus (F2), free any pending packets */ - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - /* Clear any pending interrupts now that F2 is disabled */ - W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); - - /* Turn off the backplane clock (only) */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - - /* Clear the data packet queues */ - pktq_flush(osh, &bus->txq, TRUE); - - /* Clear any held glomming stuff */ - if (bus->glomd) - PKTFREE(osh, bus->glomd, FALSE); - - if (bus->glom) - PKTFREE(osh, bus->glom, FALSE); - - bus->glom = bus->glomd = NULL; - - /* Clear rx control and wake any waiters */ - bus->rxlen = 0; - dhd_os_ioctl_resp_wake(bus->dhd); - - /* Reset some F2 state stuff */ - bus->rxskip = FALSE; - bus->tx_seq = bus->rx_seq = 0; - - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); -} - -int -dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) -{ - dhd_bus_t *bus = dhdp->bus; - dhd_timeout_t tmo; - uint retries = 0; - uint8 ready, enable; - int err, ret = BCME_ERROR; - uint8 saveclk; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(bus->dhd); - if (!bus->dhd) - return BCME_OK; - - if (enforce_mutex) - dhd_os_sdlock(bus->dhd); - - /* Make sure backplane clock is on, needed to generate F2 interrupt */ - err = dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if ((err != BCME_OK) || (bus->clkstate != CLK_AVAIL)) { - DHD_ERROR(("%s: Failed to set backplane clock: err %d\n", __FUNCTION__, err)); - goto exit; - } - - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); - goto exit; - } - - /* Enable function 2 (frame transfers) */ - W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT), - &bus->regs->tosbmailboxdata, retries); - enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - - /* Give the dongle some time to do its thing and set IOR2 */ - dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000); - - ready = 0; - while (ready != enable && !dhd_timeout_expired(&tmo)) - ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL); - - - DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", - __FUNCTION__, enable, ready, tmo.elapsed)); - - - /* If F2 successfully enabled, set core and enable interrupts */ - if (ready == enable) { - /* Make sure we're talking to the core. */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0))) - bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); - - /* Set up the interrupt mask and enable interrupts */ - bus->hostintmask = HOSTINTMASK; - W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); - - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); - - /* Set bus state according to enable result */ - dhdp->busstate = DHD_BUS_DATA; - - /* bcmsdh_intr_unmask(bus->sdh); */ - - bus->intdis = FALSE; - if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", __FUNCTION__)); - bcmsdh_intr_enable(bus->sdh); - } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - } - - } - - - else { - /* Disable F2 again */ - enable = SDIO_FUNC_ENABLE_1; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); - } - - /* Restore previous clock setting */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); - - - /* If we didn't come up, turn off backplane clock */ - if (dhdp->busstate != DHD_BUS_DATA) - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - - ret = BCME_OK; -exit: - if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); - - return ret; -} - -static void -dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - uint16 lastrbc; - uint8 hi, lo; - int err; - - DHD_ERROR(("%s: %sterminate frame%s\n", __FUNCTION__, - (abort ? "abort command, " : ""), (rtx ? ", send NAK" : ""))); - - if (abort) { - bcmsdh_abort(sdh, SDIO_FUNC_2); - } - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - bus->f1regdata++; - - /* Wait until the packet has been flushed (device/FIFO stable) */ - for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); - bus->f1regdata += 2; - - if ((hi == 0) && (lo == 0)) - break; - - if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { - DHD_ERROR(("%s: count growing: last 0x%04x now 0x%04x\n", - __FUNCTION__, lastrbc, ((hi << 8) + lo))); - } - lastrbc = (hi << 8) + lo; - } - - if (!retries) { - DHD_ERROR(("%s: count never zeroed: last 0x%04x\n", __FUNCTION__, lastrbc)); - } else { - DHD_INFO(("%s: flush took %d iterations\n", __FUNCTION__, (0xffff - retries))); - } - - if (rtx) { - bus->rxrtx++; - W_SDREG(SMB_NAK, ®s->tosbmailbox, retries); - bus->f1regdata++; - if (retries <= retry_limit) { - bus->rxskip = TRUE; - } - } - - /* Clear partial in any case */ - bus->nextlen = 0; - - /* If we can't reach the device, signal failure */ - if (err || bcmsdh_regfail(sdh)) - bus->dhd->busstate = DHD_BUS_DOWN; -} - -static void -dhdsdio_read_control(dhd_bus_t *bus, uint8 *hdr, uint len, uint doff) -{ - bcmsdh_info_t *sdh = bus->sdh; - uint rdlen, pad; - - int sdret; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Control data already received in aligned rxctl */ - if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) - goto gotpkt; - - ASSERT(bus->rxbuf); - /* Set rxctl for frame (w/optional alignment) */ - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - - /* Copy the already-read portion over */ - bcopy(hdr, bus->rxctl, firstread); - if (len <= firstread) - goto gotpkt; - - /* Copy the full data pkt in gSPI case and process ioctl. */ - if (bus->bus == SPI_BUS) { - bcopy(hdr, bus->rxctl, len); - goto gotpkt; - } - - /* Raise rdlen to next SDIO block to avoid tail command */ - rdlen = len - firstread; - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((len + pad) < bus->dhd->maxctl)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - /* Drop if the read is too big or it exceeds our maximum */ - if ((rdlen + firstread) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n", - __FUNCTION__, rdlen, bus->dhd->maxctl)); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - if ((len - doff) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", - __FUNCTION__, len, (len - doff), bus->dhd->maxctl)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - goto done; - } - - - /* Read remainder of frame body into the rxctl buffer */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (bus->rxctl + firstread), rdlen, NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", __FUNCTION__, rdlen, sdret)); - bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */ - dhdsdio_rxfail(bus, TRUE, TRUE); - goto done; - } - -gotpkt: - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { - prhex("RxCtrl", bus->rxctl, len); - } -#endif - - /* Point to valid data and indicate its length */ - bus->rxctl += doff; - bus->rxlen = len - doff; - -done: - /* Awake any waiters */ - dhd_os_ioctl_resp_wake(bus->dhd); -} - -static uint8 -dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) -{ - uint16 dlen, totlen; - uint8 *dptr, num = 0; - - uint16 sublen, check; - void *pfirst, *plast, *pnext, *save_pfirst; - osl_t *osh = bus->dhd->osh; - - int errcode; - uint8 chan, seq, doff, sfdoff; - uint8 txmax; - - int ifidx = 0; - bool usechain = bus->use_rxchain; - - /* If packets, issue read(s) and send up packet chain */ - /* Return sequence numbers consumed? */ - - DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, bus->glom)); - - /* If there's a descriptor, generate the packet chain */ - if (bus->glomd) { - dhd_os_sdlock_rxq(bus->dhd); - - pfirst = plast = pnext = NULL; - dlen = (uint16)PKTLEN(osh, bus->glomd); - dptr = PKTDATA(osh, bus->glomd); - if (!dlen || (dlen & 1)) { - DHD_ERROR(("%s: bad glomd len (%d), ignore descriptor\n", - __FUNCTION__, dlen)); - dlen = 0; - } - - for (totlen = num = 0; dlen; num++) { - /* Get (and move past) next length */ - sublen = ltoh16_ua(dptr); - dlen -= sizeof(uint16); - dptr += sizeof(uint16); - if ((sublen < SDPCM_HDRLEN) || - ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) { - DHD_ERROR(("%s: descriptor len %d bad: %d\n", - __FUNCTION__, num, sublen)); - pnext = NULL; - break; - } - if (sublen % DHD_SDALIGN) { - DHD_ERROR(("%s: sublen %d not a multiple of %d\n", - __FUNCTION__, sublen, DHD_SDALIGN)); - usechain = FALSE; - } - totlen += sublen; - - /* For last frame, adjust read len so total is a block multiple */ - if (!dlen) { - sublen += (ROUNDUP(totlen, bus->blocksize) - totlen); - totlen = ROUNDUP(totlen, bus->blocksize); - } - - /* Allocate/chain packet for next subframe */ - if ((pnext = PKTGET(osh, sublen + DHD_SDALIGN, FALSE)) == NULL) { - DHD_ERROR(("%s: PKTGET failed, num %d len %d\n", - __FUNCTION__, num, sublen)); - break; - } - ASSERT(!PKTLINK(pnext)); - if (!pfirst) { - ASSERT(!plast); - pfirst = plast = pnext; - } else { - ASSERT(plast); - PKTSETNEXT(osh, plast, pnext); - plast = pnext; - } - - /* Adhere to start alignment requirements */ - PKTALIGN(osh, pnext, sublen, DHD_SDALIGN); - } - - /* If all allocations succeeded, save packet chain in bus structure */ - if (pnext) { - DHD_GLOM(("%s: allocated %d-byte packet chain for %d subframes\n", - __FUNCTION__, totlen, num)); - if (DHD_GLOM_ON() && bus->nextlen) { - if (totlen != bus->nextlen) { - DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " - "rxseq %d\n", __FUNCTION__, bus->nextlen, - totlen, rxseq)); - } - } - bus->glom = pfirst; - pfirst = pnext = NULL; - } else { - if (pfirst) - PKTFREE(osh, pfirst, FALSE); - bus->glom = NULL; - num = 0; - } - - /* Done with descriptor packet */ - PKTFREE(osh, bus->glomd, FALSE); - bus->glomd = NULL; - bus->nextlen = 0; - - dhd_os_sdunlock_rxq(bus->dhd); - } - - /* Ok -- either we just generated a packet chain, or had one from before */ - if (bus->glom) { - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s: attempt superframe read, packet chain:\n", __FUNCTION__)); - for (pnext = bus->glom; pnext; pnext = PKTNEXT(osh, pnext)) { - DHD_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (uint8*)PKTDATA(osh, pnext), - PKTLEN(osh, pnext), PKTLEN(osh, pnext))); - } - } - - pfirst = bus->glom; - dlen = (uint16)pkttotlen(osh, pfirst); - - /* Do an SDIO read for the superframe. Configurable iovar to - * read directly into the chained packet, or allocate a large - * packet and and copy into the chain. - */ - if (usechain) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, (uint8*)PKTDATA(osh, pfirst), - dlen, pfirst, NULL, NULL); - } else if (bus->dataptr) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, - F2SYNC, bus->dataptr, - dlen, NULL, NULL, NULL); - sublen = (uint16)pktfrombuf(osh, pfirst, 0, dlen, bus->dataptr); - if (sublen != dlen) { - DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", - __FUNCTION__, dlen, sublen)); - errcode = -1; - } - pnext = NULL; - } else { - DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", dlen)); - errcode = -1; - } - bus->f2rxdata++; - ASSERT(errcode != BCME_PENDING); - - /* On failure, kill the superframe, allow a couple retries */ - if (errcode < 0) { - DHD_ERROR(("%s: glom read of %d bytes failed: %d\n", - __FUNCTION__, dlen, errcode)); - bus->dhd->rx_errors++; - - if (bus->glomerr++ < 3) { - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - return 0; - } - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("SUPERFRAME", PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 48)); - } -#endif - - - /* Validate the superframe header */ - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s: got frame w/nextlen too large (%d) seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - errcode = 0; - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (superframe): HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, sublen, check)); - errcode = -1; - } else if (ROUNDUP(sublen, bus->blocksize) != dlen) { - DHD_ERROR(("%s (superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", - __FUNCTION__, sublen, ROUNDUP(sublen, bus->blocksize), dlen)); - errcode = -1; - } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { - DHD_ERROR(("%s (superframe): bad channel %d\n", __FUNCTION__, - SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]))); - errcode = -1; - } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { - DHD_ERROR(("%s (superframe): got second descriptor?\n", __FUNCTION__)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || - (doff > (PKTLEN(osh, pfirst) - SDPCM_HDRLEN))) { - DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d pkt %d min %d\n", - __FUNCTION__, doff, sublen, PKTLEN(osh, pfirst), SDPCM_HDRLEN)); - errcode = -1; - } - - /* Check sequence number of superframe SW header */ - if (rxseq != seq) { - DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - - /* Remove superframe header, remember offset */ - PKTPULL(osh, pfirst, doff); - sfdoff = doff; - - /* Validate all the subframe headers */ - for (num = 0, pnext = pfirst; pnext && !errcode; - num++, pnext = PKTNEXT(osh, pnext)) { - dptr = (uint8 *)PKTDATA(osh, pnext); - dlen = (uint16)PKTLEN(osh, pnext); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(uint16)); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("subframe", dptr, 32); - } -#endif - - if ((uint16)~(sublen^check)) { - DHD_ERROR(("%s (subframe %d): HW hdr error: " - "len/check 0x%04x/0x%04x\n", - __FUNCTION__, num, sublen, check)); - errcode = -1; - } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { - DHD_ERROR(("%s (subframe %d): length mismatch: " - "len 0x%04x, expect 0x%04x\n", - __FUNCTION__, num, sublen, dlen)); - errcode = -1; - } else if ((chan != SDPCM_DATA_CHANNEL) && - (chan != SDPCM_EVENT_CHANNEL)) { - DHD_ERROR(("%s (subframe %d): bad channel %d\n", - __FUNCTION__, num, chan)); - errcode = -1; - } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { - DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n", - __FUNCTION__, num, doff, sublen, SDPCM_HDRLEN)); - errcode = -1; - } - } - - if (errcode) { - /* Terminate frame on error, request a couple retries */ - if (bus->glomerr++ < 3) { - /* Restore superframe header space */ - PKTPUSH(osh, pfirst, sfdoff); - dhdsdio_rxfail(bus, TRUE, TRUE); - } else { - bus->glomerr = 0; - dhdsdio_rxfail(bus, TRUE, FALSE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rxglomfail++; - bus->glom = NULL; - } - bus->nextlen = 0; - return 0; - } - - /* Basic SD framing looks ok - process each packet (header) */ - save_pfirst = pfirst; - bus->glom = NULL; - plast = NULL; - - dhd_os_sdlock_rxq(bus->dhd); - for (num = 0; pfirst; rxseq++, pfirst = pnext) { - pnext = PKTNEXT(osh, pfirst); - PKTSETNEXT(osh, pfirst, NULL); - - dptr = (uint8 *)PKTDATA(osh, pfirst); - sublen = ltoh16_ua(dptr); - chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - - DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", - __FUNCTION__, num, pfirst, PKTDATA(osh, pfirst), - PKTLEN(osh, pfirst), sublen, chan, seq)); - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL)); - - if (rxseq != seq) { - DHD_GLOM(("%s: rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Subframe Data", dptr, dlen); - } -#endif - - PKTSETLEN(osh, pfirst, sublen); - PKTPULL(osh, pfirst, doff); - - if (PKTLEN(osh, pfirst) == 0) { - PKTFREE(bus->dhd->osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - bus->dhd->rx_errors++; - PKTFREE(osh, pfirst, FALSE); - if (plast) { - PKTSETNEXT(osh, plast, pnext); - } else { - ASSERT(save_pfirst == pfirst); - save_pfirst = pnext; - } - continue; - } - - /* this packet will go up, link back into chain and count it */ - PKTSETNEXT(osh, pfirst, pnext); - plast = pfirst; - num++; - -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n", - __FUNCTION__, num, pfirst, - PKTDATA(osh, pfirst), PKTLEN(osh, pfirst), - PKTNEXT(osh, pfirst), PKTLINK(pfirst))); - prhex("", (uint8 *)PKTDATA(osh, pfirst), - MIN(PKTLEN(osh, pfirst), 32)); - } -#endif /* DHD_DEBUG */ - } - dhd_os_sdunlock_rxq(bus->dhd); - if (num) { - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num); - dhd_os_sdlock(bus->dhd); - } - - bus->rxglomframes++; - bus->rxglompkts += num; - } - return num; -} - -/* Return TRUE if there may be more frames to read */ -static uint -dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) -{ - osl_t *osh = bus->dhd->osh; - bcmsdh_info_t *sdh = bus->sdh; - - uint16 len, check; /* Extracted hardware header fields */ - uint8 chan, seq, doff; /* Extracted software header fields */ - uint8 fcbits; /* Extracted fcbits from software header */ - uint8 delta; - - void *pkt; /* Packet for event or data frames */ - uint16 pad; /* Number of pad bytes to read */ - uint16 rdlen; /* Total number of bytes to read */ - uint8 rxseq; /* Next sequence number to expect */ - uint rxleft = 0; /* Remaining number of frames allowed */ - int sdret; /* Return code from bcmsdh calls */ - uint8 txmax; /* Maximum tx sequence offered */ - bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */ - uint8 *rxbuf; - int ifidx = 0; - uint rxcount = 0; /* Total frames read */ - -#if defined(DHD_DEBUG) || defined(SDTEST) - bool sdtest = FALSE; /* To limit message spew from test mode */ -#endif - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - ASSERT(maxframes); - -#ifdef SDTEST - /* Allow pktgen to override maxframes */ - if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) { - maxframes = bus->pktgen_count; - sdtest = TRUE; - } -#endif - - /* Not finished unless we encounter no more frames indication */ - *finished = FALSE; - - - for (rxseq = bus->rx_seq, rxleft = maxframes; - !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN; - rxseq++, rxleft--) { - - /* Handle glomming separately */ - if (bus->glom || bus->glomd) { - uint8 cnt; - DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", - __FUNCTION__, bus->glomd, bus->glom)); - cnt = dhdsdio_rxglom(bus, rxseq); - DHD_GLOM(("%s: rxglom returned %d\n", __FUNCTION__, cnt)); - rxseq += cnt - 1; - rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; - continue; - } - - /* Try doing single read if we can */ - if (dhd_readahead && bus->nextlen) { - uint16 nextlen = bus->nextlen; - bus->nextlen = 0; - - if (bus->bus == SPI_BUS) { - rdlen = len = nextlen; - } - else { - rdlen = len = nextlen << 4; - - /* Pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - } - - /* We use bus->rxctl buffer in WinXP for initial control pkt receives. - * Later we use buffer-poll for data as well as control packets. - * This is required becuase dhd receives full frame in gSPI unlike SDIO. - * After the frame is received we have to distinguish whether it is data - * or non-data frame. - */ - /* Allocate a packet buffer */ - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, rdlen + DHD_SDALIGN, FALSE))) { - if (bus->bus == SPI_BUS) { - bus->usebufpool = FALSE; - bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { - bus->rxctl += firstread; - if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) - bus->rxctl += (DHD_SDALIGN - pad); - bus->rxctl -= firstread; - } - ASSERT(bus->rxctl >= bus->rxbuf); - rxbuf = bus->rxctl; - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - NULL, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - - /* Control frame failures need retransmission */ - if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - /* dhd.rx_ctlerrs is higher level */ - bus->rxc_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } else { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): PKTGET failed: len %d rdlen %d " - "expected rxseq %d\n", - __FUNCTION__, len, rdlen, rxseq)); - /* Just go try again w/normal header read */ - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } else { - if (bus->bus == SPI_BUS) - bus->usebufpool = TRUE; - - ASSERT(!PKTLINK(pkt)); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - rxbuf = (uint8 *)PKTDATA(osh, pkt); - /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, - F2SYNC, rxbuf, rdlen, - pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", - __FUNCTION__, rdlen, sdret)); - PKTFREE(bus->dhd->osh, pkt, FALSE); - bus->dhd->rx_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - /* Force retry w/normal header read. Don't attemp NAK for - * gSPI - */ - dhdsdio_rxfail(bus, TRUE, - (bus->bus == SPI_BUS) ? FALSE : TRUE); - continue; - } - } - dhd_os_sdunlock_rxq(bus->dhd); - - /* Now check the header */ - bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN); - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means readahead info was bad */ - if (!(len|check)) { - DHD_INFO(("%s (nextlen): read zeros in HW header???\n", - __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" - " 0x%04x/0x%04x/0x%04x\n", __FUNCTION__, nextlen, - len, check)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s (nextlen): HW hdr length invalid: %d\n", - __FUNCTION__, len)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; - continue; - } - - /* Check for consistency with readahead info */ - len_consistent = (nextlen != (ROUNDUP(len, 16) >> 4)); - if (len_consistent) { - /* Mismatch, force retry w/normal header (may be >4K) */ - DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " - "expected rxseq %d\n", - __FUNCTION__, nextlen, len, ROUNDUP(len, 16), rxseq)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, TRUE, (bus->bus == SPI_BUS) ? FALSE : TRUE); - GSPI_PR55150_BAILOUT; - continue; - } - - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - bus->nextlen = - bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large" - " (%d), seq %d\n", __FUNCTION__, bus->nextlen, - seq)); - bus->nextlen = 0; - } - - bus->dhd->rx_readahead_cnt ++; - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s (nextlen): rx_seq %d, expected %d\n", - __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", rxbuf, len); - } else if (DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - if (chan == SDPCM_CONTROL_CHANNEL) { - if (bus->bus == SPI_BUS) { - dhdsdio_read_control(bus, rxbuf, len, doff); - if (bus->usebufpool) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - } - continue; - } else { - DHD_ERROR(("%s (nextlen): readahead on control" - " packet %d?\n", __FUNCTION__, seq)); - /* Force retry w/normal header read */ - bus->nextlen = 0; - dhdsdio_rxfail(bus, FALSE, TRUE); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } - } - - if ((bus->bus == SPI_BUS) && !bus->usebufpool) { - DHD_ERROR(("Received %d bytes on %d channel. Running out of " - "rx pktbuf's or not yet malloced.\n", len, chan)); - continue; - } - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* All done with this one -- now deliver the packet */ - goto deliver; - } - /* gSPI frames should not be handled in fractions */ - if (bus->bus == SPI_BUS) { - break; - } - - /* Read frame header (hardware and software) */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - bus->rxhdr, firstread, NULL, NULL, NULL); - bus->f2rxhdrs++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __FUNCTION__, sdret)); - bus->rx_hdrfail++; - dhdsdio_rxfail(bus, TRUE, TRUE); - continue; - } - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() || DHD_HDRS_ON()) { - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); - } -#endif - - /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); - - /* All zeros means no more frames */ - if (!(len|check)) { - *finished = TRUE; - break; - } - - /* Validate check bytes */ - if ((uint16)~(len^check)) { - DHD_ERROR(("%s: HW hdr error: len/check 0x%04x/0x%04x\n", - __FUNCTION__, len, check)); - bus->rx_badhdr++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Validate frame length */ - if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s: HW hdr length invalid: %d\n", __FUNCTION__, len)); - continue; - } - - /* Extract software header fields */ - chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - /* Validate data offset */ - if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d seq %d\n", - __FUNCTION__, doff, len, SDPCM_HDRLEN, seq)); - bus->rx_badhdr++; - ASSERT(0); - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - /* Save the readahead length if there is one */ - bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; - if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large (%d), seq %d\n", - __FUNCTION__, bus->nextlen, seq)); - bus->nextlen = 0; - } - - /* Handle Flow Control */ - fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } - - if (delta) { - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Check and update sequence number */ - if (rxseq != seq) { - DHD_INFO(("%s: rx_seq %d, expected %d\n", __FUNCTION__, seq, rxseq)); - bus->rx_badseq++; - rxseq = seq; - } - - /* Check window for sanity */ - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_seq + 2; - } - bus->tx_max = txmax; - - /* Call a separate function for control frames */ - if (chan == SDPCM_CONTROL_CHANNEL) { - dhdsdio_read_control(bus, bus->rxhdr, len, doff); - continue; - } - - ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL) || - (chan == SDPCM_TEST_CHANNEL) || (chan == SDPCM_GLOM_CHANNEL)); - - /* Length to read */ - rdlen = (len > firstread) ? (len - firstread) : 0; - - /* May pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { - pad = bus->blocksize - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((rdlen + pad + firstread) < MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); - } - - /* Satisfy length-alignment requirements */ - if (forcealign && (rdlen & (ALIGNMENT - 1))) - rdlen = ROUNDUP(rdlen, ALIGNMENT); - - if ((rdlen + firstread) > MAX_RX_DATASZ) { - /* Too long -- skip this frame */ - DHD_ERROR(("%s: too long: len %d rdlen %d\n", __FUNCTION__, len, rdlen)); - bus->dhd->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, FALSE, FALSE); - continue; - } - - dhd_os_sdlock_rxq(bus->dhd); - if (!(pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), FALSE))) { - /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: PKTGET failed: rdlen %d chan %d\n", - __FUNCTION__, rdlen, chan)); - bus->dhd->rx_dropped++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, FALSE, RETRYCHAN(chan)); - continue; - } - dhd_os_sdunlock_rxq(bus->dhd); - - ASSERT(!PKTLINK(pkt)); - - /* Leave room for what we already read, and align remainder */ - ASSERT(firstread < (PKTLEN(osh, pkt))); - PKTPULL(osh, pkt, firstread); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - - /* Read the remaining frame data */ - sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - ((uint8 *)PKTDATA(osh, pkt)), rdlen, pkt, NULL, NULL); - bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); - - if (sdret < 0) { - DHD_ERROR(("%s: read %d %s bytes failed: %d\n", __FUNCTION__, rdlen, - ((chan == SDPCM_EVENT_CHANNEL) ? "event" : - ((chan == SDPCM_DATA_CHANNEL) ? "data" : "test")), sdret)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, TRUE, RETRYCHAN(chan)); - continue; - } - - /* Copy the already-read portion */ - PKTPUSH(osh, pkt, firstread); - bcopy(bus->rxhdr, PKTDATA(osh, pkt), firstread); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - prhex("Rx Data", PKTDATA(osh, pkt), len); - } -#endif - -deliver: - /* Save superframe descriptor and allocate packet frame */ - if (chan == SDPCM_GLOM_CHANNEL) { - if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { - DHD_GLOM(("%s: got glom descriptor, %d bytes:\n", - __FUNCTION__, len)); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - prhex("Glom Data", PKTDATA(osh, pkt), len); - } -#endif - PKTSETLEN(osh, pkt, len); - ASSERT(doff == SDPCM_HDRLEN); - PKTPULL(osh, pkt, SDPCM_HDRLEN); - bus->glomd = pkt; - } else { - DHD_ERROR(("%s: glom superframe w/o descriptor!\n", __FUNCTION__)); - dhdsdio_rxfail(bus, FALSE, FALSE); - } - continue; - } - - /* Fill in packet len and prio, deliver upward */ - PKTSETLEN(osh, pkt, len); - PKTPULL(osh, pkt, doff); - -#ifdef SDTEST - /* Test channel packets are processed separately */ - if (chan == SDPCM_TEST_CHANNEL) { - dhdsdio_testrcv(bus, pkt, seq); - continue; - } -#endif /* SDTEST */ - - if (PKTLEN(osh, pkt) == 0) { - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, FALSE); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - continue; - } - - - /* Unlock during rx call */ - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, pkt, 1); - dhd_os_sdlock(bus->dhd); - } - rxcount = maxframes - rxleft; -#ifdef DHD_DEBUG - /* Message if we hit the limit */ - if (!rxleft && !sdtest) - DHD_DATA(("%s: hit rx limit of %d frames\n", __FUNCTION__, maxframes)); - else -#endif /* DHD_DEBUG */ - DHD_DATA(("%s: processed %d frames\n", __FUNCTION__, rxcount)); - /* Back off rxseq if awaiting rtx, update rx_seq */ - if (bus->rxskip) - rxseq--; - bus->rx_seq = rxseq; - - return rxcount; -} - -static uint32 -dhdsdio_hostmail(dhd_bus_t *bus) -{ - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus = 0; - uint32 hmb_data; - uint8 fcbits; - uint retries = 0; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Read mailbox data and ack that we did so */ - R_SDREG(hmb_data, ®s->tohostmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_INT_ACK, ®s->tosbmailbox, retries); - bus->f1regdata += 2; - - /* Dongle recomposed rx frames, accept them again */ - if (hmb_data & HMB_DATA_NAKHANDLED) { - DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n", bus->rx_seq)); - if (!bus->rxskip) { - DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __FUNCTION__)); - } - bus->rxskip = FALSE; - intstatus |= I_HMB_FRAME_IND; - } - - /* - * DEVREADY does not occur with gSPI. - */ - if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) { - bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; - if (bus->sdpcm_ver != SDPCM_PROT_VERSION) - DHD_ERROR(("Version mismatch, dongle reports %d, expecting %d\n", - bus->sdpcm_ver, SDPCM_PROT_VERSION)); - else - DHD_INFO(("Dongle ready, protocol version %d\n", bus->sdpcm_ver)); - } - - /* - * Flow Control has been moved into the RX headers and this out of band - * method isn't used any more. Leae this here for possibly remaining backward - * compatible with older dongles - */ - if (hmb_data & HMB_DATA_FC) { - fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT; - - if (fcbits & ~bus->flowcontrol) - bus->fc_xoff++; - if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; - - bus->fc_rcvd++; - bus->flowcontrol = fcbits; - } - - /* Shouldn't be any others */ - if (hmb_data & ~(HMB_DATA_DEVREADY | - HMB_DATA_NAKHANDLED | - HMB_DATA_FC | - HMB_DATA_FWREADY | - HMB_DATA_FCDATA_MASK | - HMB_DATA_VERSION_MASK)) { - DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data)); - } - - return intstatus; -} - -bool -dhdsdio_dpc(dhd_bus_t *bus) -{ - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; - uint32 intstatus, newstatus = 0; - uint retries = 0; - uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */ - uint txlimit = dhd_txbound; /* Tx frames to send before resched */ - uint framecnt = 0; /* Temporary counter of tx/rx frames */ - bool rxdone = TRUE; /* Flag for no more read data */ - bool resched = FALSE; /* Flag indicating resched wanted */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - /* Start with leftover status bits */ - intstatus = bus->intstatus; - - dhd_os_sdlock(bus->dhd); - - /* If waiting for HTAVAIL, check status */ - if (bus->clkstate == CLK_PENDING) { - int err; - uint8 clkctl, devctl = 0; - -#ifdef DHD_DEBUG - /* Check for inconsistent device control */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } else { - ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY); - } -#endif /* DHD_DEBUG */ - - /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - DHD_ERROR(("%s: error reading CSR: %d\n", __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - - DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl)); - - if (SBSDIO_HTAV(clkctl)) { - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - if (err) { - DHD_ERROR(("%s: error writing DEVCTL: %d\n", - __FUNCTION__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } - bus->clkstate = CLK_AVAIL; - } else { - goto clkwait; - } - } - - BUS_WAKE(bus); - - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); - if (bus->clkstate == CLK_PENDING) - goto clkwait; - - /* Pending interrupt indicates new device status */ - if (bus->ipend) { - bus->ipend = FALSE; - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata++; - if (bcmsdh_regfail(bus->sdh)) - newstatus = 0; - newstatus &= bus->hostintmask; - bus->fcstate = !!(newstatus & I_HMB_FC_STATE); - if (newstatus) { - W_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata++; - } - } - - /* Merge new bits with previous */ - intstatus |= newstatus; - bus->intstatus = 0; - - /* Handle flow-control change: read new state in case our ack - * crossed another change interrupt. If change still set, assume - * FC ON for safety, let next loop through do the debounce. - */ - if (intstatus & I_HMB_FC_CHANGE) { - intstatus &= ~I_HMB_FC_CHANGE; - W_SDREG(I_HMB_FC_CHANGE, ®s->intstatus, retries); - R_SDREG(newstatus, ®s->intstatus, retries); - bus->f1regdata += 2; - bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); - intstatus |= (newstatus & bus->hostintmask); - } - - /* Handle host mailbox indication */ - if (intstatus & I_HMB_HOST_INT) { - intstatus &= ~I_HMB_HOST_INT; - intstatus |= dhdsdio_hostmail(bus); - } - - /* Generally don't ask for these, can get CRC errors... */ - if (intstatus & I_WR_OOSYNC) { - DHD_ERROR(("Dongle reports WR_OOSYNC\n")); - intstatus &= ~I_WR_OOSYNC; - } - - if (intstatus & I_RD_OOSYNC) { - DHD_ERROR(("Dongle reports RD_OOSYNC\n")); - intstatus &= ~I_RD_OOSYNC; - } - - if (intstatus & I_SBINT) { - DHD_ERROR(("Dongle reports SBINT\n")); - intstatus &= ~I_SBINT; - } - - /* Would be active due to wake-wlan in gSPI */ - if (intstatus & I_CHIPACTIVE) { - DHD_INFO(("Dongle reports CHIPACTIVE\n")); - intstatus &= ~I_CHIPACTIVE; - } - - /* Ignore frame indications if rxskip is set */ - if (bus->rxskip) - intstatus &= ~I_HMB_FRAME_IND; - - /* On frame indication, read available frames */ - if (PKT_AVAILABLE()) { - framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone); - if (rxdone || bus->rxskip) - intstatus &= ~I_HMB_FRAME_IND; - rxlimit -= MIN(framecnt, rxlimit); - } - - /* Keep still-pending events for next scheduling */ - bus->intstatus = intstatus; - -clkwait: - /* Re-enable interrupts to detect new device events (mailbox, rx frame) - * or clock availability. (Allows tx loop to check ipend if desired.) - * (Unless register access seems hosed, as we may not be able to ACK...) - */ - if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) { - DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n", - __FUNCTION__, rxdone, framecnt)); - bus->intdis = FALSE; -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - bcmsdh_intr_enable(sdh); - } - - if (DATAOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { - int ret, i; - - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, - NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - - if (ret < 0) { - /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __FUNCTION__, ret)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - - printf("Return_dpc value is : %d\n", ret); - bus->ctrl_frame_stat = FALSE; - dhd_wait_event_wakeup(bus->dhd); - } - /* Send queued frames (limit 1 if rx may still be pending) */ - else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { - framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax); - framecnt = dhdsdio_sendfromq(bus, framecnt); - txlimit -= framecnt; - } - - /* Resched if events or tx frames are pending, else await next interrupt */ - /* On failed register access, all bets are off: no resched or interrupts */ - if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { - DHD_ERROR(("%s: failed backplane access over SDIO, halting operation %d \n", - __FUNCTION__, bcmsdh_regfail(sdh))); - bus->dhd->busstate = DHD_BUS_DOWN; - bus->intstatus = 0; - } else if (bus->clkstate == CLK_PENDING) { - DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting \ - I_CHIPACTIVE interrupt", __FUNCTION__)); - resched = TRUE; - } else if (bus->intstatus || bus->ipend || - (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) || - PKT_AVAILABLE()) { /* Read multiple frames */ - resched = TRUE; - } - - - bus->dpc_sched = resched; - - /* If we're done for now, turn off clock request. */ - if ((bus->clkstate != CLK_PENDING) && bus->idletime == DHD_IDLE_IMMEDIATE) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - - dhd_os_sdunlock(bus->dhd); - - return resched; -} - -bool -dhd_bus_dpc(struct dhd_bus *bus) -{ - bool resched; - - /* Call the DPC directly. */ - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - resched = dhdsdio_dpc(bus); - - return resched; -} - -void -dhdsdio_isr(void *arg) -{ - dhd_bus_t *bus = (dhd_bus_t*)arg; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (!bus) { - DHD_ERROR(("%s : bus is null pointer , exit \n", __FUNCTION__)); - return; - } - sdh = bus->sdh; - - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); - return; - } - /* Count the interrupt call */ - bus->intrcount++; - bus->ipend = TRUE; - - /* Shouldn't get this interrupt if we're sleeping? */ - if (bus->sleeping) { - DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); - return; - } - - /* Disable additional interrupts (is this needed now)? */ - if (bus->intr) { - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - } else { - DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n")); - } - - bcmsdh_intr_disable(sdh); - bus->intdis = TRUE; - -#if defined(SDIO_ISR_THREAD) - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); - dhd_os_wake_lock(bus->dhd); - while (dhdsdio_dpc(bus)); - dhd_os_wake_unlock(bus->dhd); -#else - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); -#endif - -} - -#ifdef SDTEST -static void -dhdsdio_pktgen_init(dhd_bus_t *bus) -{ - /* Default to specified length, or full range */ - if (dhd_pktgen_len) { - bus->pktgen_maxlen = MIN(dhd_pktgen_len, MAX_PKTGEN_LEN); - bus->pktgen_minlen = bus->pktgen_maxlen; - } else { - bus->pktgen_maxlen = MAX_PKTGEN_LEN; - bus->pktgen_minlen = 0; - } - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Default to per-watchdog burst with 10s print time */ - bus->pktgen_freq = 1; - bus->pktgen_print = 10000 / dhd_watchdog_ms; - bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; - - /* Default to echo mode */ - bus->pktgen_mode = DHD_PKTGEN_ECHO; - bus->pktgen_stop = 1; -} - -static void -dhdsdio_pktgen(dhd_bus_t *bus) -{ - void *pkt; - uint8 *data; - uint pktcount; - uint fillbyte; - osl_t *osh = bus->dhd->osh; - uint16 len; - - /* Display current count if appropriate */ - if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { - bus->pktgen_ptick = 0; - printf("%s: send attempts %d rcvd %d\n", - __FUNCTION__, bus->pktgen_sent, bus->pktgen_rcvd); - } - - /* For recv mode, just make sure dongle has started sending */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (!bus->pktgen_rcvd) - dhdsdio_sdtest_set(bus, TRUE); - return; - } - - /* Otherwise, generate or request the specified number of packets */ - for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) { - /* Stop if total has been reached */ - if (bus->pktgen_total && (bus->pktgen_sent >= bus->pktgen_total)) { - bus->pktgen_count = 0; - break; - } - - /* Allocate an appropriate-sized packet */ - len = bus->pktgen_len; - if (!(pkt = PKTGET(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), - TRUE))) {; - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - break; - } - PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Write test header cmd and extra based on mode */ - switch (bus->pktgen_mode) { - case DHD_PKTGEN_ECHO: - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_SEND: - *data++ = SDPCM_TEST_DISCARD; - *data++ = (uint8)bus->pktgen_sent; - break; - - case DHD_PKTGEN_RXBURST: - *data++ = SDPCM_TEST_BURST; - *data++ = (uint8)bus->pktgen_count; - break; - - default: - DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - PKTFREE(osh, pkt, TRUE); - bus->pktgen_count = 0; - return; - } - - /* Write test header length field */ - *data++ = (len >> 0); - *data++ = (len >> 8); - - /* Then fill in the remainder -- N/A for burst, but who cares... */ - for (fillbyte = 0; fillbyte < len; fillbyte++) - *data++ = SDPCM_TEST_FILL(fillbyte, (uint8)bus->pktgen_sent); - -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - prhex("dhdsdio_pktgen: Tx Data", data, PKTLEN(osh, pkt) - SDPCM_HDRLEN); - } -#endif - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) { - bus->pktgen_fail++; - if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail) - bus->pktgen_count = 0; - } - bus->pktgen_sent++; - - /* Bump length if not fixed, wrap at max */ - if (++bus->pktgen_len > bus->pktgen_maxlen) - bus->pktgen_len = (uint16)bus->pktgen_minlen; - - /* Special case for burst mode: just send one request! */ - if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) - break; - } -} - -static void -dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) -{ - void *pkt; - uint8 *data; - osl_t *osh = bus->dhd->osh; - - /* Allocate the packet */ - if (!(pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, TRUE))) { - DHD_ERROR(("%s: PKTGET failed!\n", __FUNCTION__)); - return; - } - PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; - - /* Fill in the test header */ - *data++ = SDPCM_TEST_SEND; - *data++ = start; - *data++ = (bus->pktgen_maxlen >> 0); - *data++ = (bus->pktgen_maxlen >> 8); - - /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE)) - bus->pktgen_fail++; -} - - -static void -dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) -{ - osl_t *osh = bus->dhd->osh; - uint8 *data; - uint pktlen; - - uint8 cmd; - uint8 extra; - uint16 len; - uint16 offset; - - /* Check for min length */ - if ((pktlen = PKTLEN(osh, pkt)) < SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - PKTFREE(osh, pkt, FALSE); - return; - } - - /* Extract header fields */ - data = PKTDATA(osh, pkt); - cmd = *data++; - extra = *data++; - len = *data++; len += *data++ << 8; - - /* Check length for relevant commands */ - if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) { - if (pktlen != len + SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - return; - } - } - - /* Process as per command */ - switch (cmd) { - case SDPCM_TEST_ECHOREQ: - /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ - *(uint8 *)(PKTDATA(osh, pkt)) = SDPCM_TEST_ECHORSP; - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE) == 0) { - bus->pktgen_sent++; - } else { - bus->pktgen_fail++; - PKTFREE(osh, pkt, FALSE); - } - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_ECHORSP: - if (bus->ext_loop) { - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - } - - for (offset = 0; offset < len; offset++, data++) { - if (*data != SDPCM_TEST_FILL(offset, extra)) { - DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " - "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n", - offset, len, SDPCM_TEST_FILL(offset, extra), *data)); - break; - } - } - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_DISCARD: - PKTFREE(osh, pkt, FALSE); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_BURST: - case SDPCM_TEST_SEND: - default: - DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, pktlen %d seq %d" - " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, FALSE); - break; - } - - /* For recv mode, stop at limie (and tell dongle to stop sending) */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { - if (bus->pktgen_total && (bus->pktgen_rcvd >= bus->pktgen_total)) { - bus->pktgen_count = 0; - dhdsdio_sdtest_set(bus, FALSE); - } - } -} -#endif /* SDTEST */ - -extern bool -dhd_bus_watchdog(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus; - - DHD_TIMER(("%s: Enter\n", __FUNCTION__)); - - bus = dhdp->bus; - - if (bus->dhd->dongle_reset) - return FALSE; - - /* Ignore the timer if simulating bus down */ - if (bus->sleeping) - return FALSE; - - /* Poll period: check device if appropriate. */ - if (bus->poll && (++bus->polltick >= bus->pollrate)) { - uint32 intstatus = 0; - - /* Reset poll tick */ - bus->polltick = 0; - - /* Check device if no interrupts */ - if (!bus->intr || (bus->intrcount == bus->lastintrs)) { - - if (!bus->dpc_sched) { - uint8 devpend; - devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, - SDIOD_CCCR_INTPEND, NULL); - intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); - } - - /* If there is something, make like the ISR and schedule the DPC */ - if (intstatus) { - bus->pollcnt++; - bus->ipend = TRUE; - if (bus->intr) { - bcmsdh_intr_disable(bus->sdh); - } - bus->dpc_sched = TRUE; - dhd_sched_dpc(bus->dhd); - - } - } - - /* Update interrupt tracking */ - bus->lastintrs = bus->intrcount; - } - -#ifdef DHD_DEBUG - /* Poll for console output periodically */ - if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) { - bus->console.count += dhd_watchdog_ms; - if (bus->console.count >= dhd_console_ms) { - bus->console.count -= dhd_console_ms; - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - if (dhdsdio_readconsole(bus) < 0) - dhd_console_ms = 0; /* On error, stop trying */ - } - } -#endif /* DHD_DEBUG */ - -#ifdef SDTEST - /* Generate packets if configured */ - if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { - /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - bus->pktgen_tick = 0; - dhdsdio_pktgen(bus); - } -#endif - - /* On idle timeout clear activity flag and/or turn off clock */ - if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { - if (++bus->idlecount >= bus->idletime) { - bus->idlecount = 0; - if (bus->activity) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - } - } - } - - return bus->ipend; -} - -#ifdef DHD_DEBUG -extern int -dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen) -{ - dhd_bus_t *bus = dhdp->bus; - uint32 addr, val; - int rv; - void *pkt; - - /* Address could be zero if CONSOLE := 0 in dongle Makefile */ - if (bus->console_addr == 0) - return BCME_UNSUPPORTED; - - /* Exclusive bus access */ - dhd_os_sdlock(bus->dhd); - - /* Don't allow input if dongle is in reset */ - if (bus->dhd->dongle_reset) { - dhd_os_sdunlock(bus->dhd); - return BCME_NOTREADY; - } - - /* Request clock to allow SDIO accesses */ - BUS_WAKE(bus); - /* No pend allowed since txpkt is called later, ht clk has to be on */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - /* Zero cbuf_index */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf_idx); - val = htol32(0); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Write message into cbuf */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)msg, msglen)) < 0) - goto done; - - /* Write length into vcons_in */ - addr = bus->console_addr + OFFSETOF(hndrte_cons_t, vcons_in); - val = htol32(msglen); - if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) - goto done; - - /* Bump dongle by sending an empty event pkt. - * sdpcm_sendup (RX) checks for virtual console input. - */ - if (((pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, TRUE)) != NULL) && - bus->clkstate == CLK_AVAIL) - dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, TRUE); - -done: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { - bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, TRUE); - } - - dhd_os_sdunlock(bus->dhd); - - return rv; -} -#endif /* DHD_DEBUG */ - -#ifdef DHD_DEBUG -static void -dhd_dump_cis(uint fn, uint8 *cis) -{ - uint byte, tag, tdata; - DHD_INFO(("Function %d CIS:\n", fn)); - - for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) { - if ((byte % 16) == 0) - DHD_INFO((" ")); - DHD_INFO(("%02x ", cis[byte])); - if ((byte % 16) == 15) - DHD_INFO(("\n")); - if (!tdata--) { - tag = cis[byte]; - if (tag == 0xff) - break; - else if (!tag) - tdata = 0; - else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT) - tdata = cis[byte + 1] + 1; - else - DHD_INFO(("]")); - } - } - if ((byte % 16) != 15) - DHD_INFO(("\n")); -} -#endif /* DHD_DEBUG */ - -static bool -dhdsdio_chipmatch(uint16 chipid) -{ - if (chipid == BCM4325_CHIP_ID) - return TRUE; - if (chipid == BCM4329_CHIP_ID) - return TRUE; - if (chipid == BCM4315_CHIP_ID) - return TRUE; - if (chipid == BCM4319_CHIP_ID) - return TRUE; - return FALSE; -} - -static void * -dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, - uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh) -{ - int ret; - dhd_bus_t *bus; - - /* Init global variables at run-time, not as part of the declaration. - * This is required to support init/de-init of the driver. Initialization - * of globals as part of the declaration results in non-deterministic - * behavior since the value of the globals may be different on the - * first time that the driver is initialized vs subsequent initializations. - */ - dhd_txbound = DHD_TXBOUND; - dhd_rxbound = DHD_RXBOUND; - dhd_alignctl = TRUE; - sd1idle = TRUE; - dhd_readahead = TRUE; - retrydata = FALSE; - dhd_doflow = FALSE; - dhd_dongle_memsize = 0; - dhd_txminmax = DHD_TXMINMAX; - - forcealign = TRUE; - - - dhd_common_init(); - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid)); - - /* We make assumptions about address window mappings */ - ASSERT((uintptr)regsva == SI_ENUM_BASE); - - /* BCMSDH passes venid and devid based on CIS parsing -- but low-power start - * means early parse could fail, so here we should get either an ID - * we recognize OR (-1) indicating we must request power first. - */ - /* Check the Vendor ID */ - switch (venid) { - case 0x0000: - case VENDOR_BROADCOM: - break; - default: - DHD_ERROR(("%s: unknown vendor: 0x%04x\n", - __FUNCTION__, venid)); - return NULL; - } - - /* Check the Device ID and make sure it's one that we support */ - switch (devid) { - case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ - case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ - case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ - DHD_INFO(("%s: found 4325 Dongle\n", __FUNCTION__)); - break; - case BCM4329_D11NDUAL_ID: /* 4329 802.11n dualband device */ - case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ - case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ - case 0x4329: - DHD_INFO(("%s: found 4329 Dongle\n", __FUNCTION__)); - break; - case BCM4315_D11DUAL_ID: /* 4315 802.11a/g id */ - case BCM4315_D11G_ID: /* 4315 802.11g id */ - case BCM4315_D11A_ID: /* 4315 802.11a id */ - DHD_INFO(("%s: found 4315 Dongle\n", __FUNCTION__)); - break; - case BCM4319_D11N_ID: /* 4319 802.11n id */ - case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ - case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ - DHD_INFO(("%s: found 4319 Dongle\n", __FUNCTION__)); - break; - case 0: - DHD_INFO(("%s: allow device id 0, will check chip internals\n", - __FUNCTION__)); - break; - - default: - DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", - __FUNCTION__, venid, devid)); - return NULL; - } - - if (osh == NULL) { - /* Ask the OS interface part for an OSL handle */ - if (!(osh = dhd_osl_attach(sdh, DHD_BUS))) { - DHD_ERROR(("%s: osl_attach failed!\n", __FUNCTION__)); - return NULL; - } - } - - /* Allocate private bus interface state */ - if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) { - DHD_ERROR(("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__)); - goto fail; - } - bzero(bus, sizeof(dhd_bus_t)); - bus->sdh = sdh; - bus->cl_devid = (uint16)devid; - bus->bus = DHD_BUS; - bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; - bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */ - - /* attempt to attach to the dongle */ - if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) { - DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __FUNCTION__)); - goto fail; - } - - /* Attach to the dhd/OS/network interface */ - if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) { - DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__)); - goto fail; - } - - /* Allocate buffers */ - if (!(dhdsdio_probe_malloc(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__)); - goto fail; - } - - if (!(dhdsdio_probe_init(bus, osh, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __FUNCTION__)); - goto fail; - } - - /* Register interrupt callback, but mask it (not operational yet). */ - DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__)); - bcmsdh_intr_disable(sdh); - if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) { - DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n", - __FUNCTION__, ret)); - goto fail; - } - DHD_INTR(("%s: registered SDIO interrupt function ok\n", __FUNCTION__)); - - DHD_INFO(("%s: completed!!\n", __FUNCTION__)); - - - /* if firmware path present try to download and bring up bus */ - if ((ret = dhd_bus_start(bus->dhd)) != 0) { -#if 1 - DHD_ERROR(("%s: failed\n", __FUNCTION__)); - goto fail; -#else - if (ret == BCME_NOTUP) { - DHD_ERROR(("%s: dongle is not responding\n", __FUNCTION__)); - goto fail; - } -#endif - } - /* Ok, have the per-port tell the stack we're open for business */ - if (dhd_net_attach(bus->dhd, 0) != 0) { - DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__)); - goto fail; - } - - return bus; - -fail: - dhdsdio_release(bus, osh); - return NULL; -} - - -static bool -dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, - uint16 devid) -{ - uint8 clkctl = 0; - int err = 0; - - bus->alp_only = TRUE; - - /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) { - DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__)); - } - -#ifdef DHD_DEBUG - printf("F1 signature read @0x18000000=0x%4x\n", - bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4)); - - -#endif /* DHD_DEBUG */ - - - /* Force PLL off until si_attach() programs PLL control regs */ - - - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err); - if (!err) - clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - - if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) { - DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", - err, DHD_INIT_CLKCTL1, clkctl)); - goto fail; - } - - -#ifdef DHD_DEBUG - if (DHD_INFO_ON()) { - uint fn, numfn; - uint8 *cis[SDIOD_MAX_IOFUNCS]; - int err = 0; - - numfn = bcmsdh_query_iofnum(sdh); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - /* Make sure ALP is available before trying to read CIS */ - SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), - !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY); - - /* Now request ALP be put on the bus */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - DHD_INIT_CLKCTL2, &err); - OSL_DELAY(65); - - for (fn = 0; fn <= numfn; fn++) { - if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn)); - break; - } - bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT); - - if ((err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT))) { - DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err)); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - break; - } - dhd_dump_cis(fn, cis[fn]); - } - - while (fn-- > 0) { - ASSERT(cis[fn]); - MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); - } - - if (err) { - DHD_ERROR(("dhdsdio_probe: failure reading or parsing CIS\n")); - goto fail; - } - } -#endif /* DHD_DEBUG */ - - /* si_attach() will provide an SI handle and scan the backplane */ - if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh, - &bus->vars, &bus->varsz))) { - DHD_ERROR(("%s: si_attach failed!\n", __FUNCTION__)); - goto fail; - } - - bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); - - if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) { - DHD_ERROR(("%s: unsupported chip: 0x%04x\n", - __FUNCTION__, bus->sih->chip)); - goto fail; - } - - si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); - - - /* Get info on the ARM and SOCRAM cores... */ - if (!DHD_NOPMU(bus)) { - if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) || - (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - bus->armrev = si_corerev(bus->sih); - } else { - DHD_ERROR(("%s: failed to find ARM core!\n", __FUNCTION__)); - goto fail; - } - if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { - DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); - goto fail; - } - bus->ramsize = bus->orig_ramsize; - if (dhd_dongle_memsize) - dhd_dongle_setmemsize(bus, dhd_dongle_memsize); - - DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", - bus->ramsize, bus->orig_ramsize)); - } - - /* ...but normally deal with the SDPCMDEV core */ - if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) && - !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) { - DHD_ERROR(("%s: failed to find SDIODEV core!\n", __FUNCTION__)); - goto fail; - } - bus->sdpcmrev = si_corerev(bus->sih); - - /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN); - - pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); - - /* Locate an appropriately-aligned portion of hdrbuf */ - bus->rxhdr = (uint8 *)ROUNDUP((uintptr)&bus->hdrbuf[0], DHD_SDALIGN); - - /* Set the poll and/or interrupt flags */ - bus->intr = (bool)dhd_intr; - if ((bus->poll = (bool)dhd_poll)) - bus->pollrate = 1; - - return TRUE; - -fail: - return FALSE; -} - -static bool -dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifndef DHD_USE_STATIC_BUF - if (bus->dhd->maxctl) { - bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; - if (!(bus->rxbuf = MALLOC(osh, bus->rxblen))) { - DHD_ERROR(("%s: MALLOC of %d-byte rxbuf failed\n", - __FUNCTION__, bus->rxblen)); - goto fail; - } - } - - /* Allocate buffer to receive glomed packet */ - if (!(bus->databuf = MALLOC(osh, MAX_DATA_BUF))) { - DHD_ERROR(("%s: MALLOC of %d-byte databuf failed\n", - __FUNCTION__, MAX_DATA_BUF)); - /* release rxbuf which was already located as above */ - if (!bus->rxblen) MFREE(osh, bus->rxbuf, bus->rxblen); - goto fail; - } -#else - if (bus->dhd->maxctl) { - bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; - if (!(bus->rxbuf = dhd_os_prealloc(DHD_PREALLOC_RXBUF, bus->rxblen))) { - DHD_ERROR(("%s: MALLOC of %d-byte rxbuf failed\n", - __FUNCTION__, bus->rxblen)); - goto fail; - } - } - /* Allocate buffer to receive glomed packet */ - if (!(bus->databuf = dhd_os_prealloc(DHD_PREALLOC_DATABUF, MAX_DATA_BUF))) { - DHD_ERROR(("%s: MALLOC of %d-byte databuf failed\n", - __FUNCTION__, MAX_DATA_BUF)); - goto fail; - } -#endif /* DHD_USE_STATIC_BUF */ - - /* Align the buffer */ - if ((uintptr)bus->databuf % DHD_SDALIGN) - bus->dataptr = bus->databuf + (DHD_SDALIGN - ((uintptr)bus->databuf % DHD_SDALIGN)); - else - bus->dataptr = bus->databuf; - - return TRUE; - -fail: - return FALSE; -} - - -static bool -dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) -{ - int32 fnum; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - -#ifdef SDTEST - dhdsdio_pktgen_init(bus); -#endif /* SDTEST */ - - /* Disable F2 to clear any intermediate frame state on the dongle */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - - bus->dhd->busstate = DHD_BUS_DOWN; - bus->sleeping = FALSE; - bus->rxflow = FALSE; - bus->prev_rxlim_hit = 0; - - - /* Done with backplane-dependent accesses, can drop clock... */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - - /* ...and initialize clock/power states */ - bus->clkstate = CLK_SDONLY; - bus->idletime = (int32)dhd_idletime; - bus->idleclock = DHD_IDLE_ACTIVE; - - /* Query the SD clock speed */ - if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_divisor")); - bus->sd_divisor = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_divisor", bus->sd_divisor)); - } - - /* Query the SD bus mode */ - if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_mode")); - bus->sd_mode = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_mode", bus->sd_mode)); - } - - /* Query the F2 block size, set roundup accordingly */ - fnum = 2; - if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(int32), - &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { - bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize")); - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __FUNCTION__, "sd_blocksize", bus->blocksize)); - } - bus->roundup = MIN(max_roundup, bus->blocksize); - - /* Query if bus module supports packet chaining, default to use if supported */ - if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, - &bus->sd_rxchain, sizeof(int32), FALSE) != BCME_OK) { - bus->sd_rxchain = FALSE; - } else { - DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n", - __FUNCTION__, (bus->sd_rxchain ? "supports" : "does not support"))); - } - bus->use_rxchain = (bool)bus->sd_rxchain; - - return TRUE; -} - -bool -dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, - char *fw_path, char *nv_path) -{ - bool ret; - bus->fw_path = fw_path; - bus->nv_path = nv_path; - - ret = dhdsdio_download_firmware(bus, osh, bus->sdh); - - return ret; -} - -static bool -dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) -{ - bool ret; - - /* Download the firmware */ - dhd_os_wake_lock(bus->dhd); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - - ret = _dhdsdio_download_firmware(bus) == 0; - - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - dhd_os_wake_unlock(bus->dhd); - return ret; -} - -/* Detach and free everything */ -static void -dhdsdio_release(dhd_bus_t *bus, osl_t *osh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(osh); - - - /* De-register interrupt handler */ - bcmsdh_intr_disable(bus->sdh); - bcmsdh_intr_dereg(bus->sdh); - - if (bus->dhd) { - - dhdsdio_release_dongle(bus, osh, TRUE); - - dhd_detach(bus->dhd); - bus->dhd = NULL; - } - - dhdsdio_release_malloc(bus, osh); - - - MFREE(osh, bus, sizeof(dhd_bus_t)); - } - - if (osh) - dhd_osl_detach(osh); - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus->dhd && bus->dhd->dongle_reset) - return; - - if (bus->rxbuf) { -#ifndef DHD_USE_STATIC_BUF - MFREE(osh, bus->rxbuf, bus->rxblen); -#endif - bus->rxctl = bus->rxbuf = NULL; - bus->rxlen = 0; - } - - if (bus->databuf) { -#ifndef DHD_USE_STATIC_BUF - MFREE(osh, bus->databuf, MAX_DATA_BUF); -#endif - bus->databuf = NULL; - } -} - - -static void -dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag) - return; - - if (bus->sih) { - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -#if !defined(BCMLXSDMMC) - si_watchdog(bus->sih, 4); -#endif /* !defined(BCMLXSDMMC) */ - dhdsdio_clkctl(bus, CLK_NONE, FALSE); - si_detach(bus->sih); - if (bus->vars && bus->varsz) - MFREE(osh, bus->vars, bus->varsz); - bus->vars = NULL; - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - -static void -dhdsdio_disconnect(void *ptr) -{ - dhd_bus_t *bus = (dhd_bus_t *)ptr; - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (bus) { - ASSERT(bus->dhd); - dhdsdio_release(bus, bus->dhd->osh); - } - - DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); -} - - -/* Register/Unregister functions are called by the main DHD entry - * point (e.g. module insertion) to link with the bus driver, in - * order to look for or await the device. - */ - -static bcmsdh_driver_t dhd_sdio = { - dhdsdio_probe, - dhdsdio_disconnect -}; - -int -dhd_bus_register(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - return bcmsdh_register(&dhd_sdio); -} - -void -dhd_bus_unregister(void) -{ - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_unregister(); -} - -#ifdef BCMEMBEDIMAGE -static int -dhdsdio_download_code_array(struct dhd_bus *bus) -{ - int bcmerror = -1; - int offset = 0; - - DHD_INFO(("%s: download embedded firmware...\n", __FUNCTION__)); - - /* Download image */ - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, dlarray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, - dlarray + offset, sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - -#ifdef DHD_DEBUG - /* Upload and compare the downloaded code */ - { - unsigned char *ularray; - - ularray = MALLOC(bus->dhd->osh, bus->ramsize); - /* Upload image to verify downloaded contents. */ - offset = 0; - memset(ularray, 0xaa, bus->ramsize); - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, ularray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, FALSE, offset, - ularray + offset, sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; - } - } - - if (memcmp(dlarray, ularray, sizeof(dlarray))) { - DHD_ERROR(("%s: Downloaded image is corrupted.\n", __FUNCTION__)); - ASSERT(0); - goto err; - } else - DHD_ERROR(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__)); - - MFREE(bus->dhd->osh, ularray, bus->ramsize); - } -#endif /* DHD_DEBUG */ - -err: - return bcmerror; -} -#endif /* BCMEMBEDIMAGE */ - -static int -dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) -{ - int bcmerror = -1; - int offset = 0; - uint len; - void *image = NULL; - uint8 *memblock = NULL, *memptr; - - DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, fw_path)); - - image = dhd_os_open_image(fw_path); - if (image == NULL) - goto err; - - memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); - goto err; - } - if ((uint32)(uintptr)memblock % DHD_SDALIGN) - memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); - - /* Download image */ - while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, image))) { - bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -/* - * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. - * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. - * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. -*/ - -static uint -process_nvram_vars(char *varbuf, uint len) -{ - char *dp; - bool findNewline; - int column; - uint buf_len, n; - - dp = varbuf; - - findNewline = FALSE; - column = 0; - - for (n = 0; n < len; n++) { - if (varbuf[n] == 0) - break; - if (varbuf[n] == '\r') - continue; - if (findNewline && varbuf[n] != '\n') - continue; - findNewline = FALSE; - if (varbuf[n] == '#') { - findNewline = TRUE; - continue; - } - if (varbuf[n] == '\n') { - if (column == 0) - continue; - *dp++ = 0; - column = 0; - continue; - } - *dp++ = varbuf[n]; - column++; - } - buf_len = dp - varbuf; - - while (dp < varbuf + n) - *dp++ = 0; - - return buf_len; -} - -/* - EXAMPLE: nvram_array - nvram_arry format: - name=value - Use carriage return at the end of each assignment, and an empty string with - carriage return at the end of array. - - For example: - unsigned char nvram_array[] = {"name1=value1\n", "name2=value2\n", "\n"}; - Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx. - - Search "EXAMPLE: nvram_array" to see how the array is activated. -*/ - -void -dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params) -{ - bus->nvram_params = nvram_params; -} - -static int -dhdsdio_download_nvram(struct dhd_bus *bus) -{ - int bcmerror = -1; - uint len; - void * image = NULL; - char * memblock = NULL; - char *bufp; - char *nv_path; - bool nvram_file_exists; - - nv_path = bus->nv_path; - - nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0')); - if (!nvram_file_exists && (bus->nvram_params == NULL)) - return (0); - - if (nvram_file_exists) { - image = dhd_os_open_image(nv_path); - if (image == NULL) - goto err; - } - - memblock = MALLOC(bus->dhd->osh, MEMBLOCK); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MEMBLOCK)); - goto err; - } - - /* Download variables */ - if (nvram_file_exists) { - len = dhd_os_get_image_block(memblock, MEMBLOCK, image); - } - else { - len = strlen(bus->nvram_params); - ASSERT(len <= MEMBLOCK); - if (len > MEMBLOCK) - len = MEMBLOCK; - memcpy(memblock, bus->nvram_params, len); - } - - if (len > 0 && len < MEMBLOCK) { - bufp = (char *)memblock; - bufp[len] = 0; - len = process_nvram_vars(bufp, len); - bufp += len; - *bufp++ = 0; - if (len) - bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); - if (bcmerror) { - DHD_ERROR(("%s: error downloading vars: %d\n", - __FUNCTION__, bcmerror)); - } - } - else { - DHD_ERROR(("%s: error reading nvram file: %d\n", - __FUNCTION__, len)); - bcmerror = BCME_SDIO_ERROR; - } - -err: - if (memblock) - MFREE(bus->dhd->osh, memblock, MEMBLOCK); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -static int -_dhdsdio_download_firmware(struct dhd_bus *bus) -{ - int bcmerror = -1; - - bool embed = FALSE; /* download embedded firmware */ - bool dlok = FALSE; /* download firmware succeeded */ - - /* Out immediately if no image to download */ - if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) { -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - return bcmerror; -#endif - } - - /* Keep arm in reset */ - if (dhdsdio_download_state(bus, TRUE)) { - DHD_ERROR(("%s: error placing ARM core in reset\n", __FUNCTION__)); - goto err; - } - - /* External image takes precedence if specified */ - if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { - if (dhdsdio_download_code_file(bus, bus->fw_path)) { - DHD_ERROR(("%s: dongle image file download failed\n", __FUNCTION__)); -#ifdef BCMEMBEDIMAGE - embed = TRUE; -#else - goto err; -#endif - } - else { - embed = FALSE; - dlok = TRUE; - } - } -#ifdef BCMEMBEDIMAGE - if (embed) { - if (dhdsdio_download_code_array(bus)) { - DHD_ERROR(("%s: dongle image array download failed\n", __FUNCTION__)); - goto err; - } - else { - dlok = TRUE; - } - } -#endif - if (!dlok) { - DHD_ERROR(("%s: dongle image download failed\n", __FUNCTION__)); - goto err; - } - - /* EXAMPLE: nvram_array */ - /* If a valid nvram_arry is specified as above, it can be passed down to dongle */ - /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ - - /* External nvram takes precedence if specified */ - if (dhdsdio_download_nvram(bus)) { - DHD_ERROR(("%s: dongle nvram file download failed\n", __FUNCTION__)); - } - - /* Take arm out of reset */ - if (dhdsdio_download_state(bus, FALSE)) { - DHD_ERROR(("%s: error getting out of ARM core reset\n", __FUNCTION__)); - goto err; - } - - bcmerror = 0; - -err: - return bcmerror; -} - -static int -dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - int status; - - /* 4329: GSPI check */ - status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle); - return status; -} - -static int -dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, - void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -{ - return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle)); -} - -uint -dhd_bus_chip(struct dhd_bus *bus) -{ - ASSERT(bus->sih != NULL); - return bus->sih->chip; -} - -void * -dhd_bus_pub(struct dhd_bus *bus) -{ - return bus->dhd; -} - -void * -dhd_bus_txq(struct dhd_bus *bus) -{ - return &bus->txq; -} - -uint -dhd_bus_hdrlen(struct dhd_bus *bus) -{ - return SDPCM_HDRLEN; -} - -int -dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) -{ - int bcmerror = 0; - dhd_bus_t *bus; - - bus = dhdp->bus; - - if (flag == TRUE) { - if (!bus->dhd->dongle_reset) { - dhd_os_sdlock(dhdp); - /* Turning off watchdog */ - dhd_os_wd_timer(dhdp, 0); -#if !defined(IGNORE_ETH0_DOWN) - /* Force flow control as protection when stop come before ifconfig_down */ - dhd_txflowcontrol(bus->dhd, 0, ON); -#endif /* !defined(IGNORE_ETH0_DOWN) */ - /* Expect app to have torn down any connection before calling */ - /* Stop the bus, disable F2 */ - dhd_bus_stop(bus, FALSE); -#if defined(OOB_INTR_ONLY) - bcmsdh_set_irq(FALSE); -#endif /* defined(OOB_INTR_ONLY) */ - /* Clean tx/rx buffer pointers, detach from the dongle */ - dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE); - - bus->dhd->dongle_reset = TRUE; - bus->dhd->up = FALSE; - dhd_os_sdunlock(dhdp); - - DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__)); - /* App can now remove power from device */ - } else - bcmerror = BCME_SDIO_ERROR; - } else { - /* App must have restored power to device before calling */ - - DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __FUNCTION__)); - - if (bus->dhd->dongle_reset) { - /* Turn on WLAN */ - dhd_os_sdlock(dhdp); - - /* Reset SD client */ - bcmsdh_reset(bus->sdh); - - /* Attempt to re-attach & download */ - if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh, - (uint32 *)SI_ENUM_BASE, - bus->cl_devid)) { - /* Attempt to download binary to the dongle */ - if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) && - dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) { - - /* Re-init bus, enable F2 transfer */ - bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); - if (bcmerror == BCME_OK) { -#if defined(OOB_INTR_ONLY) - bcmsdh_set_irq(TRUE); - dhd_enable_oob_intr(bus, TRUE); -#endif /* defined(OOB_INTR_ONLY) */ - bus->dhd->dongle_reset = FALSE; - bus->dhd->up = TRUE; -#if !defined(IGNORE_ETH0_DOWN) - /* Restore flow control */ - dhd_txflowcontrol(bus->dhd, 0, OFF); -#endif - /* Turning on watchdog back */ - dhd_os_wd_timer(dhdp, dhd_watchdog_ms); - - DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); - } else { - dhd_bus_stop(bus, FALSE); - dhdsdio_release_dongle(bus, bus->dhd->osh, FALSE); - } - } else - bcmerror = BCME_SDIO_ERROR; - } else - bcmerror = BCME_SDIO_ERROR; - - dhd_os_sdunlock(dhdp); - } else { - bcmerror = BCME_NOTDOWN; - DHD_ERROR(("%s: Set DEVRESET=FALSE invoked when device is on\n", - __FUNCTION__)); - bcmerror = BCME_SDIO_ERROR; - } - } - return bcmerror; -} diff --git a/drivers/net/wireless/bcm4329/dngl_stats.h b/drivers/net/wireless/bcm4329/dngl_stats.h deleted file mode 100644 index e5db54e7edfe..000000000000 --- a/drivers/net/wireless/bcm4329/dngl_stats.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Common stats definitions for clients of dongle - * ports - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dngl_stats.h,v 1.2.140.3 2008/05/26 16:52:08 Exp $ - */ - -#ifndef _dngl_stats_h_ -#define _dngl_stats_h_ - -typedef struct { - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmitted */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmitted */ - unsigned long rx_errors; /* bad packets received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* packets dropped by dongle */ - unsigned long tx_dropped; /* packets dropped by dongle */ - unsigned long multicast; /* multicast packets received */ -} dngl_stats_t; - -#endif /* _dngl_stats_h_ */ diff --git a/drivers/net/wireless/bcm4329/hndpmu.c b/drivers/net/wireless/bcm4329/hndpmu.c deleted file mode 100644 index 307347a43bde..000000000000 --- a/drivers/net/wireless/bcm4329/hndpmu.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Misc utility routines for accessing PMU corerev specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: hndpmu.c,v 1.95.2.17.4.11.2.63 2010/07/21 13:55:09 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug/trace */ -#define PMU_ERROR(args) - -#define PMU_MSG(args) - - -/* SDIO Pad drive strength to select value mappings */ -typedef struct { - uint8 strength; /* Pad Drive Strength in mA */ - uint8 sel; /* Chip-specific select value */ -} sdiod_drive_str_t; - -/* SDIO Drive Strength to sel value table for PMU Rev 1 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { - {4, 0x2}, - {2, 0x3}, - {1, 0x0}, - {0, 0x0} }; - -/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { - {12, 0x7}, - {10, 0x6}, - {8, 0x5}, - {6, 0x4}, - {4, 0x2}, - {2, 0x1}, - {0, 0x0} }; - -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) - -void -si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength) -{ - chipcregs_t *cc; - uint origidx, intr_val = 0; - sdiod_drive_str_t *str_tab = NULL; - uint32 str_mask = 0; - uint32 str_shift = 0; - - if (!(sih->cccaps & CC_CAP_PMU)) { - return; - } - - /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); - - switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; - str_mask = 0x30000000; - str_shift = 28; - break; - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): - case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; - str_mask = 0x00003800; - str_shift = 11; - break; - - default: - PMU_MSG(("No SDIO Drive strength init done for chip %x rev %d pmurev %d\n", - sih->chip, sih->chiprev, sih->pmurev)); - - break; - } - - if (str_tab != NULL) { - uint32 drivestrength_sel = 0; - uint32 cc_data_temp; - int i; - - for (i = 0; str_tab[i].strength != 0; i ++) { - if (drivestrength >= str_tab[i].strength) { - drivestrength_sel = str_tab[i].sel; - break; - } - } - - W_REG(osh, &cc->chipcontrol_addr, 1); - cc_data_temp = R_REG(osh, &cc->chipcontrol_data); - cc_data_temp &= ~str_mask; - drivestrength_sel <<= str_shift; - cc_data_temp |= drivestrength_sel; - W_REG(osh, &cc->chipcontrol_data, cc_data_temp); - - PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n", - drivestrength, cc_data_temp)); - } - - /* Return to original core */ - si_restore_core(sih, origidx, intr_val); -} diff --git a/drivers/net/wireless/bcm4329/include/Makefile b/drivers/net/wireless/bcm4329/include/Makefile deleted file mode 100644 index 439ead14a0e6..000000000000 --- a/drivers/net/wireless/bcm4329/include/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# include/Makefile -# -# Copyright 2005, Broadcom, Inc. -# -# $Id: Makefile,v 13.5 2005/02/17 19:11:31 Exp $ -# - -SRCBASE = .. - -TARGETS = epivers.h - - -all release: - bash epivers.sh - -clean: - rm -rf ${TARGETS} *.prev - - -.PHONY: all release clean diff --git a/drivers/net/wireless/bcm4329/include/aidmp.h b/drivers/net/wireless/bcm4329/include/aidmp.h deleted file mode 100644 index a927e5dae586..000000000000 --- a/drivers/net/wireless/bcm4329/include/aidmp.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Broadcom AMBA Interconnect definitions. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: aidmp.h,v 13.2.10.1 2008/05/07 20:32:12 Exp $ - */ - - -#ifndef _AIDMP_H -#define _AIDMP_H - - -#define MFGID_ARM 0x43b -#define MFGID_BRCM 0x4bf -#define MFGID_MIPS 0x4a7 - - -#define CC_SIM 0 -#define CC_EROM 1 -#define CC_CORESIGHT 9 -#define CC_VERIF 0xb -#define CC_OPTIMO 0xd -#define CC_GEN 0xe -#define CC_PRIMECELL 0xf - - -#define ER_EROMENTRY 0x000 -#define ER_REMAPCONTROL 0xe00 -#define ER_REMAPSELECT 0xe04 -#define ER_MASTERSELECT 0xe10 -#define ER_ITCR 0xf00 -#define ER_ITIP 0xf04 - - -#define ER_TAG 0xe -#define ER_TAG1 0x6 -#define ER_VALID 1 -#define ER_CI 0 -#define ER_MP 2 -#define ER_ADD 4 -#define ER_END 0xe -#define ER_BAD 0xffffffff - - -#define CIA_MFG_MASK 0xfff00000 -#define CIA_MFG_SHIFT 20 -#define CIA_CID_MASK 0x000fff00 -#define CIA_CID_SHIFT 8 -#define CIA_CCL_MASK 0x000000f0 -#define CIA_CCL_SHIFT 4 - - -#define CIB_REV_MASK 0xff000000 -#define CIB_REV_SHIFT 24 -#define CIB_NSW_MASK 0x00f80000 -#define CIB_NSW_SHIFT 19 -#define CIB_NMW_MASK 0x0007c000 -#define CIB_NMW_SHIFT 14 -#define CIB_NSP_MASK 0x00003e00 -#define CIB_NSP_SHIFT 9 -#define CIB_NMP_MASK 0x000001f0 -#define CIB_NMP_SHIFT 4 - - -#define MPD_MUI_MASK 0x0000ff00 -#define MPD_MUI_SHIFT 8 -#define MPD_MP_MASK 0x000000f0 -#define MPD_MP_SHIFT 4 - - -#define AD_ADDR_MASK 0xfffff000 -#define AD_SP_MASK 0x00000f00 -#define AD_SP_SHIFT 8 -#define AD_ST_MASK 0x000000c0 -#define AD_ST_SHIFT 6 -#define AD_ST_SLAVE 0x00000000 -#define AD_ST_BRIDGE 0x00000040 -#define AD_ST_SWRAP 0x00000080 -#define AD_ST_MWRAP 0x000000c0 -#define AD_SZ_MASK 0x00000030 -#define AD_SZ_SHIFT 4 -#define AD_SZ_4K 0x00000000 -#define AD_SZ_8K 0x00000010 -#define AD_SZ_16K 0x00000020 -#define AD_SZ_SZD 0x00000030 -#define AD_AG32 0x00000008 -#define AD_ADDR_ALIGN 0x00000fff -#define AD_SZ_BASE 0x00001000 - - -#define SD_SZ_MASK 0xfffff000 -#define SD_SG32 0x00000008 -#define SD_SZ_ALIGN 0x00000fff - - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _aidmp { - uint32 oobselina30; - uint32 oobselina74; - uint32 PAD[6]; - uint32 oobselinb30; - uint32 oobselinb74; - uint32 PAD[6]; - uint32 oobselinc30; - uint32 oobselinc74; - uint32 PAD[6]; - uint32 oobselind30; - uint32 oobselind74; - uint32 PAD[38]; - uint32 oobselouta30; - uint32 oobselouta74; - uint32 PAD[6]; - uint32 oobseloutb30; - uint32 oobseloutb74; - uint32 PAD[6]; - uint32 oobseloutc30; - uint32 oobseloutc74; - uint32 PAD[6]; - uint32 oobseloutd30; - uint32 oobseloutd74; - uint32 PAD[38]; - uint32 oobsynca; - uint32 oobseloutaen; - uint32 PAD[6]; - uint32 oobsyncb; - uint32 oobseloutben; - uint32 PAD[6]; - uint32 oobsyncc; - uint32 oobseloutcen; - uint32 PAD[6]; - uint32 oobsyncd; - uint32 oobseloutden; - uint32 PAD[38]; - uint32 oobaextwidth; - uint32 oobainwidth; - uint32 oobaoutwidth; - uint32 PAD[5]; - uint32 oobbextwidth; - uint32 oobbinwidth; - uint32 oobboutwidth; - uint32 PAD[5]; - uint32 oobcextwidth; - uint32 oobcinwidth; - uint32 oobcoutwidth; - uint32 PAD[5]; - uint32 oobdextwidth; - uint32 oobdinwidth; - uint32 oobdoutwidth; - uint32 PAD[37]; - uint32 ioctrlset; - uint32 ioctrlclear; - uint32 ioctrl; - uint32 PAD[61]; - uint32 iostatus; - uint32 PAD[127]; - uint32 ioctrlwidth; - uint32 iostatuswidth; - uint32 PAD[62]; - uint32 resetctrl; - uint32 resetstatus; - uint32 resetreadid; - uint32 resetwriteid; - uint32 PAD[60]; - uint32 errlogctrl; - uint32 errlogdone; - uint32 errlogstatus; - uint32 errlogaddrlo; - uint32 errlogaddrhi; - uint32 errlogid; - uint32 errloguser; - uint32 errlogflags; - uint32 PAD[56]; - uint32 intstatus; - uint32 PAD[127]; - uint32 config; - uint32 PAD[63]; - uint32 itcr; - uint32 PAD[3]; - uint32 itipooba; - uint32 itipoobb; - uint32 itipoobc; - uint32 itipoobd; - uint32 PAD[4]; - uint32 itipoobaout; - uint32 itipoobbout; - uint32 itipoobcout; - uint32 itipoobdout; - uint32 PAD[4]; - uint32 itopooba; - uint32 itopoobb; - uint32 itopoobc; - uint32 itopoobd; - uint32 PAD[4]; - uint32 itopoobain; - uint32 itopoobbin; - uint32 itopoobcin; - uint32 itopoobdin; - uint32 PAD[4]; - uint32 itopreset; - uint32 PAD[15]; - uint32 peripherialid4; - uint32 peripherialid5; - uint32 peripherialid6; - uint32 peripherialid7; - uint32 peripherialid0; - uint32 peripherialid1; - uint32 peripherialid2; - uint32 peripherialid3; - uint32 componentid0; - uint32 componentid1; - uint32 componentid2; - uint32 componentid3; -} aidmp_t; - -#endif - - -#define OOB_BUSCONFIG 0x020 -#define OOB_STATUSA 0x100 -#define OOB_STATUSB 0x104 -#define OOB_STATUSC 0x108 -#define OOB_STATUSD 0x10c -#define OOB_ENABLEA0 0x200 -#define OOB_ENABLEA1 0x204 -#define OOB_ENABLEA2 0x208 -#define OOB_ENABLEA3 0x20c -#define OOB_ENABLEB0 0x280 -#define OOB_ENABLEB1 0x284 -#define OOB_ENABLEB2 0x288 -#define OOB_ENABLEB3 0x28c -#define OOB_ENABLEC0 0x300 -#define OOB_ENABLEC1 0x304 -#define OOB_ENABLEC2 0x308 -#define OOB_ENABLEC3 0x30c -#define OOB_ENABLED0 0x380 -#define OOB_ENABLED1 0x384 -#define OOB_ENABLED2 0x388 -#define OOB_ENABLED3 0x38c -#define OOB_ITCR 0xf00 -#define OOB_ITIPOOBA 0xf10 -#define OOB_ITIPOOBB 0xf14 -#define OOB_ITIPOOBC 0xf18 -#define OOB_ITIPOOBD 0xf1c -#define OOB_ITOPOOBA 0xf30 -#define OOB_ITOPOOBB 0xf34 -#define OOB_ITOPOOBC 0xf38 -#define OOB_ITOPOOBD 0xf3c - - -#define AI_OOBSELINA30 0x000 -#define AI_OOBSELINA74 0x004 -#define AI_OOBSELINB30 0x020 -#define AI_OOBSELINB74 0x024 -#define AI_OOBSELINC30 0x040 -#define AI_OOBSELINC74 0x044 -#define AI_OOBSELIND30 0x060 -#define AI_OOBSELIND74 0x064 -#define AI_OOBSELOUTA30 0x100 -#define AI_OOBSELOUTA74 0x104 -#define AI_OOBSELOUTB30 0x120 -#define AI_OOBSELOUTB74 0x124 -#define AI_OOBSELOUTC30 0x140 -#define AI_OOBSELOUTC74 0x144 -#define AI_OOBSELOUTD30 0x160 -#define AI_OOBSELOUTD74 0x164 -#define AI_OOBSYNCA 0x200 -#define AI_OOBSELOUTAEN 0x204 -#define AI_OOBSYNCB 0x220 -#define AI_OOBSELOUTBEN 0x224 -#define AI_OOBSYNCC 0x240 -#define AI_OOBSELOUTCEN 0x244 -#define AI_OOBSYNCD 0x260 -#define AI_OOBSELOUTDEN 0x264 -#define AI_OOBAEXTWIDTH 0x300 -#define AI_OOBAINWIDTH 0x304 -#define AI_OOBAOUTWIDTH 0x308 -#define AI_OOBBEXTWIDTH 0x320 -#define AI_OOBBINWIDTH 0x324 -#define AI_OOBBOUTWIDTH 0x328 -#define AI_OOBCEXTWIDTH 0x340 -#define AI_OOBCINWIDTH 0x344 -#define AI_OOBCOUTWIDTH 0x348 -#define AI_OOBDEXTWIDTH 0x360 -#define AI_OOBDINWIDTH 0x364 -#define AI_OOBDOUTWIDTH 0x368 -#define AI_IOCTRLSET 0x400 -#define AI_IOCTRLCLEAR 0x404 -#define AI_IOCTRL 0x408 -#define AI_IOSTATUS 0x500 -#define AI_IOCTRLWIDTH 0x700 -#define AI_IOSTATUSWIDTH 0x704 -#define AI_RESETCTRL 0x800 -#define AI_RESETSTATUS 0x804 -#define AI_RESETREADID 0x808 -#define AI_RESETWRITEID 0x80c -#define AI_ERRLOGCTRL 0xa00 -#define AI_ERRLOGDONE 0xa04 -#define AI_ERRLOGSTATUS 0xa08 -#define AI_ERRLOGADDRLO 0xa0c -#define AI_ERRLOGADDRHI 0xa10 -#define AI_ERRLOGID 0xa14 -#define AI_ERRLOGUSER 0xa18 -#define AI_ERRLOGFLAGS 0xa1c -#define AI_INTSTATUS 0xa00 -#define AI_CONFIG 0xe00 -#define AI_ITCR 0xf00 -#define AI_ITIPOOBA 0xf10 -#define AI_ITIPOOBB 0xf14 -#define AI_ITIPOOBC 0xf18 -#define AI_ITIPOOBD 0xf1c -#define AI_ITIPOOBAOUT 0xf30 -#define AI_ITIPOOBBOUT 0xf34 -#define AI_ITIPOOBCOUT 0xf38 -#define AI_ITIPOOBDOUT 0xf3c -#define AI_ITOPOOBA 0xf50 -#define AI_ITOPOOBB 0xf54 -#define AI_ITOPOOBC 0xf58 -#define AI_ITOPOOBD 0xf5c -#define AI_ITOPOOBAIN 0xf70 -#define AI_ITOPOOBBIN 0xf74 -#define AI_ITOPOOBCIN 0xf78 -#define AI_ITOPOOBDIN 0xf7c -#define AI_ITOPRESET 0xf90 -#define AI_PERIPHERIALID4 0xfd0 -#define AI_PERIPHERIALID5 0xfd4 -#define AI_PERIPHERIALID6 0xfd8 -#define AI_PERIPHERIALID7 0xfdc -#define AI_PERIPHERIALID0 0xfe0 -#define AI_PERIPHERIALID1 0xfe4 -#define AI_PERIPHERIALID2 0xfe8 -#define AI_PERIPHERIALID3 0xfec -#define AI_COMPONENTID0 0xff0 -#define AI_COMPONENTID1 0xff4 -#define AI_COMPONENTID2 0xff8 -#define AI_COMPONENTID3 0xffc - - -#define AIRC_RESET 1 - - -#define AICFG_OOB 0x00000020 -#define AICFG_IOS 0x00000010 -#define AICFG_IOC 0x00000008 -#define AICFG_TO 0x00000004 -#define AICFG_ERRL 0x00000002 -#define AICFG_RST 0x00000001 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmcdc.h b/drivers/net/wireless/bcm4329/include/bcmcdc.h deleted file mode 100644 index c2a860beab24..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmcdc.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * CDC network driver ioctl/indication encoding - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmcdc.h,v 13.14.16.3.16.4 2009/04/12 16:58:45 Exp $ - */ -#include - -typedef struct cdc_ioctl { - uint32 cmd; /* ioctl command value */ - uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ - uint32 flags; /* flag defns given below */ - uint32 status; /* status code returned from the device */ -} cdc_ioctl_t; - -/* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN - -/* len field is divided into input and output buffer lengths */ -#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */ - /* excluding IOCTL header */ -#define CDCL_IOC_OUTLEN_SHIFT 0 -#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */ -#define CDCL_IOC_INLEN_SHIFT 16 - -/* CDC flag definitions */ -#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -#define CDCF_IOC_IF_SHIFT 12 -#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */ -#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ - -#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) - -#define CDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -#define CDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) - -/* - * BDC header - * - * The BDC header is used on data packets to convey priority across USB. - */ - -#define BDC_HEADER_LEN 4 - -#define BDC_PROTO_VER 1 /* Protocol version */ - -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ - -#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ - -#define BDC_PRIORITY_MASK 0x7 - -#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ - /* FLOW CONTROL info only */ -#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ - -#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the packet was received */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - uint8 flags; /* Flags */ - uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow control info for usb */ - uint8 flags2; - uint8 rssi; -}; diff --git a/drivers/net/wireless/bcm4329/include/bcmdefs.h b/drivers/net/wireless/bcm4329/include/bcmdefs.h deleted file mode 100644 index f4e99461971b..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmdefs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Misc system wide definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: bcmdefs.h,v 13.38.4.10.2.7.6.11 2010/02/01 05:51:55 Exp $ - */ - - -#ifndef _bcmdefs_h_ -#define _bcmdefs_h_ - -#define STATIC static - -#define SI_BUS 0 -#define PCI_BUS 1 -#define PCMCIA_BUS 2 -#define SDIO_BUS 3 -#define JTAG_BUS 4 -#define USB_BUS 5 -#define SPI_BUS 6 - - -#ifdef BCMBUSTYPE -#define BUSTYPE(bus) (BCMBUSTYPE) -#else -#define BUSTYPE(bus) (bus) -#endif - - -#ifdef BCMCHIPTYPE -#define CHIPTYPE(bus) (BCMCHIPTYPE) -#else -#define CHIPTYPE(bus) (bus) -#endif - - - -#if defined(BCMSPROMBUS) -#define SPROMBUS (BCMSPROMBUS) -#elif defined(SI_PCMCIA_SROM) -#define SPROMBUS (PCMCIA_BUS) -#else -#define SPROMBUS (PCI_BUS) -#endif - - -#ifdef BCMCHIPID -#define CHIPID(chip) (BCMCHIPID) -#else -#define CHIPID(chip) (chip) -#endif - - -#define DMADDR_MASK_32 0x0 -#define DMADDR_MASK_30 0xc0000000 -#define DMADDR_MASK_0 0xffffffff - -#define DMADDRWIDTH_30 30 -#define DMADDRWIDTH_32 32 -#define DMADDRWIDTH_63 63 -#define DMADDRWIDTH_64 64 - - -#define BCMEXTRAHDROOM 164 - - -#define BCMDONGLEHDRSZ 12 -#define BCMDONGLEPADSZ 16 - -#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) - - - -#define BITFIELD_MASK(width) \ - (((unsigned)1 << (width)) - 1) -#define GFIELD(val, field) \ - (((val) >> field ## _S) & field ## _M) -#define SFIELD(val, field, bits) \ - (((val) & (~(field ## _M << field ## _S))) | \ - ((unsigned)(bits) << field ## _S)) - - -#ifdef BCMSMALL -#undef BCMSPACE -#define bcmspace FALSE -#else -#define BCMSPACE -#define bcmspace TRUE -#endif - - -#define MAXSZ_NVRAM_VARS 4096 - -#define LOCATOR_EXTERN static - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmdevs.h b/drivers/net/wireless/bcm4329/include/bcmdevs.h deleted file mode 100644 index 14853f17795c..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmdevs.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Broadcom device-specific manifest constants. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmdevs.h,v 13.172.4.5.4.10.2.36 2010/05/25 08:33:44 Exp $ - */ - - -#ifndef _BCMDEVS_H -#define _BCMDEVS_H - - -#define VENDOR_EPIGRAM 0xfeda -#define VENDOR_BROADCOM 0x14e4 -#define VENDOR_SI_IMAGE 0x1095 -#define VENDOR_TI 0x104c -#define VENDOR_RICOH 0x1180 -#define VENDOR_JMICRON 0x197b - - -#define VENDOR_BROADCOM_PCMCIA 0x02d0 - - -#define VENDOR_BROADCOM_SDIO 0x00BF - - -#define BCM_DNGL_VID 0xa5c -#define BCM_DNGL_BL_PID_4320 0xbd11 -#define BCM_DNGL_BL_PID_4328 0xbd12 -#define BCM_DNGL_BL_PID_4322 0xbd13 -#define BCM_DNGL_BL_PID_4325 0xbd14 -#define BCM_DNGL_BL_PID_4315 0xbd15 -#define BCM_DNGL_BL_PID_4319 0xbd16 -#define BCM_DNGL_BDC_PID 0xbdc - -#define BCM4325_D11DUAL_ID 0x431b -#define BCM4325_D11G_ID 0x431c -#define BCM4325_D11A_ID 0x431d -#define BCM4329_D11NDUAL_ID 0x432e -#define BCM4329_D11N2G_ID 0x432f -#define BCM4329_D11N5G_ID 0x4330 -#define BCM4336_D11N_ID 0x4343 -#define BCM4315_D11DUAL_ID 0x4334 -#define BCM4315_D11G_ID 0x4335 -#define BCM4315_D11A_ID 0x4336 -#define BCM4319_D11N_ID 0x4337 -#define BCM4319_D11N2G_ID 0x4338 -#define BCM4319_D11N5G_ID 0x4339 - - -#define SDIOH_FPGA_ID 0x43f2 -#define SPIH_FPGA_ID 0x43f5 -#define BCM4710_DEVICE_ID 0x4710 -#define BCM27XX_SDIOH_ID 0x2702 -#define PCIXX21_FLASHMEDIA0_ID 0x8033 -#define PCIXX21_SDIOH0_ID 0x8034 -#define PCIXX21_FLASHMEDIA_ID 0x803b -#define PCIXX21_SDIOH_ID 0x803c -#define R5C822_SDIOH_ID 0x0822 -#define JMICRON_SDIOH_ID 0x2381 - - -#define BCM4306_CHIP_ID 0x4306 -#define BCM4311_CHIP_ID 0x4311 -#define BCM4312_CHIP_ID 0x4312 -#define BCM4315_CHIP_ID 0x4315 -#define BCM4318_CHIP_ID 0x4318 -#define BCM4319_CHIP_ID 0x4319 -#define BCM4320_CHIP_ID 0x4320 -#define BCM4321_CHIP_ID 0x4321 -#define BCM4322_CHIP_ID 0x4322 -#define BCM4325_CHIP_ID 0x4325 -#define BCM4328_CHIP_ID 0x4328 -#define BCM4329_CHIP_ID 0x4329 -#define BCM4336_CHIP_ID 0x4336 -#define BCM4402_CHIP_ID 0x4402 -#define BCM4704_CHIP_ID 0x4704 -#define BCM4710_CHIP_ID 0x4710 -#define BCM4712_CHIP_ID 0x4712 -#define BCM4785_CHIP_ID 0x4785 -#define BCM5350_CHIP_ID 0x5350 -#define BCM5352_CHIP_ID 0x5352 -#define BCM5354_CHIP_ID 0x5354 -#define BCM5365_CHIP_ID 0x5365 - - - -#define BCM4303_PKG_ID 2 -#define BCM4309_PKG_ID 1 -#define BCM4712LARGE_PKG_ID 0 -#define BCM4712SMALL_PKG_ID 1 -#define BCM4712MID_PKG_ID 2 -#define BCM4328USBD11G_PKG_ID 2 -#define BCM4328USBDUAL_PKG_ID 3 -#define BCM4328SDIOD11G_PKG_ID 4 -#define BCM4328SDIODUAL_PKG_ID 5 -#define BCM4329_289PIN_PKG_ID 0 -#define BCM4329_182PIN_PKG_ID 1 -#define BCM5354E_PKG_ID 1 -#define HDLSIM5350_PKG_ID 1 -#define HDLSIM_PKG_ID 14 -#define HWSIM_PKG_ID 15 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmendian.h b/drivers/net/wireless/bcm4329/include/bcmendian.h deleted file mode 100644 index ae468383aa74..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmendian.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Byte order utilities - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmendian.h,v 1.31.302.1.16.1 2009/02/03 18:34:31 Exp $ - * - * This file by default provides proper behavior on little-endian architectures. - * On big-endian architectures, IL_BIGENDIAN should be defined. - */ - - -#ifndef _BCMENDIAN_H_ -#define _BCMENDIAN_H_ - -#include - - -#define BCMSWAP16(val) \ - ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ - (((uint16)(val) & (uint16)0xff00U) >> 8))) - - -#define BCMSWAP32(val) \ - ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ - (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ - (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ - (((uint32)(val) & (uint32)0xff000000U) >> 24))) - - -#define BCMSWAP32BY16(val) \ - ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ - (((uint32)(val) & (uint32)0xffff0000U) >> 16))) - - -static INLINE uint16 -bcmswap16(uint16 val) -{ - return BCMSWAP16(val); -} - -static INLINE uint32 -bcmswap32(uint32 val) -{ - return BCMSWAP32(val); -} - -static INLINE uint32 -bcmswap32by16(uint32 val) -{ - return BCMSWAP32BY16(val); -} - - - - -static INLINE void -bcmswap16_buf(uint16 *buf, uint len) -{ - len = len / 2; - - while (len--) { - *buf = bcmswap16(*buf); - buf++; - } -} - -#ifndef hton16 -#ifndef IL_BIGENDIAN -#define HTON16(i) BCMSWAP16(i) -#define HTON32(i) BCMSWAP32(i) -#define hton16(i) bcmswap16(i) -#define hton32(i) bcmswap32(i) -#define ntoh16(i) bcmswap16(i) -#define ntoh32(i) bcmswap32(i) -#define HTOL16(i) (i) -#define HTOL32(i) (i) -#define ltoh16(i) (i) -#define ltoh32(i) (i) -#define htol16(i) (i) -#define htol32(i) (i) -#else -#define HTON16(i) (i) -#define HTON32(i) (i) -#define hton16(i) (i) -#define hton32(i) (i) -#define ntoh16(i) (i) -#define ntoh32(i) (i) -#define HTOL16(i) BCMSWAP16(i) -#define HTOL32(i) BCMSWAP32(i) -#define ltoh16(i) bcmswap16(i) -#define ltoh32(i) bcmswap32(i) -#define htol16(i) bcmswap16(i) -#define htol32(i) bcmswap32(i) -#endif -#endif - -#ifndef IL_BIGENDIAN -#define ltoh16_buf(buf, i) -#define htol16_buf(buf, i) -#else -#define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)buf, i) -#define htol16_buf(buf, i) bcmswap16_buf((uint16 *)buf, i) -#endif - - -static INLINE void -htol16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = val >> 8; -} - - -static INLINE void -htol32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = (val >> 8) & 0xff; - bytes[2] = (val >> 16) & 0xff; - bytes[3] = val >> 24; -} - - -static INLINE void -hton16_ua_store(uint16 val, uint8 *bytes) -{ - bytes[0] = val >> 8; - bytes[1] = val & 0xff; -} - - -static INLINE void -hton32_ua_store(uint32 val, uint8 *bytes) -{ - bytes[0] = val >> 24; - bytes[1] = (val >> 16) & 0xff; - bytes[2] = (val >> 8) & 0xff; - bytes[3] = val & 0xff; -} - -#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) - - -static INLINE uint16 -ltoh16_ua(const void *bytes) -{ - return _LTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ltoh32_ua(const void *bytes) -{ - return _LTOH32_UA((const uint8 *)bytes); -} - - -static INLINE uint16 -ntoh16_ua(const void *bytes) -{ - return _NTOH16_UA((const uint8 *)bytes); -} - - -static INLINE uint32 -ntoh32_ua(const void *bytes) -{ - return _NTOH32_UA((const uint8 *)bytes); -} - -#define ltoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)ptr : \ - sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)ptr) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)ptr) : \ - 0xfeedf00d) - -#define ntoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)ptr : \ - sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)ptr) : \ - sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)ptr) : \ - 0xfeedf00d) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmpcispi.h b/drivers/net/wireless/bcm4329/include/bcmpcispi.h deleted file mode 100644 index 7d98fb7cbdc8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmpcispi.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Broadcom PCI-SPI Host Controller Register Definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmpcispi.h,v 13.11.8.3 2008/07/09 21:23:29 Exp $ - */ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -/* -+---------------------------------------------------------------------------+ -| | -| 7 6 5 4 3 2 1 0 | -| 0x0000 SPI_CTRL SPIE SPE 0 MSTR CPOL CPHA SPR1 SPR0 | -| 0x0004 SPI_STAT SPIF WCOL ST1 ST0 WFFUL WFEMP RFFUL RFEMP | -| 0x0008 SPI_DATA Bits 31:0, data to send out on MOSI | -| 0x000C SPI_EXT ICNT1 ICNT0 BSWAP *HSMODE ESPR1 ESPR0 | -| 0x0020 GPIO_OE 0=input, 1=output PWR_OE CS_OE | -| 0x0024 GPIO_DATA CARD:1=missing, 0=present CARD PWR_DAT CS_DAT | -| 0x0040 INT_EDGE 0=level, 1=edge DEV_E SPI_E | -| 0x0044 INT_POL 1=active high, 0=active low DEV_P SPI_P | -| 0x0048 INTMASK DEV SPI | -| 0x004C INTSTATUS DEV SPI | -| 0x0060 HEXDISP Reset value: 0x14e443f5. In hexdisp mode, value | -| shows on the Raggedstone1 4-digit 7-segment display. | -| 0x0064 CURRENT_MA Low 16 bits indicate card current consumption in mA | -| 0x006C DISP_SEL Display mode (0=hexdisp, 1=current) DSP | -| 0x00C0 PLL_CTL bit31=ext_clk, remainder unused. | -| 0x00C4 PLL_STAT LOCK | -| 0x00C8 CLK_FREQ | -| 0x00CC CLK_CNT | -| | -| *Notes: HSMODE is not implemented, never set this bit! | -| BSWAP is available in rev >= 8 | -| | -+---------------------------------------------------------------------------+ -*/ - -typedef volatile struct { - uint32 spih_ctrl; /* 0x00 SPI Control Register */ - uint32 spih_stat; /* 0x04 SPI Status Register */ - uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */ - uint32 spih_ext; /* 0x0C SPI Extension Register */ - uint32 PAD[4]; /* 0x10-0x1F PADDING */ - - uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */ - uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */ - uint32 PAD[6]; /* 0x28-0x3F PADDING */ - - uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */ - uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */ - /* 1=Active High) */ - uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */ - uint32 spih_int_status; /* 0x4C SPI Interrupt Status */ - uint32 PAD[4]; /* 0x50-0x5F PADDING */ - - uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */ - uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */ - uint32 PAD[1]; /* 0x68 PADDING */ - uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */ - uint32 PAD[4]; /* 0x70-0x7F PADDING */ - uint32 PAD[8]; /* 0x80-0x9F PADDING */ - uint32 PAD[8]; /* 0xA0-0xBF PADDING */ - uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */ - uint32 spih_pll_status; /* 0xC4 PLL Status Register */ - uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */ - uint32 spih_clk_count; /* 0xCC External Clock Count Register */ - -} spih_regs_t; - -typedef volatile struct { - uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */ - uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */ - - uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */ - uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */ - uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */ - uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */ - uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */ - uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */ - uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */ - uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */ - uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */ - uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */ - uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */ - uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */ - uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */ - uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */ - uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */ - uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */ - uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */ - uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */ - uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */ - uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */ - uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */ - uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */ - uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */ - uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */ - uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */ - uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */ - - uint32 PAD[5]; /* 0x16C-0x17F PADDING */ - - uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */ - uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */ - uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */ - uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */ - uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */ - uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */ - uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */ - uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */ - uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */ - uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */ - uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */ - uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */ - uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */ - uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */ - uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */ - uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */ - uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */ - uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */ - uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */ - uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */ - uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */ - uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */ - uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */ - uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */ - uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */ - uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */ - - uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */ - uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */ - uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */ -} spih_pciregs_t; - -/* - * PCI Core interrupt enable and status bit definitions. - */ - -/* PCI Core ICR Register bit definitions */ -#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */ -#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */ -#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */ -#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */ -#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */ -#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */ - - -/* PCI Core ISR Register bit definitions */ -#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */ -#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */ -#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */ -#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */ -#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */ - - -/* Registers on the Wishbone bus */ -#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */ -#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */ -#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */ - -/* GPIO Bit definitions */ -#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */ -#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */ -#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */ - -/* SPI Status Register Bit definitions */ -#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */ -#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */ -#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */ -#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */ -#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */ -#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */ - -#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */ - -#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */ -#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */ - -/* Spin bit loop bound check */ -#define SPI_SPIN_BOUND 0xf4240 /* 1 million */ diff --git a/drivers/net/wireless/bcm4329/include/bcmperf.h b/drivers/net/wireless/bcm4329/include/bcmperf.h deleted file mode 100644 index 2a78784e85d3..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmperf.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Performance counters software interface. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmperf.h,v 13.5 2007/09/14 22:00:59 Exp $ - */ -/* essai */ -#ifndef _BCMPERF_H_ -#define _BCMPERF_H_ -/* get cache hits and misses */ -#define BCMPERF_ENABLE_INSTRCOUNT() -#define BCMPERF_ENABLE_ICACHE_MISS() -#define BCMPERF_ENABLE_ICACHE_HIT() -#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) -#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) -#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) -#endif /* _BCMPERF_H_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdbus.h b/drivers/net/wireless/bcm4329/include/bcmsdbus.h deleted file mode 100644 index b7b67bc66248..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdbus.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Definitions for API from sdio common code (bcmsdh) to individual - * host controller drivers. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdbus.h,v 13.11.14.2.6.6 2009/10/27 17:20:28 Exp $ - */ - -#ifndef _sdio_api_h_ -#define _sdio_api_h_ - - -#define SDIOH_API_RC_SUCCESS (0x00) -#define SDIOH_API_RC_FAIL (0x01) -#define SDIOH_API_SUCCESS(status) (status == 0) - -#define SDIOH_READ 0 /* Read request */ -#define SDIOH_WRITE 1 /* Write request */ - -#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -#define SDIOH_DATA_INC 1 /* Incremental addressing */ - -#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ - -#define SDIOH_DATA_PIO 0 /* PIO mode */ -#define SDIOH_DATA_DMA 1 /* DMA mode */ - - -typedef int SDIOH_API_RC; - -/* SDio Host structure */ -typedef struct sdioh_info sdioh_info_t; - -/* callback function, taking one arg */ -typedef void (*sdioh_cb_fn_t)(void *); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -extern sdioh_info_t * sdioh_attach(osl_t *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si); -extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); - -/* query whether SD interrupt is enabled or not */ -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); - -/* enable or disable SD interrupt */ -extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); - -#if defined(DHD_DEBUG) -extern bool sdioh_interrupt_pending(sdioh_info_t *si); -#endif - -/* read or write one byte using cmd52 */ -extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, uint addr, uint8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, uint rw, uint fnc, - uint addr, uint32 *word, uint nbyte); - -/* read or write any buffer using cmd53 */ -extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc, - uint rw, uint fnc_num, uint32 addr, uint regwidth, uint32 buflen, uint8 *buffer, - void *pkt); - -/* get cis data */ -extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis, uint32 length); - -extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); -extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); - -/* query number of io functions */ -extern uint sdioh_query_iofnum(sdioh_info_t *si); - -/* handle iovars */ -extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Issue abort to the specified function and clear controller as needed */ -extern int sdioh_abort(sdioh_info_t *si, uint fnc); - -/* Start and Stop SDIO without re-enumerating the SD card. */ -extern int sdioh_start(sdioh_info_t *si, int stage); -extern int sdioh_stop(sdioh_info_t *si); - -/* Reset and re-initialize the device */ -extern int sdioh_sdio_reset(sdioh_info_t *si); - -/* Helper function */ -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - - - -#endif /* _sdio_api_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdh.h b/drivers/net/wireless/bcm4329/include/bcmsdh.h deleted file mode 100644 index f5dee5c58445..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdh.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * SDIO host client driver interface of Broadcom HNBU - * export functions to client drivers - * abstract OS and BUS specific details of SDIO - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh.h,v 13.35.14.7.6.8 2009/10/14 04:22:25 Exp $ - */ - -#ifndef _bcmsdh_h_ -#define _bcmsdh_h_ - -#define BCMSDH_ERROR_VAL 0x0001 /* Error */ -#define BCMSDH_INFO_VAL 0x0002 /* Info */ -extern const uint bcmsdh_msglevel; - -#define BCMSDH_ERROR(x) -#define BCMSDH_INFO(x) - -/* forward declarations */ -typedef struct bcmsdh_info bcmsdh_info_t; -typedef void (*bcmsdh_cb_fn_t)(void *); - -/* Attach and build an interface to the underlying SD host driver. - * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. - * - Returns the bcmsdh handle and virtual address base for register access. - * The returned handle should be used in all subsequent calls, but the bcmsh - * implementation may maintain a single "default" handle (e.g. the first or - * most recent one) to enable single-instance implementations to pass NULL. - */ -extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq); - -/* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(osl_t *osh, void *sdh); - -/* Query if SD device interrupts are enabled */ -extern bool bcmsdh_intr_query(void *sdh); - -/* Enable/disable SD interrupt */ -extern int bcmsdh_intr_enable(void *sdh); -extern int bcmsdh_intr_disable(void *sdh); - -/* Register/deregister device interrupt handler. */ -extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -extern int bcmsdh_intr_dereg(void *sdh); - -#if defined(DHD_DEBUG) -/* Query pending interrupt status from the host controller */ -extern bool bcmsdh_intr_pending(void *sdh); -#endif - -#ifdef BCMLXSDMMC -extern int bcmsdh_claim_host_and_lock(void *sdh); -extern int bcmsdh_release_host_and_unlock(void *sdh); -#endif /* BCMLXSDMMC */ - -/* Register a callback to be called if and when bcmsdh detects - * device removal. No-op in the case of non-removable/hardwired devices. - */ -extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); - -/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). - * fn: function number - * addr: unmodified SDIO-space address - * data: data byte to write - * err: pointer to error code (or NULL) - */ -extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err); -extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data, int *err); - -/* Read/Write 4bytes from/to cfg space */ -extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err); -extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err); - -/* Read CIS content for specified function. - * fn: function whose CIS is being requested (0 is common CIS) - * cis: pointer to memory location to place results - * length: number of bytes to read - * Internally, this routine uses the values from the cis base regs (0x9-0xB) - * to form an SDIO-space address to read the data from. - */ -extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length); - -/* Synchronous access to device (client) core registers via CMD53 to F1. - * addr: backplane address (i.e. >= regsva from attach) - * size: register width in bytes (2 or 4) - * data: data for register write - */ -extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size); -extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data); - -/* Indicate if last reg read/write failed */ -extern bool bcmsdh_regfail(void *sdh); - -/* Buffer transfer to/from device (client) core via cmd53. - * fn: function number - * addr: backplane address (i.e. >= regsva from attach) - * flags: backplane width, address increment, sync/async - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * pkt: pointer to packet associated with buf (if any) - * complete: callback function for command completion (async only) - * handle: handle for completion callback (first arg in callback) - * Returns 0 or error code. - * NOTE: Async operation is not currently supported. - */ -typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting); -extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); -extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, - uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); - -/* Flags bits */ -#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ -#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ -#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ - -/* Pending (non-error) return code */ -#define BCME_PENDING 1 - -/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). - * rw: read or write (0/1) - * addr: direct SDIO address - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * Returns 0 or error code. - */ -extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes); - -/* Issue an abort to the specified function */ -extern int bcmsdh_abort(void *sdh, uint fn); - -/* Start SDIO Host Controller communication */ -extern int bcmsdh_start(void *sdh, int stage); - -/* Stop SDIO Host Controller communication */ -extern int bcmsdh_stop(void *sdh); - -/* Returns the "Device ID" of target device on the SDIO bus. */ -extern int bcmsdh_query_device(void *sdh); - -/* Returns the number of IO functions reported by the device */ -extern uint bcmsdh_query_iofnum(void *sdh); - -/* Miscellaneous knob tweaker. */ -extern int bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Reset and reinitialize the device */ -extern int bcmsdh_reset(bcmsdh_info_t *sdh); - -/* helper functions */ - -extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -/* callback functions */ -typedef struct { - /* attach to device */ - void *(*attach)(uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot, - uint16 func, uint bustype, void * regsva, osl_t * osh, - void * param); - /* detach from device */ - void (*detach)(void *ch); -} bcmsdh_driver_t; - -/* platform specific/high level functions */ -extern int bcmsdh_register(bcmsdh_driver_t *driver); -extern void bcmsdh_unregister(void); -extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device); -extern void bcmsdh_device_remove(void * sdh); - -#if defined(OOB_INTR_ONLY) -extern int bcmsdh_register_oob_intr(void * dhdp); -extern void bcmsdh_unregister_oob_intr(void); -extern void bcmsdh_oob_intr_set(bool enable); -#endif /* defined(OOB_INTR_ONLY) */ -/* Function to pass device-status bits to DHD. */ -extern uint32 bcmsdh_get_dstatus(void *sdh); - -/* Function to return current window addr */ -extern uint32 bcmsdh_cur_sbwad(void *sdh); - -/* Function to pass chipid and rev to lower layers for controlling pr's */ -extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev); - - -#endif /* _bcmsdh_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h deleted file mode 100644 index 4e6d1b5bd94f..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdh_sdmmc.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdh_sdmmc.h,v 13.1.2.1.8.7 2009/10/27 18:22:52 Exp $ - */ - -#ifndef __BCMSDH_SDMMC_H__ -#define __BCMSDH_SDMMC_H__ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); - -/* Allocate/init/free per-OS private data */ -extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -struct sdioh_info { - osl_t *osh; /* osh handler */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - uint max_dma_len; - uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ -// SDDMA_DESCRIPTOR SGList[32]; /* Scatter/Gather DMA List */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdh_sdmmc.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); - - -/************************************************************** - * Internal interfaces: bcmsdh_sdmmc.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); - -typedef struct _BCMSDH_SDMMC_INSTANCE { - sdioh_info_t *sd; - struct sdio_func *func[SDIOD_MAX_IOFUNCS]; -} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; - -#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdpcm.h b/drivers/net/wireless/bcm4329/include/bcmsdpcm.h deleted file mode 100644 index 77aca4500ad8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdpcm.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Broadcom SDIO/PCMCIA - * Software-specific definitions shared between device and host side - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdpcm.h,v 1.1.2.4 2010/07/02 01:15:46 Exp $ - */ - -#ifndef _bcmsdpcm_h_ -#define _bcmsdpcm_h_ - -/* - * Software allocation of To SB Mailbox resources - */ - -/* intstatus bits */ -#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ - -/* tosbmailbox bits corresponding to intstatus bits */ -#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ - -/* tosbmailboxdata */ -#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ - -/* - * Software allocation of To Host Mailbox resources - */ - -/* intstatus bits */ -#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ - -/* tohostmailbox bits corresponding to intstatus bits */ -#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ - -/* tohostmailboxdata */ -#define HMB_DATA_NAKHANDLED 1 /* we're ready to retransmit NAK'd frame to host */ -#define HMB_DATA_DEVREADY 2 /* we're ready to to talk to host after enable */ -#define HMB_DATA_FC 4 /* per prio flowcontrol update flag to host */ -#define HMB_DATA_FWREADY 8 /* firmware is ready for protocol activity */ - -#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ - -#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ - -/* - * Software-defined protocol header - */ - -/* Current protocol version */ -#define SDPCM_PROT_VERSION 4 - -/* SW frame header */ -#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ - -#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ - -#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ - -/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -#define SDPCM_NEXTLEN_OFFSET 2 - -/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -#define SDPCM_DOFFSET_MASK 0xff000000 -#define SDPCM_DOFFSET_SHIFT 24 - -#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) -#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -#define SDPCM_VERSION_OFFSET 6 /* Version # */ -#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) - -#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ - -/* logical channel numbers */ -#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -#define SDPCM_MAX_CHANNEL 15 - -#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ - -#define SDPCM_FLAG_RESVD0 0x01 -#define SDPCM_FLAG_RESVD1 0x02 -#define SDPCM_FLAG_GSPI_TXENAB 0x04 -#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ - -/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) - -#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) - -/* For TEST_CHANNEL packets, define another 4-byte header */ -#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); - * Semantics of Ext byte depend on command. - * Len is current or requested frame length, not - * including test header; sent little-endian. - */ -#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ -#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ - -/* Handy macro for filling in datagen packets with a pattern */ -#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) - -/* - * Software counters (first part matches hardware counters) - */ - -typedef volatile struct { - uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ - uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ - uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ - uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ - uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ - uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ - uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ - uint32 rxdescuflo; /* receive descriptor underflows */ - uint32 rxfifooflo; /* receive fifo overflows */ - uint32 txfifouflo; /* transmit fifo underflows */ - uint32 runt; /* runt (too short) frames recv'd from bus */ - uint32 badlen; /* frame's rxh len does not match its hw tag len */ - uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ - uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ - uint32 rxfcrc; /* frame rx header indicates crc error */ - uint32 rxfwoos; /* frame rx header indicates write out of sync */ - uint32 rxfwft; /* frame rx header indicates write frame termination */ - uint32 rxfabort; /* frame rx header indicates frame aborted */ - uint32 woosint; /* write out of sync interrupt */ - uint32 roosint; /* read out of sync interrupt */ - uint32 rftermint; /* read frame terminate interrupt */ - uint32 wftermint; /* write frame terminate interrupt */ -} sdpcmd_cnt_t; - -/* - * Register Access Macros - */ - -#define SDIODREV_IS(var, val) ((var) == (val)) -#define SDIODREV_GE(var, val) ((var) >= (val)) -#define SDIODREV_GT(var, val) ((var) > (val)) -#define SDIODREV_LT(var, val) ((var) < (val)) -#define SDIODREV_LE(var, val) ((var) <= (val)) - -#define SDIODDMAREG32(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) - -#define SDIODDMAREG64(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ - (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) - -#define SDIODDMAREG(h, dir, chnl) \ - (SDIODREV_LT((h)->corerev, 1) ? \ - SDIODDMAREG32((h), (dir), (chnl)) : \ - SDIODDMAREG64((h), (dir), (chnl))) - -#define PCMDDMAREG(h, dir, chnl) \ - ((dir) == DMA_TX ? \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ - (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) - -#define SDPCMDMAREG(h, dir, chnl, coreid) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODDMAREG(h, dir, chnl) : \ - PCMDDMAREG(h, dir, chnl)) - -#define SDIODFIFOREG(h, corerev) \ - (SDIODREV_LT((corerev), 1) ? \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) - -#define PCMDFIFOREG(h) \ - ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) - -#define SDPCMFIFOREG(h, coreid, corerev) \ - ((coreid) == SDIOD_CORE_ID ? \ - SDIODFIFOREG(h, corerev) : \ - PCMDFIFOREG(h)) - -/* - * Shared structure between dongle and the host - * The structure contains pointers to trap or assert information shared with the host - */ -#define SDPCM_SHARED_VERSION 0x0002 -#define SDPCM_SHARED_VERSION_MASK 0x00FF -#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -#define SDPCM_SHARED_ASSERT 0x0200 -#define SDPCM_SHARED_TRAP 0x0400 - -typedef struct { - uint32 flags; - uint32 trap_addr; - uint32 assert_exp_addr; - uint32 assert_file_addr; - uint32 assert_line; - uint32 console_addr; /* Address of hndrte_cons_t */ - uint32 msgtrace_addr; - uint8 tag[32]; -} sdpcm_shared_t; - -extern sdpcm_shared_t sdpcm_shared; - -#endif /* _bcmsdpcm_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/bcmsdspi.h b/drivers/net/wireless/bcm4329/include/bcmsdspi.h deleted file mode 100644 index eaae10d8bf19..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdspi.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdspi.h,v 13.8.10.2 2008/06/30 21:09:40 Exp $ - */ - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#undef ERROR -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint bar0; /* BAR0 for PCI Device */ - osl_t *osh; /* osh handler */ - void *controller; /* Pointer to SPI Controller's private data struct */ - - uint lockcount; /* nest count of sdspi_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint32 target_dev; /* Target device ID */ - uint32 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - uint32 intrcount; /* Client interrupts */ - uint32 local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - bool got_hcint; /* Host Controller interrupt. */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current register transfer size */ - uint32 cmd53_wr_data; /* Used to pass CMD53 write data */ - uint32 card_response; /* Used to pass back response status byte */ - uint32 card_rsp_data; /* Used to pass back response data word */ - uint16 card_rca; /* Current Address */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; - ulong dma_phys; - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdspi.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/************************************************************** - * Internal interfaces: bcmsdspi.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size); -extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size); - -/* Interrupt (de)registration routines */ -extern int spi_register_irq(sdioh_info_t *sd, uint irq); -extern void spi_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void spi_lock(sdioh_info_t *sd); -extern void spi_unlock(sdioh_info_t *sd); - -/* Allocate/init/free per-OS private data */ -extern int spi_osinit(sdioh_info_t *sd); -extern void spi_osfree(sdioh_info_t *sd); diff --git a/drivers/net/wireless/bcm4329/include/bcmsdstd.h b/drivers/net/wireless/bcm4329/include/bcmsdstd.h deleted file mode 100644 index 974b3d41698d..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmsdstd.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 'Standard' SDIO HOST CONTROLLER driver - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmsdstd.h,v 13.16.18.1.16.3 2009/12/10 01:09:23 Exp $ - */ - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) -#define sd_dma(x) - -#define sd_sync_dma(sd, read, nbytes) -#define sd_init_dma(sd) -#define sd_ack_intr(sd) -#define sd_wakeup(sd); -/* Allocate/init/free per-OS private data */ -extern int sdstd_osinit(sdioh_info_t *sd); -extern void sdstd_osfree(sdioh_info_t *sd); - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 -#define SDIOH_MODE_SD1 1 -#define SDIOH_MODE_SD4 2 - -#define MAX_SLOTS 6 /* For PCI: Only 6 BAR entries => 6 slots */ -#define SDIOH_REG_WINSZ 0x100 /* Number of registers in Standard Host Controller */ - -#define SDIOH_TYPE_ARASAN_HDK 1 -#define SDIOH_TYPE_BCM27XX 2 -#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */ -#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */ -#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */ - -/* For linux, allow yielding for dongle */ -#define BCMSDYIELD - -/* Expected card status value for CMD7 */ -#define SDIOH_CMD7_EXP_STATUS 0x00001E00 - -#define RETRIES_LARGE 100000 -#define RETRIES_SMALL 100 - - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -#define USE_FIFO 0x8 /* Fifo vs non-fifo */ - -#define CLIENT_INTR 0x100 /* Get rid of this! */ - - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - uint32 curr_caps; /* max current capabilities reg */ - - osl_t *osh; /* osh handler */ - volatile char *mem_space; /* pci device memory va */ - uint lockcount; /* nest count of sdstd_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint target_dev; /* Target device ID */ - uint16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - int local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current transfer */ - uint16 card_rca; /* Current Address */ - int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - void *dma_buf; /* DMA Buffer virtual address */ - ulong dma_phys; /* DMA Buffer physical address */ - void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */ - ulong adma2_dscr_phys; /* ADMA2 Descriptor Buffer physical address */ - - /* adjustments needed to make the dma align properly */ - void *dma_start_buf; - ulong dma_start_phys; - uint alloced_dma_size; - void *adma2_dscr_start_buf; - ulong adma2_dscr_start_phys; - uint alloced_adma2_dscr_size; - - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ - bool got_hcint; /* local interrupt flag */ - uint16 last_intrstatus; /* to cache intrstatus */ -}; - -#define DMA_MODE_NONE 0 -#define DMA_MODE_SDMA 1 -#define DMA_MODE_ADMA1 2 -#define DMA_MODE_ADMA2 3 -#define DMA_MODE_ADMA2_64 4 -#define DMA_MODE_AUTO -1 - -#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE)) - -/* SDIO Host Control Register DMA Mode Definitions */ -#define SDIOH_SDMA_MODE 0 -#define SDIOH_ADMA1_MODE 1 -#define SDIOH_ADMA2_MODE 2 -#define SDIOH_ADMA2_64_MODE 3 - -#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */ -#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */ -#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */ -#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */ -#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */ -#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */ -#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */ -#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */ - -/* ADMA2 Descriptor Table Entry for 32-bit Address */ -typedef struct adma2_dscr_32b { - uint32 len_attr; - uint32 phys_addr; -} adma2_dscr_32b_t; - -/* ADMA1 Descriptor Table Entry */ -typedef struct adma1_dscr { - uint32 phys_addr_attr; -} adma1_dscr_t; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdstd.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdstd_devintr_on(sdioh_info_t *sd); -extern void sdstd_devintr_off(sdioh_info_t *sd); - -/* Enable/disable interrupts for local controller events */ -extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err); -extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err); - -/* Wait for specified interrupt and error bits to be set */ -extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err); - - -/************************************************************** - * Internal interfaces: bcmsdstd.c references to per-port code - */ - -/* Register mapping routines */ -extern uint32 *sdstd_reg_map(osl_t *osh, int32 addr, int size); -extern void sdstd_reg_unmap(osl_t *osh, int32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdstd_register_irq(sdioh_info_t *sd, uint irq); -extern void sdstd_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void sdstd_lock(sdioh_info_t *sd); -extern void sdstd_unlock(sdioh_info_t *sd); - -/* OS-specific wait-for-interrupt-or-status */ -extern uint16 sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield); diff --git a/drivers/net/wireless/bcm4329/include/bcmspi.h b/drivers/net/wireless/bcm4329/include/bcmspi.h deleted file mode 100644 index 2e2bc935716f..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmspi.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Broadcom SPI Low-Level Hardware Driver API - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmspi.h,v 13.3.10.2 2008/06/30 21:09:40 Exp $ - */ - -extern void spi_devintr_off(sdioh_info_t *sd); -extern void spi_devintr_on(sdioh_info_t *sd); -extern bool spi_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor); -extern bool spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode); -extern bool spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr); -extern bool spi_hw_attach(sdioh_info_t *sd); -extern bool spi_hw_detach(sdioh_info_t *sd); -extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen); -extern void spi_spinbits(sdioh_info_t *sd); -extern void spi_waitbits(sdioh_info_t *sd, bool yield); diff --git a/drivers/net/wireless/bcm4329/include/bcmspibrcm.h b/drivers/net/wireless/bcm4329/include/bcmspibrcm.h deleted file mode 100644 index 9dce878d11e2..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmspibrcm.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * SD-SPI Protocol Conversion - BCMSDH->gSPI Translation Layer - * - * Copyright (C) 2010, Broadcom Corporation - * All Rights Reserved. - * - * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; - * the contents of this file may not be disclosed to third parties, copied - * or duplicated in any form, in whole or in part, without the prior - * written permission of Broadcom Corporation. - * - * $Id: bcmspibrcm.h,v 1.4.4.1.4.3.6.1 2008/09/27 17:03:25 Exp $ - */ - -/* global msglevel for debug messages - bitvals come from sdiovar.h */ - -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) - -#define sd_log(x) - -#define SDIOH_ASSERT(exp) \ - do { if (!(exp)) \ - printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ - } while (0) - -#define BLOCK_SIZE_F1 64 -#define BLOCK_SIZE_F2 2048 -#define BLOCK_SIZE_F3 2048 - -/* internal return code */ -#define SUCCESS 0 -#undef ERROR -#define ERROR 1 -#define ERROR_UF 2 -#define ERROR_OF 3 - -/* private bus modes */ -#define SDIOH_MODE_SPI 0 - -#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -#define USE_MULTIBLOCK 0x4 - -struct sdioh_info { - uint cfg_bar; /* pci cfg address for bar */ - uint32 caps; /* cached value of capabilities reg */ - void *bar0; /* BAR0 for PCI Device */ - osl_t *osh; /* osh handler */ - void *controller; /* Pointer to SPI Controller's private data struct */ - - uint lockcount; /* nest count of spi_lock() calls */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - bool initialized; /* card initialized */ - uint32 target_dev; /* Target device ID */ - uint32 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint32 controller_type; /* Host controller type */ - uint8 version; /* Host Controller Spec Compliance Version */ - uint irq; /* Client irq */ - uint32 intrcount; /* Client interrupts */ - uint32 local_intrcount; /* Controller interrupts */ - bool host_init_done; /* Controller initted */ - bool card_init_done; /* Client SDIO interface initted */ - bool polled_mode; /* polling for command completion */ - - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - /* polling hack in wl_linux.c:wl_timer() */ - int adapter_slot; /* Maybe dealing with multiple slots/controllers */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SPI_MAX_IOFUNCS]; /* Blocksize */ - uint32 data_xfer_count; /* Current transfer */ - uint16 card_rca; /* Current Address */ - uint8 num_funcs; /* Supported funcs on client */ - uint32 card_dstatus; /* 32bit device status */ - uint32 com_cis_ptr; - uint32 func_cis_ptr[SPI_MAX_IOFUNCS]; - void *dma_buf; - ulong dma_phys; - int r_cnt; /* rx count */ - int t_cnt; /* tx_count */ - uint32 wordlen; /* host processor 16/32bits */ - uint32 prev_fun; - uint32 chip; - uint32 chiprev; - bool resp_delay_all; - bool dwordmode; - - struct spierrstats_t spierrstats; -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmspibrcm.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/************************************************************** - * Internal interfaces: bcmspibrcm.c references to per-port code - */ - -/* Interrupt (de)registration routines */ -extern int spi_register_irq(sdioh_info_t *sd, uint irq); -extern void spi_free_irq(uint irq, sdioh_info_t *sd); - -/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -extern void spi_lock(sdioh_info_t *sd); -extern void spi_unlock(sdioh_info_t *sd); - -/* Allocate/init/free per-OS private data */ -extern int spi_osinit(sdioh_info_t *sd); -extern void spi_osfree(sdioh_info_t *sd); - -#define SPI_RW_FLAG_M BITFIELD_MASK(1) /* Bit [31] - R/W Command Bit */ -#define SPI_RW_FLAG_S 31 -#define SPI_ACCESS_M BITFIELD_MASK(1) /* Bit [30] - Fixed/Incr Access */ -#define SPI_ACCESS_S 30 -#define SPI_FUNCTION_M BITFIELD_MASK(2) /* Bit [29:28] - Function Number */ -#define SPI_FUNCTION_S 28 -#define SPI_REG_ADDR_M BITFIELD_MASK(17) /* Bit [27:11] - Address */ -#define SPI_REG_ADDR_S 11 -#define SPI_LEN_M BITFIELD_MASK(11) /* Bit [10:0] - Packet length */ -#define SPI_LEN_S 0 diff --git a/drivers/net/wireless/bcm4329/include/bcmutils.h b/drivers/net/wireless/bcm4329/include/bcmutils.h deleted file mode 100644 index f85ed351d663..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmutils.h +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Misc useful os-independent macros and functions. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: bcmutils.h,v 13.184.4.6.2.1.18.25 2010/04/26 06:05:24 Exp $ - */ - - -#ifndef _bcmutils_h_ -#define _bcmutils_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -#define _BCM_U 0x01 -#define _BCM_L 0x02 -#define _BCM_D 0x04 -#define _BCM_C 0x08 -#define _BCM_P 0x10 -#define _BCM_S 0x20 -#define _BCM_X 0x40 -#define _BCM_SP 0x80 - -extern const unsigned char bcm_ctype[]; -#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) - -#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) - - - -struct bcmstrbuf { - char *buf; - unsigned int size; - char *origbuf; - unsigned int origsize; -}; - - -#ifdef BCMDRIVER -#include - -#define GPIO_PIN_NOTDEFINED 0x20 - - -#define SPINWAIT(exp, us) { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) {\ - OSL_DELAY(10); \ - countdown -= 10; \ - } \ -} - - - -#ifndef PKTQ_LEN_DEFAULT -#define PKTQ_LEN_DEFAULT 128 -#endif -#ifndef PKTQ_MAX_PREC -#define PKTQ_MAX_PREC 16 -#endif - -typedef struct pktq_prec { - void *head; - void *tail; - uint16 len; - uint16 max; -} pktq_prec_t; - - - -struct pktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[PKTQ_MAX_PREC]; -}; - - -struct spktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; - - struct pktq_prec q[1]; -}; - -#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) - - - - -struct ether_addr; - -extern int ether_isbcast(const void *ea); -extern int ether_isnulladdr(const void *ea); - - - -#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -#define pktq_plen(pq, prec) ((pq)->q[prec].len) -#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) - -#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) - -extern void *pktq_penq(struct pktq *pq, int prec, void *p); -extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -extern void *pktq_pdeq(struct pktq *pq, int prec); -extern void *pktq_pdeq_tail(struct pktq *pq, int prec); - -extern bool pktq_pdel(struct pktq *pq, void *p, int prec); - - -extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); - -extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); - - - -extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); - - - -#define pktq_len(pq) ((int)(pq)->len) -#define pktq_max(pq) ((int)(pq)->max) -#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -#define pktq_full(pq) ((pq)->len >= (pq)->max) -#define pktq_empty(pq) ((pq)->len == 0) - - -#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) - -extern void pktq_init(struct pktq *pq, int num_prec, int max_len); - -extern void *pktq_deq(struct pktq *pq, int *prec_out); -extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -extern void *pktq_peek(struct pktq *pq, int *prec_out); -extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); - - - -extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); -extern uint pkttotlen(osl_t *osh, void *p); -extern void *pktlast(osl_t *osh, void *p); -extern uint pktsegcnt(osl_t *osh, void *p); - - -extern uint pktsetprio(void *pkt, bool update_vtag); -#define PKTPRIO_VDSCP 0x100 -#define PKTPRIO_VLAN 0x200 -#define PKTPRIO_UPD 0x400 -#define PKTPRIO_DSCP 0x800 - - -extern int bcm_atoi(char *s); -extern ulong bcm_strtoul(char *cp, char **endp, uint base); -extern char *bcmstrstr(char *haystack, char *needle); -extern char *bcmstrcat(char *dest, const char *src); -extern char *bcmstrncat(char *dest, const char *src, uint size); -extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); -int bcmstricmp(const char *s1, const char *s2); -int bcmstrnicmp(const char* s1, const char* s2, int cnt); - - - -extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -extern int bcm_ether_atoe(char *p, struct ether_addr *ea); - - -struct ipv4_addr; -extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); - - -extern void bcm_mdelay(uint ms); - -extern char *getvar(char *vars, const char *name); -extern int getintvar(char *vars, const char *name); -extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -#define bcm_perf_enable() -#define bcmstats(fmt) -#define bcmlog(fmt, a1, a2) -#define bcmdumplog(buf, size) *buf = '\0' -#define bcmdumplogent(buf, idx) -1 - -#define bcmtslog(tstamp, fmt, a1, a2) -#define bcmprinttslogs() -#define bcmprinttstamp(us) - - - - -typedef struct bcm_iovar { - const char *name; - uint16 varid; - uint16 flags; - uint16 type; - uint16 minlen; -} bcm_iovar_t; - - - - -#define IOV_GET 0 -#define IOV_SET 1 - - -#define IOV_GVAL(id) ((id)*2) -#define IOV_SVAL(id) (((id)*2)+IOV_SET) -#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) - - - -extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); -extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); - -#endif - - -#define IOVT_VOID 0 -#define IOVT_BOOL 1 -#define IOVT_INT8 2 -#define IOVT_UINT8 3 -#define IOVT_INT16 4 -#define IOVT_UINT16 5 -#define IOVT_INT32 6 -#define IOVT_UINT32 7 -#define IOVT_BUFFER 8 -#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) - - -#define BCM_IOV_TYPE_INIT { \ - "void", \ - "bool", \ - "int8", \ - "uint8", \ - "int16", \ - "uint16", \ - "int32", \ - "uint32", \ - "buffer", \ - "" } - -#define BCM_IOVT_IS_INT(type) (\ - (type == IOVT_BOOL) || \ - (type == IOVT_INT8) || \ - (type == IOVT_UINT8) || \ - (type == IOVT_INT16) || \ - (type == IOVT_UINT16) || \ - (type == IOVT_INT32) || \ - (type == IOVT_UINT32)) - - - -#define BCME_STRLEN 64 -#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) - - - - -#define BCME_OK 0 -#define BCME_ERROR -1 -#define BCME_BADARG -2 -#define BCME_BADOPTION -3 -#define BCME_NOTUP -4 -#define BCME_NOTDOWN -5 -#define BCME_NOTAP -6 -#define BCME_NOTSTA -7 -#define BCME_BADKEYIDX -8 -#define BCME_RADIOOFF -9 -#define BCME_NOTBANDLOCKED -10 -#define BCME_NOCLK -11 -#define BCME_BADRATESET -12 -#define BCME_BADBAND -13 -#define BCME_BUFTOOSHORT -14 -#define BCME_BUFTOOLONG -15 -#define BCME_BUSY -16 -#define BCME_NOTASSOCIATED -17 -#define BCME_BADSSIDLEN -18 -#define BCME_OUTOFRANGECHAN -19 -#define BCME_BADCHAN -20 -#define BCME_BADADDR -21 -#define BCME_NORESOURCE -22 -#define BCME_UNSUPPORTED -23 -#define BCME_BADLEN -24 -#define BCME_NOTREADY -25 -#define BCME_EPERM -26 -#define BCME_NOMEM -27 -#define BCME_ASSOCIATED -28 -#define BCME_RANGE -29 -#define BCME_NOTFOUND -30 -#define BCME_WME_NOT_ENABLED -31 -#define BCME_TSPEC_NOTFOUND -32 -#define BCME_ACM_NOTSUPPORTED -33 -#define BCME_NOT_WME_ASSOCIATION -34 -#define BCME_SDIO_ERROR -35 -#define BCME_DONGLE_DOWN -36 -#define BCME_VERSION -37 -#define BCME_TXFAIL -38 -#define BCME_RXFAIL -39 -#define BCME_NODEVICE -40 -#define BCME_UNFINISHED -41 -#define BCME_LAST BCME_UNFINISHED - - -#define BCMERRSTRINGTABLE { \ - "OK", \ - "Undefined error", \ - "Bad Argument", \ - "Bad Option", \ - "Not up", \ - "Not down", \ - "Not AP", \ - "Not STA", \ - "Bad Key Index", \ - "Radio Off", \ - "Not band locked", \ - "No clock", \ - "Bad Rate valueset", \ - "Bad Band", \ - "Buffer too short", \ - "Buffer too long", \ - "Busy", \ - "Not Associated", \ - "Bad SSID len", \ - "Out of Range Channel", \ - "Bad Channel", \ - "Bad Address", \ - "Not Enough Resources", \ - "Unsupported", \ - "Bad length", \ - "Not Ready", \ - "Not Permitted", \ - "No Memory", \ - "Associated", \ - "Not In Range", \ - "Not Found", \ - "WME Not Enabled", \ - "TSPEC Not Found", \ - "ACM Not Supported", \ - "Not WME Association", \ - "SDIO Bus Error", \ - "Dongle Not Accessible", \ - "Incorrect version", \ - "TX Failure", \ - "RX Failure", \ - "Device Not Present", \ - "Command not finished", \ -} - -#ifndef ABS -#define ABS(a) (((a) < 0)?-(a):(a)) -#endif - -#ifndef MIN -#define MIN(a, b) (((a) < (b))?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a, b) (((a) > (b))?(a):(b)) -#endif - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) -#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ - & ~((boundary) - 1)) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) -#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -#ifndef OFFSETOF -#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -#endif -#ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - - -#ifndef setbit -#ifndef NBBY -#define NBBY 8 -#endif -#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif - -#define NBITS(type) (sizeof(type) * 8) -#define NBITVAL(nbits) (1 << (nbits)) -#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -#define NBITMASK(nbits) MAXBITVAL(nbits) -#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) - - -#define MUX(pred, true, false) ((pred) ? (true) : (false)) - - -#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) - - -#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) - - -#define MODADD(x, y, bound) \ - MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -#define MODSUB(x, y, bound) \ - MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) - - -#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) - - -#define CRC8_INIT_VALUE 0xff -#define CRC8_GOOD_VALUE 0x9f -#define CRC16_INIT_VALUE 0xffff -#define CRC16_GOOD_VALUE 0xf0b8 -#define CRC32_INIT_VALUE 0xffffffff -#define CRC32_GOOD_VALUE 0xdebb20e3 - - -typedef struct bcm_bit_desc { - uint32 bit; - const char* name; -} bcm_bit_desc_t; - - -typedef struct bcm_tlv { - uint8 id; - uint8 len; - uint8 data[1]; -} bcm_tlv_t; - - -#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) - - -#define ETHER_ADDR_STR_LEN 18 - - -#ifdef IL_BIGENDIAN -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[0] = (v >> 24) & 0xff; - a[1] = (v >> 16) & 0xff; - a[2] = (v >> 8) & 0xff; - a[3] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[0] << 8) | a[1]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[0] = (v >> 8) & 0xff; - a[1] = v & 0xff; -} - -#else - -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[3] = (v >> 24) & 0xff; - a[2] = (v >> 16) & 0xff; - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[1] << 8) | a[0]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -#endif - - - -static INLINE void -xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) -{ - if ( -#ifdef __i386__ - 1 || -#endif - (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { - - - ((uint32 *)dst)[0] = ((uint32 *)src1)[0] ^ ((uint32 *)src2)[0]; - ((uint32 *)dst)[1] = ((uint32 *)src1)[1] ^ ((uint32 *)src2)[1]; - ((uint32 *)dst)[2] = ((uint32 *)src1)[2] ^ ((uint32 *)src2)[2]; - ((uint32 *)dst)[3] = ((uint32 *)src1)[3] ^ ((uint32 *)src2)[3]; - } else { - - int k; - for (k = 0; k < 16; k++) - dst[k] = src1[k] ^ src2[k]; - } -} - - - -extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); -extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); -extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); - -#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ - defined(WLMSG_ASSOC) -extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); -extern int bcm_format_hex(char *str, const void *bytes, int len); -extern void prhex(const char *msg, uchar *buf, uint len); -#endif -extern char *bcm_brev_str(uint32 brev, char *buf); -extern void printbig(char *buf); - - -extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); -extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); - - -extern const char *bcmerrorstr(int bcmerror); - - -typedef uint32 mbool; -#define mboolset(mb, bit) ((mb) |= (bit)) -#define mboolclr(mb, bit) ((mb) &= ~(bit)) -#define mboolisset(mb, bit) (((mb) & (bit)) != 0) -#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) - - -extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -extern uint8 bcm_mw_to_qdbm(uint16 mw); - - -struct fielddesc { - const char *nameandfmt; - uint32 offset; - uint32 len; -}; - -extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -extern int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes); -extern void bcm_print_bytes(char *name, const uchar *cdata, int len); - -typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); -extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, - char *buf, uint32 bufsize); - -extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); -extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); - -#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ - defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); -#endif - - -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/drivers/net/wireless/bcm4329/include/bcmwifi.h b/drivers/net/wireless/bcm4329/include/bcmwifi.h deleted file mode 100644 index 038aedcdb3c8..000000000000 --- a/drivers/net/wireless/bcm4329/include/bcmwifi.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Misc utility routines for WL and Apps - * This header file housing the define and function prototype use by - * both the wl driver, tools & Apps. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: bcmwifi.h,v 1.15.30.4 2010/03/10 20:10:52 Exp $ - */ - - -#ifndef _bcmwifi_h_ -#define _bcmwifi_h_ - - - -typedef uint16 chanspec_t; - - -#define CH_UPPER_SB 0x01 -#define CH_LOWER_SB 0x02 -#define CH_EWA_VALID 0x04 -#define CH_20MHZ_APART 4 -#define CH_10MHZ_APART 2 -#define CH_5MHZ_APART 1 -#define CH_MAX_2G_CHANNEL 14 -#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL -#define MAXCHANNEL 224 - -#define WL_CHANSPEC_CHAN_MASK 0x00ff -#define WL_CHANSPEC_CHAN_SHIFT 0 - -#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -#define WL_CHANSPEC_CTL_SB_SHIFT 8 -#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -#define WL_CHANSPEC_CTL_SB_NONE 0x0300 - -#define WL_CHANSPEC_BW_MASK 0x0C00 -#define WL_CHANSPEC_BW_SHIFT 10 -#define WL_CHANSPEC_BW_10 0x0400 -#define WL_CHANSPEC_BW_20 0x0800 -#define WL_CHANSPEC_BW_40 0x0C00 - -#define WL_CHANSPEC_BAND_MASK 0xf000 -#define WL_CHANSPEC_BAND_SHIFT 12 -#define WL_CHANSPEC_BAND_5G 0x1000 -#define WL_CHANSPEC_BAND_2G 0x2000 -#define INVCHANSPEC 255 - - -#define WF_CHAN_FACTOR_2_4_G 4814 -#define WF_CHAN_FACTOR_5_G 10000 -#define WF_CHAN_FACTOR_4_G 8000 - - -#define LOWER_20_SB(channel) ((channel > CH_10MHZ_APART) ? (channel - CH_10MHZ_APART) : 0) -#define UPPER_20_SB(channel) ((channel < (MAXCHANNEL - CH_10MHZ_APART)) ? \ - (channel + CH_10MHZ_APART) : 0) -#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ - WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ - WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -#define NEXT_20MHZ_CHAN(channel) ((channel < (MAXCHANNEL - CH_20MHZ_APART)) ? \ - (channel + CH_20MHZ_APART) : 0) -#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ - ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ - ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ - WL_CHANSPEC_BAND_5G)) -#define CHSPEC_CHANNEL(chspec) ((uint8)(chspec & WL_CHANSPEC_CHAN_MASK)) -#define CHSPEC_BAND(chspec) (chspec & WL_CHANSPEC_BAND_MASK) - -#ifdef WL20MHZ_ONLY - -#define CHSPEC_CTL_SB(chspec) WL_CHANSPEC_CTL_SB_NONE -#define CHSPEC_BW(chspec) WL_CHANSPEC_BW_20 -#define CHSPEC_IS10(chspec) 0 -#define CHSPEC_IS20(chspec) 1 -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) 0 -#endif - -#else - -#define CHSPEC_CTL_SB(chspec) (chspec & WL_CHANSPEC_CTL_SB_MASK) -#define CHSPEC_BW(chspec) (chspec & WL_CHANSPEC_BW_MASK) -#define CHSPEC_IS10(chspec) ((chspec & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -#define CHSPEC_IS20(chspec) ((chspec & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -#endif - -#endif - -#define CHSPEC_IS5G(chspec) ((chspec & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -#define CHSPEC_IS2G(chspec) ((chspec & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -#define CHSPEC_SB_NONE(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -#define CHSPEC_SB_UPPER(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -#define CHSPEC_SB_LOWER(chspec) ((chspec & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ - (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ - (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) - -#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G((chspec))? WLC_BAND_5G: WLC_BAND_2G) - -#define CHANSPEC_STR_LEN 8 - - -#define WLC_MAXRATE 108 -#define WLC_RATE_1M 2 -#define WLC_RATE_2M 4 -#define WLC_RATE_5M5 11 -#define WLC_RATE_11M 22 -#define WLC_RATE_6M 12 -#define WLC_RATE_9M 18 -#define WLC_RATE_12M 24 -#define WLC_RATE_18M 36 -#define WLC_RATE_24M 48 -#define WLC_RATE_36M 72 -#define WLC_RATE_48M 96 -#define WLC_RATE_54M 108 - -#define WLC_2G_25MHZ_OFFSET 5 - - -extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); - - -extern chanspec_t wf_chspec_aton(char *a); - - -extern int wf_mhz2channel(uint freq, uint start_factor); - - -extern int wf_channel2mhz(uint channel, uint start_factor); - -#endif diff --git a/drivers/net/wireless/bcm4329/include/dhdioctl.h b/drivers/net/wireless/bcm4329/include/dhdioctl.h deleted file mode 100644 index 980a14301003..000000000000 --- a/drivers/net/wireless/bcm4329/include/dhdioctl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Definitions for ioctls to access DHD iovars. - * Based on wlioctl.h (for Broadcom 802.11abg driver). - * (Moves towards generic ioctls for BCM drivers/iovars.) - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: dhdioctl.h,v 13.7.8.1.4.1.16.5 2010/05/21 21:49:38 Exp $ - */ - -#ifndef _dhdioctl_h_ -#define _dhdioctl_h_ - -#include - - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - - -/* Linux network driver ioctl encoding */ -typedef struct dhd_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ - uint driver; /* to identify target driver */ -} dhd_ioctl_t; - -/* per-driver magic numbers */ -#define DHD_IOCTL_MAGIC 0x00444944 - -/* bump this number if you change the ioctl interface */ -#define DHD_IOCTL_VERSION 1 - -#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define DHD_GET_MAGIC 0 -#define DHD_GET_VERSION 1 -#define DHD_GET_VAR 2 -#define DHD_SET_VAR 3 - -/* message levels */ -#define DHD_ERROR_VAL 0x0001 -#define DHD_TRACE_VAL 0x0002 -#define DHD_INFO_VAL 0x0004 -#define DHD_DATA_VAL 0x0008 -#define DHD_CTL_VAL 0x0010 -#define DHD_TIMER_VAL 0x0020 -#define DHD_HDRS_VAL 0x0040 -#define DHD_BYTES_VAL 0x0080 -#define DHD_INTR_VAL 0x0100 -#define DHD_LOG_VAL 0x0200 -#define DHD_GLOM_VAL 0x0400 -#define DHD_EVENT_VAL 0x0800 -#define DHD_BTA_VAL 0x1000 -#define DHD_ISCAN_VAL 0x2000 - -#ifdef SDTEST -/* For pktgen iovar */ -typedef struct dhd_pktgen { - uint version; /* To allow structure change tracking */ - uint freq; /* Max ticks between tx/rx attempts */ - uint count; /* Test packets to send/rcv each attempt */ - uint print; /* Print counts every attempts */ - uint total; /* Total packets (or bursts) */ - uint minlen; /* Minimum length of packets to send */ - uint maxlen; /* Maximum length of packets to send */ - uint numsent; /* Count of test packets sent */ - uint numrcvd; /* Count of test packets received */ - uint numfail; /* Count of test send failures */ - uint mode; /* Test mode (type of test packets) */ - uint stop; /* Stop after this many tx failures */ -} dhd_pktgen_t; - -/* Version in case structure changes */ -#define DHD_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous tx dongle */ -#endif /* SDTEST */ - -/* Enter idle immediately (no timeout) */ -#define DHD_IDLE_IMMEDIATE (-1) - -/* Values for idleclock iovar: other values are the sd_divisor to use when idle */ -#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */ -#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */ - - -/* require default structure packing */ -#include - - -#endif /* _dhdioctl_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/epivers.h b/drivers/net/wireless/bcm4329/include/epivers.h deleted file mode 100644 index cd66a9501cb6..000000000000 --- a/drivers/net/wireless/bcm4329/include/epivers.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: epivers.h.in,v 13.25 2005/10/28 18:35:33 Exp $ - * -*/ - - -#ifndef _epivers_h_ -#define _epivers_h_ - -#define EPI_MAJOR_VERSION 4 - -#define EPI_MINOR_VERSION 218 - -#define EPI_RC_NUMBER 248 - -#define EPI_INCREMENTAL_NUMBER 23 - -#define EPI_BUILD_NUMBER 0 - -#define EPI_VERSION 4, 218, 248, 23 - -#define EPI_VERSION_NUM 0x04daf817 - - -#define EPI_VERSION_STR "4.218.248.23" -#define EPI_ROUTER_VERSION_STR "4.219.248.23" - -#endif diff --git a/drivers/net/wireless/bcm4329/include/hndpmu.h b/drivers/net/wireless/bcm4329/include/hndpmu.h deleted file mode 100644 index e829b3df2d0b..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndpmu.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * HND SiliconBackplane PMU support. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: hndpmu.h,v 13.14.4.3.4.3.8.7 2010/04/09 13:20:51 Exp $ - */ - -#ifndef _hndpmu_h_ -#define _hndpmu_h_ - - -extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength); - -#endif /* _hndpmu_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h b/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h deleted file mode 100644 index ca3281b6d901..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndrte_armtrap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * HNDRTE arm trap handling. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: hndrte_armtrap.h,v 13.3.196.2 2010/07/15 19:06:11 Exp $ - */ - -#ifndef _hndrte_armtrap_h -#define _hndrte_armtrap_h - - -/* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -/* Trap locations in lo memory */ -#define TRAP_STRIDE 4 -#define FIRST_TRAP TR_RST -#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) - -#if defined(__ARM_ARCH_4T__) -#define MAX_TRAP_TYPE (TR_FIQ + 1) -#elif defined(__ARM_ARCH_7M__) -#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -#endif /* __ARM_ARCH_7M__ */ - -/* The trap structure is defined here as offsets for assembly */ -#define TR_TYPE 0x00 -#define TR_EPC 0x04 -#define TR_CPSR 0x08 -#define TR_SPSR 0x0c -#define TR_REGS 0x10 -#define TR_REG(n) (TR_REGS + (n) * 4) -#define TR_SP TR_REG(13) -#define TR_LR TR_REG(14) -#define TR_PC TR_REG(15) - -#define TRAP_T_SIZE 80 - -#ifndef _LANGUAGE_ASSEMBLY - -#include - -typedef struct _trap_struct { - uint32 type; - uint32 epc; - uint32 cpsr; - uint32 spsr; - uint32 r0; - uint32 r1; - uint32 r2; - uint32 r3; - uint32 r4; - uint32 r5; - uint32 r6; - uint32 r7; - uint32 r8; - uint32 r9; - uint32 r10; - uint32 r11; - uint32 r12; - uint32 r13; - uint32 r14; - uint32 pc; -} trap_t; - -#endif /* !_LANGUAGE_ASSEMBLY */ - -#endif /* _hndrte_armtrap_h */ diff --git a/drivers/net/wireless/bcm4329/include/hndrte_cons.h b/drivers/net/wireless/bcm4329/include/hndrte_cons.h deleted file mode 100644 index a42417478a16..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndrte_cons.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Console support for hndrte. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: hndrte_cons.h,v 13.1.2.4 2010/07/15 19:06:11 Exp $ - */ - -#include - -#define CBUF_LEN (128) - -#define LOG_BUF_LEN 1024 - -typedef struct { - uint32 buf; /* Can't be pointer on (64-bit) hosts */ - uint buf_size; - uint idx; - char *_buf_compat; /* Redundant pointer for backward compat. */ -} hndrte_log_t; - -typedef struct { - /* Virtual UART - * When there is no UART (e.g. Quickturn), the host should write a complete - * input line directly into cbuf and then write the length into vcons_in. - * This may also be used when there is a real UART (at risk of conflicting with - * the real UART). vcons_out is currently unused. - */ - volatile uint vcons_in; - volatile uint vcons_out; - - /* Output (logging) buffer - * Console output is written to a ring buffer log_buf at index log_idx. - * The host may read the output when it sees log_idx advance. - * Output will be lost if the output wraps around faster than the host polls. - */ - hndrte_log_t log; - - /* Console input line buffer - * Characters are read one at a time into cbuf until is received, then - * the buffer is processed as a command line. Also used for virtual UART. - */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; -} hndrte_cons_t; diff --git a/drivers/net/wireless/bcm4329/include/hndsoc.h b/drivers/net/wireless/bcm4329/include/hndsoc.h deleted file mode 100644 index 35424175f55e..000000000000 --- a/drivers/net/wireless/bcm4329/include/hndsoc.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Broadcom HND chip & on-chip-interconnect-related definitions. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: hndsoc.h,v 13.3.10.3 2008/08/06 03:43:25 Exp $ - */ - -#ifndef _HNDSOC_H -#define _HNDSOC_H - -/* Include the soci specific files */ -#include -#include - -/* - * SOC Interconnect Address Map. - * All regions may not exist on all chips. - */ -#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ - -#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -#ifndef SI_MAXCORES -#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software - * convenience and could be changed if we - * make any larger chips - */ -#endif - -#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ - -#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ - -#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), low 32 bits - */ -#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), high 32 bits - */ - -/* core codes */ -#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -#define CC_CORE_ID 0x800 /* chipcommon core */ -#define ILINE20_CORE_ID 0x801 /* iline20 core */ -#define SRAM_CORE_ID 0x802 /* sram core */ -#define SDRAM_CORE_ID 0x803 /* sdram core */ -#define PCI_CORE_ID 0x804 /* pci core */ -#define MIPS_CORE_ID 0x805 /* mips core */ -#define ENET_CORE_ID 0x806 /* enet mac core */ -#define CODEC_CORE_ID 0x807 /* v90 codec core */ -#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -#define ADSL_CORE_ID 0x809 /* ADSL core */ -#define ILINE100_CORE_ID 0x80a /* iline100 core */ -#define IPSEC_CORE_ID 0x80b /* ipsec core */ -#define UTOPIA_CORE_ID 0x80c /* utopia core */ -#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -#define MEMC_CORE_ID 0x80f /* memc sdram core */ -#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -#define EXTIF_CORE_ID 0x811 /* external interface core */ -#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -#define SDIOH_CORE_ID 0x81b /* sdio host core */ -#define ROBO_CORE_ID 0x81c /* roboswitch core */ -#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -#define PCIE_CORE_ID 0x820 /* pci express core */ -#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -#define PMU_CORE_ID 0x827 /* PMU core */ -#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -#define QNPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -#define SC_CORE_ID 0x831 /* shared common core */ -#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -#define SPIH_CORE_ID 0x833 /* SPI host core */ -#define I2S_CORE_ID 0x834 /* I2S core */ -#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all - * unused address ranges - */ - -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ -#define SI_CC_IDX 0 - -/* SOC Interconnect types (aka chip types) */ -#define SOCI_SB 0 -#define SOCI_AI 1 - -/* Common core control flags */ -#define SICF_BIST_EN 0x8000 -#define SICF_PME_EN 0x4000 -#define SICF_CORE_BITS 0x3ffc -#define SICF_FGC 0x0002 -#define SICF_CLOCK_EN 0x0001 - -/* Common core status flags */ -#define SISF_BIST_DONE 0x8000 -#define SISF_BIST_ERROR 0x4000 -#define SISF_GATED_CLK 0x2000 -#define SISF_DMA64 0x1000 -#define SISF_CORE_BITS 0x0fff - -/* A register that is common to all cores to - * communicate w/PMU regarding clock control. - */ -#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ - -/* clk_ctl_st register */ -#define CCS_FORCEALP 0x00000001 /* force ALP request */ -#define CCS_FORCEHT 0x00000002 /* force HT request */ -#define CCS_FORCEILP 0x00000004 /* force ILP request */ -#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -#define CCS_HTAVAIL 0x00020000 /* HT is available */ -#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ - -/* Not really related to SOC Interconnect, but a couple of software - * conventions for the use the flash space: - */ - -/* Minumum amount of flash we support */ -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -/* A boot/binary may have an embedded block that describes its size */ -#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -#define BISZ_TXTST_IDX 1 /* 1: text start */ -#define BISZ_TXTEND_IDX 2 /* 2: text end */ -#define BISZ_DATAST_IDX 3 /* 3: data start */ -#define BISZ_DATAEND_IDX 4 /* 4: data end */ -#define BISZ_BSSST_IDX 5 /* 5: bss start */ -#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ - -#endif /* _HNDSOC_H */ diff --git a/drivers/net/wireless/bcm4329/include/linux_osl.h b/drivers/net/wireless/bcm4329/include/linux_osl.h deleted file mode 100644 index b059c2adb17d..000000000000 --- a/drivers/net/wireless/bcm4329/include/linux_osl.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: linux_osl.h,v 13.131.30.8 2010/04/26 05:42:18 Exp $ - */ - - -#ifndef _linux_osl_h_ -#define _linux_osl_h_ - -#include - - -#include - - -#ifdef __GNUC__ -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#if GCC_VERSION > 30100 -#define ASSERT(exp) do {} while (0) -#else - -#define ASSERT(exp) -#endif -#endif - - -#define OSL_DELAY(usec) osl_delay(usec) -extern void osl_delay(uint usec); - - - -#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ - osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ - osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); - - -#define OSL_PCI_READ_CONFIG(osh, offset, size) \ - osl_pci_read_config((osh), (offset), (size)) -#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ - osl_pci_write_config((osh), (offset), (size), (val)) -extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); - - -#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(osl_t *osh); -extern uint osl_pci_slot(osl_t *osh); - - -typedef struct { - bool pkttag; - uint pktalloced; - bool mmbus; - pktfree_cb_fn_t tx_fn; - void *tx_ctx; -} osl_pubinfo_t; - - -extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); -extern void osl_detach(osl_t *osh); - -#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ - do { \ - ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ - ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ - } while (0) - - -#define BUS_SWAP32(v) (v) - - -#define MALLOC(osh, size) osl_malloc((osh), (size)) -#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -#define MALLOCED(osh) osl_malloced((osh)) - - -#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) - -extern void *osl_malloc(osl_t *osh, uint size); -extern void osl_mfree(osl_t *osh, void *addr, uint size); -extern uint osl_malloced(osl_t *osh); -extern uint osl_malloc_failed(osl_t *osh); - - -#define DMA_CONSISTENT_ALIGN PAGE_SIZE -#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ - osl_dma_alloc_consistent((osh), (size), (pap)) -#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ - osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); -extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); - - -#define DMA_TX 1 -#define DMA_RX 2 - - -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) -#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ - osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); - - -#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) - - -#include -#define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r)))) - -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ - mmap_op else bus_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ - mmap_op : bus_op - - - - -#ifndef printf -#define printf(fmt, args...) printk(fmt, ## args) -#endif -#include -#include - - -#ifndef IL_BIGENDIAN -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ - sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ - readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \ -) -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ - case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ - case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#else -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): __osl_v = \ - readb((volatile uint8*)((uintptr)(r)^3)); break; \ - case sizeof(uint16): __osl_v = \ - readw((volatile uint16*)((uintptr)(r)^2)); break; \ - case sizeof(uint32): __osl_v = \ - readl((volatile uint32*)(r)); break; \ - } \ - __osl_v; \ - }), \ - OSL_READ_REG(osh, r)) \ -) -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), \ - (volatile uint8*)((uintptr)(r)^3)); break; \ - case sizeof(uint16): writew((uint16)(v), \ - (volatile uint16*)((uintptr)(r)^2)); break; \ - case sizeof(uint32): writel((uint32)(v), \ - (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#endif - -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) - - -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) - - -#define OSL_UNCACHED(va) ((void*)va) - - -#if defined(__i386__) -#define OSL_GETCYCLES(x) rdtscl((x)) -#else -#define OSL_GETCYCLES(x) ((x) = 0) -#endif - - -#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) - - -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif -#define REG_UNMAP(va) iounmap((va)) - - -#define R_SM(r) *(r) -#define W_SM(r, v) (*(r) = (v)) -#define BZERO_SM(r, len) memset((r), '\0', (len)) - - -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#ifdef DHD_USE_STATIC_BUF -#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) -#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -#endif -#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced -#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -#define PKTPOOL(osh, skb) FALSE -#define PKTPOOLLEN(osh, pktp) (0) -#define PKTPOOLAVAIL(osh, pktp) (0) -#define PKTPOOLADD(osh, pktp, p) BCME_ERROR -#define PKTPOOLGET(osh, pktp) NULL -#define PKTLIST_DUMP(osh, buf) - -extern void *osl_pktget(osl_t *osh, uint len); -extern void osl_pktfree(osl_t *osh, void *skb, bool send); -extern void *osl_pktget_static(osl_t *osh, uint len); -extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); -extern void *osl_pktdup(osl_t *osh, void *skb); - - - -static INLINE void * -osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero((void*)skb->cb, OSL_PKTTAG_SZ); - - - for (nskb = skb; nskb; nskb = nskb->next) { - osh->pktalloced++; - } - - return (void *)skb; -} -#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb)) - - -static INLINE struct sk_buff * -osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced--; - } - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt)) - -#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) -#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ - ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) - -#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) - - -#define OSL_ERROR(bcmerror) osl_error(bcmerror) -extern int osl_error(int bcmerror); - - -#define PKTBUFSZ 2048 - - -#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) -#endif diff --git a/drivers/net/wireless/bcm4329/include/linuxver.h b/drivers/net/wireless/bcm4329/include/linuxver.h deleted file mode 100644 index 6ed22658a72b..000000000000 --- a/drivers/net/wireless/bcm4329/include/linuxver.h +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Linux-specific abstractions to gain some independence from linux kernel versions. - * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: linuxver.h,v 13.38.8.1.8.6 2010/04/29 05:00:46 Exp $ - */ - - -#ifndef _linuxver_h_ -#define _linuxver_h_ - -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#include -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) -#include -#endif -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) - -#ifdef __UNDEF_NO_VERSION__ -#undef __NO_VERSION__ -#else -#define __NO_VERSION__ -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -#define module_param_string(_name_, _string_, _size_, _perm_) \ - MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -#undef IP_TOS -#endif -#include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) -#include -#else -#include -#ifndef work_struct -#define work_struct tq_struct -#endif -#ifndef INIT_WORK -#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -#endif -#ifndef schedule_work -#define schedule_work(_work) schedule_task((_work)) -#endif -#ifndef flush_scheduled_work -#define flush_scheduled_work() flush_scheduled_tasks() -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func) -#else -#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func, _data) -typedef void (*work_func_t)(void *work); -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#ifndef IRQ_NONE -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif -#else -typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#define IRQF_SHARED SA_SHIRQ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) -#ifdef CONFIG_NET_RADIO -#define CONFIG_WIRELESS_EXT -#endif -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -#ifndef SANDGATE2G -#define MOD_INC_USE_COUNT -#endif -#endif - - -#ifndef __exit -#define __exit -#endif -#ifndef __devexit -#define __devexit -#endif -#ifndef __devinit -#define __devinit __init -#endif -#ifndef __devinitdata -#define __devinitdata -#endif -#ifndef __devexit_p -#define __devexit_p(x) x -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) - -#define pci_get_drvdata(dev) (dev)->sysdata -#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) - - - -struct pci_device_id { - unsigned int vendor, device; - unsigned int subvendor, subdevice; - unsigned int class, class_mask; - unsigned long driver_data; -}; - -struct pci_driver { - struct list_head node; - char *name; - const struct pci_device_id *id_table; - int (*probe)(struct pci_dev *dev, - const struct pci_device_id *id); - void (*remove)(struct pci_dev *dev); - void (*suspend)(struct pci_dev *dev); - void (*resume)(struct pci_dev *dev); -}; - -#define MODULE_DEVICE_TABLE(type, name) -#define PCI_ANY_ID (~0) - - -#define pci_module_init pci_register_driver -extern int pci_register_driver(struct pci_driver *drv); -extern void pci_unregister_driver(struct pci_driver *drv); - -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) -#define pci_module_init pci_register_driver -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) -#ifdef MODULE -#define module_init(x) int init_module(void) { return x(); } -#define module_exit(x) void cleanup_module(void) { x(); } -#else -#define module_init(x) __initcall(x); -#define module_exit(x) __exitcall(x); -#endif -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) -#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) -#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) -#define pci_enable_device(dev) do { } while (0) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) -#define net_device device -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) - - - -#ifndef PCI_DMA_TODEVICE -#define PCI_DMA_TODEVICE 1 -#define PCI_DMA_FROMDEVICE 2 -#endif - -typedef u32 dma_addr_t; - - -static inline int get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} - -static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC | GFP_DMA; - - ret = (void *)__get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} -static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} -#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -#define pci_unmap_single(cookie, address, size, dir) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) - -#define dev_kfree_skb_any(a) dev_kfree_skb(a) -#define netif_down(dev) do { (dev)->start = 0; } while (0) - - -#ifndef _COMPAT_NETDEVICE_H - - - -#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -#define netif_wake_queue(dev) \ - do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) -#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) - -static inline void netif_start_queue(struct net_device *dev) -{ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; -} - -#define netif_queue_stopped(dev) (dev)->tbusy -#define netif_running(dev) (dev)->start - -#endif - -#define netif_device_attach(dev) netif_start_queue(dev) -#define netif_device_detach(dev) netif_stop_queue(dev) - - -#define tasklet_struct tq_struct -static inline void tasklet_schedule(struct tasklet_struct *tasklet) -{ - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -static inline void tasklet_init(struct tasklet_struct *tasklet, - void (*func)(unsigned long), - unsigned long data) -{ - tasklet->next = NULL; - tasklet->sync = 0; - tasklet->routine = (void (*)(void *))func; - tasklet->data = (void *)data; -} -#define tasklet_kill(tasklet) { do {} while (0); } - - -#define del_timer_sync(timer) del_timer(timer) - -#else - -#define netif_down(dev) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) - - -#define PREPARE_TQUEUE(_tq, _routine, _data) \ - do { \ - (_tq)->routine = _routine; \ - (_tq)->data = _data; \ - } while (0) - - -#define INIT_TQUEUE(_tq, _routine, _data) \ - do { \ - INIT_LIST_HEAD(&(_tq)->list); \ - (_tq)->sync = 0; \ - PREPARE_TQUEUE((_tq), (_routine), (_data)); \ - } while (0) - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) - - - -static inline int -pci_save_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - if (buffer) { - for (i = 0; i < 16; i++) - pci_read_config_dword(dev, i * 4, &buffer[i]); - } - return 0; -} - -static inline int -pci_restore_state(struct pci_dev *dev, u32 *buffer) -{ - int i; - - if (buffer) { - for (i = 0; i < 16; i++) - pci_write_config_dword(dev, i * 4, buffer[i]); - } - - else { - for (i = 0; i < 6; i ++) - pci_write_config_dword(dev, - PCI_BASE_ADDRESS_0 + (i * 4), - pci_resource_start(dev, i)); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } - return 0; -} - -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) -#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -#endif - - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define OLD_MOD_INC_USE_COUNT do {} while (0) -#define OLD_MOD_DEC_USE_COUNT do {} while (0) -#endif -#else -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do {} while (0) -#endif -#ifndef MOD_INC_USE_COUNT -#define MOD_INC_USE_COUNT do {} while (0) -#endif -#ifndef MOD_DEC_USE_COUNT -#define MOD_DEC_USE_COUNT do {} while (0) -#endif -#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#endif - -#ifndef SET_NETDEV_DEV -#define SET_NETDEV_DEV(net, pdev) do {} while (0) -#endif - -#ifndef HAVE_FREE_NETDEV -#define free_netdev(dev) kfree(dev) -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) - -#define af_packet_priv data -#endif - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -#define DRV_SUSPEND_STATE_TYPE pm_message_t -#else -#define DRV_SUSPEND_STATE_TYPE uint32 -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -#define CHECKSUM_HW CHECKSUM_PARTIAL -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -#define KILL_PROC(pid, sig) \ -{ \ - struct task_struct *tsk; \ - tsk = pid_task(find_vpid(pid), PIDTYPE_PID); \ - if (tsk) send_sig(sig, tsk, 1); \ -} -#else -#define KILL_PROC(pid, sig) \ -{ \ - kill_proc(pid, sig, 1); \ -} -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -#define netdev_priv(dev) dev->priv -#endif - -#endif diff --git a/drivers/net/wireless/bcm4329/include/miniopt.h b/drivers/net/wireless/bcm4329/include/miniopt.h deleted file mode 100644 index 3667fb1e215b..000000000000 --- a/drivers/net/wireless/bcm4329/include/miniopt.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Command line options parser. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: miniopt.h,v 1.1.6.2 2009/01/14 23:52:48 Exp $ - */ - - -#ifndef MINI_OPT_H -#define MINI_OPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---- Include Files ---------------------------------------------------- */ -/* ---- Constants and Types ---------------------------------------------- */ - -#define MINIOPT_MAXKEY 128 /* Max options */ -typedef struct miniopt { - - /* These are persistent after miniopt_init() */ - const char* name; /* name for prompt in error strings */ - const char* flags; /* option chars that take no args */ - bool longflags; /* long options may be flags */ - bool opt_end; /* at end of options (passed a "--") */ - - /* These are per-call to miniopt() */ - - int consumed; /* number of argv entries cosumed in - * the most recent call to miniopt() - */ - bool positional; - bool good_int; /* 'val' member is the result of a sucessful - * strtol conversion of the option value - */ - char opt; - char key[MINIOPT_MAXKEY]; - char* valstr; /* positional param, or value for the option, - * or null if the option had - * no accompanying value - */ - uint uval; /* strtol translation of valstr */ - int val; /* strtol translation of valstr */ -} miniopt_t; - -void miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags); -int miniopt(miniopt_t *t, char **argv); - - -/* ---- Variable Externs ------------------------------------------------- */ -/* ---- Function Prototypes ---------------------------------------------- */ - - -#ifdef __cplusplus - } -#endif - -#endif /* MINI_OPT_H */ diff --git a/drivers/net/wireless/bcm4329/include/msgtrace.h b/drivers/net/wireless/bcm4329/include/msgtrace.h deleted file mode 100644 index 1479086dba3e..000000000000 --- a/drivers/net/wireless/bcm4329/include/msgtrace.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Trace messages sent over HBUS - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: msgtrace.h,v 1.1.2.4 2009/01/27 04:09:40 Exp $ - */ - -#ifndef _MSGTRACE_H -#define _MSGTRACE_H - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -/* This marks the start of a packed structure section. */ -#include - -#define MSGTRACE_VERSION 1 - -/* Message trace header */ -typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { - uint8 version; - uint8 spare; - uint16 len; /* Len of the trace */ - uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost - * because of DMA error or a bus reset (ex: SDIO Func2) - */ - uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */ - uint32 discarded_printf; /* Number of discarded printf because of trace overflow */ -} BWL_POST_PACKED_STRUCT msgtrace_hdr_t; - -#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) - -/* The hbus driver generates traces when sending a trace message. This causes endless traces. - * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put. - * This prevents endless traces but generates hasardous lost of traces only in bus device code. - * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing - * hbus error traces. hbus error trace should not generates endless traces. - */ -extern bool msgtrace_hbus_trace; - -typedef void (*msgtrace_func_send_t)(void *hdl1, void *hdl2, uint8 *hdr, - uint16 hdrlen, uint8 *buf, uint16 buflen); - -extern void msgtrace_sent(void); -extern void msgtrace_put(char *buf, int count); -extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _MSGTRACE_H */ diff --git a/drivers/net/wireless/bcm4329/include/osl.h b/drivers/net/wireless/bcm4329/include/osl.h deleted file mode 100644 index 5599e536eeea..000000000000 --- a/drivers/net/wireless/bcm4329/include/osl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * OS Abstraction Layer - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: osl.h,v 13.37.32.1 2008/11/20 00:51:15 Exp $ - */ - - -#ifndef _osl_h_ -#define _osl_h_ - - -typedef struct osl_info osl_t; -typedef struct osl_dmainfo osldma_t; - -#define OSL_PKTTAG_SZ 32 - - -typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); - -#include - - - - -#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) - -#ifndef AND_REG -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#endif - -#ifndef OR_REG -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -#endif - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/packed_section_end.h b/drivers/net/wireless/bcm4329/include/packed_section_end.h deleted file mode 100644 index 5b61c18fcd08..000000000000 --- a/drivers/net/wireless/bcm4329/include/packed_section_end.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: packed_section_end.h,v 1.1.6.3 2008/12/10 00:27:54 Exp $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #undef BWL_PACKED_SECTION -#else - #error "BWL_PACKED_SECTION is NOT defined!" -#endif - - - - - -#undef BWL_PRE_PACKED_STRUCT -#undef BWL_POST_PACKED_STRUCT diff --git a/drivers/net/wireless/bcm4329/include/packed_section_start.h b/drivers/net/wireless/bcm4329/include/packed_section_start.h deleted file mode 100644 index cb93aa64079a..000000000000 --- a/drivers/net/wireless/bcm4329/include/packed_section_start.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Declare directives for structure packing. No padding will be provided - * between the members of packed structures, and therefore, there is no - * guarantee that structure members will be aligned. - * - * Declaring packed structures is compiler specific. In order to handle all - * cases, packed structures should be delared as: - * - * #include - * - * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { - * some_struct_members; - * } BWL_POST_PACKED_STRUCT foobar_t; - * - * #include - * - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: packed_section_start.h,v 1.1.6.3 2008/12/10 00:27:54 Exp $ - */ - - - - -#ifdef BWL_PACKED_SECTION - #error "BWL_PACKED_SECTION is already defined!" -#else - #define BWL_PACKED_SECTION -#endif - - - - - -#if defined(__GNUC__) - #define BWL_PRE_PACKED_STRUCT - #define BWL_POST_PACKED_STRUCT __attribute__((packed)) -#elif defined(__CC_ARM) - #define BWL_PRE_PACKED_STRUCT __packed - #define BWL_POST_PACKED_STRUCT -#else - #error "Unknown compiler!" -#endif diff --git a/drivers/net/wireless/bcm4329/include/pcicfg.h b/drivers/net/wireless/bcm4329/include/pcicfg.h deleted file mode 100644 index 898962c942a8..000000000000 --- a/drivers/net/wireless/bcm4329/include/pcicfg.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * pcicfg.h: PCI configuration constants and structures. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: pcicfg.h,v 1.41.12.3 2008/06/26 22:49:41 Exp $ - */ - - -#ifndef _h_pcicfg_ -#define _h_pcicfg_ - - -#define PCI_CFG_VID 0 -#define PCI_CFG_CMD 4 -#define PCI_CFG_REV 8 -#define PCI_CFG_BAR0 0x10 -#define PCI_CFG_BAR1 0x14 -#define PCI_BAR0_WIN 0x80 -#define PCI_INT_STATUS 0x90 -#define PCI_INT_MASK 0x94 - -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) -#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) - -#define PCI_BAR0_WINSZ (16 * 1024) - - -#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) -#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) -#define PCI_16KBB0_WINSZ (16 * 1024) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/802.11.h b/drivers/net/wireless/bcm4329/include/proto/802.11.h deleted file mode 100644 index fd26317361da..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.11.h +++ /dev/null @@ -1,1433 +0,0 @@ -/* - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * Fundamental types and constants relating to 802.11 - * - * $Id: 802.11.h,v 9.219.4.1.4.5.6.11 2010/02/09 13:23:26 Exp $ - */ - - -#ifndef _802_11_H_ -#define _802_11_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -#ifndef _NET_ETHERNET_H_ -#include -#endif - -#include - - -#include - - -#define DOT11_TU_TO_US 1024 - - -#define DOT11_A3_HDR_LEN 24 -#define DOT11_A4_HDR_LEN 30 -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_FCS_LEN 4 -#define DOT11_ICV_LEN 4 -#define DOT11_ICV_AES_LEN 8 -#define DOT11_QOS_LEN 2 -#define DOT11_HTC_LEN 4 - -#define DOT11_KEY_INDEX_SHIFT 6 -#define DOT11_IV_LEN 4 -#define DOT11_IV_TKIP_LEN 8 -#define DOT11_IV_AES_OCB_LEN 4 -#define DOT11_IV_AES_CCM_LEN 8 -#define DOT11_IV_MAX_LEN 8 - - -#define DOT11_MAX_MPDU_BODY_LEN 2304 - -#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ - DOT11_QOS_LEN + \ - DOT11_IV_AES_CCM_LEN + \ - DOT11_MAX_MPDU_BODY_LEN + \ - DOT11_ICV_LEN + \ - DOT11_FCS_LEN) - -#define DOT11_MAX_SSID_LEN 32 - - -#define DOT11_DEFAULT_RTS_LEN 2347 -#define DOT11_MAX_RTS_LEN 2347 - - -#define DOT11_MIN_FRAG_LEN 256 -#define DOT11_MAX_FRAG_LEN 2346 -#define DOT11_DEFAULT_FRAG_LEN 2346 - - -#define DOT11_MIN_BEACON_PERIOD 1 -#define DOT11_MAX_BEACON_PERIOD 0xFFFF - - -#define DOT11_MIN_DTIM_PERIOD 1 -#define DOT11_MAX_DTIM_PERIOD 0xFF - - -#define DOT11_LLC_SNAP_HDR_LEN 8 -#define DOT11_OUI_LEN 3 -BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { - uint8 dsap; - uint8 ssap; - uint8 ctl; - uint8 oui[DOT11_OUI_LEN]; - uint16 type; -} BWL_POST_PACKED_STRUCT; - - -#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) - - - -BWL_PRE_PACKED_STRUCT struct dot11_header { - uint16 fc; - uint16 durid; - struct ether_addr a1; - struct ether_addr a2; - struct ether_addr a3; - uint16 seq; - struct ether_addr a4; -} BWL_POST_PACKED_STRUCT; - - - -BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_RTS_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTS_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACK_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { - uint16 fc; - uint16 durid; - struct ether_addr bssid; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_PS_POLL_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr bssid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CS_END_LEN 16 - -BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1040]; - struct dot11_action_wifi_vendor_specific* next_node; -} BWL_POST_PACKED_STRUCT; - -typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; - -#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 -#define DOT11_BA_CTL_POLICY_NOACK 0x0001 -#define DOT11_BA_CTL_POLICY_MASK 0x0001 - -#define DOT11_BA_CTL_MTID 0x0002 -#define DOT11_BA_CTL_COMPRESSED 0x0004 - -#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 -#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 - -#define DOT11_BA_CTL_TID_MASK 0xF000 -#define DOT11_BA_CTL_TID_SHIFT 12 - - -BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; -#define DOT11_CTL_HDR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct dot11_bar { - uint16 bar_control; - uint16 seqnum; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BAR_LEN 4 - -#define DOT11_BA_BITMAP_LEN 128 -#define DOT11_BA_CMP_BITMAP_LEN 8 - -BWL_PRE_PACKED_STRUCT struct dot11_ba { - uint16 ba_control; - uint16 seqnum; - uint8 bitmap[DOT11_BA_BITMAP_LEN]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BA_LEN 4 - - -BWL_PRE_PACKED_STRUCT struct dot11_management_header { - uint16 fc; - uint16 durid; - struct ether_addr da; - struct ether_addr sa; - struct ether_addr bssid; - uint16 seq; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_HDR_LEN 24 - - - -BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { - uint32 timestamp[2]; - uint16 beacon_interval; - uint16 capability; -} BWL_POST_PACKED_STRUCT; -#define DOT11_BCN_PRB_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_auth { - uint16 alg; - uint16 seq; - uint16 status; -} BWL_POST_PACKED_STRUCT; -#define DOT11_AUTH_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { - uint16 capability; - uint16 listen; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_REQ_FIXED_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { - uint16 capability; - uint16 listen; - struct ether_addr ap; -} BWL_POST_PACKED_STRUCT; -#define DOT11_REASSOC_REQ_FIXED_LEN 10 - -BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { - uint16 capability; - uint16 status; - uint16 aid; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_RESP_FIXED_LEN 6 - -BWL_PRE_PACKED_STRUCT struct dot11_action_measure { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_MEASURE_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { - uint8 category; - uint8 action; - uint8 ch_width; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { - uint8 category; - uint8 action; - uint8 control; -} BWL_POST_PACKED_STRUCT; - -#define SM_PWRSAVE_ENABLE 1 -#define SM_PWRSAVE_MODE 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { - uint8 id; - uint8 len; - uint8 power; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cnst dot11_power_cnst_t; - -BWL_PRE_PACKED_STRUCT struct dot11_power_cap { - uint8 min; - uint8 max; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_power_cap dot11_power_cap_t; - -BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { - uint8 id; - uint8 len; - uint8 tx_pwr; - uint8 margin; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_tpc_rep dot11_tpc_rep_t; -#define DOT11_MNG_IE_TPC_REPORT_LEN 2 - -BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { - uint8 id; - uint8 len; - uint8 first_channel; - uint8 num_channels; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_supp_channels dot11_supp_channels_t; - - -BWL_PRE_PACKED_STRUCT struct dot11_extch { - uint8 id; - uint8 len; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extch dot11_extch_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint8 extch; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; - -#define BRCM_EXTCH_IE_LEN 5 -#define BRCM_EXTCH_IE_TYPE 53 -#define DOT11_EXTCH_IE_LEN 1 -#define DOT11_EXT_CH_MASK 0x03 -#define DOT11_EXT_CH_UPPER 0x01 -#define DOT11_EXT_CH_LOWER 0x03 -#define DOT11_EXT_CH_NONE 0x00 - -BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { - uint8 category; - uint8 action; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_FRMHDR_LEN 2 - - -BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { - uint8 id; - uint8 len; - uint8 mode; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_channel_switch dot11_chan_switch_ie_t; - -#define DOT11_SWITCH_IE_LEN 3 - -#define DOT11_CSA_MODE_ADVISORY 0 -#define DOT11_CSA_MODE_NO_TX 1 - -BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { - uint8 category; - uint8 action; - dot11_chan_switch_ie_t chan_switch_ie; - dot11_brcm_extch_ie_t extch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_csa_body { - uint8 mode; - uint8 reg; - uint8 channel; - uint8 count; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { - uint8 id; - uint8 len; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { - uint8 category; - uint8 action; - struct dot11_csa_body b; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -#define DOT11_EXT_CSA_IE_LEN 4 - -BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { - uint8 category; - uint8 action; - dot11_ext_csa_ie_t chan_switch_ie; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { - uint8 id; - uint8 len; - uint8 info; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_coex dot11_obss_coex_t; -#define DOT11_OBSS_COEXINFO_LEN 1 - -#define DOT11_OBSS_COEX_INFO_REQ 0x01 -#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 - -BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { - uint8 id; - uint8 len; - uint8 regclass; - uint8 chanlist[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 - -BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { - uint8 id; - uint8 len; - uint8 cap; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_extcap_ie dot11_extcap_ie_t; -#define DOT11_EXTCAP_LEN 1 - - - -#define DOT11_MEASURE_TYPE_BASIC 0 -#define DOT11_MEASURE_TYPE_CCA 1 -#define DOT11_MEASURE_TYPE_RPI 2 - - -#define DOT11_MEASURE_MODE_ENABLE (1<<1) -#define DOT11_MEASURE_MODE_REQUEST (1<<2) -#define DOT11_MEASURE_MODE_REPORT (1<<3) - -#define DOT11_MEASURE_MODE_LATE (1<<0) -#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) -#define DOT11_MEASURE_MODE_REFUSED (1<<2) - -#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) -#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) -#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) -#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) -#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) - -BWL_PRE_PACKED_STRUCT struct dot11_meas_req { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - uint8 channel; - uint8 start_time[8]; - uint16 duration; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_req dot11_meas_req_t; -#define DOT11_MNG_IE_MREQ_LEN 14 - -#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - BWL_PRE_PACKED_STRUCT union - { - BWL_PRE_PACKED_STRUCT struct { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; - } BWL_POST_PACKED_STRUCT basic; - uint8 data[1]; - } BWL_POST_PACKED_STRUCT rep; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep dot11_meas_rep_t; - - -#define DOT11_MNG_IE_MREP_FIXED_LEN 3 - -BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -#define DOT11_MEASURE_BASIC_REP_LEN 12 - -BWL_PRE_PACKED_STRUCT struct dot11_quiet { - uint8 id; - uint8 len; - uint8 count; - uint8 period; - uint16 duration; - uint16 offset; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_quiet dot11_quiet_t; - -BWL_PRE_PACKED_STRUCT struct chan_map_tuple { - uint8 channel; - uint8 map; -} BWL_POST_PACKED_STRUCT; -typedef struct chan_map_tuple chan_map_tuple_t; - -BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { - uint8 id; - uint8 len; - uint8 eaddr[ETHER_ADDR_LEN]; - uint8 interval; - chan_map_tuple_t map[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; - - -#define WME_OUI "\x00\x50\xf2" -#define WME_VER 1 -#define WME_TYPE 2 -#define WME_SUBTYPE_IE 0 -#define WME_SUBTYPE_PARAM_IE 1 -#define WME_SUBTYPE_TSPEC 2 - - -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 -#define AC_COUNT 4 - -typedef uint8 ac_bitmap_t; - -#define AC_BITMAP_NONE 0x0 -#define AC_BITMAP_ALL 0xf -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) -#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) - - -BWL_PRE_PACKED_STRUCT struct wme_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_ie wme_ie_t; -#define WME_IE_LEN 7 - -BWL_PRE_PACKED_STRUCT struct edcf_acparam { - uint8 ACI; - uint8 ECW; - uint16 TXOP; -} BWL_POST_PACKED_STRUCT; -typedef struct edcf_acparam edcf_acparam_t; - - -BWL_PRE_PACKED_STRUCT struct wme_param_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct wme_param_ie wme_param_ie_t; -#define WME_PARAM_IE_LEN 24 - - -#define WME_QI_AP_APSD_MASK 0x80 -#define WME_QI_AP_APSD_SHIFT 7 -#define WME_QI_AP_COUNT_MASK 0x0f -#define WME_QI_AP_COUNT_SHIFT 0 - - -#define WME_QI_STA_MAXSPLEN_MASK 0x60 -#define WME_QI_STA_MAXSPLEN_SHIFT 5 -#define WME_QI_STA_APSD_ALL_MASK 0xf -#define WME_QI_STA_APSD_ALL_SHIFT 0 -#define WME_QI_STA_APSD_BE_MASK 0x8 -#define WME_QI_STA_APSD_BE_SHIFT 3 -#define WME_QI_STA_APSD_BK_MASK 0x4 -#define WME_QI_STA_APSD_BK_SHIFT 2 -#define WME_QI_STA_APSD_VI_MASK 0x2 -#define WME_QI_STA_APSD_VI_SHIFT 1 -#define WME_QI_STA_APSD_VO_MASK 0x1 -#define WME_QI_STA_APSD_VO_SHIFT 0 - - -#define EDCF_AIFSN_MIN 1 -#define EDCF_AIFSN_MAX 15 -#define EDCF_AIFSN_MASK 0x0f -#define EDCF_ACM_MASK 0x10 -#define EDCF_ACI_MASK 0x60 -#define EDCF_ACI_SHIFT 5 -#define EDCF_AIFSN_SHIFT 12 - - -#define EDCF_ECW_MIN 0 -#define EDCF_ECW_MAX 15 -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f -#define EDCF_ECWMAX_MASK 0xf0 -#define EDCF_ECWMAX_SHIFT 4 - - -#define EDCF_TXOP_MIN 0 -#define EDCF_TXOP_MAX 65535 -#define EDCF_TXOP2USEC(txop) ((txop) << 5) - - -#define NON_EDCF_AC_BE_ACI_STA 0x02 - - -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VO_TXOP_STA 0x002f - - -#define EDCF_AC_BE_ACI_AP 0x03 -#define EDCF_AC_BE_ECW_AP 0x64 -#define EDCF_AC_BE_TXOP_AP 0x0000 -#define EDCF_AC_BK_ACI_AP 0x27 -#define EDCF_AC_BK_ECW_AP 0xA4 -#define EDCF_AC_BK_TXOP_AP 0x0000 -#define EDCF_AC_VI_ACI_AP 0x41 -#define EDCF_AC_VI_ECW_AP 0x43 -#define EDCF_AC_VI_TXOP_AP 0x005e -#define EDCF_AC_VO_ACI_AP 0x61 -#define EDCF_AC_VO_ECW_AP 0x32 -#define EDCF_AC_VO_TXOP_AP 0x002f - - -BWL_PRE_PACKED_STRUCT struct edca_param_ie { - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; -typedef struct edca_param_ie edca_param_ie_t; -#define EDCA_PARAM_IE_LEN 18 - - -BWL_PRE_PACKED_STRUCT struct qos_cap_ie { - uint8 qosinfo; -} BWL_POST_PACKED_STRUCT; -typedef struct qos_cap_ie qos_cap_ie_t; - -BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { - uint8 id; - uint8 length; - uint16 station_count; - uint8 channel_utilization; - uint16 aac; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; - - -#define FIXED_MSDU_SIZE 0x8000 -#define MSDU_SIZE_MASK 0x7fff - - - -#define INTEGER_SHIFT 13 -#define FRACTION_MASK 0x1FFF - - -BWL_PRE_PACKED_STRUCT struct dot11_management_notification { - uint8 category; - uint8 action; - uint8 token; - uint8 status; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_NOTIFICATION_LEN 4 - - -#define WME_ADDTS_REQUEST 0 -#define WME_ADDTS_RESPONSE 1 -#define WME_DELTS_REQUEST 2 - - -#define WME_ADMISSION_ACCEPTED 0 -#define WME_INVALID_PARAMETERS 1 -#define WME_ADMISSION_REFUSED 3 - - -#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) - - -#define DOT11_OPEN_SYSTEM 0 -#define DOT11_SHARED_KEY 1 - -#define DOT11_OPEN_SHARED 2 -#define DOT11_CHALLENGE_LEN 128 - - -#define FC_PVER_MASK 0x3 -#define FC_PVER_SHIFT 0 -#define FC_TYPE_MASK 0xC -#define FC_TYPE_SHIFT 2 -#define FC_SUBTYPE_MASK 0xF0 -#define FC_SUBTYPE_SHIFT 4 -#define FC_TODS 0x100 -#define FC_TODS_SHIFT 8 -#define FC_FROMDS 0x200 -#define FC_FROMDS_SHIFT 9 -#define FC_MOREFRAG 0x400 -#define FC_MOREFRAG_SHIFT 10 -#define FC_RETRY 0x800 -#define FC_RETRY_SHIFT 11 -#define FC_PM 0x1000 -#define FC_PM_SHIFT 12 -#define FC_MOREDATA 0x2000 -#define FC_MOREDATA_SHIFT 13 -#define FC_WEP 0x4000 -#define FC_WEP_SHIFT 14 -#define FC_ORDER 0x8000 -#define FC_ORDER_SHIFT 15 - - -#define SEQNUM_SHIFT 4 -#define SEQNUM_MAX 0x1000 -#define FRAGNUM_MASK 0xF - - - - -#define FC_TYPE_MNG 0 -#define FC_TYPE_CTL 1 -#define FC_TYPE_DATA 2 - - -#define FC_SUBTYPE_ASSOC_REQ 0 -#define FC_SUBTYPE_ASSOC_RESP 1 -#define FC_SUBTYPE_REASSOC_REQ 2 -#define FC_SUBTYPE_REASSOC_RESP 3 -#define FC_SUBTYPE_PROBE_REQ 4 -#define FC_SUBTYPE_PROBE_RESP 5 -#define FC_SUBTYPE_BEACON 8 -#define FC_SUBTYPE_ATIM 9 -#define FC_SUBTYPE_DISASSOC 10 -#define FC_SUBTYPE_AUTH 11 -#define FC_SUBTYPE_DEAUTH 12 -#define FC_SUBTYPE_ACTION 13 -#define FC_SUBTYPE_ACTION_NOACK 14 - - -#define FC_SUBTYPE_CTL_WRAPPER 7 -#define FC_SUBTYPE_BLOCKACK_REQ 8 -#define FC_SUBTYPE_BLOCKACK 9 -#define FC_SUBTYPE_PS_POLL 10 -#define FC_SUBTYPE_RTS 11 -#define FC_SUBTYPE_CTS 12 -#define FC_SUBTYPE_ACK 13 -#define FC_SUBTYPE_CF_END 14 -#define FC_SUBTYPE_CF_END_ACK 15 - - -#define FC_SUBTYPE_DATA 0 -#define FC_SUBTYPE_DATA_CF_ACK 1 -#define FC_SUBTYPE_DATA_CF_POLL 2 -#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 -#define FC_SUBTYPE_NULL 4 -#define FC_SUBTYPE_CF_ACK 5 -#define FC_SUBTYPE_CF_POLL 6 -#define FC_SUBTYPE_CF_ACK_POLL 7 -#define FC_SUBTYPE_QOS_DATA 8 -#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 -#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 -#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 -#define FC_SUBTYPE_QOS_NULL 12 -#define FC_SUBTYPE_QOS_CF_POLL 14 -#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 - - -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) - - -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) - -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) - -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) - -#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) -#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) -#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) -#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) -#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) -#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) -#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) -#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) - -#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) -#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) -#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) -#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) -#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) -#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) - -#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) -#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) -#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) -#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) -#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) - - - - -#define QOS_PRIO_SHIFT 0 -#define QOS_PRIO_MASK 0x0007 -#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) - - -#define QOS_TID_SHIFT 0 -#define QOS_TID_MASK 0x000f -#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) - - -#define QOS_EOSP_SHIFT 4 -#define QOS_EOSP_MASK 0x0010 -#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) - - -#define QOS_ACK_NORMAL_ACK 0 -#define QOS_ACK_NO_ACK 1 -#define QOS_ACK_NO_EXP_ACK 2 -#define QOS_ACK_BLOCK_ACK 3 -#define QOS_ACK_SHIFT 5 -#define QOS_ACK_MASK 0x0060 -#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) - - -#define QOS_AMSDU_SHIFT 7 -#define QOS_AMSDU_MASK 0x0080 - - - - - - -#define DOT11_MNG_AUTH_ALGO_LEN 2 -#define DOT11_MNG_AUTH_SEQ_LEN 2 -#define DOT11_MNG_BEACON_INT_LEN 2 -#define DOT11_MNG_CAP_LEN 2 -#define DOT11_MNG_AP_ADDR_LEN 6 -#define DOT11_MNG_LISTEN_INT_LEN 2 -#define DOT11_MNG_REASON_LEN 2 -#define DOT11_MNG_AID_LEN 2 -#define DOT11_MNG_STATUS_LEN 2 -#define DOT11_MNG_TIMESTAMP_LEN 8 - - -#define DOT11_AID_MASK 0x3fff - - -#define DOT11_RC_RESERVED 0 -#define DOT11_RC_UNSPECIFIED 1 -#define DOT11_RC_AUTH_INVAL 2 -#define DOT11_RC_DEAUTH_LEAVING 3 -#define DOT11_RC_INACTIVITY 4 -#define DOT11_RC_BUSY 5 -#define DOT11_RC_INVAL_CLASS_2 6 -#define DOT11_RC_INVAL_CLASS_3 7 -#define DOT11_RC_DISASSOC_LEAVING 8 -#define DOT11_RC_NOT_AUTH 9 -#define DOT11_RC_BAD_PC 10 -#define DOT11_RC_BAD_CHANNELS 11 - - - -#define DOT11_RC_UNSPECIFIED_QOS 32 -#define DOT11_RC_INSUFFCIENT_BW 33 -#define DOT11_RC_EXCESSIVE_FRAMES 34 -#define DOT11_RC_TX_OUTSIDE_TXOP 35 -#define DOT11_RC_LEAVING_QBSS 36 -#define DOT11_RC_BAD_MECHANISM 37 -#define DOT11_RC_SETUP_NEEDED 38 -#define DOT11_RC_TIMEOUT 39 - -#define DOT11_RC_MAX 23 - - -#define DOT11_SC_SUCCESS 0 -#define DOT11_SC_FAILURE 1 -#define DOT11_SC_CAP_MISMATCH 10 -#define DOT11_SC_REASSOC_FAIL 11 -#define DOT11_SC_ASSOC_FAIL 12 -#define DOT11_SC_AUTH_MISMATCH 13 -#define DOT11_SC_AUTH_SEQ 14 -#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 -#define DOT11_SC_AUTH_TIMEOUT 16 -#define DOT11_SC_ASSOC_BUSY_FAIL 17 -#define DOT11_SC_ASSOC_RATE_MISMATCH 18 -#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 -#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 -#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 -#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 -#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 -#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 -#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 -#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 -#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 - -#define DOT11_SC_DECLINED 37 -#define DOT11_SC_INVALID_PARAMS 38 - - -#define DOT11_MNG_DS_PARAM_LEN 1 -#define DOT11_MNG_IBSS_PARAM_LEN 2 - - -#define DOT11_MNG_TIM_FIXED_LEN 3 -#define DOT11_MNG_TIM_DTIM_COUNT 0 -#define DOT11_MNG_TIM_DTIM_PERIOD 1 -#define DOT11_MNG_TIM_BITMAP_CTL 2 -#define DOT11_MNG_TIM_PVB 3 - - -#define TLV_TAG_OFF 0 -#define TLV_LEN_OFF 1 -#define TLV_HDR_LEN 2 -#define TLV_BODY_OFF 2 - - -#define DOT11_MNG_SSID_ID 0 -#define DOT11_MNG_RATES_ID 1 -#define DOT11_MNG_FH_PARMS_ID 2 -#define DOT11_MNG_DS_PARMS_ID 3 -#define DOT11_MNG_CF_PARMS_ID 4 -#define DOT11_MNG_TIM_ID 5 -#define DOT11_MNG_IBSS_PARMS_ID 6 -#define DOT11_MNG_COUNTRY_ID 7 -#define DOT11_MNG_HOPPING_PARMS_ID 8 -#define DOT11_MNG_HOPPING_TABLE_ID 9 -#define DOT11_MNG_REQUEST_ID 10 -#define DOT11_MNG_QBSS_LOAD_ID 11 -#define DOT11_MNG_EDCA_PARAM_ID 12 -#define DOT11_MNG_CHALLENGE_ID 16 -#define DOT11_MNG_PWR_CONSTRAINT_ID 32 -#define DOT11_MNG_PWR_CAP_ID 33 -#define DOT11_MNG_TPC_REQUEST_ID 34 -#define DOT11_MNG_TPC_REPORT_ID 35 -#define DOT11_MNG_SUPP_CHANNELS_ID 36 -#define DOT11_MNG_CHANNEL_SWITCH_ID 37 -#define DOT11_MNG_MEASURE_REQUEST_ID 38 -#define DOT11_MNG_MEASURE_REPORT_ID 39 -#define DOT11_MNG_QUIET_ID 40 -#define DOT11_MNG_IBSS_DFS_ID 41 -#define DOT11_MNG_ERP_ID 42 -#define DOT11_MNG_TS_DELAY_ID 43 -#define DOT11_MNG_HT_CAP 45 -#define DOT11_MNG_QOS_CAP_ID 46 -#define DOT11_MNG_NONERP_ID 47 -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_EXT_RATES_ID 50 -#define DOT11_MNG_REGCLASS_ID 59 -#define DOT11_MNG_EXT_CSA_ID 60 -#define DOT11_MNG_HT_ADD 61 -#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 -#define DOT11_MNG_WAPI_ID 68 -#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 -#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 -#define DOT11_MNG_HT_OBSS_ID 74 -#define DOT11_MNG_EXT_CAP 127 -#define DOT11_MNG_WPA_ID 221 -#define DOT11_MNG_PROPR_ID 221 - - -#define DOT11_RATE_BASIC 0x80 -#define DOT11_RATE_MASK 0x7F - - -#define DOT11_MNG_ERP_LEN 1 -#define DOT11_MNG_NONERP_PRESENT 0x01 -#define DOT11_MNG_USE_PROTECTION 0x02 -#define DOT11_MNG_BARKER_PREAMBLE 0x04 - -#define DOT11_MGN_TS_DELAY_LEN 4 -#define TS_DELAY_FIELD_SIZE 4 - - -#define DOT11_CAP_ESS 0x0001 -#define DOT11_CAP_IBSS 0x0002 -#define DOT11_CAP_POLLABLE 0x0004 -#define DOT11_CAP_POLL_RQ 0x0008 -#define DOT11_CAP_PRIVACY 0x0010 -#define DOT11_CAP_SHORT 0x0020 -#define DOT11_CAP_PBCC 0x0040 -#define DOT11_CAP_AGILITY 0x0080 -#define DOT11_CAP_SPECTRUM 0x0100 -#define DOT11_CAP_SHORTSLOT 0x0400 -#define DOT11_CAP_CCK_OFDM 0x2000 - - -#define DOT11_OBSS_COEX_MNG_SUPPORT 0x01 - - -#define DOT11_ACTION_HDR_LEN 2 -#define DOT11_ACTION_CAT_ERR_MASK 0x80 -#define DOT11_ACTION_CAT_MASK 0x7F -#define DOT11_ACTION_CAT_SPECT_MNG 0 -#define DOT11_ACTION_CAT_BLOCKACK 3 -#define DOT11_ACTION_CAT_PUBLIC 4 -#define DOT11_ACTION_CAT_HT 7 -#define DOT11_ACTION_CAT_VS 127 -#define DOT11_ACTION_NOTIFICATION 0x11 - -#define DOT11_ACTION_ID_M_REQ 0 -#define DOT11_ACTION_ID_M_REP 1 -#define DOT11_ACTION_ID_TPC_REQ 2 -#define DOT11_ACTION_ID_TPC_REP 3 -#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 -#define DOT11_ACTION_ID_EXT_CSA 5 - - -#define DOT11_ACTION_ID_HT_CH_WIDTH 0 -#define DOT11_ACTION_ID_HT_MIMO_PS 1 - - -#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 -#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 - - -#define DOT11_BA_ACTION_ADDBA_REQ 0 -#define DOT11_BA_ACTION_ADDBA_RESP 1 -#define DOT11_BA_ACTION_DELBA 2 - - -#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 -#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 -#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 -#define DOT11_ADDBA_PARAM_TID_MASK 0x003c -#define DOT11_ADDBA_PARAM_TID_SHIFT 2 -#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 -#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 - -#define DOT11_ADDBA_POLICY_DELAYED 0 -#define DOT11_ADDBA_POLICY_IMMEDIATE 1 - -BWL_PRE_PACKED_STRUCT struct dot11_addba_req { - uint8 category; - uint8 action; - uint8 token; - uint16 addba_param_set; - uint16 timeout; - uint16 start_seqnum; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_req dot11_addba_req_t; -#define DOT11_ADDBA_REQ_LEN 9 - -BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { - uint8 category; - uint8 action; - uint8 token; - uint16 status; - uint16 addba_param_set; - uint16 timeout; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_addba_resp dot11_addba_resp_t; -#define DOT11_ADDBA_RESP_LEN 9 - - -#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 -#define DOT11_DELBA_PARAM_INIT_SHIFT 11 -#define DOT11_DELBA_PARAM_TID_MASK 0xf000 -#define DOT11_DELBA_PARAM_TID_SHIFT 12 - -BWL_PRE_PACKED_STRUCT struct dot11_delba { - uint8 category; - uint8 action; - uint16 delba_param_set; - uint16 reason; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_delba dot11_delba_t; -#define DOT11_DELBA_LEN 6 - - -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -#define DOT11_BSSTYPE_INDEPENDENT 1 -#define DOT11_BSSTYPE_ANY 2 -#define DOT11_SCANTYPE_ACTIVE 0 -#define DOT11_SCANTYPE_PASSIVE 1 - - -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 8 -#define PREN_PREAMBLE_EXT 4 - - -#define NPHY_RIFS_TIME 2 - - -#define APHY_SLOT_TIME 9 -#define APHY_SIFS_TIME 16 -#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SYMBOL_TIME 4 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define APHY_CWMIN 15 - - -#define BPHY_SLOT_TIME 20 -#define BPHY_SIFS_TIME 10 -#define BPHY_DIFS_TIME 50 -#define BPHY_PLCP_TIME 192 -#define BPHY_PLCP_SHORT_TIME 96 -#define BPHY_CWMIN 31 - - -#define DOT11_OFDM_SIGNAL_EXTENSION 6 - -#define PHY_CWMAX 1023 - -#define DOT11_MAXNUMFRAGS 16 - - -typedef struct d11cnt { - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; -} d11cnt_t; - - -#define BRCM_PROP_OUI "\x00\x90\x4C" - - - - -BWL_PRE_PACKED_STRUCT struct brcm_prop_ie_s { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint16 cap; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_prop_ie_s brcm_prop_ie_t; - -#define BRCM_PROP_IE_LEN 6 - -#define DPT_IE_TYPE 2 - - -#define BRCM_OUI "\x00\x10\x18" - - -BWL_PRE_PACKED_STRUCT struct brcm_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 ver; - uint8 assoc; - uint8 flags; - uint8 flags1; - uint16 amsdu_mtu_pref; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_ie brcm_ie_t; -#define BRCM_IE_LEN 11 -#define BRCM_IE_VER 2 -#define BRCM_IE_LEGACY_AES_VER 1 - - -#ifdef WLAFTERBURNER -#define BRF_ABCAP 0x1 -#define BRF_ABRQRD 0x2 -#define BRF_ABCOUNTER_MASK 0xf0 -#define BRF_ABCOUNTER_SHIFT 4 -#endif -#define BRF_LZWDS 0x4 -#define BRF_BLOCKACK 0x8 - - -#define BRF1_AMSDU 0x1 -#define BRF1_WMEPS 0x4 -#define BRF1_PSOFIX 0x8 - -#ifdef WLAFTERBURNER -#define AB_WDS_TIMEOUT_MAX 15 -#define AB_WDS_TIMEOUT_MIN 1 -#endif - -#define AB_GUARDCOUNT 10 - -#define MCSSET_LEN 16 -#define MAX_MCS_NUM (128) - -BWL_PRE_PACKED_STRUCT struct ht_cap_ie { - uint16 cap; - uint8 params; - uint8 supp_mcs[MCSSET_LEN]; - uint16 ext_htcap; - uint32 txbf_cap; - uint8 as_cap; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_cap_ie ht_cap_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_cap_ie_t cap_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; -#define HT_PROP_IE_OVERHEAD 4 -#define HT_CAP_IE_LEN 26 -#define HT_CAP_IE_TYPE 51 - -#define HT_CAP_LDPC_CODING 0x0001 -#define HT_CAP_40MHZ 0x0002 -#define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_SHIFT 0x0002 -#define HT_CAP_MIMO_PS_OFF 0x0003 -#define HT_CAP_MIMO_PS_RTS 0x0001 -#define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_GF 0x0010 -#define HT_CAP_SHORT_GI_20 0x0020 -#define HT_CAP_SHORT_GI_40 0x0040 -#define HT_CAP_TX_STBC 0x0080 -#define HT_CAP_RX_STBC_MASK 0x0300 -#define HT_CAP_RX_STBC_SHIFT 8 -#define HT_CAP_DELAYED_BA 0x0400 -#define HT_CAP_MAX_AMSDU 0x0800 -#define HT_CAP_DSSS_CCK 0x1000 -#define HT_CAP_PSMP 0x2000 -#define HT_CAP_40MHZ_INTOLERANT 0x4000 -#define HT_CAP_LSIG_TXOP 0x8000 - -#define HT_CAP_RX_STBC_NO 0x0 -#define HT_CAP_RX_STBC_ONE_STREAM 0x1 -#define HT_CAP_RX_STBC_TWO_STREAM 0x2 -#define HT_CAP_RX_STBC_THREE_STREAM 0x3 - -#define HT_MAX_AMSDU 7935 -#define HT_MIN_AMSDU 3835 - -#define HT_PARAMS_RX_FACTOR_MASK 0x03 -#define HT_PARAMS_DENSITY_MASK 0x1C -#define HT_PARAMS_DENSITY_SHIFT 2 - - -#define AMPDU_MAX_MPDU_DENSITY 7 -#define AMPDU_RX_FACTOR_64K 3 -#define AMPDU_RX_FACTOR_BASE 8*1024 -#define AMPDU_DELIMITER_LEN 4 - -#define HT_CAP_EXT_PCO 0x0001 -#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 -#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 -#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 -#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 -#define HT_CAP_EXT_HTC 0x0400 -#define HT_CAP_EXT_RD_RESP 0x0800 - -BWL_PRE_PACKED_STRUCT struct ht_add_ie { - uint8 ctl_ch; - uint8 byte1; - uint16 opmode; - uint16 misc_bits; - uint8 basic_mcs[MCSSET_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_add_ie ht_add_ie_t; - - - -BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - ht_add_ie_t add_ie; -} BWL_POST_PACKED_STRUCT; -typedef struct ht_prop_add_ie ht_prop_add_ie_t; - -#define HT_ADD_IE_LEN 22 -#define HT_ADD_IE_TYPE 52 - - -#define HT_BW_ANY 0x04 -#define HT_RIFS_PERMITTED 0x08 - - -#define HT_OPMODE_MASK 0x0003 -#define HT_OPMODE_SHIFT 0 -#define HT_OPMODE_PURE 0x0000 -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 - - -#define HT_BASIC_STBC_MCS 0x007f -#define HT_DUAL_STBC_PROT 0x0080 -#define HT_SECOND_BCN 0x0100 -#define HT_LSIG_TXOP 0x0200 -#define HT_PCO_ACTIVE 0x0400 -#define HT_PCO_PHASE 0x0800 -#define HT_DUALCTS_PROTECTION 0x0080 - - -#define DOT11N_2G_TXBURST_LIMIT 6160 -#define DOT11N_5G_TXBURST_LIMIT 3080 - - -#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - >> HT_OPMODE_SHIFT) -#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_MIXED) -#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_HT20IN40) -#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_OPTIONAL) -#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ - HT_MIXEDMODE_PRESENT((add_ie))) -#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ - == HT_OPMODE_NONGF) -#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ - == DOT11N_TXBURST) -#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ - == DOT11N_OBSS_NONHT) - -BWL_PRE_PACKED_STRUCT struct obss_params { - uint16 passive_dwell; - uint16 active_dwell; - uint16 bss_widthscan_interval; - uint16 passive_total; - uint16 active_total; - uint16 chanwidth_transition_dly; - uint16 activity_threshold; -} BWL_POST_PACKED_STRUCT; -typedef struct obss_params obss_params_t; - -BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { - uint8 id; - uint8 len; - obss_params_t obss_params; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_obss_ie dot11_obss_ie_t; -#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) - - -BWL_PRE_PACKED_STRUCT struct vndr_ie { - uchar id; - uchar len; - uchar oui [3]; - uchar data [1]; -} BWL_POST_PACKED_STRUCT; -typedef struct vndr_ie vndr_ie_t; - -#define VNDR_IE_HDR_LEN 2 -#define VNDR_IE_MIN_LEN 3 -#define VNDR_IE_MAX_LEN 256 - - -#define WPA_VERSION 1 -#define WPA_OUI "\x00\x50\xF2" - -#define WPA2_VERSION 1 -#define WPA2_VERSION_LEN 2 -#define WPA2_OUI "\x00\x0F\xAC" - -#define WPA_OUI_LEN 3 - - -#define RSN_AKM_NONE 0 -#define RSN_AKM_UNSPECIFIED 1 -#define RSN_AKM_PSK 2 - - -#define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_MAX_KEY_SIZE 32 -#define DOT11_MAX_IV_SIZE 16 -#define DOT11_EXT_IV_FLAG (1<<5) -#define DOT11_WPA_KEY_RSC_LEN 8 - -#define WEP1_KEY_SIZE 5 -#define WEP1_KEY_HEX_SIZE 10 -#define WEP128_KEY_SIZE 13 -#define WEP128_KEY_HEX_SIZE 26 -#define TKIP_MIC_SIZE 8 -#define TKIP_EOM_SIZE 7 -#define TKIP_EOM_FLAG 0x5a -#define TKIP_KEY_SIZE 32 -#define TKIP_MIC_AUTH_TX 16 -#define TKIP_MIC_AUTH_RX 24 -#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX -#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX -#define AES_KEY_SIZE 16 -#define AES_MIC_SIZE 8 - -#define SMS4_KEY_LEN 16 -#define SMS4_WPI_CBC_MAC_LEN 16 - - -#include - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/802.11e.h b/drivers/net/wireless/bcm4329/include/proto/802.11e.h deleted file mode 100644 index 1dd6f45b1ed8..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.11e.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 802.11e protocol header file - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: 802.11e.h,v 1.5.56.1 2008/11/20 00:51:18 Exp $ - */ - -#ifndef _802_11e_H_ -#define _802_11e_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - - -/* WME Traffic Specification (TSPEC) element */ -#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */ -#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */ - -#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */ -#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */ -#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */ -#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */ - -BWL_PRE_PACKED_STRUCT struct tsinfo { - uint8 octets[3]; -} BWL_POST_PACKED_STRUCT; - -typedef struct tsinfo tsinfo_t; - -/* 802.11e TSPEC IE */ -typedef BWL_PRE_PACKED_STRUCT struct tspec { - uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ - uint8 type; /* WME_TYPE */ - uint8 subtype; /* WME_SUBTYPE_TSPEC */ - uint8 version; /* WME_VERSION */ - tsinfo_t tsinfo; /* TS Info bit field */ - uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ - uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ - uint32 min_srv_interval; /* Minimum Service Interval (us) */ - uint32 max_srv_interval; /* Maximum Service Interval (us) */ - uint32 inactivity_interval; /* Inactivity Interval (us) */ - uint32 suspension_interval; /* Suspension Interval (us) */ - uint32 srv_start_time; /* Service Start Time (us) */ - uint32 min_data_rate; /* Minimum Data Rate (bps) */ - uint32 mean_data_rate; /* Mean Data Rate (bps) */ - uint32 peak_data_rate; /* Peak Data Rate (bps) */ - uint32 max_burst_size; /* Maximum Burst Size (bytes) */ - uint32 delay_bound; /* Delay Bound (us) */ - uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ - uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */ - uint16 medium_time; /* Medium Time (32 us/s periods) */ -} BWL_POST_PACKED_STRUCT tspec_t; - -#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */ - -/* ts_info */ -/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ -#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */ -#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */ -#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */ -#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */ -#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */ -#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */ -#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */ -#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */ -#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */ -#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */ -#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */ -#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */ -/* TS info. user priority mask */ -#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT) - -/* Macro to get/set bit(s) field in TSINFO */ -#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT) -#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \ - TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT) -#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT) -#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \ - TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT) - -#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \ - ((id) << TS_INFO_TID_SHIFT)) -#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \ - ((prio) << TS_INFO_USER_PRIO_SHIFT)) - -/* 802.11e QBSS Load IE */ -#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */ -#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */ - -#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */ - -/* 802.11e ADDTS status code */ -#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */ -#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ -#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ -#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ - -/* 802.11e DELTS status code */ -#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ -#define DOT11E_STATUS_END_TS 37 /* END TS */ -#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */ -#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */ - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _802_11e_CAC_H_ */ diff --git a/drivers/net/wireless/bcm4329/include/proto/802.1d.h b/drivers/net/wireless/bcm4329/include/proto/802.1d.h deleted file mode 100644 index 45c728bc2976..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/802.1d.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * Fundamental types and constants relating to 802.1D - * - * $Id: 802.1d.h,v 9.3 2007/04/10 21:33:06 Exp $ - */ - - -#ifndef _802_1_D_ -#define _802_1_D_ - - -#define PRIO_8021D_NONE 2 -#define PRIO_8021D_BK 1 -#define PRIO_8021D_BE 0 -#define PRIO_8021D_EE 3 -#define PRIO_8021D_CL 4 -#define PRIO_8021D_VI 5 -#define PRIO_8021D_VO 6 -#define PRIO_8021D_NC 7 -#define MAXPRIO 7 -#define NUMPRIO (MAXPRIO + 1) - -#define ALLPRIO -1 - - -#define PRIO2PREC(prio) \ - (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmeth.h b/drivers/net/wireless/bcm4329/include/proto/bcmeth.h deleted file mode 100644 index fdb5a2a5648f..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmeth.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Broadcom Ethernettype protocol definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: bcmeth.h,v 9.9.46.1 2008/11/20 00:51:20 Exp $ - */ - - - - -#ifndef _BCMETH_H_ -#define _BCMETH_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - - - - - -#define BCMILCP_SUBTYPE_RATE 1 -#define BCMILCP_SUBTYPE_LINK 2 -#define BCMILCP_SUBTYPE_CSA 3 -#define BCMILCP_SUBTYPE_LARQ 4 -#define BCMILCP_SUBTYPE_VENDOR 5 -#define BCMILCP_SUBTYPE_FLH 17 - -#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -#define BCMILCP_SUBTYPE_CERT 32770 -#define BCMILCP_SUBTYPE_SES 32771 - - -#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 -#define BCMILCP_BCM_SUBTYPE_SES 2 - - -#define BCMILCP_BCM_SUBTYPE_DPT 4 - -#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 - - -typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr -{ - uint16 subtype; - uint16 length; - uint8 version; - uint8 oui[3]; - - uint16 usr_subtype; -} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmevent.h b/drivers/net/wireless/bcm4329/include/proto/bcmevent.h deleted file mode 100644 index 1f8ecb14d97a..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmevent.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Broadcom Event protocol definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * - * Dependencies: proto/bcmeth.h - * - * $Id: bcmevent.h,v 9.34.4.1.20.16.64.1 2010/11/08 21:57:03 Exp $ - * - */ - - - - -#ifndef _BCMEVENT_H_ -#define _BCMEVENT_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define BCM_EVENT_MSG_VERSION 1 -#define BCM_MSG_IFNAME_MAX 16 - - -#define WLC_EVENT_MSG_LINK 0x01 -#define WLC_EVENT_MSG_FLUSHTXQ 0x02 -#define WLC_EVENT_MSG_GROUP 0x04 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint16 version; - uint16 flags; - uint32 event_type; - uint32 status; - uint32 reason; - uint32 auth_type; - uint32 datalen; - struct ether_addr addr; - char ifname[BCM_MSG_IFNAME_MAX]; -} BWL_POST_PACKED_STRUCT wl_event_msg_t; - - -typedef BWL_PRE_PACKED_STRUCT struct bcm_event { - struct ether_header eth; - bcmeth_hdr_t bcm_hdr; - wl_event_msg_t event; - -} BWL_POST_PACKED_STRUCT bcm_event_t; - -#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) - - -#define WLC_E_SET_SSID 0 -#define WLC_E_JOIN 1 -#define WLC_E_START 2 -#define WLC_E_AUTH 3 -#define WLC_E_AUTH_IND 4 -#define WLC_E_DEAUTH 5 -#define WLC_E_DEAUTH_IND 6 -#define WLC_E_ASSOC 7 -#define WLC_E_ASSOC_IND 8 -#define WLC_E_REASSOC 9 -#define WLC_E_REASSOC_IND 10 -#define WLC_E_DISASSOC 11 -#define WLC_E_DISASSOC_IND 12 -#define WLC_E_QUIET_START 13 -#define WLC_E_QUIET_END 14 -#define WLC_E_BEACON_RX 15 -#define WLC_E_LINK 16 -#define WLC_E_MIC_ERROR 17 -#define WLC_E_NDIS_LINK 18 -#define WLC_E_ROAM 19 -#define WLC_E_TXFAIL 20 -#define WLC_E_PMKID_CACHE 21 -#define WLC_E_RETROGRADE_TSF 22 -#define WLC_E_PRUNE 23 -#define WLC_E_AUTOAUTH 24 -#define WLC_E_EAPOL_MSG 25 -#define WLC_E_SCAN_COMPLETE 26 -#define WLC_E_ADDTS_IND 27 -#define WLC_E_DELTS_IND 28 -#define WLC_E_BCNSENT_IND 29 -#define WLC_E_BCNRX_MSG 30 -#define WLC_E_BCNLOST_MSG 31 -#define WLC_E_ROAM_PREP 32 -#define WLC_E_PFN_NET_FOUND 33 -#define WLC_E_PFN_NET_LOST 34 -#define WLC_E_RESET_COMPLETE 35 -#define WLC_E_JOIN_START 36 -#define WLC_E_ROAM_START 37 -#define WLC_E_ASSOC_START 38 -#define WLC_E_IBSS_ASSOC 39 -#define WLC_E_RADIO 40 -#define WLC_E_PSM_WATCHDOG 41 -#define WLC_E_PROBREQ_MSG 44 -#define WLC_E_SCAN_CONFIRM_IND 45 -#define WLC_E_PSK_SUP 46 -#define WLC_E_COUNTRY_CODE_CHANGED 47 -#define WLC_E_EXCEEDED_MEDIUM_TIME 48 -#define WLC_E_ICV_ERROR 49 -#define WLC_E_UNICAST_DECODE_ERROR 50 -#define WLC_E_MULTICAST_DECODE_ERROR 51 -#define WLC_E_TRACE 52 -#define WLC_E_IF 54 -#define WLC_E_RSSI 56 -#define WLC_E_PFN_SCAN_COMPLETE 57 -#define WLC_E_ACTION_FRAME 58 -#define WLC_E_ACTION_FRAME_COMPLETE 59 - -#define WLC_E_ESCAN_RESULT 69 -#define WLC_E_WAKE_EVENT 70 -#define WLC_E_RELOAD 71 -#define WLC_E_LAST 72 - - - -#define WLC_E_STATUS_SUCCESS 0 -#define WLC_E_STATUS_FAIL 1 -#define WLC_E_STATUS_TIMEOUT 2 -#define WLC_E_STATUS_NO_NETWORKS 3 -#define WLC_E_STATUS_ABORT 4 -#define WLC_E_STATUS_NO_ACK 5 -#define WLC_E_STATUS_UNSOLICITED 6 -#define WLC_E_STATUS_ATTEMPT 7 -#define WLC_E_STATUS_PARTIAL 8 -#define WLC_E_STATUS_NEWSCAN 9 -#define WLC_E_STATUS_NEWASSOC 10 -#define WLC_E_STATUS_11HQUIET 11 -#define WLC_E_STATUS_SUPPRESS 12 -#define WLC_E_STATUS_NOCHANS 13 -#define WLC_E_STATUS_CCXFASTRM 14 -#define WLC_E_STATUS_CS_ABORT 15 - - -#define WLC_E_REASON_INITIAL_ASSOC 0 -#define WLC_E_REASON_LOW_RSSI 1 -#define WLC_E_REASON_DEAUTH 2 -#define WLC_E_REASON_DISASSOC 3 -#define WLC_E_REASON_BCNS_LOST 4 -#define WLC_E_REASON_FAST_ROAM_FAILED 5 -#define WLC_E_REASON_DIRECTED_ROAM 6 -#define WLC_E_REASON_TSPEC_REJECTED 7 -#define WLC_E_REASON_BETTER_AP 8 - - -#define WLC_E_PRUNE_ENCR_MISMATCH 1 -#define WLC_E_PRUNE_BCAST_BSSID 2 -#define WLC_E_PRUNE_MAC_DENY 3 -#define WLC_E_PRUNE_MAC_NA 4 -#define WLC_E_PRUNE_REG_PASSV 5 -#define WLC_E_PRUNE_SPCT_MGMT 6 -#define WLC_E_PRUNE_RADAR 7 -#define WLC_E_RSN_MISMATCH 8 -#define WLC_E_PRUNE_NO_COMMON_RATES 9 -#define WLC_E_PRUNE_BASIC_RATES 10 -#define WLC_E_PRUNE_CIPHER_NA 12 -#define WLC_E_PRUNE_KNOWN_STA 13 -#define WLC_E_PRUNE_WDS_PEER 15 -#define WLC_E_PRUNE_QBSS_LOAD 16 -#define WLC_E_PRUNE_HOME_AP 17 - - -#define WLC_E_SUP_OTHER 0 -#define WLC_E_SUP_DECRYPT_KEY_DATA 1 -#define WLC_E_SUP_BAD_UCAST_WEP128 2 -#define WLC_E_SUP_BAD_UCAST_WEP40 3 -#define WLC_E_SUP_UNSUP_KEY_LEN 4 -#define WLC_E_SUP_PW_KEY_CIPHER 5 -#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 -#define WLC_E_SUP_MSG3_IE_MISMATCH 7 -#define WLC_E_SUP_NO_INSTALL_FLAG 8 -#define WLC_E_SUP_MSG3_NO_GTK 9 -#define WLC_E_SUP_GRP_KEY_CIPHER 10 -#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 -#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 -#define WLC_E_SUP_SEND_FAIL 13 -#define WLC_E_SUP_DEAUTH 14 -#define WLC_E_SUP_WPA_PSK_TMO 15 - - -#define WLC_E_IF_ADD 1 -#define WLC_E_IF_DEL 2 - -#define WLC_E_RELOAD_STATUS1 1 - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/bcmip.h b/drivers/net/wireless/bcm4329/include/proto/bcmip.h deleted file mode 100644 index 9d2fd6fba484..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/bcmip.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * Fundamental constants relating to IP Protocol - * - * $Id: bcmip.h,v 9.16.186.4 2009/01/27 04:25:25 Exp $ - */ - - -#ifndef _bcmip_h_ -#define _bcmip_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - - - -#define IP_VER_OFFSET 0x0 -#define IP_VER_MASK 0xf0 -#define IP_VER_SHIFT 4 -#define IP_VER_4 4 -#define IP_VER_6 6 - -#define IP_VER(ip_body) \ - ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) - -#define IP_PROT_ICMP 0x1 -#define IP_PROT_TCP 0x6 -#define IP_PROT_UDP 0x11 - - -#define IPV4_VER_HL_OFFSET 0 -#define IPV4_TOS_OFFSET 1 -#define IPV4_PKTLEN_OFFSET 2 -#define IPV4_PKTFLAG_OFFSET 6 -#define IPV4_PROT_OFFSET 9 -#define IPV4_CHKSUM_OFFSET 10 -#define IPV4_SRC_IP_OFFSET 12 -#define IPV4_DEST_IP_OFFSET 16 -#define IPV4_OPTIONS_OFFSET 20 - - -#define IPV4_VER_MASK 0xf0 -#define IPV4_VER_SHIFT 4 - -#define IPV4_HLEN_MASK 0x0f -#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) - -#define IPV4_ADDR_LEN 4 - -#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ - ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) - -#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ - ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) - -#define IPV4_TOS_DSCP_MASK 0xfc -#define IPV4_TOS_DSCP_SHIFT 2 - -#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) - -#define IPV4_TOS_PREC_MASK 0xe0 -#define IPV4_TOS_PREC_SHIFT 5 - -#define IPV4_TOS_LOWDELAY 0x10 -#define IPV4_TOS_THROUGHPUT 0x8 -#define IPV4_TOS_RELIABILITY 0x4 - -#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) - -#define IPV4_FRAG_RESV 0x8000 -#define IPV4_FRAG_DONT 0x4000 -#define IPV4_FRAG_MORE 0x2000 -#define IPV4_FRAG_OFFSET_MASK 0x1fff - -#define IPV4_ADDR_STR_LEN 16 - - -BWL_PRE_PACKED_STRUCT struct ipv4_addr { - uint8 addr[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - -BWL_PRE_PACKED_STRUCT struct ipv4_hdr { - uint8 version_ihl; - uint8 tos; - uint16 tot_len; - uint16 id; - uint16 frag; - uint8 ttl; - uint8 prot; - uint16 hdr_chksum; - uint8 src_ip[IPV4_ADDR_LEN]; - uint8 dst_ip[IPV4_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; - - -#define IPV6_PAYLOAD_LEN_OFFSET 4 -#define IPV6_NEXT_HDR_OFFSET 6 -#define IPV6_HOP_LIMIT_OFFSET 7 -#define IPV6_SRC_IP_OFFSET 8 -#define IPV6_DEST_IP_OFFSET 24 - - -#define IPV6_TRAFFIC_CLASS(ipv6_body) \ - (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ - ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) - -#define IPV6_FLOW_LABEL(ipv6_body) \ - (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ - (((uint8 *)(ipv6_body))[2] << 8) | \ - (((uint8 *)(ipv6_body))[3])) - -#define IPV6_PAYLOAD_LEN(ipv6_body) \ - ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ - ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) - -#define IPV6_NEXT_HDR(ipv6_body) \ - (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) - -#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) - -#define IPV6_ADDR_LEN 16 - - -#ifndef IP_TOS -#define IP_TOS(ip_body) \ - (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ - IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) -#endif - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/eapol.h b/drivers/net/wireless/bcm4329/include/proto/eapol.h deleted file mode 100644 index 95e76ff18c6b..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/eapol.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 802.1x EAPOL definitions - * - * See - * IEEE Std 802.1X-2001 - * IEEE 802.1X RADIUS Usage Guidelines - * - * Copyright (C) 2002 Broadcom Corporation - * - * $Id: eapol.h,v 9.18.260.1.2.1.6.6 2009/04/08 05:00:08 Exp $ - */ - -#ifndef _eapol_h_ -#define _eapol_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -/* This marks the start of a packed structure section. */ -#include - -#define AKW_BLOCK_LEN 8 /* The only def we need here */ - -/* EAPOL for 802.3/Ethernet */ -typedef struct { - struct ether_header eth; /* 802.3/Ethernet header */ - unsigned char version; /* EAPOL protocol version */ - unsigned char type; /* EAPOL type */ - unsigned short length; /* Length of body */ - unsigned char body[1]; /* Body (optional) */ -} eapol_header_t; - -#define EAPOL_HEADER_LEN 18 - -/* EAPOL version */ -#define WPA2_EAPOL_VERSION 2 -#define WPA_EAPOL_VERSION 1 -#define LEAP_EAPOL_VERSION 1 -#define SES_EAPOL_VERSION 1 - -/* EAPOL types */ -#define EAP_PACKET 0 -#define EAPOL_START 1 -#define EAPOL_LOGOFF 2 -#define EAPOL_KEY 3 -#define EAPOL_ASF 4 - -/* EAPOL-Key types */ -#define EAPOL_RC4_KEY 1 -#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */ -#define EAPOL_WPA_KEY 254 /* WPA */ - -/* RC4 EAPOL-Key header field sizes */ -#define EAPOL_KEY_REPLAY_LEN 8 -#define EAPOL_KEY_IV_LEN 16 -#define EAPOL_KEY_SIG_LEN 16 - -/* RC4 EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short length; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */ - unsigned char index; /* Key Flags & Index */ - unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */ - unsigned char key[1]; /* Key (optional) */ -} BWL_POST_PACKED_STRUCT eapol_key_header_t; - -#define EAPOL_KEY_HEADER_LEN 44 - -/* RC4 EAPOL-Key flags */ -#define EAPOL_KEY_FLAGS_MASK 0x80 -#define EAPOL_KEY_BROADCAST 0 -#define EAPOL_KEY_UNICAST 0x80 - -/* RC4 EAPOL-Key index */ -#define EAPOL_KEY_INDEX_MASK 0x7f - -/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */ -#define EAPOL_WPA_KEY_REPLAY_LEN 8 -#define EAPOL_WPA_KEY_NONCE_LEN 32 -#define EAPOL_WPA_KEY_IV_LEN 16 -#define EAPOL_WPA_KEY_ID_LEN 8 -#define EAPOL_WPA_KEY_RSC_LEN 8 -#define EAPOL_WPA_KEY_MIC_LEN 16 -#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN) -#define EAPOL_WPA_MAX_KEY_SIZE 32 - -/* WPA EAPOL-Key */ -typedef BWL_PRE_PACKED_STRUCT struct { - unsigned char type; /* Key Descriptor Type */ - unsigned short key_info; /* Key Information (unaligned) */ - unsigned short key_len; /* Key Length (unaligned) */ - unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */ - unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */ - unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */ - unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */ - unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */ - unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */ - unsigned short data_len; /* Key Data Length */ - unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */ -} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t; - -#define EAPOL_WPA_KEY_LEN 95 - -/* WPA/802.11i/WPA2 KEY KEY_INFO bits */ -#define WPA_KEY_DESC_V1 0x01 -#define WPA_KEY_DESC_V2 0x02 -#define WPA_KEY_PAIRWISE 0x08 -#define WPA_KEY_INSTALL 0x40 -#define WPA_KEY_ACK 0x80 -#define WPA_KEY_MIC 0x100 -#define WPA_KEY_SECURE 0x200 -#define WPA_KEY_ERROR 0x400 -#define WPA_KEY_REQ 0x800 - -/* WPA-only KEY KEY_INFO bits */ -#define WPA_KEY_INDEX_0 0x00 -#define WPA_KEY_INDEX_1 0x10 -#define WPA_KEY_INDEX_2 0x20 -#define WPA_KEY_INDEX_3 0x30 -#define WPA_KEY_INDEX_MASK 0x30 -#define WPA_KEY_INDEX_SHIFT 0x04 - -/* 802.11i/WPA2-only KEY KEY_INFO bits */ -#define WPA_KEY_ENCRYPTED_DATA 0x1000 - -/* Key Data encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 type; - uint8 length; - uint8 oui[3]; - uint8 subtype; - uint8 data[1]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t; - -#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6 - -#define WPA2_KEY_DATA_SUBTYPE_GTK 1 -#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2 -#define WPA2_KEY_DATA_SUBTYPE_MAC 3 -#define WPA2_KEY_DATA_SUBTYPE_PMKID 4 - -/* GTK encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 flags; - uint8 reserved; - uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t; - -#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2 - -#define WPA2_GTK_INDEX_MASK 0x03 -#define WPA2_GTK_INDEX_SHIFT 0x00 - -#define WPA2_GTK_TRANSMIT 0x04 - -/* STAKey encapsulation */ -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 reserved[2]; - uint8 mac[ETHER_ADDR_LEN]; - uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE]; -} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t; - -#define WPA2_KEY_DATA_PAD 0xdd - - -/* This marks the end of a packed structure section. */ -#include - -#endif /* _eapol_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/proto/ethernet.h b/drivers/net/wireless/bcm4329/include/proto/ethernet.h deleted file mode 100644 index 9ad2ea0c70fd..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/ethernet.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: ethernet.h,v 9.45.56.5 2010/02/22 22:04:36 Exp $ - */ - - -#ifndef _NET_ETHERNET_H_ -#define _NET_ETHERNET_H_ - -#ifndef _TYPEDEFS_H_ -#include "typedefs.h" -#endif - - -#include - - - -#define ETHER_ADDR_LEN 6 - - -#define ETHER_TYPE_LEN 2 - - -#define ETHER_CRC_LEN 4 - - -#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) - - -#define ETHER_MIN_LEN 64 - - -#define ETHER_MIN_DATA 46 - - -#define ETHER_MAX_LEN 1518 - - -#define ETHER_MAX_DATA 1500 - - -#define ETHER_TYPE_MIN 0x0600 -#define ETHER_TYPE_IP 0x0800 -#define ETHER_TYPE_ARP 0x0806 -#define ETHER_TYPE_8021Q 0x8100 -#define ETHER_TYPE_BRCM 0x886c -#define ETHER_TYPE_802_1X 0x888e -#define ETHER_TYPE_WAI 0x88b4 -#ifdef BCMWPA2 -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 -#endif - - -#define ETHER_BRCM_SUBTYPE_LEN 4 -#define ETHER_BRCM_CRAM 1 - - -#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) -#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) -#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) - - -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - - -#ifndef __INCif_etherh - -BWL_PRE_PACKED_STRUCT struct ether_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 ether_type; -} BWL_POST_PACKED_STRUCT; - - -BWL_PRE_PACKED_STRUCT struct ether_addr { - uint8 octet[ETHER_ADDR_LEN]; -} BWL_POST_PACKED_STRUCT; -#endif - - -#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) -#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xd)) -#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) - - -#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) - - -#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) - - - -#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ - !(((short*)a)[1] == ((short*)b)[1]) | \ - !(((short*)a)[2] == ((short*)b)[2])) - - -#define ether_copy(s, d) { \ - ((short*)d)[0] = ((short*)s)[0]; \ - ((short*)d)[1] = ((short*)s)[1]; \ - ((short*)d)[2] = ((short*)s)[2]; } - - -static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; - -#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ - ((uint8 *)(ea))[1] & \ - ((uint8 *)(ea))[2] & \ - ((uint8 *)(ea))[3] & \ - ((uint8 *)(ea))[4] & \ - ((uint8 *)(ea))[5]) == 0xff) -#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ - ((uint8 *)(ea))[1] | \ - ((uint8 *)(ea))[2] | \ - ((uint8 *)(ea))[3] | \ - ((uint8 *)(ea))[4] | \ - ((uint8 *)(ea))[5]) == 0) - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/sdspi.h b/drivers/net/wireless/bcm4329/include/proto/sdspi.h deleted file mode 100644 index 7739e68a2440..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/sdspi.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SD-SPI Protocol Standard - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sdspi.h,v 9.1.20.1 2008/05/06 22:59:19 Exp $ - */ - -#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */ -#define SPI_START_S 31 -#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */ -#define SPI_DIR_S 30 -#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */ -#define SPI_CMD_INDEX_S 24 -#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */ -#define SPI_RW_S 23 -#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */ -#define SPI_FUNC_S 20 -#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */ -#define SPI_RAW_S 19 -#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */ -#define SPI_STUFF_S 18 -#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */ -#define SPI_BLKMODE_S 19 -#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */ -#define SPI_OPCODE_S 18 -#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */ -#define SPI_ADDR_S 1 -#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */ -#define SPI_STUFF0_S 0 - -#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */ -#define SPI_RSP_START_S 7 -#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */ -#define SPI_RSP_PARAM_ERR_S 6 -#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */ -#define SPI_RSP_RFU5_S 5 -#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */ -#define SPI_RSP_FUNC_ERR_S 4 -#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */ -#define SPI_RSP_CRC_ERR_S 3 -#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */ -#define SPI_RSP_ILL_CMD_S 2 -#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */ -#define SPI_RSP_RFU1_S 1 -#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */ -#define SPI_RSP_IDLE_S 0 - -/* SD-SPI Protocol Definitions */ -#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */ -#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */ -#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */ -#define SDSPI_START_BIT_MASK 0x80 diff --git a/drivers/net/wireless/bcm4329/include/proto/vlan.h b/drivers/net/wireless/bcm4329/include/proto/vlan.h deleted file mode 100644 index 670bc44c6bd6..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/vlan.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 802.1Q VLAN protocol definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: vlan.h,v 9.4.196.2 2008/12/07 21:19:20 Exp $ - */ - - -#ifndef _vlan_h_ -#define _vlan_h_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - - -#include - -#define VLAN_VID_MASK 0xfff -#define VLAN_CFI_SHIFT 12 -#define VLAN_PRI_SHIFT 13 - -#define VLAN_PRI_MASK 7 - -#define VLAN_TAG_LEN 4 -#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) - -#define VLAN_TPID 0x8100 - -struct ethervlan_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 vlan_type; - uint16 vlan_tag; - uint16 ether_type; -}; - -#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/proto/wpa.h b/drivers/net/wireless/bcm4329/include/proto/wpa.h deleted file mode 100644 index f5d0cd539777..000000000000 --- a/drivers/net/wireless/bcm4329/include/proto/wpa.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Fundamental types and constants relating to WPA - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: wpa.h,v 1.16.166.1.20.1 2008/11/20 00:51:31 Exp $ - */ - - -#ifndef _proto_wpa_h_ -#define _proto_wpa_h_ - -#include -#include - - - -#include - - - - -#define DOT11_RC_INVALID_WPA_IE 13 -#define DOT11_RC_MIC_FAILURE 14 -#define DOT11_RC_4WH_TIMEOUT 15 -#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 -#define DOT11_RC_WPA_IE_MISMATCH 17 -#define DOT11_RC_INVALID_MC_CIPHER 18 -#define DOT11_RC_INVALID_UC_CIPHER 19 -#define DOT11_RC_INVALID_AKMP 20 -#define DOT11_RC_BAD_WPA_VERSION 21 -#define DOT11_RC_INVALID_WPA_CAP 22 -#define DOT11_RC_8021X_AUTH_FAIL 23 - -#define WPA2_PMKID_LEN 16 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 tag; - uint8 length; - uint8 oui[3]; - uint8 oui_type; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -#define WPA_IE_OUITYPE_LEN 4 -#define WPA_IE_FIXED_LEN 8 -#define WPA_IE_TAG_FIXED_LEN 6 - -typedef BWL_PRE_PACKED_STRUCT struct { - uint8 tag; - uint8 length; - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -#define WPA_RSN_IE_FIXED_LEN 4 -#define WPA_RSN_IE_TAG_FIXED_LEN 2 -typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - uint8 oui[3]; - uint8 type; -} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -#define WPA_SUITE_LEN 4 - - -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_suite_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -#define WPA_IE_SUITE_COUNT_LEN 2 -typedef BWL_PRE_PACKED_STRUCT struct -{ - BWL_PRE_PACKED_STRUCT struct { - uint8 low; - uint8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_pmkid_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; - - -#define WPA_CIPHER_NONE 0 -#define WPA_CIPHER_WEP_40 1 -#define WPA_CIPHER_TKIP 2 -#define WPA_CIPHER_AES_OCB 3 -#define WPA_CIPHER_AES_CCM 4 -#define WPA_CIPHER_WEP_104 5 - -#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ - (cipher) == WPA_CIPHER_WEP_40 || \ - (cipher) == WPA_CIPHER_WEP_104 || \ - (cipher) == WPA_CIPHER_TKIP || \ - (cipher) == WPA_CIPHER_AES_OCB || \ - (cipher) == WPA_CIPHER_AES_CCM) - - -#define WPA_TKIP_CM_DETECT 60 -#define WPA_TKIP_CM_BLOCK 60 - - -#define RSN_CAP_LEN 2 - - -#define RSN_CAP_PREAUTH 0x0001 -#define RSN_CAP_NOPAIRWISE 0x0002 -#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 -#define RSN_CAP_1_REPLAY_CNTR 0 -#define RSN_CAP_2_REPLAY_CNTRS 1 -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK - - -#define WPA_CAP_LEN RSN_CAP_LEN - -#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH - - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbchipc.h b/drivers/net/wireless/bcm4329/include/sbchipc.h deleted file mode 100644 index 39e5c8d6aed0..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbchipc.h +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * SiliconBackplane Chipcommon core hardware definitions. - * - * The chipcommon core provides chip identification, SB control, - * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, - * gpio interface, extbus, and support for serial and parallel flashes. - * - * $Id: sbchipc.h,v 13.103.2.5.4.5.2.9 2009/07/03 14:23:21 Exp $ - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - */ - - -#ifndef _SBCHIPC_H -#define _SBCHIPC_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -typedef volatile struct { - uint32 chipid; - uint32 capabilities; - uint32 corecontrol; - uint32 bist; - - - uint32 otpstatus; - uint32 otpcontrol; - uint32 otpprog; - uint32 PAD; - - - uint32 intstatus; - uint32 intmask; - uint32 chipcontrol; - uint32 chipstatus; - - - uint32 jtagcmd; - uint32 jtagir; - uint32 jtagdr; - uint32 jtagctrl; - - - uint32 flashcontrol; - uint32 flashaddress; - uint32 flashdata; - uint32 PAD[1]; - - - uint32 broadcastaddress; - uint32 broadcastdata; - - - uint32 gpiopullup; - uint32 gpiopulldown; - uint32 gpioin; - uint32 gpioout; - uint32 gpioouten; - uint32 gpiocontrol; - uint32 gpiointpolarity; - uint32 gpiointmask; - - - uint32 gpioevent; - uint32 gpioeventintmask; - - - uint32 watchdog; - - - uint32 gpioeventintpolarity; - - - uint32 gpiotimerval; - uint32 gpiotimeroutmask; - - - uint32 clockcontrol_n; - uint32 clockcontrol_sb; - uint32 clockcontrol_pci; - uint32 clockcontrol_m2; - uint32 clockcontrol_m3; - uint32 clkdiv; - uint32 PAD[2]; - - - uint32 pll_on_delay; - uint32 fref_sel_delay; - uint32 slow_clk_ctl; - uint32 PAD[1]; - - - uint32 system_clk_ctl; - uint32 clkstatestretch; - uint32 PAD[13]; - - - uint32 eromptr; - - - uint32 pcmcia_config; - uint32 pcmcia_memwait; - uint32 pcmcia_attrwait; - uint32 pcmcia_iowait; - uint32 ide_config; - uint32 ide_memwait; - uint32 ide_attrwait; - uint32 ide_iowait; - uint32 prog_config; - uint32 prog_waitcount; - uint32 flash_config; - uint32 flash_waitcount; - uint32 PAD[4]; - uint32 PAD[40]; - - - - uint32 clk_ctl_st; - uint32 hw_war; - uint32 PAD[70]; - - - uint8 uart0data; - uint8 uart0imr; - uint8 uart0fcr; - uint8 uart0lcr; - uint8 uart0mcr; - uint8 uart0lsr; - uint8 uart0msr; - uint8 uart0scratch; - uint8 PAD[248]; - - uint8 uart1data; - uint8 uart1imr; - uint8 uart1fcr; - uint8 uart1lcr; - uint8 uart1mcr; - uint8 uart1lsr; - uint8 uart1msr; - uint8 uart1scratch; - uint32 PAD[126]; - - - uint32 pmucontrol; - uint32 pmucapabilities; - uint32 pmustatus; - uint32 res_state; - uint32 res_pending; - uint32 pmutimer; - uint32 min_res_mask; - uint32 max_res_mask; - uint32 res_table_sel; - uint32 res_dep_mask; - uint32 res_updn_timer; - uint32 res_timer; - uint32 clkstretch; - uint32 pmuwatchdog; - uint32 gpiosel; - uint32 gpioenable; - uint32 res_req_timer_sel; - uint32 res_req_timer; - uint32 res_req_mask; - uint32 PAD; - uint32 chipcontrol_addr; - uint32 chipcontrol_data; - uint32 regcontrol_addr; - uint32 regcontrol_data; - uint32 pllcontrol_addr; - uint32 pllcontrol_data; - uint32 PAD[102]; - uint16 otp[768]; -} chipcregs_t; - -#endif - -#define CC_CHIPID 0 -#define CC_CAPABILITIES 4 -#define CC_OTPST 0x10 -#define CC_CHIPST 0x2c -#define CC_JTAGCMD 0x30 -#define CC_JTAGIR 0x34 -#define CC_JTAGDR 0x38 -#define CC_JTAGCTRL 0x3c -#define CC_WATCHDOG 0x80 -#define CC_CLKC_N 0x90 -#define CC_CLKC_M0 0x94 -#define CC_CLKC_M1 0x98 -#define CC_CLKC_M2 0x9c -#define CC_CLKC_M3 0xa0 -#define CC_CLKDIV 0xa4 -#define CC_SYS_CLK_CTL 0xc0 -#define CC_CLK_CTL_ST SI_CLK_CTL_ST -#define CC_EROMPTR 0xfc -#define PMU_CTL 0x600 -#define PMU_CAP 0x604 -#define PMU_ST 0x608 -#define PMU_RES_STATE 0x60c -#define PMU_TIMER 0x614 -#define PMU_MIN_RES_MASK 0x618 -#define PMU_MAX_RES_MASK 0x61c -#define PMU_REG_CONTROL_ADDR 0x658 -#define PMU_REG_CONTROL_DATA 0x65C -#define PMU_PLL_CONTROL_ADDR 0x660 -#define PMU_PLL_CONTROL_DATA 0x664 -#define CC_OTP 0x800 - - -#define CID_ID_MASK 0x0000ffff -#define CID_REV_MASK 0x000f0000 -#define CID_REV_SHIFT 16 -#define CID_PKG_MASK 0x00f00000 -#define CID_PKG_SHIFT 20 -#define CID_CC_MASK 0x0f000000 -#define CID_CC_SHIFT 24 -#define CID_TYPE_MASK 0xf0000000 -#define CID_TYPE_SHIFT 28 - - -#define CC_CAP_UARTS_MASK 0x00000003 -#define CC_CAP_MIPSEB 0x00000004 -#define CC_CAP_UCLKSEL 0x00000018 -#define CC_CAP_UINTCLK 0x00000008 -#define CC_CAP_UARTGPIO 0x00000020 -#define CC_CAP_EXTBUS_MASK 0x000000c0 -#define CC_CAP_EXTBUS_NONE 0x00000000 -#define CC_CAP_EXTBUS_FULL 0x00000040 -#define CC_CAP_EXTBUS_PROG 0x00000080 -#define CC_CAP_FLASH_MASK 0x00000700 -#define CC_CAP_PLL_MASK 0x00038000 -#define CC_CAP_PWR_CTL 0x00040000 -#define CC_CAP_OTPSIZE 0x00380000 -#define CC_CAP_OTPSIZE_SHIFT 19 -#define CC_CAP_OTPSIZE_BASE 5 -#define CC_CAP_JTAGP 0x00400000 -#define CC_CAP_ROM 0x00800000 -#define CC_CAP_BKPLN64 0x08000000 -#define CC_CAP_PMU 0x10000000 -#define CC_CAP_ECI 0x20000000 - - -#define PLL_NONE 0x00000000 -#define PLL_TYPE1 0x00010000 -#define PLL_TYPE2 0x00020000 -#define PLL_TYPE3 0x00030000 -#define PLL_TYPE4 0x00008000 -#define PLL_TYPE5 0x00018000 -#define PLL_TYPE6 0x00028000 -#define PLL_TYPE7 0x00038000 - - -#define ILP_CLOCK 32000 - - -#define ALP_CLOCK 20000000 - - -#define HT_CLOCK 80000000 - - -#define CC_UARTCLKO 0x00000001 -#define CC_SE 0x00000002 -#define CC_UARTCLKEN 0x00000008 - - -#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -#define CHIPCTRL_4321_PLL_DOWN 0x800000 - - -#define OTPS_OL_MASK 0x000000ff -#define OTPS_OL_MFG 0x00000001 -#define OTPS_OL_OR1 0x00000002 -#define OTPS_OL_OR2 0x00000004 -#define OTPS_OL_GU 0x00000008 -#define OTPS_GUP_MASK 0x00000f00 -#define OTPS_GUP_SHIFT 8 -#define OTPS_GUP_HW 0x00000100 -#define OTPS_GUP_SW 0x00000200 -#define OTPS_GUP_CI 0x00000400 -#define OTPS_GUP_FUSE 0x00000800 -#define OTPS_READY 0x00001000 -#define OTPS_RV(x) (1 << (16 + (x))) -#define OTPS_RV_MASK 0x0fff0000 - - -#define OTPC_PROGSEL 0x00000001 -#define OTPC_PCOUNT_MASK 0x0000000e -#define OTPC_PCOUNT_SHIFT 1 -#define OTPC_VSEL_MASK 0x000000f0 -#define OTPC_VSEL_SHIFT 4 -#define OTPC_TMM_MASK 0x00000700 -#define OTPC_TMM_SHIFT 8 -#define OTPC_ODM 0x00000800 -#define OTPC_PROGEN 0x80000000 - - -#define OTPP_COL_MASK 0x000000ff -#define OTPP_COL_SHIFT 0 -#define OTPP_ROW_MASK 0x0000ff00 -#define OTPP_ROW_SHIFT 8 -#define OTPP_OC_MASK 0x0f000000 -#define OTPP_OC_SHIFT 24 -#define OTPP_READERR 0x10000000 -#define OTPP_VALUE_MASK 0x20000000 -#define OTPP_VALUE_SHIFT 29 -#define OTPP_START_BUSY 0x80000000 - - -#define OTPPOC_READ 0 -#define OTPPOC_BIT_PROG 1 -#define OTPPOC_VERIFY 3 -#define OTPPOC_INIT 4 -#define OTPPOC_SET 5 -#define OTPPOC_RESET 6 -#define OTPPOC_OCST 7 -#define OTPPOC_ROW_LOCK 8 -#define OTPPOC_PRESCN_TEST 9 - - -#define JCMD_START 0x80000000 -#define JCMD_BUSY 0x80000000 -#define JCMD_STATE_MASK 0x60000000 -#define JCMD_STATE_TLR 0x00000000 -#define JCMD_STATE_PIR 0x20000000 -#define JCMD_STATE_PDR 0x40000000 -#define JCMD_STATE_RTI 0x60000000 -#define JCMD0_ACC_MASK 0x0000f000 -#define JCMD0_ACC_IRDR 0x00000000 -#define JCMD0_ACC_DR 0x00001000 -#define JCMD0_ACC_IR 0x00002000 -#define JCMD0_ACC_RESET 0x00003000 -#define JCMD0_ACC_IRPDR 0x00004000 -#define JCMD0_ACC_PDR 0x00005000 -#define JCMD0_IRW_MASK 0x00000f00 -#define JCMD_ACC_MASK 0x000f0000 -#define JCMD_ACC_IRDR 0x00000000 -#define JCMD_ACC_DR 0x00010000 -#define JCMD_ACC_IR 0x00020000 -#define JCMD_ACC_RESET 0x00030000 -#define JCMD_ACC_IRPDR 0x00040000 -#define JCMD_ACC_PDR 0x00050000 -#define JCMD_ACC_PIR 0x00060000 -#define JCMD_ACC_IRDR_I 0x00070000 -#define JCMD_ACC_DR_I 0x00080000 -#define JCMD_IRW_MASK 0x00001f00 -#define JCMD_IRW_SHIFT 8 -#define JCMD_DRW_MASK 0x0000003f - - -#define JCTRL_FORCE_CLK 4 -#define JCTRL_EXT_EN 2 -#define JCTRL_EN 1 - - -#define CLKD_SFLASH 0x0f000000 -#define CLKD_SFLASH_SHIFT 24 -#define CLKD_OTP 0x000f0000 -#define CLKD_OTP_SHIFT 16 -#define CLKD_JTAG 0x00000f00 -#define CLKD_JTAG_SHIFT 8 -#define CLKD_UART 0x000000ff - - -#define CI_GPIO 0x00000001 -#define CI_EI 0x00000002 -#define CI_TEMP 0x00000004 -#define CI_SIRQ 0x00000008 -#define CI_ECI 0x00000010 -#define CI_PMU 0x00000020 -#define CI_UART 0x00000040 -#define CI_WDRESET 0x80000000 - - -#define SCC_SS_MASK 0x00000007 -#define SCC_SS_LPO 0x00000000 -#define SCC_SS_XTAL 0x00000001 -#define SCC_SS_PCI 0x00000002 -#define SCC_LF 0x00000200 -#define SCC_LP 0x00000400 -#define SCC_FS 0x00000800 -#define SCC_IP 0x00001000 -#define SCC_XC 0x00002000 -#define SCC_XP 0x00004000 -#define SCC_CD_MASK 0xffff0000 -#define SCC_CD_SHIFT 16 - - -#define SYCC_IE 0x00000001 -#define SYCC_AE 0x00000002 -#define SYCC_FP 0x00000004 -#define SYCC_AR 0x00000008 -#define SYCC_HR 0x00000010 -#define SYCC_CD_MASK 0xffff0000 -#define SYCC_CD_SHIFT 16 - - -#define CF_EN 0x00000001 -#define CF_EM_MASK 0x0000000e -#define CF_EM_SHIFT 1 -#define CF_EM_FLASH 0 -#define CF_EM_SYNC 2 -#define CF_EM_PCMCIA 4 -#define CF_DS 0x00000010 -#define CF_BS 0x00000020 -#define CF_CD_MASK 0x000000c0 -#define CF_CD_SHIFT 6 -#define CF_CD_DIV2 0x00000000 -#define CF_CD_DIV3 0x00000040 -#define CF_CD_DIV4 0x00000080 -#define CF_CE 0x00000100 -#define CF_SB 0x00000200 - - -#define PM_W0_MASK 0x0000003f -#define PM_W1_MASK 0x00001f00 -#define PM_W1_SHIFT 8 -#define PM_W2_MASK 0x001f0000 -#define PM_W2_SHIFT 16 -#define PM_W3_MASK 0x1f000000 -#define PM_W3_SHIFT 24 - - -#define PA_W0_MASK 0x0000003f -#define PA_W1_MASK 0x00001f00 -#define PA_W1_SHIFT 8 -#define PA_W2_MASK 0x001f0000 -#define PA_W2_SHIFT 16 -#define PA_W3_MASK 0x1f000000 -#define PA_W3_SHIFT 24 - - -#define PI_W0_MASK 0x0000003f -#define PI_W1_MASK 0x00001f00 -#define PI_W1_SHIFT 8 -#define PI_W2_MASK 0x001f0000 -#define PI_W2_SHIFT 16 -#define PI_W3_MASK 0x1f000000 -#define PI_W3_SHIFT 24 - - -#define PW_W0_MASK 0x0000001f -#define PW_W1_MASK 0x00001f00 -#define PW_W1_SHIFT 8 -#define PW_W2_MASK 0x001f0000 -#define PW_W2_SHIFT 16 -#define PW_W3_MASK 0x1f000000 -#define PW_W3_SHIFT 24 - -#define PW_W0 0x0000000c -#define PW_W1 0x00000a00 -#define PW_W2 0x00020000 -#define PW_W3 0x01000000 - - -#define FW_W0_MASK 0x0000003f -#define FW_W1_MASK 0x00001f00 -#define FW_W1_SHIFT 8 -#define FW_W2_MASK 0x001f0000 -#define FW_W2_SHIFT 16 -#define FW_W3_MASK 0x1f000000 -#define FW_W3_SHIFT 24 - - -#define WATCHDOG_CLOCK 48000000 -#define WATCHDOG_CLOCK_5354 32000 - - -#define PCTL_ILP_DIV_MASK 0xffff0000 -#define PCTL_ILP_DIV_SHIFT 16 -#define PCTL_PLL_PLLCTL_UPD 0x00000400 -#define PCTL_NOILP_ON_WAIT 0x00000200 -#define PCTL_HT_REQ_EN 0x00000100 -#define PCTL_ALP_REQ_EN 0x00000080 -#define PCTL_XTALFREQ_MASK 0x0000007c -#define PCTL_XTALFREQ_SHIFT 2 -#define PCTL_ILP_DIV_EN 0x00000002 -#define PCTL_LPO_SEL 0x00000001 - - -#define CSTRETCH_HT 0xffff0000 -#define CSTRETCH_ALP 0x0000ffff - - -#define GPIO_ONTIME_SHIFT 16 - - -#define CN_N1_MASK 0x3f -#define CN_N2_MASK 0x3f00 -#define CN_N2_SHIFT 8 -#define CN_PLLC_MASK 0xf0000 -#define CN_PLLC_SHIFT 16 - - -#define CC_M1_MASK 0x3f -#define CC_M2_MASK 0x3f00 -#define CC_M2_SHIFT 8 -#define CC_M3_MASK 0x3f0000 -#define CC_M3_SHIFT 16 -#define CC_MC_MASK 0x1f000000 -#define CC_MC_SHIFT 24 - - -#define CC_F6_2 0x02 -#define CC_F6_3 0x03 -#define CC_F6_4 0x05 -#define CC_F6_5 0x09 -#define CC_F6_6 0x11 -#define CC_F6_7 0x21 - -#define CC_F5_BIAS 5 - -#define CC_MC_BYPASS 0x08 -#define CC_MC_M1 0x04 -#define CC_MC_M1M2 0x02 -#define CC_MC_M1M2M3 0x01 -#define CC_MC_M1M3 0x11 - - -#define CC_T2_BIAS 2 -#define CC_T2M2_BIAS 3 - -#define CC_T2MC_M1BYP 1 -#define CC_T2MC_M2BYP 2 -#define CC_T2MC_M3BYP 4 - - -#define CC_T6_MMASK 1 -#define CC_T6_M0 120000000 -#define CC_T6_M1 100000000 -#define SB2MIPS_T6(sb) (2 * (sb)) - - -#define CC_CLOCK_BASE1 24000000 -#define CC_CLOCK_BASE2 12500000 - - -#define CLKC_5350_N 0x0311 -#define CLKC_5350_M 0x04020009 - - -#define FLASH_NONE 0x000 -#define SFLASH_ST 0x100 -#define SFLASH_AT 0x200 -#define PFLASH 0x700 - - -#define CC_CFG_EN 0x0001 -#define CC_CFG_EM_MASK 0x000e -#define CC_CFG_EM_ASYNC 0x0000 -#define CC_CFG_EM_SYNC 0x0002 -#define CC_CFG_EM_PCMCIA 0x0004 -#define CC_CFG_EM_IDE 0x0006 -#define CC_CFG_DS 0x0010 -#define CC_CFG_CD_MASK 0x00e0 -#define CC_CFG_CE 0x0100 -#define CC_CFG_SB 0x0200 -#define CC_CFG_IS 0x0400 - - -#define CC_EB_BASE 0x1a000000 -#define CC_EB_PCMCIA_MEM 0x1a000000 -#define CC_EB_PCMCIA_IO 0x1a200000 -#define CC_EB_PCMCIA_CFG 0x1a400000 -#define CC_EB_IDE 0x1a800000 -#define CC_EB_PCMCIA1_MEM 0x1a800000 -#define CC_EB_PCMCIA1_IO 0x1aa00000 -#define CC_EB_PCMCIA1_CFG 0x1ac00000 -#define CC_EB_PROGIF 0x1b000000 - - - -#define SFLASH_OPCODE 0x000000ff -#define SFLASH_ACTION 0x00000700 -#define SFLASH_CS_ACTIVE 0x00001000 -#define SFLASH_START 0x80000000 -#define SFLASH_BUSY SFLASH_START - - -#define SFLASH_ACT_OPONLY 0x0000 -#define SFLASH_ACT_OP1D 0x0100 -#define SFLASH_ACT_OP3A 0x0200 -#define SFLASH_ACT_OP3A1D 0x0300 -#define SFLASH_ACT_OP3A4D 0x0400 -#define SFLASH_ACT_OP3A4X4D 0x0500 -#define SFLASH_ACT_OP3A1X4D 0x0700 - - -#define SFLASH_ST_WREN 0x0006 -#define SFLASH_ST_WRDIS 0x0004 -#define SFLASH_ST_RDSR 0x0105 -#define SFLASH_ST_WRSR 0x0101 -#define SFLASH_ST_READ 0x0303 -#define SFLASH_ST_PP 0x0302 -#define SFLASH_ST_SE 0x02d8 -#define SFLASH_ST_BE 0x00c7 -#define SFLASH_ST_DP 0x00b9 -#define SFLASH_ST_RES 0x03ab -#define SFLASH_ST_CSA 0x1000 - - -#define SFLASH_ST_WIP 0x01 -#define SFLASH_ST_WEL 0x02 -#define SFLASH_ST_BP_MASK 0x1c -#define SFLASH_ST_BP_SHIFT 2 -#define SFLASH_ST_SRWD 0x80 - - -#define SFLASH_AT_READ 0x07e8 -#define SFLASH_AT_PAGE_READ 0x07d2 -#define SFLASH_AT_BUF1_READ -#define SFLASH_AT_BUF2_READ -#define SFLASH_AT_STATUS 0x01d7 -#define SFLASH_AT_BUF1_WRITE 0x0384 -#define SFLASH_AT_BUF2_WRITE 0x0387 -#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -#define SFLASH_AT_BUF1_PROGRAM 0x0288 -#define SFLASH_AT_BUF2_PROGRAM 0x0289 -#define SFLASH_AT_PAGE_ERASE 0x0281 -#define SFLASH_AT_BLOCK_ERASE 0x0250 -#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -#define SFLASH_AT_BUF1_LOAD 0x0253 -#define SFLASH_AT_BUF2_LOAD 0x0255 -#define SFLASH_AT_BUF1_COMPARE 0x0260 -#define SFLASH_AT_BUF2_COMPARE 0x0261 -#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -#define SFLASH_AT_BUF2_REPROGRAM 0x0259 - - -#define SFLASH_AT_READY 0x80 -#define SFLASH_AT_MISMATCH 0x40 -#define SFLASH_AT_ID_MASK 0x38 -#define SFLASH_AT_ID_SHIFT 3 - - - -#define UART_RX 0 -#define UART_TX 0 -#define UART_DLL 0 -#define UART_IER 1 -#define UART_DLM 1 -#define UART_IIR 2 -#define UART_FCR 2 -#define UART_LCR 3 -#define UART_MCR 4 -#define UART_LSR 5 -#define UART_MSR 6 -#define UART_SCR 7 -#define UART_LCR_DLAB 0x80 -#define UART_LCR_WLEN8 0x03 -#define UART_MCR_OUT2 0x08 -#define UART_MCR_LOOP 0x10 -#define UART_LSR_RX_FIFO 0x80 -#define UART_LSR_TDHR 0x40 -#define UART_LSR_THRE 0x20 -#define UART_LSR_BREAK 0x10 -#define UART_LSR_FRAMING 0x08 -#define UART_LSR_PARITY 0x04 -#define UART_LSR_OVERRUN 0x02 -#define UART_LSR_RXRDY 0x01 -#define UART_FCR_FIFO_ENABLE 1 - - -#define UART_IIR_FIFO_MASK 0xc0 -#define UART_IIR_INT_MASK 0xf -#define UART_IIR_MDM_CHG 0x0 -#define UART_IIR_NOINT 0x1 -#define UART_IIR_THRE 0x2 -#define UART_IIR_RCVD_DATA 0x4 -#define UART_IIR_RCVR_STATUS 0x6 -#define UART_IIR_CHAR_TIME 0xc - - -#define UART_IER_EDSSI 8 -#define UART_IER_ELSI 4 -#define UART_IER_ETBEI 2 -#define UART_IER_ERBFI 1 - - -#define PST_INTPEND 0x0040 -#define PST_SBCLKST 0x0030 -#define PST_SBCLKST_ILP 0x0010 -#define PST_SBCLKST_ALP 0x0020 -#define PST_SBCLKST_HT 0x0030 -#define PST_ALPAVAIL 0x0008 -#define PST_HTAVAIL 0x0004 -#define PST_RESINIT 0x0003 - - -#define PCAP_REV_MASK 0x000000ff -#define PCAP_RC_MASK 0x00001f00 -#define PCAP_RC_SHIFT 8 -#define PCAP_TC_MASK 0x0001e000 -#define PCAP_TC_SHIFT 13 -#define PCAP_PC_MASK 0x001e0000 -#define PCAP_PC_SHIFT 17 -#define PCAP_VC_MASK 0x01e00000 -#define PCAP_VC_SHIFT 21 -#define PCAP_CC_MASK 0x1e000000 -#define PCAP_CC_SHIFT 25 -#define PCAP5_PC_MASK 0x003e0000 -#define PCAP5_PC_SHIFT 17 -#define PCAP5_VC_MASK 0x07c00000 -#define PCAP5_VC_SHIFT 22 -#define PCAP5_CC_MASK 0xf8000000 -#define PCAP5_CC_SHIFT 27 - - - -#define PRRT_TIME_MASK 0x03ff -#define PRRT_INTEN 0x0400 -#define PRRT_REQ_ACTIVE 0x0800 -#define PRRT_ALP_REQ 0x1000 -#define PRRT_HT_REQ 0x2000 - - -#define PMURES_BIT(bit) (1 << (bit)) - - -#define PMURES_MAX_RESNUM 30 - - - - -#define PMU0_PLL0_PLLCTL0 0 -#define PMU0_PLL0_PC0_PDIV_MASK 1 -#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 - - -#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 -#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 - - -#define PMU0_PLL0_PLLCTL1 1 -#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 - - -#define PMU0_PLL0_PLLCTL2 2 -#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 - - -#define RES4328_EXT_SWITCHER_PWM 0 -#define RES4328_BB_SWITCHER_PWM 1 -#define RES4328_BB_SWITCHER_BURST 2 -#define RES4328_BB_EXT_SWITCHER_BURST 3 -#define RES4328_ILP_REQUEST 4 -#define RES4328_RADIO_SWITCHER_PWM 5 -#define RES4328_RADIO_SWITCHER_BURST 6 -#define RES4328_ROM_SWITCH 7 -#define RES4328_PA_REF_LDO 8 -#define RES4328_RADIO_LDO 9 -#define RES4328_AFE_LDO 10 -#define RES4328_PLL_LDO 11 -#define RES4328_BG_FILTBYP 12 -#define RES4328_TX_FILTBYP 13 -#define RES4328_RX_FILTBYP 14 -#define RES4328_XTAL_PU 15 -#define RES4328_XTAL_EN 16 -#define RES4328_BB_PLL_FILTBYP 17 -#define RES4328_RF_PLL_FILTBYP 18 -#define RES4328_BB_PLL_PU 19 - -#define RES5354_EXT_SWITCHER_PWM 0 -#define RES5354_BB_SWITCHER_PWM 1 -#define RES5354_BB_SWITCHER_BURST 2 -#define RES5354_BB_EXT_SWITCHER_BURST 3 -#define RES5354_ILP_REQUEST 4 -#define RES5354_RADIO_SWITCHER_PWM 5 -#define RES5354_RADIO_SWITCHER_BURST 6 -#define RES5354_ROM_SWITCH 7 -#define RES5354_PA_REF_LDO 8 -#define RES5354_RADIO_LDO 9 -#define RES5354_AFE_LDO 10 -#define RES5354_PLL_LDO 11 -#define RES5354_BG_FILTBYP 12 -#define RES5354_TX_FILTBYP 13 -#define RES5354_RX_FILTBYP 14 -#define RES5354_XTAL_PU 15 -#define RES5354_XTAL_EN 16 -#define RES5354_BB_PLL_FILTBYP 17 -#define RES5354_RF_PLL_FILTBYP 18 -#define RES5354_BB_PLL_PU 19 - - - -#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) - - -#define PMU2_PHY_PLL_PLLCTL 4 -#define PMU2_SI_PLL_PLLCTL 10 - - -#define RES4325_BUCK_BOOST_BURST 0 -#define RES4325_CBUCK_BURST 1 -#define RES4325_CBUCK_PWM 2 -#define RES4325_CLDO_CBUCK_BURST 3 -#define RES4325_CLDO_CBUCK_PWM 4 -#define RES4325_BUCK_BOOST_PWM 5 -#define RES4325_ILP_REQUEST 6 -#define RES4325_ABUCK_BURST 7 -#define RES4325_ABUCK_PWM 8 -#define RES4325_LNLDO1_PU 9 -#define RES4325_OTP_PU 10 -#define RES4325_LNLDO3_PU 11 -#define RES4325_LNLDO4_PU 12 -#define RES4325_XTAL_PU 13 -#define RES4325_ALP_AVAIL 14 -#define RES4325_RX_PWRSW_PU 15 -#define RES4325_TX_PWRSW_PU 16 -#define RES4325_RFPLL_PWRSW_PU 17 -#define RES4325_LOGEN_PWRSW_PU 18 -#define RES4325_AFE_PWRSW_PU 19 -#define RES4325_BBPLL_PWRSW_PU 20 -#define RES4325_HT_AVAIL 21 - - -#define RES4325B0_CBUCK_LPOM 1 -#define RES4325B0_CBUCK_BURST 2 -#define RES4325B0_CBUCK_PWM 3 -#define RES4325B0_CLDO_PU 4 - - -#define RES4325C1_OTP_PWRSW_PU 10 -#define RES4325C1_LNLDO2_PU 12 - - -#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4325_DEFCIS_SEL 0 -#define CST4325_SPROM_SEL 1 -#define CST4325_OTP_SEL 2 -#define CST4325_OTP_PWRDN 3 -#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -#define CST4325_SDIO_USB_MODE_SHIFT 2 -#define CST4325_RCAL_VALID_MASK 0x00000008 -#define CST4325_RCAL_VALID_SHIFT 3 -#define CST4325_RCAL_VALUE_MASK 0x000001f0 -#define CST4325_RCAL_VALUE_SHIFT 4 -#define CST4325_PMUTOP_2B_MASK 0x00000200 -#define CST4325_PMUTOP_2B_SHIFT 9 - -#define RES4329_RESERVED0 0 -#define RES4329_CBUCK_LPOM 1 -#define RES4329_CBUCK_BURST 2 -#define RES4329_CBUCK_PWM 3 -#define RES4329_CLDO_PU 4 -#define RES4329_PALDO_PU 5 -#define RES4329_ILP_REQUEST 6 -#define RES4329_RESERVED7 7 -#define RES4329_RESERVED8 8 -#define RES4329_LNLDO1_PU 9 -#define RES4329_OTP_PU 10 -#define RES4329_RESERVED11 11 -#define RES4329_LNLDO2_PU 12 -#define RES4329_XTAL_PU 13 -#define RES4329_ALP_AVAIL 14 -#define RES4329_RX_PWRSW_PU 15 -#define RES4329_TX_PWRSW_PU 16 -#define RES4329_RFPLL_PWRSW_PU 17 -#define RES4329_LOGEN_PWRSW_PU 18 -#define RES4329_AFE_PWRSW_PU 19 -#define RES4329_BBPLL_PWRSW_PU 20 -#define RES4329_HT_AVAIL 21 - -#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4329_DEFCIS_SEL 0 -#define CST4329_SPROM_SEL 1 -#define CST4329_OTP_SEL 2 -#define CST4329_OTP_PWRDN 3 -#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -#define CST4329_SPI_SDIO_MODE_SHIFT 2 - - -#define RES4312_SWITCHER_BURST 0 -#define RES4312_SWITCHER_PWM 1 -#define RES4312_PA_REF_LDO 2 -#define RES4312_CORE_LDO_BURST 3 -#define RES4312_CORE_LDO_PWM 4 -#define RES4312_RADIO_LDO 5 -#define RES4312_ILP_REQUEST 6 -#define RES4312_BG_FILTBYP 7 -#define RES4312_TX_FILTBYP 8 -#define RES4312_RX_FILTBYP 9 -#define RES4312_XTAL_PU 10 -#define RES4312_ALP_AVAIL 11 -#define RES4312_BB_PLL_FILTBYP 12 -#define RES4312_RF_PLL_FILTBYP 13 -#define RES4312_HT_AVAIL 14 - -#define RES4322_RF_LDO 0 -#define RES4322_ILP_REQUEST 1 -#define RES4322_XTAL_PU 2 -#define RES4322_ALP_AVAIL 3 -#define RES4322_SI_PLL_ON 4 -#define RES4322_HT_SI_AVAIL 5 -#define RES4322_PHY_PLL_ON 6 -#define RES4322_HT_PHY_AVAIL 7 -#define RES4322_OTP_PU 8 - - -#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -#define CST4322_SPROM_OTP_SEL_SHIFT 6 -#define CST4322_NO_SPROM_OTP 0 -#define CST4322_SPROM_PRESENT 1 -#define CST4322_OTP_PRESENT 2 -#define CST4322_PCI_OR_USB 0x00000100 -#define CST4322_BOOT_MASK 0x00000600 -#define CST4322_BOOT_SHIFT 9 -#define CST4322_BOOT_FROM_SRAM 0 -#define CST4322_BOOT_FROM_ROM 1 -#define CST4322_BOOT_FROM_FLASH 2 -#define CST4322_BOOT_FROM_INVALID 3 -#define CST4322_ILP_DIV_EN 0x00000800 -#define CST4322_FLASH_TYPE_MASK 0x00001000 -#define CST4322_FLASH_TYPE_SHIFT 12 -#define CST4322_FLASH_TYPE_SHIFT_ST 0 -#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 -#define CST4322_ARM_TAP_SEL 0x00002000 -#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -#define CST4322_RES_INIT_MODE_SHIFT 14 -#define CST4322_RES_INIT_MODE_ILPAVAIL 0 -#define CST4322_RES_INIT_MODE_ILPREQ 1 -#define CST4322_RES_INIT_MODE_ALPAVAIL 2 -#define CST4322_RES_INIT_MODE_HTAVAIL 3 -#define CST4322_PCIPLLCLK_GATING 0x00010000 -#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -#define CST4322_PCI_CARDBUS_MODE 0x00040000 - -#define RES4315_CBUCK_LPOM 1 -#define RES4315_CBUCK_BURST 2 -#define RES4315_CBUCK_PWM 3 -#define RES4315_CLDO_PU 4 -#define RES4315_PALDO_PU 5 -#define RES4315_ILP_REQUEST 6 -#define RES4315_LNLDO1_PU 9 -#define RES4315_OTP_PU 10 -#define RES4315_LNLDO2_PU 12 -#define RES4315_XTAL_PU 13 -#define RES4315_ALP_AVAIL 14 -#define RES4315_RX_PWRSW_PU 15 -#define RES4315_TX_PWRSW_PU 16 -#define RES4315_RFPLL_PWRSW_PU 17 -#define RES4315_LOGEN_PWRSW_PU 18 -#define RES4315_AFE_PWRSW_PU 19 -#define RES4315_BBPLL_PWRSW_PU 20 -#define RES4315_HT_AVAIL 21 - -#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4315_DEFCIS_SEL 0x00000000 -#define CST4315_SPROM_SEL 0x00000001 -#define CST4315_OTP_SEL 0x00000002 -#define CST4315_OTP_PWRDN 0x00000003 -#define CST4315_SDIO_MODE 0x00000004 -#define CST4315_RCAL_VALID 0x00000008 -#define CST4315_RCAL_VALUE_MASK 0x000001f0 -#define CST4315_RCAL_VALUE_SHIFT 4 -#define CST4315_PALDO_EXTPNP 0x00000200 -#define CST4315_CBUCK_MODE_MASK 0x00000c00 -#define CST4315_CBUCK_MODE_BURST 0x00000400 -#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 - -#define PMU_MAX_TRANSITION_DLY 15000 - - -#define PMURES_UP_TRANSITION 2 - - - - - -#define ECI_BW_20 0x0 -#define ECI_BW_25 0x1 -#define ECI_BW_30 0x2 -#define ECI_BW_35 0x3 -#define ECI_BW_40 0x4 -#define ECI_BW_45 0x5 -#define ECI_BW_50 0x6 -#define ECI_BW_ALL 0x7 - - -#define WLAN_NUM_ANT1 TXANT_0 -#define WLAN_NUM_ANT2 TXANT_1 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbconfig.h b/drivers/net/wireless/bcm4329/include/sbconfig.h deleted file mode 100644 index da18ccbe9ab8..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbconfig.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Broadcom SiliconBackplane hardware register definitions. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbconfig.h,v 13.67.30.1 2008/05/07 20:17:27 Exp $ - */ - - -#ifndef _SBCONFIG_H -#define _SBCONFIG_H - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -#define SB_BUS_SIZE 0x10000 -#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) - - -#define SBCONFIGOFF 0xf00 -#define SBCONFIGSIZE 256 - -#define SBIPSFLAG 0x08 -#define SBTPSFLAG 0x18 -#define SBTMERRLOGA 0x48 -#define SBTMERRLOG 0x50 -#define SBADMATCH3 0x60 -#define SBADMATCH2 0x68 -#define SBADMATCH1 0x70 -#define SBIMSTATE 0x90 -#define SBINTVEC 0x94 -#define SBTMSTATELOW 0x98 -#define SBTMSTATEHIGH 0x9c -#define SBBWA0 0xa0 -#define SBIMCONFIGLOW 0xa8 -#define SBIMCONFIGHIGH 0xac -#define SBADMATCH0 0xb0 -#define SBTMCONFIGLOW 0xb8 -#define SBTMCONFIGHIGH 0xbc -#define SBBCONFIG 0xc0 -#define SBBSTATE 0xc8 -#define SBACTCNFG 0xd8 -#define SBFLAGST 0xe8 -#define SBIDLOW 0xf8 -#define SBIDHIGH 0xfc - - - -#define SBIMERRLOGA 0xea8 -#define SBIMERRLOG 0xeb0 -#define SBTMPORTCONNID0 0xed8 -#define SBTMPORTLOCK0 0xef8 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _sbconfig { - uint32 PAD[2]; - uint32 sbipsflag; - uint32 PAD[3]; - uint32 sbtpsflag; - uint32 PAD[11]; - uint32 sbtmerrloga; - uint32 PAD; - uint32 sbtmerrlog; - uint32 PAD[3]; - uint32 sbadmatch3; - uint32 PAD; - uint32 sbadmatch2; - uint32 PAD; - uint32 sbadmatch1; - uint32 PAD[7]; - uint32 sbimstate; - uint32 sbintvec; - uint32 sbtmstatelow; - uint32 sbtmstatehigh; - uint32 sbbwa0; - uint32 PAD; - uint32 sbimconfiglow; - uint32 sbimconfighigh; - uint32 sbadmatch0; - uint32 PAD; - uint32 sbtmconfiglow; - uint32 sbtmconfighigh; - uint32 sbbconfig; - uint32 PAD; - uint32 sbbstate; - uint32 PAD[3]; - uint32 sbactcnfg; - uint32 PAD[3]; - uint32 sbflagst; - uint32 PAD[3]; - uint32 sbidlow; - uint32 sbidhigh; -} sbconfig_t; - -#endif - - -#define SBIPS_INT1_MASK 0x3f -#define SBIPS_INT1_SHIFT 0 -#define SBIPS_INT2_MASK 0x3f00 -#define SBIPS_INT2_SHIFT 8 -#define SBIPS_INT3_MASK 0x3f0000 -#define SBIPS_INT3_SHIFT 16 -#define SBIPS_INT4_MASK 0x3f000000 -#define SBIPS_INT4_SHIFT 24 - - -#define SBTPS_NUM0_MASK 0x3f -#define SBTPS_F0EN0 0x40 - - -#define SBTMEL_CM 0x00000007 -#define SBTMEL_CI 0x0000ff00 -#define SBTMEL_EC 0x0f000000 -#define SBTMEL_ME 0x80000000 - - -#define SBIM_PC 0xf -#define SBIM_AP_MASK 0x30 -#define SBIM_AP_BOTH 0x00 -#define SBIM_AP_TS 0x10 -#define SBIM_AP_TK 0x20 -#define SBIM_AP_RSV 0x30 -#define SBIM_IBE 0x20000 -#define SBIM_TO 0x40000 -#define SBIM_BY 0x01800000 -#define SBIM_RJ 0x02000000 - - -#define SBTML_RESET 0x0001 -#define SBTML_REJ_MASK 0x0006 -#define SBTML_REJ 0x0002 -#define SBTML_TMPREJ 0x0004 - -#define SBTML_SICF_SHIFT 16 - - -#define SBTMH_SERR 0x0001 -#define SBTMH_INT 0x0002 -#define SBTMH_BUSY 0x0004 -#define SBTMH_TO 0x0020 - -#define SBTMH_SISF_SHIFT 16 - - -#define SBBWA_TAB0_MASK 0xffff -#define SBBWA_TAB1_MASK 0xffff -#define SBBWA_TAB1_SHIFT 16 - - -#define SBIMCL_STO_MASK 0x7 -#define SBIMCL_RTO_MASK 0x70 -#define SBIMCL_RTO_SHIFT 4 -#define SBIMCL_CID_MASK 0xff0000 -#define SBIMCL_CID_SHIFT 16 - - -#define SBIMCH_IEM_MASK 0xc -#define SBIMCH_TEM_MASK 0x30 -#define SBIMCH_TEM_SHIFT 4 -#define SBIMCH_BEM_MASK 0xc0 -#define SBIMCH_BEM_SHIFT 6 - - -#define SBAM_TYPE_MASK 0x3 -#define SBAM_AD64 0x4 -#define SBAM_ADINT0_MASK 0xf8 -#define SBAM_ADINT0_SHIFT 3 -#define SBAM_ADINT1_MASK 0x1f8 -#define SBAM_ADINT1_SHIFT 3 -#define SBAM_ADINT2_MASK 0x1f8 -#define SBAM_ADINT2_SHIFT 3 -#define SBAM_ADEN 0x400 -#define SBAM_ADNEG 0x800 -#define SBAM_BASE0_MASK 0xffffff00 -#define SBAM_BASE0_SHIFT 8 -#define SBAM_BASE1_MASK 0xfffff000 -#define SBAM_BASE1_SHIFT 12 -#define SBAM_BASE2_MASK 0xffff0000 -#define SBAM_BASE2_SHIFT 16 - - -#define SBTMCL_CD_MASK 0xff -#define SBTMCL_CO_MASK 0xf800 -#define SBTMCL_CO_SHIFT 11 -#define SBTMCL_IF_MASK 0xfc0000 -#define SBTMCL_IF_SHIFT 18 -#define SBTMCL_IM_MASK 0x3000000 -#define SBTMCL_IM_SHIFT 24 - - -#define SBTMCH_BM_MASK 0x3 -#define SBTMCH_RM_MASK 0x3 -#define SBTMCH_RM_SHIFT 2 -#define SBTMCH_SM_MASK 0x30 -#define SBTMCH_SM_SHIFT 4 -#define SBTMCH_EM_MASK 0x300 -#define SBTMCH_EM_SHIFT 8 -#define SBTMCH_IM_MASK 0xc00 -#define SBTMCH_IM_SHIFT 10 - - -#define SBBC_LAT_MASK 0x3 -#define SBBC_MAX0_MASK 0xf0000 -#define SBBC_MAX0_SHIFT 16 -#define SBBC_MAX1_MASK 0xf00000 -#define SBBC_MAX1_SHIFT 20 - - -#define SBBS_SRD 0x1 -#define SBBS_HRD 0x2 - - -#define SBIDL_CS_MASK 0x3 -#define SBIDL_AR_MASK 0x38 -#define SBIDL_AR_SHIFT 3 -#define SBIDL_SYNCH 0x40 -#define SBIDL_INIT 0x80 -#define SBIDL_MINLAT_MASK 0xf00 -#define SBIDL_MINLAT_SHIFT 8 -#define SBIDL_MAXLAT 0xf000 -#define SBIDL_MAXLAT_SHIFT 12 -#define SBIDL_FIRST 0x10000 -#define SBIDL_CW_MASK 0xc0000 -#define SBIDL_CW_SHIFT 18 -#define SBIDL_TP_MASK 0xf00000 -#define SBIDL_TP_SHIFT 20 -#define SBIDL_IP_MASK 0xf000000 -#define SBIDL_IP_SHIFT 24 -#define SBIDL_RV_MASK 0xf0000000 -#define SBIDL_RV_SHIFT 28 -#define SBIDL_RV_2_2 0x00000000 -#define SBIDL_RV_2_3 0x10000000 - - -#define SBIDH_RC_MASK 0x000f -#define SBIDH_RCE_MASK 0x7000 -#define SBIDH_RCE_SHIFT 8 -#define SBCOREREV(sbidh) \ - ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -#define SBIDH_CC_MASK 0x8ff0 -#define SBIDH_CC_SHIFT 4 -#define SBIDH_VC_MASK 0xffff0000 -#define SBIDH_VC_SHIFT 16 - -#define SB_COMMIT 0xfd8 - - -#define SB_VEND_BCM 0x4243 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbhnddma.h b/drivers/net/wireless/bcm4329/include/sbhnddma.h deleted file mode 100644 index 7681395f5b3b..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbhnddma.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Generic Broadcom Home Networking Division (HND) DMA engine HW interface - * This supports the following chips: BCM42xx, 44xx, 47xx . - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbhnddma.h,v 13.11.250.5.16.1 2009/07/21 14:04:51 Exp $ - */ - - -#ifndef _sbhnddma_h_ -#define _sbhnddma_h_ - - - - - - - -typedef volatile struct { - uint32 control; - uint32 addr; - uint32 ptr; - uint32 status; -} dma32regs_t; - -typedef volatile struct { - dma32regs_t xmt; - dma32regs_t rcv; -} dma32regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma32diag_t; - - -typedef volatile struct { - uint32 ctrl; - uint32 addr; -} dma32dd_t; - - -#define D32RINGALIGN_BITS 12 -#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -#define D32RINGALIGN (1 << D32RINGALIGN_BITS) -#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) - - -#define XC_XE ((uint32)1 << 0) -#define XC_SE ((uint32)1 << 1) -#define XC_LE ((uint32)1 << 2) -#define XC_FL ((uint32)1 << 4) -#define XC_PD ((uint32)1 << 11) -#define XC_AE ((uint32)3 << 16) -#define XC_AE_SHIFT 16 - - -#define XP_LD_MASK 0xfff - - -#define XS_CD_MASK 0x0fff -#define XS_XS_MASK 0xf000 -#define XS_XS_SHIFT 12 -#define XS_XS_DISABLED 0x0000 -#define XS_XS_ACTIVE 0x1000 -#define XS_XS_IDLE 0x2000 -#define XS_XS_STOPPED 0x3000 -#define XS_XS_SUSP 0x4000 -#define XS_XE_MASK 0xf0000 -#define XS_XE_SHIFT 16 -#define XS_XE_NOERR 0x00000 -#define XS_XE_DPE 0x10000 -#define XS_XE_DFU 0x20000 -#define XS_XE_BEBR 0x30000 -#define XS_XE_BEDA 0x40000 -#define XS_AD_MASK 0xfff00000 -#define XS_AD_SHIFT 20 - - -#define RC_RE ((uint32)1 << 0) -#define RC_RO_MASK 0xfe -#define RC_RO_SHIFT 1 -#define RC_FM ((uint32)1 << 8) -#define RC_SH ((uint32)1 << 9) -#define RC_OC ((uint32)1 << 10) -#define RC_PD ((uint32)1 << 11) -#define RC_AE ((uint32)3 << 16) -#define RC_AE_SHIFT 16 - - -#define RP_LD_MASK 0xfff - - -#define RS_CD_MASK 0x0fff -#define RS_RS_MASK 0xf000 -#define RS_RS_SHIFT 12 -#define RS_RS_DISABLED 0x0000 -#define RS_RS_ACTIVE 0x1000 -#define RS_RS_IDLE 0x2000 -#define RS_RS_STOPPED 0x3000 -#define RS_RE_MASK 0xf0000 -#define RS_RE_SHIFT 16 -#define RS_RE_NOERR 0x00000 -#define RS_RE_DPE 0x10000 -#define RS_RE_DFO 0x20000 -#define RS_RE_BEBW 0x30000 -#define RS_RE_BEDA 0x40000 -#define RS_AD_MASK 0xfff00000 -#define RS_AD_SHIFT 20 - - -#define FA_OFF_MASK 0xffff -#define FA_SEL_MASK 0xf0000 -#define FA_SEL_SHIFT 16 -#define FA_SEL_XDD 0x00000 -#define FA_SEL_XDP 0x10000 -#define FA_SEL_RDD 0x40000 -#define FA_SEL_RDP 0x50000 -#define FA_SEL_XFD 0x80000 -#define FA_SEL_XFP 0x90000 -#define FA_SEL_RFD 0xc0000 -#define FA_SEL_RFP 0xd0000 -#define FA_SEL_RSD 0xe0000 -#define FA_SEL_RSP 0xf0000 - - -#define CTRL_BC_MASK 0x1fff -#define CTRL_AE ((uint32)3 << 16) -#define CTRL_AE_SHIFT 16 -#define CTRL_EOT ((uint32)1 << 28) -#define CTRL_IOC ((uint32)1 << 29) -#define CTRL_EOF ((uint32)1 << 30) -#define CTRL_SOF ((uint32)1 << 31) - - -#define CTRL_CORE_MASK 0x0ff00000 - - - - -typedef volatile struct { - uint32 control; - uint32 ptr; - uint32 addrlow; - uint32 addrhigh; - uint32 status0; - uint32 status1; -} dma64regs_t; - -typedef volatile struct { - dma64regs_t tx; - dma64regs_t rx; -} dma64regp_t; - -typedef volatile struct { - uint32 fifoaddr; - uint32 fifodatalow; - uint32 fifodatahigh; - uint32 pad; -} dma64diag_t; - - -typedef volatile struct { - uint32 ctrl1; - uint32 ctrl2; - uint32 addrlow; - uint32 addrhigh; -} dma64dd_t; - - -#define D64RINGALIGN_BITS 13 -#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -#define D64RINGALIGN (1 << D64RINGALIGN_BITS) -#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) - - -#define D64_XC_XE 0x00000001 -#define D64_XC_SE 0x00000002 -#define D64_XC_LE 0x00000004 -#define D64_XC_FL 0x00000010 -#define D64_XC_PD 0x00000800 -#define D64_XC_AE 0x00030000 -#define D64_XC_AE_SHIFT 16 - - -#define D64_XP_LD_MASK 0x00000fff - - -#define D64_XS0_CD_MASK 0x00001fff -#define D64_XS0_XS_MASK 0xf0000000 -#define D64_XS0_XS_SHIFT 28 -#define D64_XS0_XS_DISABLED 0x00000000 -#define D64_XS0_XS_ACTIVE 0x10000000 -#define D64_XS0_XS_IDLE 0x20000000 -#define D64_XS0_XS_STOPPED 0x30000000 -#define D64_XS0_XS_SUSP 0x40000000 - -#define D64_XS1_AD_MASK 0x0001ffff -#define D64_XS1_XE_MASK 0xf0000000 -#define D64_XS1_XE_SHIFT 28 -#define D64_XS1_XE_NOERR 0x00000000 -#define D64_XS1_XE_DPE 0x10000000 -#define D64_XS1_XE_DFU 0x20000000 -#define D64_XS1_XE_DTE 0x30000000 -#define D64_XS1_XE_DESRE 0x40000000 -#define D64_XS1_XE_COREE 0x50000000 - - -#define D64_RC_RE 0x00000001 -#define D64_RC_RO_MASK 0x000000fe -#define D64_RC_RO_SHIFT 1 -#define D64_RC_FM 0x00000100 -#define D64_RC_SH 0x00000200 -#define D64_RC_OC 0x00000400 -#define D64_RC_PD 0x00000800 -#define D64_RC_AE 0x00030000 -#define D64_RC_AE_SHIFT 16 - - -#define D64_RP_LD_MASK 0x00000fff - - -#define D64_RS0_CD_MASK 0x00001fff -#define D64_RS0_RS_MASK 0xf0000000 -#define D64_RS0_RS_SHIFT 28 -#define D64_RS0_RS_DISABLED 0x00000000 -#define D64_RS0_RS_ACTIVE 0x10000000 -#define D64_RS0_RS_IDLE 0x20000000 -#define D64_RS0_RS_STOPPED 0x30000000 -#define D64_RS0_RS_SUSP 0x40000000 - -#define D64_RS1_AD_MASK 0x0001ffff -#define D64_RS1_RE_MASK 0xf0000000 -#define D64_RS1_RE_SHIFT 28 -#define D64_RS1_RE_NOERR 0x00000000 -#define D64_RS1_RE_DPO 0x10000000 -#define D64_RS1_RE_DFU 0x20000000 -#define D64_RS1_RE_DTE 0x30000000 -#define D64_RS1_RE_DESRE 0x40000000 -#define D64_RS1_RE_COREE 0x50000000 - - -#define D64_FA_OFF_MASK 0xffff -#define D64_FA_SEL_MASK 0xf0000 -#define D64_FA_SEL_SHIFT 16 -#define D64_FA_SEL_XDD 0x00000 -#define D64_FA_SEL_XDP 0x10000 -#define D64_FA_SEL_RDD 0x40000 -#define D64_FA_SEL_RDP 0x50000 -#define D64_FA_SEL_XFD 0x80000 -#define D64_FA_SEL_XFP 0x90000 -#define D64_FA_SEL_RFD 0xc0000 -#define D64_FA_SEL_RFP 0xd0000 -#define D64_FA_SEL_RSD 0xe0000 -#define D64_FA_SEL_RSP 0xf0000 - - -#define D64_CTRL1_EOT ((uint32)1 << 28) -#define D64_CTRL1_IOC ((uint32)1 << 29) -#define D64_CTRL1_EOF ((uint32)1 << 30) -#define D64_CTRL1_SOF ((uint32)1 << 31) - - -#define D64_CTRL2_BC_MASK 0x00007fff -#define D64_CTRL2_AE 0x00030000 -#define D64_CTRL2_AE_SHIFT 16 -#define D64_CTRL2_PARITY 0x00040000 - - -#define D64_CTRL_CORE_MASK 0x0ff00000 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbpcmcia.h b/drivers/net/wireless/bcm4329/include/sbpcmcia.h deleted file mode 100644 index d6d80334258a..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbpcmcia.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbpcmcia.h,v 13.31.4.1.2.3.8.7 2009/06/22 05:14:24 Exp $ - */ - - -#ifndef _SBPCMCIA_H -#define _SBPCMCIA_H - - - - -#define PCMCIA_FCR (0x700 / 2) - -#define FCR0_OFF 0 -#define FCR1_OFF (0x40 / 2) -#define FCR2_OFF (0x80 / 2) -#define FCR3_OFF (0xc0 / 2) - -#define PCMCIA_FCR0 (0x700 / 2) -#define PCMCIA_FCR1 (0x740 / 2) -#define PCMCIA_FCR2 (0x780 / 2) -#define PCMCIA_FCR3 (0x7c0 / 2) - - - -#define PCMCIA_COR 0 - -#define COR_RST 0x80 -#define COR_LEV 0x40 -#define COR_IRQEN 0x04 -#define COR_BLREN 0x01 -#define COR_FUNEN 0x01 - - -#define PCICIA_FCSR (2 / 2) -#define PCICIA_PRR (4 / 2) -#define PCICIA_SCR (6 / 2) -#define PCICIA_ESR (8 / 2) - - -#define PCM_MEMOFF 0x0000 -#define F0_MEMOFF 0x1000 -#define F1_MEMOFF 0x2000 -#define F2_MEMOFF 0x3000 -#define F3_MEMOFF 0x4000 - - -#define MEM_ADDR0 (0x728 / 2) -#define MEM_ADDR1 (0x72a / 2) -#define MEM_ADDR2 (0x72c / 2) - - -#define PCMCIA_ADDR0 (0x072e / 2) -#define PCMCIA_ADDR1 (0x0730 / 2) -#define PCMCIA_ADDR2 (0x0732 / 2) - -#define MEM_SEG (0x0734 / 2) -#define SROM_CS (0x0736 / 2) -#define SROM_DATAL (0x0738 / 2) -#define SROM_DATAH (0x073a / 2) -#define SROM_ADDRL (0x073c / 2) -#define SROM_ADDRH (0x073e / 2) -#define SROM_INFO2 (0x0772 / 2) -#define SROM_INFO (0x07be / 2) - - -#define SROM_IDLE 0 -#define SROM_WRITE 1 -#define SROM_READ 2 -#define SROM_WEN 4 -#define SROM_WDS 7 -#define SROM_DONE 8 - - -#define SRI_SZ_MASK 0x03 -#define SRI_BLANK 0x04 -#define SRI_OTP 0x80 - - - -#define SBTML_INT_ACK 0x40000 -#define SBTML_INT_EN 0x20000 - - -#define SBTMH_INT_STATUS 0x40000 - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sbsdio.h b/drivers/net/wireless/bcm4329/include/sbsdio.h deleted file mode 100644 index 75aaf4d88f7d..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsdio.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * SDIO device core hardware definitions. - * sdio is a portion of the pcmcia core in core rev 3 - rev 8 - * - * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbsdio.h,v 13.29.4.1.22.3 2009/03/11 20:26:57 Exp $ - */ - -#ifndef _SBSDIO_H -#define _SBSDIO_H - -#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ - -/* function 1 miscellaneous registers */ -#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ -#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ -#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ -#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ -#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ -#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ -#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ -#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ -#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ -#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ - -/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ -#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ -#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ -#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ -#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ -#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ -#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ -#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ -#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ -#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ -#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ - -#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ - -/* SBSDIO_SPROM_CS */ -#define SBSDIO_SPROM_IDLE 0 -#define SBSDIO_SPROM_WRITE 1 -#define SBSDIO_SPROM_READ 2 -#define SBSDIO_SPROM_WEN 4 -#define SBSDIO_SPROM_WDS 7 -#define SBSDIO_SPROM_DONE 8 - -/* SBSDIO_SPROM_INFO */ -#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ -#define SROM_BLANK 0x04 /* depreciated in corerev 6 */ -#define SROM_OTP 0x80 /* OTP present */ - -/* SBSDIO_CHIP_CTRL */ -#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu, - * 1: power on oscillator - * (for 4318 only) - */ -/* SBSDIO_WATERMARK */ -#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device - * to wait before sending data to host - */ - -/* SBSDIO_DEVICE_CTL */ -#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when - * receiving CMD53 - */ -#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is - * synchronous to the sdio clock - */ -#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host - * except the chipActive (rev 8) - */ -#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put - * external pads in tri-state; requires - * sdio bus power cycle to clear (rev 9) - */ -#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ - - -/* SBSDIO_FUNC1_CHIPCLKCSR */ -#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ -/* In rev8, actual avail bits followed original docs */ -#define SBSDIO_Rev8_HT_AVAIL 0x40 -#define SBSDIO_Rev8_ALP_AVAIL 0x80 - -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ - (alponly ? 1 : SBSDIO_HTAV(regval))) - -/* SBSDIO_FUNC1_SDIOPULLUP */ -#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */ -#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */ -#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */ -#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */ -#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */ - -/* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ - -/* some duplication with sbsdpcmdev.h here */ -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ -#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ -#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ - -/* direct(mapped) cis space */ -#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */ - -#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ - -#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, - * link bytes - */ - -/* indirect cis access (in sprom) */ -#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from - * 8th byte - */ - -#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one - * data comamnd - */ - -#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ - -#endif /* _SBSDIO_H */ diff --git a/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h b/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h deleted file mode 100644 index 7c7c7e4de0f6..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsdpcmdev.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific device core support - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbsdpcmdev.h,v 13.29.4.1.4.6.6.2 2008/12/31 21:16:51 Exp $ - */ - -#ifndef _sbsdpcmdev_h_ -#define _sbsdpcmdev_h_ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - - -typedef volatile struct { - dma64regs_t xmt; /* dma tx */ - uint32 PAD[2]; - dma64regs_t rcv; /* dma rx */ - uint32 PAD[2]; -} dma64p_t; - -/* dma64 sdiod corerev >= 1 */ -typedef volatile struct { - dma64p_t dma64regs[2]; - dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */ - uint32 PAD[92]; -} sdiodma64_t; - -/* dma32 sdiod corerev == 0 */ -typedef volatile struct { - dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */ - uint32 PAD[108]; -} sdiodma32_t; - -/* dma32 regs for pcmcia core */ -typedef volatile struct { - dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */ - uint32 PAD[116]; -} pcmdma32_t; - -/* core registers */ -typedef volatile struct { - uint32 corecontrol; /* CoreControl, 0x000, rev8 */ - uint32 corestatus; /* CoreStatus, 0x004, rev8 */ - uint32 PAD[1]; - uint32 biststatus; /* BistStatus, 0x00c, rev8 */ - - /* PCMCIA access */ - uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */ - uint16 PAD[1]; - uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */ - uint16 PAD[1]; - uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */ - uint16 PAD[1]; - uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */ - uint16 PAD[1]; - - /* interrupt */ - uint32 intstatus; /* IntStatus, 0x020, rev8 */ - uint32 hostintmask; /* IntHostMask, 0x024, rev8 */ - uint32 intmask; /* IntSbMask, 0x028, rev8 */ - uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */ - uint32 sbintmask; /* SBIntMask, 0x030, rev8 */ - uint32 PAD[3]; - uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */ - uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */ - uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */ - uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */ - - /* synchronized access to registers in SDIO clock domain */ - uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */ - uint32 PAD[3]; - - /* PCMCIA frame control */ - uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */ - uint8 PAD[3]; - uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */ - uint8 PAD[155]; - - /* interrupt batching control */ - uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */ - uint32 PAD[3]; - - /* counters */ - uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */ - uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */ - uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */ - uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */ - uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */ - uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */ - uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */ - uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */ - uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */ - uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */ - uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */ - uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */ - uint32 PAD[40]; - uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */ - uint32 PAD[7]; - - /* DMA engines */ - volatile union { - pcmdma32_t pcm32; - sdiodma32_t sdiod32; - sdiodma64_t sdiod64; - } dma; - - /* SDIO/PCMCIA CIS region */ - char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */ - - /* PCMCIA function control registers */ - char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */ - uint16 PAD[55]; - - /* PCMCIA backplane access */ - uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */ - uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */ - uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */ - uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */ - uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */ - uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */ - uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */ - uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */ - uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */ - uint16 PAD[31]; - - /* sprom "size" & "blank" info */ - uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */ - uint32 PAD[464]; - - /* Sonics SiliconBackplane registers */ - sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */ -} sdpcmd_regs_t; - -/* corecontrol */ -#define CC_CISRDY (1 << 0) /* CIS Ready */ -#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */ -#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ -#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */ - -/* corestatus */ -#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */ -#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */ -#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */ - -#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */ -#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */ -#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */ -#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */ - -/* intstatus */ -#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ -#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ -#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ -#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ -#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ -#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ -#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ -#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ -#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ -#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ -#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ -#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ -#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ -#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ -#define I_PC (1 << 10) /* descriptor error */ -#define I_PD (1 << 11) /* data error */ -#define I_DE (1 << 12) /* Descriptor protocol Error */ -#define I_RU (1 << 13) /* Receive descriptor Underflow */ -#define I_RO (1 << 14) /* Receive fifo Overflow */ -#define I_XU (1 << 15) /* Transmit fifo Underflow */ -#define I_RI (1 << 16) /* Receive Interrupt */ -#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ -#define I_XI (1 << 24) /* Transmit Interrupt */ -#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ -#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ -#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ -#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ -#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */ -#define I_SRESET (1 << 30) /* CCCR RES interrupt */ -#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */ -#define I_DMA (I_RI | I_XI | I_ERRORS) - -/* sbintstatus */ -#define I_SB_SERR (1 << 8) /* Backplane SError (write) */ -#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */ -#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */ - -/* sdioaccess */ -#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */ -#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */ -#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */ -#define SDA_WRITE 0x01000000 /* Write bit */ -#define SDA_READ 0x00000000 /* Write bit cleared for Read */ -#define SDA_BUSY 0x80000000 /* Busy bit */ - -/* sdioaccess-accessible register address spaces */ -#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */ -#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */ -#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */ -#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */ - -/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */ -#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */ -#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */ -#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */ -#define SDA_DEVICECONTROL 0x009 /* DeviceControl */ -#define SDA_SBADDRLOW 0x00a /* SbAddrLow */ -#define SDA_SBADDRMID 0x00b /* SbAddrMid */ -#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */ -#define SDA_FRAMECTRL 0x00d /* FrameCtrl */ -#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */ -#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */ -#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */ -#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */ -#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */ -#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */ - -/* SDA_F2WATERMARK */ -#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */ - -/* SDA_SBADDRLOW */ -#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */ - -/* SDA_SBADDRMID */ -#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */ - -/* SDA_SBADDRHIGH */ -#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */ - -/* SDA_FRAMECTRL */ -#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */ -#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */ - -/* pcmciaframectrl */ -#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */ - -/* intrcvlazy */ -#define IRL_TO_MASK 0x00ffffff /* timeout */ -#define IRL_FC_MASK 0xff000000 /* frame count */ -#define IRL_FC_SHIFT 24 /* frame count */ - -/* rx header */ -typedef volatile struct { - uint16 len; - uint16 flags; -} sdpcmd_rxh_t; - -/* rx header flags */ -#define RXF_CRC 0x0001 /* CRC error detected */ -#define RXF_WOOS 0x0002 /* write frame out of sync */ -#define RXF_WF_TERM 0x0004 /* write frame terminated */ -#define RXF_ABORT 0x0008 /* write frame aborted */ -#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */ - -/* HW frame tag */ -#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ - -#endif /* _sbsdpcmdev_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/sbsocram.h b/drivers/net/wireless/bcm4329/include/sbsocram.h deleted file mode 100644 index 5ede0b66d97f..000000000000 --- a/drivers/net/wireless/bcm4329/include/sbsocram.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * BCM47XX Sonics SiliconBackplane embedded ram core - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbsocram.h,v 13.9.162.2 2008/12/12 14:13:27 Exp $ - */ - - -#ifndef _SBSOCRAM_H -#define _SBSOCRAM_H - -#ifndef _LANGUAGE_ASSEMBLY - - -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - - -typedef volatile struct sbsocramregs { - uint32 coreinfo; - uint32 bwalloc; - uint32 extracoreinfo; - uint32 biststat; - uint32 bankidx; - uint32 standbyctrl; - - uint32 errlogstatus; - uint32 errlogaddr; - - uint32 cambankidx; - uint32 cambankstandbyctrl; - uint32 cambankpatchctrl; - uint32 cambankpatchtblbaseaddr; - uint32 cambankcmdreg; - uint32 cambankdatareg; - uint32 cambankmaskreg; - uint32 PAD[17]; - uint32 extmemconfig; - uint32 extmemparitycsr; - uint32 extmemparityerrdata; - uint32 extmemparityerrcnt; - uint32 extmemwrctrlandsize; - uint32 PAD[84]; - uint32 workaround; - uint32 pwrctl; -} sbsocramregs_t; - -#endif - - -#define SR_COREINFO 0x00 -#define SR_BWALLOC 0x04 -#define SR_BISTSTAT 0x0c -#define SR_BANKINDEX 0x10 -#define SR_BANKSTBYCTL 0x14 -#define SR_PWRCTL 0x1e8 - - -#define SRCI_PT_MASK 0x00070000 -#define SRCI_PT_SHIFT 16 - -#define SRCI_PT_OCP_OCP 0 -#define SRCI_PT_AXI_OCP 1 -#define SRCI_PT_ARM7AHB_OCP 2 -#define SRCI_PT_CM3AHB_OCP 3 -#define SRCI_PT_AXI_AXI 4 -#define SRCI_PT_AHB_AXI 5 - -#define SRCI_LSS_MASK 0x00f00000 -#define SRCI_LSS_SHIFT 20 -#define SRCI_LRS_MASK 0x0f000000 -#define SRCI_LRS_SHIFT 24 - - -#define SRCI_MS0_MASK 0xf -#define SR_MS0_BASE 16 - - -#define SRCI_ROMNB_MASK 0xf000 -#define SRCI_ROMNB_SHIFT 12 -#define SRCI_ROMBSZ_MASK 0xf00 -#define SRCI_ROMBSZ_SHIFT 8 -#define SRCI_SRNB_MASK 0xf0 -#define SRCI_SRNB_SHIFT 4 -#define SRCI_SRBSZ_MASK 0xf -#define SRCI_SRBSZ_SHIFT 0 - -#define SR_BSZ_BASE 14 - - -#define SRSC_SBYOVR_MASK 0x80000000 -#define SRSC_SBYOVR_SHIFT 31 -#define SRSC_SBYOVRVAL_MASK 0x60000000 -#define SRSC_SBYOVRVAL_SHIFT 29 -#define SRSC_SBYEN_MASK 0x01000000 -#define SRSC_SBYEN_SHIFT 24 - - -#define SRPC_PMU_STBYDIS_MASK 0x00000010 -#define SRPC_PMU_STBYDIS_SHIFT 4 -#define SRPC_STBYOVRVAL_MASK 0x00000008 -#define SRPC_STBYOVRVAL_SHIFT 3 -#define SRPC_STBYOVR_MASK 0x00000007 -#define SRPC_STBYOVR_SHIFT 0 - - -#define SRECC_NUM_BANKS_MASK 0x000000F0 -#define SRECC_NUM_BANKS_SHIFT 4 -#define SRECC_BANKSIZE_MASK 0x0000000F -#define SRECC_BANKSIZE_SHIFT 0 - -#define SRECC_BANKSIZE(value) (1 << (value)) - - -#define SRCBPC_PATCHENABLE 0x80000000 - -#define SRP_ADDRESS 0x0001FFFC -#define SRP_VALID 0x8000 - - -#define SRCMD_WRITE 0x00020000 -#define SRCMD_READ 0x00010000 -#define SRCMD_DONE 0x80000000 - -#define SRCMD_DONE_DLY 1000 - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/sdio.h b/drivers/net/wireless/bcm4329/include/sdio.h deleted file mode 100644 index 280cb845fb04..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdio.h +++ /dev/null @@ -1,566 +0,0 @@ -/* - * SDIO spec header file - * Protocol and standard (common) device definitions - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sdio.h,v 13.24.4.1.4.1.16.1 2009/08/12 01:08:02 Exp $ - */ - -#ifndef _SDIO_H -#define _SDIO_H - - -/* CCCR structure for function 0 */ -typedef volatile struct { - uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */ - uint8 sd_rev; /* RO, sd spec revision */ - uint8 io_en; /* I/O enable */ - uint8 io_rdy; /* I/O ready reg */ - uint8 intr_ctl; /* Master and per function interrupt enable control */ - uint8 intr_status; /* RO, interrupt pending status */ - uint8 io_abort; /* read/write abort or reset all functions */ - uint8 bus_inter; /* bus interface control */ - uint8 capability; /* RO, card capability */ - - uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */ - uint8 cis_base_mid; - uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */ - - /* suspend/resume registers */ - uint8 bus_suspend; /* 0xC */ - uint8 func_select; /* 0xD */ - uint8 exec_flag; /* 0xE */ - uint8 ready_flag; /* 0xF */ - - uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */ - - uint8 power_control; /* 0x12 (SDIO version 1.10) */ - - uint8 speed_control; /* 0x13 */ -} sdio_regs_t; - -/* SDIO Device CCCR offsets */ -#define SDIOD_CCCR_REV 0x00 -#define SDIOD_CCCR_SDREV 0x01 -#define SDIOD_CCCR_IOEN 0x02 -#define SDIOD_CCCR_IORDY 0x03 -#define SDIOD_CCCR_INTEN 0x04 -#define SDIOD_CCCR_INTPEND 0x05 -#define SDIOD_CCCR_IOABORT 0x06 -#define SDIOD_CCCR_BICTRL 0x07 -#define SDIOD_CCCR_CAPABLITIES 0x08 -#define SDIOD_CCCR_CISPTR_0 0x09 -#define SDIOD_CCCR_CISPTR_1 0x0A -#define SDIOD_CCCR_CISPTR_2 0x0B -#define SDIOD_CCCR_BUSSUSP 0x0C -#define SDIOD_CCCR_FUNCSEL 0x0D -#define SDIOD_CCCR_EXECFLAGS 0x0E -#define SDIOD_CCCR_RDYFLAGS 0x0F -#define SDIOD_CCCR_BLKSIZE_0 0x10 -#define SDIOD_CCCR_BLKSIZE_1 0x11 -#define SDIOD_CCCR_POWER_CONTROL 0x12 -#define SDIOD_CCCR_SPEED_CONTROL 0x13 - -/* Broadcom extensions (corerev >= 1) */ -#define SDIOD_CCCR_BRCM_SEPINT 0xf2 - -/* cccr_sdio_rev */ -#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ -#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ - -/* sd_rev */ -#define SD_REV_PHY_MASK 0x0f /* SD format version number */ - -/* io_en */ -#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ -#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */ - -/* io_rdys */ -#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ -#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */ - -/* intr_ctl */ -#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ -#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ -#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */ - -/* intr_status */ -#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ -#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */ - -/* io_abort */ -#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ -#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */ - -/* bus_inter */ -#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ -#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ -#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ -#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */ -#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ -#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ - -/* capability */ -#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ -#define SDIO_CAP_LSC 0x40 /* low speed card */ -#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ -#define SDIO_CAP_SRW 0x04 /* support read wait */ -#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ -#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */ - -/* power_control */ -#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */ -#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */ - -/* speed_control (control device entry into high-speed clocking mode) */ -#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */ -#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */ - -/* brcm sepint */ -#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */ -#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */ -#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */ - -/* FBR structure for function 1-7, FBR addresses and register offsets */ -typedef volatile struct { - uint8 devctr; /* device interface, CSA control */ - uint8 ext_dev; /* extended standard I/O device type code */ - uint8 pwr_sel; /* power selection support */ - uint8 PAD[6]; /* reserved */ - - uint8 cis_low; /* CIS LSB */ - uint8 cis_mid; - uint8 cis_high; /* CIS MSB */ - uint8 csa_low; /* code storage area, LSB */ - uint8 csa_mid; - uint8 csa_high; /* code storage area, MSB */ - uint8 csa_dat_win; /* data access window to function */ - - uint8 fnx_blk_size[2]; /* block size, little endian */ -} sdio_fbr_t; - -/* Maximum number of I/O funcs */ -#define SDIOD_MAX_IOFUNCS 7 - -/* SDIO Device FBR Start Address */ -#define SDIOD_FBR_STARTADDR 0x100 - -/* SDIO Device FBR Size */ -#define SDIOD_FBR_SIZE 0x100 - -/* Macro to calculate FBR register base */ -#define SDIOD_FBR_BASE(n) ((n) * 0x100) - -/* Function register offsets */ -#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */ -#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */ -#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */ - -/* SDIO Function CIS ptr offset */ -#define SDIOD_FBR_CISPTR_0 0x09 -#define SDIOD_FBR_CISPTR_1 0x0A -#define SDIOD_FBR_CISPTR_2 0x0B - -/* Code Storage Area pointer */ -#define SDIOD_FBR_CSA_ADDR_0 0x0C -#define SDIOD_FBR_CSA_ADDR_1 0x0D -#define SDIOD_FBR_CSA_ADDR_2 0x0E -#define SDIOD_FBR_CSA_DATA 0x0F - -/* SDIO Function I/O Block Size */ -#define SDIOD_FBR_BLKSIZE_0 0x10 -#define SDIOD_FBR_BLKSIZE_1 0x11 - -/* devctr */ -#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */ -#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */ -#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */ -/* interface codes */ -#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */ -#define SDIOD_DIC_UART 1 -#define SDIOD_DIC_BLUETOOTH_A 2 -#define SDIOD_DIC_BLUETOOTH_B 3 -#define SDIOD_DIC_GPS 4 -#define SDIOD_DIC_CAMERA 5 -#define SDIOD_DIC_PHS 6 -#define SDIOD_DIC_WLAN 7 -#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */ - -/* pwr_sel */ -#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */ -#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */ - -/* misc defines */ -#define SDIO_FUNC_0 0 -#define SDIO_FUNC_1 1 -#define SDIO_FUNC_2 2 -#define SDIO_FUNC_3 3 -#define SDIO_FUNC_4 4 -#define SDIO_FUNC_5 5 -#define SDIO_FUNC_6 6 -#define SDIO_FUNC_7 7 - -#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */ -#define SD_CARD_TYPE_IO 1 /* IO only card */ -#define SD_CARD_TYPE_MEMORY 2 /* memory only card */ -#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */ - -#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */ -#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */ - -/* Card registers: status bit position */ -#define CARDREG_STATUS_BIT_OUTOFRANGE 31 -#define CARDREG_STATUS_BIT_COMCRCERROR 23 -#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22 -#define CARDREG_STATUS_BIT_ERROR 19 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9 -#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4 - - - -#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ -#define SD_CMD_SEND_OPCOND 1 -#define SD_CMD_MMC_SET_RCA 3 -#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ -#define SD_CMD_SELECT_DESELECT_CARD 7 -#define SD_CMD_SEND_CSD 9 -#define SD_CMD_SEND_CID 10 -#define SD_CMD_STOP_TRANSMISSION 12 -#define SD_CMD_SEND_STATUS 13 -#define SD_CMD_GO_INACTIVE_STATE 15 -#define SD_CMD_SET_BLOCKLEN 16 -#define SD_CMD_READ_SINGLE_BLOCK 17 -#define SD_CMD_READ_MULTIPLE_BLOCK 18 -#define SD_CMD_WRITE_BLOCK 24 -#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SD_CMD_PROGRAM_CSD 27 -#define SD_CMD_SET_WRITE_PROT 28 -#define SD_CMD_CLR_WRITE_PROT 29 -#define SD_CMD_SEND_WRITE_PROT 30 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_ERASE 38 -#define SD_CMD_LOCK_UNLOCK 42 -#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ -#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ -#define SD_CMD_APP_CMD 55 -#define SD_CMD_GEN_CMD 56 -#define SD_CMD_READ_OCR 58 -#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ -#define SD_ACMD_SD_STATUS 13 -#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 -#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 -#define SD_ACMD_SD_SEND_OP_COND 41 -#define SD_ACMD_SET_CLR_CARD_DETECT 42 -#define SD_ACMD_SEND_SCR 51 - -/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ -#define SD_IO_OP_READ 0 /* Read_Write: Read */ -#define SD_IO_OP_WRITE 1 /* Read_Write: Write */ -#define SD_IO_RW_NORMAL 0 /* no RAW */ -#define SD_IO_RW_RAW 1 /* RAW */ -#define SD_IO_BYTE_MODE 0 /* Byte Mode */ -#define SD_IO_BLOCK_MODE 1 /* BlockMode */ -#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ -#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */ - -/* build SD_CMD_IO_RW_DIRECT Argument */ -#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \ - (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF)) - -/* build SD_CMD_IO_RW_EXTENDED Argument */ -#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \ - (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF)) - -/* SDIO response parameters */ -#define SD_RSP_NO_NONE 0 -#define SD_RSP_NO_1 1 -#define SD_RSP_NO_2 2 -#define SD_RSP_NO_3 3 -#define SD_RSP_NO_4 4 -#define SD_RSP_NO_5 5 -#define SD_RSP_NO_6 6 - - /* Modified R6 response (to CMD3) */ -#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 -#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 -#define SD_RSP_MR6_ERROR 0x2000 - - /* Modified R1 in R4 Response (to CMD5) */ -#define SD_RSP_MR1_SBIT 0x80 -#define SD_RSP_MR1_PARAMETER_ERROR 0x40 -#define SD_RSP_MR1_RFU5 0x20 -#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 -#define SD_RSP_MR1_COM_CRC_ERROR 0x08 -#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04 -#define SD_RSP_MR1_RFU1 0x02 -#define SD_RSP_MR1_IDLE_STATE 0x01 - - /* R5 response (to CMD52 and CMD53) */ -#define SD_RSP_R5_COM_CRC_ERROR 0x80 -#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 -#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 -#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 -#define SD_RSP_R5_ERROR 0x08 -#define SD_RSP_R5_RFU 0x04 -#define SD_RSP_R5_FUNC_NUM_ERROR 0x02 -#define SD_RSP_R5_OUT_OF_RANGE 0x01 - -#define SD_RSP_R5_ERRBITS 0xCB - - -/* ------------------------------------------------ - * SDIO Commands and responses - * - * I/O only commands are: - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -/* SDIO Commands */ -#define SDIOH_CMD_0 0 -#define SDIOH_CMD_3 3 -#define SDIOH_CMD_5 5 -#define SDIOH_CMD_7 7 -#define SDIOH_CMD_15 15 -#define SDIOH_CMD_52 52 -#define SDIOH_CMD_53 53 -#define SDIOH_CMD_59 59 - -/* SDIO Command Responses */ -#define SDIOH_RSP_NONE 0 -#define SDIOH_RSP_R1 1 -#define SDIOH_RSP_R2 2 -#define SDIOH_RSP_R3 3 -#define SDIOH_RSP_R4 4 -#define SDIOH_RSP_R5 5 -#define SDIOH_RSP_R6 6 - -/* - * SDIO Response Error flags - */ -#define SDIOH_RSP5_ERROR_FLAGS 0xCB - -/* ------------------------------------------------ - * SDIO Command structures. I/O only commands are: - * - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -#define CMD5_OCR_M BITFIELD_MASK(24) -#define CMD5_OCR_S 0 - -#define CMD7_RCA_M BITFIELD_MASK(16) -#define CMD7_RCA_S 16 - -#define CMD_15_RCA_M BITFIELD_MASK(16) -#define CMD_15_RCA_S 16 - -#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52 - */ -#define CMD52_DATA_S 0 -#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD52_REG_ADDR_S 9 -#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */ -#define CMD52_RAW_S 27 -#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD52_FUNCTION_S 28 -#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD52_RW_FLAG_S 31 - - -#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */ -#define CMD53_BYTE_BLK_CNT_S 0 -#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD53_REG_ADDR_S 9 -#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */ -#define CMD53_OP_CODE_S 26 -#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */ -#define CMD53_BLK_MODE_S 27 -#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD53_FUNCTION_S 28 -#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD53_RW_FLAG_S 31 - -/* ------------------------------------------------------ - * SDIO Command Response structures for SD1 and SD4 modes - * ----------------------------------------------------- - */ -#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */ -#define RSP4_IO_OCR_S 0 -#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */ -#define RSP4_STUFF_S 24 -#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */ -#define RSP4_MEM_PRESENT_S 27 -#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */ -#define RSP4_NUM_FUNCS_S 28 -#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */ -#define RSP4_CARD_READY_S 31 - -#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0] - */ -#define RSP6_STATUS_S 0 -#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */ -#define RSP6_IO_RCA_S 16 - -#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */ -#define RSP1_AKE_SEQ_ERROR_S 3 -#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP1_APP_CMD_S 5 -#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */ -#define RSP1_READY_FOR_DATA_S 8 -#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card - * when Cmd was received - */ -#define RSP1_CURR_STATE_S 9 -#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */ -#define RSP1_EARSE_RESET_S 13 -#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */ -#define RSP1_CARD_ECC_DISABLE_S 14 -#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */ -#define RSP1_WP_ERASE_SKIP_S 15 -#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits - * of CSD - */ -#define RSP1_CID_CSD_OVERW_S 16 -#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */ -#define RSP1_ERROR_S 19 -#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */ -#define RSP1_CC_ERROR_S 20 -#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed - * to correct data - */ -#define RSP1_CARD_ECC_FAILED_S 21 -#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */ -#define RSP1_ILLEGAL_CMD_S 22 -#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed - */ -#define RSP1_COM_CRC_ERROR_S 23 -#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */ -#define RSP1_LOCK_UNLOCK_FAIL_S 24 -#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */ -#define RSP1_CARD_LOCKED_S 25 -#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program - * write-protected blocks - */ -#define RSP1_WP_VIOLATION_S 26 -#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */ -#define RSP1_ERASE_PARAM_S 27 -#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */ -#define RSP1_ERASE_SEQ_ERR_S 28 -#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */ -#define RSP1_BLK_LEN_ERR_S 29 -#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */ -#define RSP1_ADDR_ERR_S 30 -#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */ -#define RSP1_OUT_OF_RANGE_S 31 - - -#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */ -#define RSP5_DATA_S 0 -#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */ -#define RSP5_FLAGS_S 8 -#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */ -#define RSP5_STUFF_S 16 - -/* ---------------------------------------------- - * SDIO Command Response structures for SPI mode - * ---------------------------------------------- - */ -#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */ -#define SPIRSP4_IO_OCR_S 0 -#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */ -#define SPIRSP4_STUFF_S 16 -#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */ -#define SPIRSP4_MEM_PRESENT_S 19 -#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */ -#define SPIRSP4_NUM_FUNCS_S 20 -#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */ -#define SPIRSP4_CARD_READY_S 23 -#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */ -#define SPIRSP4_IDLE_STATE_S 24 -#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP4_ILLEGAL_CMD_S 26 -#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP4_COM_CRC_ERROR_S 27 -#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP4_FUNC_NUM_ERROR_S 28 -#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP4_PARAM_ERROR_S 30 -#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP4_START_BIT_S 31 - -#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */ -#define SPIRSP5_DATA_S 16 -#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */ -#define SPIRSP5_IDLE_STATE_S 24 -#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP5_ILLEGAL_CMD_S 26 -#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP5_COM_CRC_ERROR_S 27 -#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP5_FUNC_NUM_ERROR_S 28 -#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP5_PARAM_ERROR_S 30 -#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP5_START_BIT_S 31 - -/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */ -#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error - */ -#define RSP6STAT_AKE_SEQ_ERROR_S 3 -#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP6STAT_APP_CMD_S 5 -#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data - * (buff empty) - */ -#define RSP6STAT_READY_FOR_DATA_S 8 -#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at - * Cmd reception - */ -#define RSP6STAT_CURR_STATE_S 9 -#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19 - */ -#define RSP6STAT_ERROR_S 13 -#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for - * card state Bit 22 - */ -#define RSP6STAT_ILLEGAL_CMD_S 14 -#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command - * failed Bit 23 - */ -#define RSP6STAT_COM_CRC_ERROR_S 15 - -#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ -#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE - -#endif /* _SDIO_H */ diff --git a/drivers/net/wireless/bcm4329/include/sdioh.h b/drivers/net/wireless/bcm4329/include/sdioh.h deleted file mode 100644 index 8123452eac2b..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdioh.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * SDIO Host Controller Spec header file - * Register map and definitions for the Standard Host Controller - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sdioh.h,v 13.13.18.1.16.3 2009/12/08 22:34:21 Exp $ - */ - -#ifndef _SDIOH_H -#define _SDIOH_H - -#define SD_SysAddr 0x000 -#define SD_BlockSize 0x004 -#define SD_BlockCount 0x006 -#define SD_Arg0 0x008 -#define SD_Arg1 0x00A -#define SD_TransferMode 0x00C -#define SD_Command 0x00E -#define SD_Response0 0x010 -#define SD_Response1 0x012 -#define SD_Response2 0x014 -#define SD_Response3 0x016 -#define SD_Response4 0x018 -#define SD_Response5 0x01A -#define SD_Response6 0x01C -#define SD_Response7 0x01E -#define SD_BufferDataPort0 0x020 -#define SD_BufferDataPort1 0x022 -#define SD_PresentState 0x024 -#define SD_HostCntrl 0x028 -#define SD_PwrCntrl 0x029 -#define SD_BlockGapCntrl 0x02A -#define SD_WakeupCntrl 0x02B -#define SD_ClockCntrl 0x02C -#define SD_TimeoutCntrl 0x02E -#define SD_SoftwareReset 0x02F -#define SD_IntrStatus 0x030 -#define SD_ErrorIntrStatus 0x032 -#define SD_IntrStatusEnable 0x034 -#define SD_ErrorIntrStatusEnable 0x036 -#define SD_IntrSignalEnable 0x038 -#define SD_ErrorIntrSignalEnable 0x03A -#define SD_CMD12ErrorStatus 0x03C -#define SD_Capabilities 0x040 -#define SD_Capabilities_Reserved 0x044 -#define SD_MaxCurCap 0x048 -#define SD_MaxCurCap_Reserved 0x04C -#define SD_ADMA_SysAddr 0x58 -#define SD_SlotInterruptStatus 0x0FC -#define SD_HostControllerVersion 0x0FE - -/* SD specific registers in PCI config space */ -#define SD_SlotInfo 0x40 - -/* SD_Capabilities reg (0x040) */ -#define CAP_TO_CLKFREQ_M BITFIELD_MASK(6) -#define CAP_TO_CLKFREQ_S 0 -#define CAP_TO_CLKUNIT_M BITFIELD_MASK(1) -#define CAP_TO_CLKUNIT_S 7 -#define CAP_BASECLK_M BITFIELD_MASK(6) -#define CAP_BASECLK_S 8 -#define CAP_MAXBLOCK_M BITFIELD_MASK(2) -#define CAP_MAXBLOCK_S 16 -#define CAP_ADMA2_M BITFIELD_MASK(1) -#define CAP_ADMA2_S 19 -#define CAP_ADMA1_M BITFIELD_MASK(1) -#define CAP_ADMA1_S 20 -#define CAP_HIGHSPEED_M BITFIELD_MASK(1) -#define CAP_HIGHSPEED_S 21 -#define CAP_DMA_M BITFIELD_MASK(1) -#define CAP_DMA_S 22 -#define CAP_SUSPEND_M BITFIELD_MASK(1) -#define CAP_SUSPEND_S 23 -#define CAP_VOLT_3_3_M BITFIELD_MASK(1) -#define CAP_VOLT_3_3_S 24 -#define CAP_VOLT_3_0_M BITFIELD_MASK(1) -#define CAP_VOLT_3_0_S 25 -#define CAP_VOLT_1_8_M BITFIELD_MASK(1) -#define CAP_VOLT_1_8_S 26 -#define CAP_64BIT_HOST_M BITFIELD_MASK(1) -#define CAP_64BIT_HOST_S 28 - -/* SD_MaxCurCap reg (0x048) */ -#define CAP_CURR_3_3_M BITFIELD_MASK(8) -#define CAP_CURR_3_3_S 0 -#define CAP_CURR_3_0_M BITFIELD_MASK(8) -#define CAP_CURR_3_0_S 8 -#define CAP_CURR_1_8_M BITFIELD_MASK(8) -#define CAP_CURR_1_8_S 16 - -/* SD_SysAddr: Offset 0x0000, Size 4 bytes */ - -/* SD_BlockSize: Offset 0x004, Size 2 bytes */ -#define BLKSZ_BLKSZ_M BITFIELD_MASK(12) -#define BLKSZ_BLKSZ_S 0 -#define BLKSZ_BNDRY_M BITFIELD_MASK(3) -#define BLKSZ_BNDRY_S 12 - -/* SD_BlockCount: Offset 0x006, size 2 bytes */ - -/* SD_Arg0: Offset 0x008, size = 4 bytes */ -/* SD_TransferMode Offset 0x00C, size = 2 bytes */ -#define XFER_DMA_ENABLE_M BITFIELD_MASK(1) -#define XFER_DMA_ENABLE_S 0 -#define XFER_BLK_COUNT_EN_M BITFIELD_MASK(1) -#define XFER_BLK_COUNT_EN_S 1 -#define XFER_CMD_12_EN_M BITFIELD_MASK(1) -#define XFER_CMD_12_EN_S 2 -#define XFER_DATA_DIRECTION_M BITFIELD_MASK(1) -#define XFER_DATA_DIRECTION_S 4 -#define XFER_MULTI_BLOCK_M BITFIELD_MASK(1) -#define XFER_MULTI_BLOCK_S 5 - -/* SD_Command: Offset 0x00E, size = 2 bytes */ -/* resp_type field */ -#define RESP_TYPE_NONE 0 -#define RESP_TYPE_136 1 -#define RESP_TYPE_48 2 -#define RESP_TYPE_48_BUSY 3 -/* type field */ -#define CMD_TYPE_NORMAL 0 -#define CMD_TYPE_SUSPEND 1 -#define CMD_TYPE_RESUME 2 -#define CMD_TYPE_ABORT 3 - -#define CMD_RESP_TYPE_M BITFIELD_MASK(2) /* Bits [0-1] - Response type */ -#define CMD_RESP_TYPE_S 0 -#define CMD_CRC_EN_M BITFIELD_MASK(1) /* Bit 3 - CRC enable */ -#define CMD_CRC_EN_S 3 -#define CMD_INDEX_EN_M BITFIELD_MASK(1) /* Bit 4 - Enable index checking */ -#define CMD_INDEX_EN_S 4 -#define CMD_DATA_EN_M BITFIELD_MASK(1) /* Bit 5 - Using DAT line */ -#define CMD_DATA_EN_S 5 -#define CMD_TYPE_M BITFIELD_MASK(2) /* Bit [6-7] - Normal, abort, resume, etc - */ -#define CMD_TYPE_S 6 -#define CMD_INDEX_M BITFIELD_MASK(6) /* Bits [8-13] - Command number */ -#define CMD_INDEX_S 8 - -/* SD_BufferDataPort0 : Offset 0x020, size = 2 or 4 bytes */ -/* SD_BufferDataPort1 : Offset 0x022, size = 2 bytes */ -/* SD_PresentState : Offset 0x024, size = 4 bytes */ -#define PRES_CMD_INHIBIT_M BITFIELD_MASK(1) /* Bit 0 May use CMD */ -#define PRES_CMD_INHIBIT_S 0 -#define PRES_DAT_INHIBIT_M BITFIELD_MASK(1) /* Bit 1 May use DAT */ -#define PRES_DAT_INHIBIT_S 1 -#define PRES_DAT_BUSY_M BITFIELD_MASK(1) /* Bit 2 DAT is busy */ -#define PRES_DAT_BUSY_S 2 -#define PRES_PRESENT_RSVD_M BITFIELD_MASK(5) /* Bit [3-7] rsvd */ -#define PRES_PRESENT_RSVD_S 3 -#define PRES_WRITE_ACTIVE_M BITFIELD_MASK(1) /* Bit 8 Write is active */ -#define PRES_WRITE_ACTIVE_S 8 -#define PRES_READ_ACTIVE_M BITFIELD_MASK(1) /* Bit 9 Read is active */ -#define PRES_READ_ACTIVE_S 9 -#define PRES_WRITE_DATA_RDY_M BITFIELD_MASK(1) /* Bit 10 Write buf is avail */ -#define PRES_WRITE_DATA_RDY_S 10 -#define PRES_READ_DATA_RDY_M BITFIELD_MASK(1) /* Bit 11 Read buf data avail */ -#define PRES_READ_DATA_RDY_S 11 -#define PRES_CARD_PRESENT_M BITFIELD_MASK(1) /* Bit 16 Card present - debounced */ -#define PRES_CARD_PRESENT_S 16 -#define PRES_CARD_STABLE_M BITFIELD_MASK(1) /* Bit 17 Debugging */ -#define PRES_CARD_STABLE_S 17 -#define PRES_CARD_PRESENT_RAW_M BITFIELD_MASK(1) /* Bit 18 Not debounced */ -#define PRES_CARD_PRESENT_RAW_S 18 -#define PRES_WRITE_ENABLED_M BITFIELD_MASK(1) /* Bit 19 Write protected? */ -#define PRES_WRITE_ENABLED_S 19 -#define PRES_DAT_SIGNAL_M BITFIELD_MASK(4) /* Bit [20-23] Debugging */ -#define PRES_DAT_SIGNAL_S 20 -#define PRES_CMD_SIGNAL_M BITFIELD_MASK(1) /* Bit 24 Debugging */ -#define PRES_CMD_SIGNAL_S 24 - -/* SD_HostCntrl: Offset 0x028, size = 1 bytes */ -#define HOST_LED_M BITFIELD_MASK(1) /* Bit 0 LED On/Off */ -#define HOST_LED_S 0 -#define HOST_DATA_WIDTH_M BITFIELD_MASK(1) /* Bit 1 4 bit enable */ -#define HOST_DATA_WIDTH_S 1 -#define HOST_HI_SPEED_EN_M BITFIELD_MASK(1) /* Bit 2 High speed vs low speed */ -#define HOST_DMA_SEL_S 3 -#define HOST_DMA_SEL_M BITFIELD_MASK(2) /* Bit 4:3 DMA Select */ -#define HOST_HI_SPEED_EN_S 2 - -/* misc defines */ -#define SD1_MODE 0x1 /* SD Host Cntrlr Spec */ -#define SD4_MODE 0x2 /* SD Host Cntrlr Spec */ - -/* SD_PwrCntrl: Offset 0x029, size = 1 bytes */ -#define PWR_BUS_EN_M BITFIELD_MASK(1) /* Bit 0 Power the bus */ -#define PWR_BUS_EN_S 0 -#define PWR_VOLTS_M BITFIELD_MASK(3) /* Bit [1-3] Voltage Select */ -#define PWR_VOLTS_S 1 - -/* SD_SoftwareReset: Offset 0x02F, size = 1 byte */ -#define SW_RESET_ALL_M BITFIELD_MASK(1) /* Bit 0 Reset All */ -#define SW_RESET_ALL_S 0 -#define SW_RESET_CMD_M BITFIELD_MASK(1) /* Bit 1 CMD Line Reset */ -#define SW_RESET_CMD_S 1 -#define SW_RESET_DAT_M BITFIELD_MASK(1) /* Bit 2 DAT Line Reset */ -#define SW_RESET_DAT_S 2 - -/* SD_IntrStatus: Offset 0x030, size = 2 bytes */ -/* Defs also serve SD_IntrStatusEnable and SD_IntrSignalEnable */ -#define INTSTAT_CMD_COMPLETE_M BITFIELD_MASK(1) /* Bit 0 */ -#define INTSTAT_CMD_COMPLETE_S 0 -#define INTSTAT_XFER_COMPLETE_M BITFIELD_MASK(1) -#define INTSTAT_XFER_COMPLETE_S 1 -#define INTSTAT_BLOCK_GAP_EVENT_M BITFIELD_MASK(1) -#define INTSTAT_BLOCK_GAP_EVENT_S 2 -#define INTSTAT_DMA_INT_M BITFIELD_MASK(1) -#define INTSTAT_DMA_INT_S 3 -#define INTSTAT_BUF_WRITE_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_WRITE_READY_S 4 -#define INTSTAT_BUF_READ_READY_M BITFIELD_MASK(1) -#define INTSTAT_BUF_READ_READY_S 5 -#define INTSTAT_CARD_INSERTION_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INSERTION_S 6 -#define INTSTAT_CARD_REMOVAL_M BITFIELD_MASK(1) -#define INTSTAT_CARD_REMOVAL_S 7 -#define INTSTAT_CARD_INT_M BITFIELD_MASK(1) -#define INTSTAT_CARD_INT_S 8 -#define INTSTAT_ERROR_INT_M BITFIELD_MASK(1) /* Bit 15 */ -#define INTSTAT_ERROR_INT_S 15 - -/* SD_ErrorIntrStatus: Offset 0x032, size = 2 bytes */ -/* Defs also serve SD_ErrorIntrStatusEnable and SD_ErrorIntrSignalEnable */ -#define ERRINT_CMD_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_CMD_TIMEOUT_S 0 -#define ERRINT_CMD_CRC_M BITFIELD_MASK(1) -#define ERRINT_CMD_CRC_S 1 -#define ERRINT_CMD_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_CMD_ENDBIT_S 2 -#define ERRINT_CMD_INDEX_M BITFIELD_MASK(1) -#define ERRINT_CMD_INDEX_S 3 -#define ERRINT_DATA_TIMEOUT_M BITFIELD_MASK(1) -#define ERRINT_DATA_TIMEOUT_S 4 -#define ERRINT_DATA_CRC_M BITFIELD_MASK(1) -#define ERRINT_DATA_CRC_S 5 -#define ERRINT_DATA_ENDBIT_M BITFIELD_MASK(1) -#define ERRINT_DATA_ENDBIT_S 6 -#define ERRINT_CURRENT_LIMIT_M BITFIELD_MASK(1) -#define ERRINT_CURRENT_LIMIT_S 7 -#define ERRINT_AUTO_CMD12_M BITFIELD_MASK(1) -#define ERRINT_AUTO_CMD12_S 8 -#define ERRINT_VENDOR_M BITFIELD_MASK(4) -#define ERRINT_VENDOR_S 12 - -/* Also provide definitions in "normal" form to allow combined masks */ -#define ERRINT_CMD_TIMEOUT_BIT 0x0001 -#define ERRINT_CMD_CRC_BIT 0x0002 -#define ERRINT_CMD_ENDBIT_BIT 0x0004 -#define ERRINT_CMD_INDEX_BIT 0x0008 -#define ERRINT_DATA_TIMEOUT_BIT 0x0010 -#define ERRINT_DATA_CRC_BIT 0x0020 -#define ERRINT_DATA_ENDBIT_BIT 0x0040 -#define ERRINT_CURRENT_LIMIT_BIT 0x0080 -#define ERRINT_AUTO_CMD12_BIT 0x0100 - -/* Masks to select CMD vs. DATA errors */ -#define ERRINT_CMD_ERRS (ERRINT_CMD_TIMEOUT_BIT | ERRINT_CMD_CRC_BIT |\ - ERRINT_CMD_ENDBIT_BIT | ERRINT_CMD_INDEX_BIT) -#define ERRINT_DATA_ERRS (ERRINT_DATA_TIMEOUT_BIT | ERRINT_DATA_CRC_BIT |\ - ERRINT_DATA_ENDBIT_BIT) -#define ERRINT_TRANSFER_ERRS (ERRINT_CMD_ERRS | ERRINT_DATA_ERRS) - -/* SD_WakeupCntr_BlockGapCntrl : Offset 0x02A , size = bytes */ -/* SD_ClockCntrl : Offset 0x02C , size = bytes */ -/* SD_SoftwareReset_TimeoutCntrl : Offset 0x02E , size = bytes */ -/* SD_IntrStatus : Offset 0x030 , size = bytes */ -/* SD_ErrorIntrStatus : Offset 0x032 , size = bytes */ -/* SD_IntrStatusEnable : Offset 0x034 , size = bytes */ -/* SD_ErrorIntrStatusEnable : Offset 0x036 , size = bytes */ -/* SD_IntrSignalEnable : Offset 0x038 , size = bytes */ -/* SD_ErrorIntrSignalEnable : Offset 0x03A , size = bytes */ -/* SD_CMD12ErrorStatus : Offset 0x03C , size = bytes */ -/* SD_Capabilities : Offset 0x040 , size = bytes */ -/* SD_MaxCurCap : Offset 0x048 , size = bytes */ -/* SD_MaxCurCap_Reserved: Offset 0x04C , size = bytes */ -/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */ -/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */ - -#endif /* _SDIOH_H */ diff --git a/drivers/net/wireless/bcm4329/include/sdiovar.h b/drivers/net/wireless/bcm4329/include/sdiovar.h deleted file mode 100644 index 0179d4cb96db..000000000000 --- a/drivers/net/wireless/bcm4329/include/sdiovar.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Structure used by apps whose drivers access SDIO drivers. - * Pulled out separately so dhdu and wlu can both use it. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sdiovar.h,v 13.5.14.2.16.2 2009/12/08 22:34:21 Exp $ - */ - -#ifndef _sdiovar_h_ -#define _sdiovar_h_ - -#include - -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - -typedef struct sdreg { - int func; - int offset; - int value; -} sdreg_t; - -/* Common msglevel constants */ -#define SDH_ERROR_VAL 0x0001 /* Error */ -#define SDH_TRACE_VAL 0x0002 /* Trace */ -#define SDH_INFO_VAL 0x0004 /* Info */ -#define SDH_DEBUG_VAL 0x0008 /* Debug */ -#define SDH_DATA_VAL 0x0010 /* Data */ -#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -#define SDH_DMA_VAL 0x0080 /* DMA */ - -#define NUM_PREV_TRANSACTIONS 16 - - -#include - -#endif /* _sdiovar_h_ */ diff --git a/drivers/net/wireless/bcm4329/include/siutils.h b/drivers/net/wireless/bcm4329/include/siutils.h deleted file mode 100644 index cb9f1407b73b..000000000000 --- a/drivers/net/wireless/bcm4329/include/siutils.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Misc utility routines for accessing the SOC Interconnects - * of Broadcom HNBU chips. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: siutils.h,v 13.197.4.2.4.3.8.16 2010/06/23 21:36:05 Exp $ - */ - - -#ifndef _siutils_h_ -#define _siutils_h_ - - -struct si_pub { - uint socitype; - - uint bustype; - uint buscoretype; - uint buscorerev; - uint buscoreidx; - int ccrev; - uint32 cccaps; - int pmurev; - uint32 pmucaps; - uint boardtype; - uint boardvendor; - uint boardflags; - uint chip; - uint chiprev; - uint chippkg; - uint32 chipst; - bool issim; - uint socirev; - bool pci_pr32414; -}; - -#if defined(WLC_HIGH) && !defined(WLC_LOW) -typedef struct si_pub si_t; -#else -typedef const struct si_pub si_t; -#endif - - -#define SI_OSH NULL - - -#define XTAL 0x1 -#define PLL 0x2 - - -#define CLK_FAST 0 -#define CLK_DYNAMIC 2 - - -#define GPIO_DRV_PRIORITY 0 -#define GPIO_APP_PRIORITY 1 -#define GPIO_HI_PRIORITY 2 - - -#define GPIO_PULLUP 0 -#define GPIO_PULLDN 1 - - -#define GPIO_REGEVT 0 -#define GPIO_REGEVT_INTMSK 1 -#define GPIO_REGEVT_INTPOL 2 - - -#define SI_DEVPATH_BUFSZ 16 - - -#define SI_DOATTACH 1 -#define SI_PCIDOWN 2 -#define SI_PCIUP 3 - -#define ISSIM_ENAB(sih) 0 - - -#if defined(BCMPMUCTL) -#define PMUCTL_ENAB(sih) (BCMPMUCTL) -#else -#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -#endif - - -#if defined(BCMPMUCTL) && BCMPMUCTL -#define CCCTL_ENAB(sih) (0) -#define CCPLL_ENAB(sih) (0) -#else -#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -#endif - -typedef void (*gpio_handler_t)(uint32 stat, void *arg); - - - -extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *si_kattach(osl_t *osh); -extern void si_detach(si_t *sih); -extern bool si_pci_war16165(si_t *sih); - -extern uint si_corelist(si_t *sih, uint coreid[]); -extern uint si_coreid(si_t *sih); -extern uint si_flag(si_t *sih); -extern uint si_intflag(si_t *sih); -extern uint si_coreidx(si_t *sih); -extern uint si_coreunit(si_t *sih); -extern uint si_corevendor(si_t *sih); -extern uint si_corerev(si_t *sih); -extern void *si_osh(si_t *sih); -extern void si_setosh(si_t *sih, osl_t *osh); -extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void *si_coreregs(si_t *sih); -extern void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val); -extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern bool si_iscoreup(si_t *sih); -extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -extern void *si_setcoreidx(si_t *sih, uint coreidx); -extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); -extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -extern int si_numaddrspaces(si_t *sih); -extern uint32 si_addrspace(si_t *sih, uint asidx); -extern uint32 si_addrspacesize(si_t *sih, uint asidx); -extern int si_corebist(si_t *sih); -extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void si_core_tofixup(si_t *sih); -extern void si_core_disable(si_t *sih, uint32 bits); -extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -extern uint32 si_clock(si_t *sih); -extern void si_clock_pmu_spuravoid(si_t *sih, bool spuravoid); -extern uint32 si_alp_clock(si_t *sih); -extern uint32 si_ilp_clock(si_t *sih); -extern void si_pci_setup(si_t *sih, uint coremask); -extern void si_pcmcia_init(si_t *sih); -extern void si_setint(si_t *sih, int siflag); -extern bool si_backplane64(si_t *sih); -extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg); -extern void si_deregister_intr_callback(si_t *sih); -extern void si_clkctl_init(si_t *sih); -extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih); -extern bool si_clkctl_cc(si_t *sih, uint mode); -extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val); -extern bool si_backplane64(si_t *sih); -extern void si_btcgpiowar(si_t *sih); -extern bool si_deviceremoved(si_t *sih); -extern uint32 si_socram_size(si_t *sih); - -extern void si_watchdog(si_t *sih, uint ticks); -extern void si_watchdog_ms(si_t *sih, uint32 ms); -extern void *si_gpiosetcore(si_t *sih); -extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioin(si_t *sih); -extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority); -extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val); -extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority); -extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val); -extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val); -extern uint32 si_gpio_int_enable(si_t *sih, bool enable); - - -extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev, gpio_handler_t cb, void *arg); -extern void si_gpio_handler_unregister(si_t *sih, void* gpioh); -extern void si_gpio_handler_process(si_t *sih); - - -extern bool si_pci_pmecap(si_t *sih); -struct osl_info; -extern bool si_pci_fastpmecap(struct osl_info *osh); -extern bool si_pci_pmeclr(si_t *sih); -extern void si_pci_pmeen(si_t *sih); -extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset); - -extern void si_sdio_init(si_t *sih); - -extern uint16 si_d11_devid(si_t *sih); -extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice, - uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader); - -#define si_eci_init(sih) (0) -#define si_eci_notify_bt(sih, type, val, interrupt) (0) - - - -extern int si_devpath(si_t *sih, char *path, int size); - -extern char *si_getdevpathvar(si_t *sih, const char *name); -extern int si_getdevpathintvar(si_t *sih, const char *name); - - -extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); -extern void si_war42780_clkreq(si_t *sih, bool clkreq); -extern void si_pci_sleep(si_t *sih); -extern void si_pci_down(si_t *sih); -extern void si_pci_up(si_t *sih); -extern void si_pcie_war_ovr_disable(si_t *sih); -extern void si_pcie_extendL1timer(si_t *sih, bool extend); -extern int si_pci_fixcfg(si_t *sih); - - - - - - - -#endif diff --git a/drivers/net/wireless/bcm4329/include/spid.h b/drivers/net/wireless/bcm4329/include/spid.h deleted file mode 100644 index c740296de9af..000000000000 --- a/drivers/net/wireless/bcm4329/include/spid.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * SPI device spec header file - * - * Copyright (C) 2010, Broadcom Corporation - * All Rights Reserved. - * - * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; - * the contents of this file may not be disclosed to third parties, copied - * or duplicated in any form, in whole or in part, without the prior - * written permission of Broadcom Corporation. - * - * $Id: spid.h,v 1.7.10.1.16.3 2009/04/09 19:23:14 Exp $ - */ - -#ifndef _SPI_H -#define _SPI_H - -/* - * Brcm SPI Device Register Map. - * - */ - -typedef volatile struct { - uint8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */ - uint8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */ - uint8 status_enable; /* 0x02, status-enable, intr with status, response_delay - * function selection, command/data error check - */ - uint8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */ - uint16 intr_reg; /* 0x04, Intr status register */ - uint16 intr_en_reg; /* 0x06, Intr mask register */ - uint32 status_reg; /* 0x08, RO, Status bits of last spi transfer */ - uint16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */ - uint16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */ - uint16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */ - uint32 test_read; /* 0x14, RO 0xfeedbead signature */ - uint32 test_rw; /* 0x18, RW */ - uint8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */ - uint8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */ - uint8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */ - uint8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */ -} spi_regs_t; - -/* SPI device register offsets */ -#define SPID_CONFIG 0x00 -#define SPID_RESPONSE_DELAY 0x01 -#define SPID_STATUS_ENABLE 0x02 -#define SPID_RESET_BP 0x03 /* (corerev >= 1) */ -#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */ -#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */ -#define SPID_STATUS_REG 0x08 /* 32 bits */ -#define SPID_F1_INFO_REG 0x0C /* 16 bits */ -#define SPID_F2_INFO_REG 0x0E /* 16 bits */ -#define SPID_F3_INFO_REG 0x10 /* 16 bits */ -#define SPID_TEST_READ 0x14 /* 32 bits */ -#define SPID_TEST_RW 0x18 /* 32 bits */ -#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */ - -/* Bit masks for SPID_CONFIG device register */ -#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */ -#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */ -#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */ -#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */ -#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */ -#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */ -#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */ - -/* Bit mask for SPID_RESPONSE_DELAY device register */ -#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */ - -/* Bit mask for SPID_STATUS_ENABLE device register */ -#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */ -#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */ -#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */ -#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */ -#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */ -#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */ - -/* Bit mask for SPID_RESET_BP device register */ -#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */ -#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */ -#define RESET_SPI 0x80 /* reset the above enabled logic */ - -/* Bit mask for SPID_INTR_REG device register */ -#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */ -#define F2_F3_FIFO_RD_UNDERFLOW 0x0002 -#define F2_F3_FIFO_WR_OVERFLOW 0x0004 -#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */ -#define DATA_ERROR 0x0010 /* Cleared by writing 1 */ -#define F2_PACKET_AVAILABLE 0x0020 -#define F3_PACKET_AVAILABLE 0x0040 -#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */ -#define MISC_INTR0 0x0100 -#define MISC_INTR1 0x0200 -#define MISC_INTR2 0x0400 -#define MISC_INTR3 0x0800 -#define MISC_INTR4 0x1000 -#define F1_INTR 0x2000 -#define F2_INTR 0x4000 -#define F3_INTR 0x8000 - -/* Bit mask for 32bit SPID_STATUS_REG device register */ -#define STATUS_DATA_NOT_AVAILABLE 0x00000001 -#define STATUS_UNDERFLOW 0x00000002 -#define STATUS_OVERFLOW 0x00000004 -#define STATUS_F2_INTR 0x00000008 -#define STATUS_F3_INTR 0x00000010 -#define STATUS_F2_RX_READY 0x00000020 -#define STATUS_F3_RX_READY 0x00000040 -#define STATUS_HOST_CMD_DATA_ERR 0x00000080 -#define STATUS_F2_PKT_AVAILABLE 0x00000100 -#define STATUS_F2_PKT_LEN_MASK 0x000FFE00 -#define STATUS_F2_PKT_LEN_SHIFT 9 -#define STATUS_F3_PKT_AVAILABLE 0x00100000 -#define STATUS_F3_PKT_LEN_MASK 0xFFE00000 -#define STATUS_F3_PKT_LEN_SHIFT 21 - -/* Bit mask for 16 bits SPID_F1_INFO_REG device register */ -#define F1_ENABLED 0x0001 -#define F1_RDY_FOR_DATA_TRANSFER 0x0002 -#define F1_MAX_PKT_SIZE 0x01FC - -/* Bit mask for 16 bits SPID_F2_INFO_REG device register */ -#define F2_ENABLED 0x0001 -#define F2_RDY_FOR_DATA_TRANSFER 0x0002 -#define F2_MAX_PKT_SIZE 0x3FFC - -/* Bit mask for 16 bits SPID_F3_INFO_REG device register */ -#define F3_ENABLED 0x0001 -#define F3_RDY_FOR_DATA_TRANSFER 0x0002 -#define F3_MAX_PKT_SIZE 0x3FFC - -/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */ -#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD - -/* Maximum number of I/O funcs */ -#define SPI_MAX_IOFUNCS 4 - -#define SPI_MAX_PKT_LEN (2048*4) - -/* Misc defines */ -#define SPI_FUNC_0 0 -#define SPI_FUNC_1 1 -#define SPI_FUNC_2 2 -#define SPI_FUNC_3 3 - -#define WAIT_F2RXFIFORDY 100 -#define WAIT_F2RXFIFORDY_DELAY 20 - -#endif /* _SPI_H */ diff --git a/drivers/net/wireless/bcm4329/include/trxhdr.h b/drivers/net/wireless/bcm4329/include/trxhdr.h deleted file mode 100644 index 8f5eed9410eb..000000000000 --- a/drivers/net/wireless/bcm4329/include/trxhdr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * TRX image file header format. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: trxhdr.h,v 13.11.310.1 2008/08/17 12:58:58 Exp $ - */ - -#include - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 /* Version 1 */ -#define TRX_MAX_LEN 0x3A0000 /* Max length */ -#define TRX_NO_HEADER 1 /* Do not write TRX header */ -#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ - -struct trx_header { - uint32 magic; /* "HDR0" */ - uint32 len; /* Length of file including header */ - uint32 crc32; /* 32-bit CRC from flag_version to end of file */ - uint32 flag_version; /* 0:15 flags, 16:31 version */ - uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -}; - -/* Compatibility */ -typedef struct trx_header TRXHDR, *PTRXHDR; diff --git a/drivers/net/wireless/bcm4329/include/typedefs.h b/drivers/net/wireless/bcm4329/include/typedefs.h deleted file mode 100644 index 4d9dd761ed64..000000000000 --- a/drivers/net/wireless/bcm4329/include/typedefs.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: typedefs.h,v 1.85.34.1.2.5 2009/01/27 04:09:40 Exp $ - */ - - -#ifndef _TYPEDEFS_H_ -#define _TYPEDEFS_H_ - -#ifdef SITE_TYPEDEFS - - - -#include "site_typedefs.h" - -#else - - - -#ifdef __cplusplus - -#define TYPEDEF_BOOL -#ifndef FALSE -#define FALSE false -#endif -#ifndef TRUE -#define TRUE true -#endif - -#else - - -#endif - -#if defined(__x86_64__) -#define TYPEDEF_UINTPTR -typedef unsigned long long int uintptr; -#endif - - - - -#if defined(TARGETOS_nucleus) - -#include - - -#define TYPEDEF_FLOAT_T -#endif - -#if defined(_NEED_SIZE_T_) -typedef long unsigned int size_t; -#endif - -#ifdef __DJGPP__ -typedef long unsigned int size_t; -#endif - - - - - -#define TYPEDEF_UINT -#ifndef TARGETENV_android -#define TYPEDEF_USHORT -#define TYPEDEF_ULONG -#endif -#ifdef __KERNEL__ -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -#define TYPEDEF_BOOL -#endif -#endif - - - - - -#if defined(__GNUC__) && defined(__STRICT_ANSI__) -#define TYPEDEF_INT64 -#define TYPEDEF_UINT64 -#endif - - -#if defined(__ICL) - -#define TYPEDEF_INT64 - -#if defined(__STDC__) -#define TYPEDEF_UINT64 -#endif - -#endif - -#if !defined(__DJGPP__) && !defined(TARGETOS_nucleus) - - -#if defined(__KERNEL__) - -#include - -#else - - -#include - -#endif - -#endif - - - - -#define USE_TYPEDEF_DEFAULTS - -#endif - - - - -#ifdef USE_TYPEDEF_DEFAULTS -#undef USE_TYPEDEF_DEFAULTS - -#ifndef TYPEDEF_BOOL -typedef unsigned char bool; -#endif - - - -#ifndef TYPEDEF_UCHAR -typedef unsigned char uchar; -#endif - -#ifndef TYPEDEF_USHORT -typedef unsigned short ushort; -#endif - -#ifndef TYPEDEF_UINT -typedef unsigned int uint; -#endif - -#ifndef TYPEDEF_ULONG -typedef unsigned long ulong; -#endif - - - -#ifndef TYPEDEF_UINT8 -typedef unsigned char uint8; -#endif - -#ifndef TYPEDEF_UINT16 -typedef unsigned short uint16; -#endif - -#ifndef TYPEDEF_UINT32 -typedef unsigned int uint32; -#endif - -#ifndef TYPEDEF_UINT64 -typedef unsigned long long uint64; -#endif - -#ifndef TYPEDEF_UINTPTR -typedef unsigned int uintptr; -#endif - -#ifndef TYPEDEF_INT8 -typedef signed char int8; -#endif - -#ifndef TYPEDEF_INT16 -typedef signed short int16; -#endif - -#ifndef TYPEDEF_INT32 -typedef signed int int32; -#endif - -#ifndef TYPEDEF_INT64 -typedef signed long long int64; -#endif - - - -#ifndef TYPEDEF_FLOAT32 -typedef float float32; -#endif - -#ifndef TYPEDEF_FLOAT64 -typedef double float64; -#endif - - - -#ifndef TYPEDEF_FLOAT_T - -#if defined(FLOAT32) -typedef float32 float_t; -#else -typedef float64 float_t; -#endif - -#endif - - - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef OFF -#define OFF 0 -#endif - -#ifndef ON -#define ON 1 -#endif - -#define AUTO (-1) - - - -#ifndef PTRSZ -#define PTRSZ sizeof(char*) -#endif - - - -#if defined(__GNUC__) - #define BWL_COMPILER_GNU -#elif defined(__CC_ARM) - #define BWL_COMPILER_ARMCC -#else - #error "Unknown compiler!" -#endif - - -#ifndef INLINE - #if defined(BWL_COMPILER_MICROSOFT) - #define INLINE __inline - #elif defined(BWL_COMPILER_GNU) - #define INLINE __inline__ - #elif defined(BWL_COMPILER_ARMCC) - #define INLINE __inline - #else - #define INLINE - #endif -#endif - -#undef TYPEDEF_BOOL -#undef TYPEDEF_UCHAR -#undef TYPEDEF_USHORT -#undef TYPEDEF_UINT -#undef TYPEDEF_ULONG -#undef TYPEDEF_UINT8 -#undef TYPEDEF_UINT16 -#undef TYPEDEF_UINT32 -#undef TYPEDEF_UINT64 -#undef TYPEDEF_UINTPTR -#undef TYPEDEF_INT8 -#undef TYPEDEF_INT16 -#undef TYPEDEF_INT32 -#undef TYPEDEF_INT64 -#undef TYPEDEF_FLOAT32 -#undef TYPEDEF_FLOAT64 -#undef TYPEDEF_FLOAT_T - -#endif - - -#define UNUSED_PARAMETER(x) (void)(x) - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/include/wlioctl.h b/drivers/net/wireless/bcm4329/include/wlioctl.h deleted file mode 100644 index 00c61f10782f..000000000000 --- a/drivers/net/wireless/bcm4329/include/wlioctl.h +++ /dev/null @@ -1,1673 +0,0 @@ -/* - * Custom OID/ioctl definitions for - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.3 2011/02/09 23:31:02 Exp $ - */ - - -#ifndef _wlioctl_h_ -#define _wlioctl_h_ - -#include -#include -#include -#include -#include -#include - - - -#define ACTION_FRAME_SIZE 1040 - -typedef struct wl_action_frame { - struct ether_addr da; - uint16 len; - uint32 packetId; - uint8 data[ACTION_FRAME_SIZE]; -} wl_action_frame_t; - -#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) - - -#define BWL_DEFAULT_PACKING -#include - -#define RWL_ACTION_WIFI_CATEGORY 127 -#define RWL_WIFI_OUI_BYTE1 0x90 -#define RWL_WIFI_OUI_BYTE2 0x4C -#define RWL_WIFI_OUI_BYTE3 0x0F -#define RWL_WIFI_ACTION_FRAME_SIZE sizeof(struct dot11_action_wifi_vendor_specific) -#define RWL_WIFI_DEFAULT 0x00 -#define RWL_WIFI_FIND_MY_PEER 0x09 -#define RWL_WIFI_FOUND_PEER 0x0A -#define RWL_ACTION_WIFI_FRAG_TYPE 0x55 - -typedef struct ssid_info -{ - uint8 ssid_len; - uint8 ssid[32]; -} ssid_info_t; - -typedef struct cnt_rx -{ - uint32 cnt_rxundec; - uint32 cnt_rxframe; -} cnt_rx_t; - - - -#define RWL_REF_MAC_ADDRESS_OFFSET 17 -#define RWL_DUT_MAC_ADDRESS_OFFSET 23 -#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50 -#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51 - - - - - -#define WL_BSS_INFO_VERSION 108 - - -typedef struct wl_bss_info { - uint32 version; - uint32 length; - struct ether_addr BSSID; - uint16 beacon_period; - uint16 capability; - uint8 SSID_len; - uint8 SSID[32]; - struct { - uint count; - uint8 rates[16]; - } rateset; - chanspec_t chanspec; - uint16 atim_window; - uint8 dtim_period; - int16 RSSI; - int8 phy_noise; - - uint8 n_cap; - uint32 nbss_cap; - uint8 ctl_ch; - uint32 reserved32[1]; - uint8 flags; - uint8 reserved[3]; - uint8 basic_mcs[MCSSET_LEN]; - - uint16 ie_offset; - uint32 ie_length; - - -} wl_bss_info_t; - -typedef struct wlc_ssid { - uint32 SSID_len; - uchar SSID[32]; -} wlc_ssid_t; - - -#define WL_BSSTYPE_INFRA 1 -#define WL_BSSTYPE_INDEP 0 -#define WL_BSSTYPE_ANY 2 - - -#define WL_SCANFLAGS_PASSIVE 0x01 -#define WL_SCANFLAGS_PROHIBITED 0x04 - -typedef struct wl_scan_params { - wlc_ssid_t ssid; - struct ether_addr bssid; - int8 bss_type; - int8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; - int32 channel_num; - uint16 channel_list[1]; -} wl_scan_params_t; - -#define WL_SCAN_PARAMS_FIXED_SIZE 64 - - -#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -#define WL_SCAN_PARAMS_NSSID_SHIFT 16 - -#define WL_SCAN_ACTION_START 1 -#define WL_SCAN_ACTION_CONTINUE 2 -#define WL_SCAN_ACTION_ABORT 3 - -#define ISCAN_REQ_VERSION 1 - - -typedef struct wl_iscan_params { - uint32 version; - uint16 action; - uint16 scan_duration; - wl_scan_params_t params; -} wl_iscan_params_t; - -#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_scan_results { - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_scan_results_t; - -#define WL_SCAN_RESULTS_FIXED_SIZE 12 - - -#define WL_SCAN_RESULTS_SUCCESS 0 -#define WL_SCAN_RESULTS_PARTIAL 1 -#define WL_SCAN_RESULTS_PENDING 2 -#define WL_SCAN_RESULTS_ABORTED 3 -#define WL_SCAN_RESULTS_NO_MEM 4 - -#define ESCAN_REQ_VERSION 1 - -typedef struct wl_escan_params { - uint32 version; - uint16 action; - uint16 sync_id; - wl_scan_params_t params; -} wl_escan_params_t; - -#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_escan_result { - uint32 buflen; - uint32 version; - uint16 sync_id; - uint16 bss_count; - wl_bss_info_t bss_info[1]; -} wl_escan_result_t; - -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) - - -typedef struct wl_iscan_results { - uint32 status; - wl_scan_results_t results; -} wl_iscan_results_t; - -#define WL_ISCAN_RESULTS_FIXED_SIZE \ - (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) - -#define WL_NUMRATES 16 -typedef struct wl_rateset { - uint32 count; - uint8 rates[WL_NUMRATES]; -} wl_rateset_t; - - -typedef struct wl_uint32_list { - - uint32 count; - - uint32 element[1]; -} wl_uint32_list_t; - - -typedef struct wl_assoc_params { - struct ether_addr bssid; - uint16 bssid_cnt; - int32 chanspec_num; - chanspec_t chanspec_list[1]; -} wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t)) - - -typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - - -typedef struct wl_join_params { - wlc_ssid_t ssid; - wl_assoc_params_t params; -} wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) - -#define WLC_CNTRY_BUF_SZ 4 - -typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - int32 rev; - char ccode[WLC_CNTRY_BUF_SZ]; -} wl_country_t; - -typedef enum sup_auth_status { - - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT, - WLC_SUP_LAST_BASIC_STATE, - - - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 -} sup_auth_status_t; - - -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 -#define CRYPTO_ALGO_SMS4 11 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 - -#define WL_SOFT_KEY (1 << 0) -#define WL_PRIMARY_KEY (1 << 1) -#define WL_KF_RES_4 (1 << 4) -#define WL_KF_RES_5 (1 << 5) -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) - -typedef struct wl_wsec_key { - uint32 index; - uint32 len; - uint8 data[DOT11_MAX_KEY_SIZE]; - uint32 pad_1[18]; - uint32 algo; - uint32 flags; - uint32 pad_2[2]; - int pad_3; - int iv_initialized; - int pad_4; - - struct { - uint32 hi; - uint16 lo; - } rxiv; - uint32 pad_5[2]; - struct ether_addr ea; -} wl_wsec_key_t; - -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - - -#define WSEC_PASSPHRASE (1<<0) - - -typedef struct { - ushort key_len; - ushort flags; - uint8 key[WSEC_MAX_PSK_LEN]; -} wsec_pmk_t; - - -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 -#define SMS4_ENABLED 0x0100 - - -#define WPA_AUTH_DISABLED 0x0000 -#define WPA_AUTH_NONE 0x0001 -#define WPA_AUTH_UNSPECIFIED 0x0002 -#define WPA_AUTH_PSK 0x0004 - -#define WPA2_AUTH_UNSPECIFIED 0x0040 -#define WPA2_AUTH_PSK 0x0080 -#define BRCM_AUTH_PSK 0x0100 -#define BRCM_AUTH_DPT 0x0200 -#define WPA_AUTH_WAPI 0x0400 - -#define WPA_AUTH_PFN_ANY 0xffffffff - - -#define MAXPMKID 16 - -typedef struct _pmkid { - struct ether_addr BSSID; - uint8 PMKID[WPA2_PMKID_LEN]; -} pmkid_t; - -typedef struct _pmkid_list { - uint32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; - -typedef struct _pmkid_cand { - struct ether_addr BSSID; - uint8 preauth; -} pmkid_cand_t; - -typedef struct _pmkid_cand_list { - uint32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; - - - - -typedef struct { - uint32 val; - struct ether_addr ea; -} scb_val_t; - - - -typedef struct channel_info { - int hw_channel; - int target_channel; - int scan_channel; -} channel_info_t; - - -struct maclist { - uint count; - struct ether_addr ea[1]; -}; - - -typedef struct get_pktcnt { - uint rx_good_pkt; - uint rx_bad_pkt; - uint tx_good_pkt; - uint tx_bad_pkt; - uint rx_ocast_good_pkt; -} get_pktcnt_t; - - -typedef struct wl_ioctl { - uint cmd; - void *buf; - uint len; - uint8 set; - uint used; - uint needed; -} wl_ioctl_t; - - - -#define WLC_IOCTL_MAGIC 0x14e46c77 - - -#define WLC_IOCTL_VERSION 1 - -#define WLC_IOCTL_MAXLEN 8192 -#define WLC_IOCTL_SMLEN 256 -#define WLC_IOCTL_MEDLEN 1536 - - - -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_GET_LOOP 4 -#define WLC_SET_LOOP 5 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 - -#define WLC_GET_RATE 12 - -#define WLC_GET_INSTANCE 14 - - - - -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 - -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -#define WLC_DUMP_RATE 40 -#define WLC_SET_RATE_PARAMS 41 - - -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE_SCAN 48 -#define WLC_SET_PASSIVE_SCAN 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_ROAM_DELTA 56 -#define WLC_SET_ROAM_DELTA 57 -#define WLC_GET_ROAM_SCAN_PERIOD 58 -#define WLC_SET_ROAM_SCAN_PERIOD 59 -#define WLC_EVM 60 -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 - - -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 - -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 - -#define WLC_GET_FORCELINK 90 -#define WLC_SET_FORCELINK 91 -#define WLC_FREQ_ACCURACY 92 -#define WLC_CARRIER_SUPPRESS 93 -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 - - -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 - - -#define WLC_GET_IGNORE_BCNS 155 -#define WLC_SET_IGNORE_BCNS 156 -#define WLC_GET_SCB_TIMEOUT 157 -#define WLC_SET_SCB_TIMEOUT 158 -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_UCFLAGS 166 -#define WLC_SET_UCFLAGS 167 -#define WLC_GET_PWRIDX 168 -#define WLC_SET_PWRIDX 169 -#define WLC_GET_TSSI 170 -#define WLC_GET_SUP_RATESET_OVERRIDE 171 -#define WLC_SET_SUP_RATESET_OVERRIDE 172 - - - - - -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_ENCRYPT_STRENGTH 181 -#define WLC_DECRYPT_STATUS 182 -#define WLC_GET_KEY_SEQ 183 -#define WLC_GET_SCAN_CHANNEL_TIME 184 -#define WLC_SET_SCAN_CHANNEL_TIME 185 -#define WLC_GET_SCAN_UNASSOC_TIME 186 -#define WLC_SET_SCAN_UNASSOC_TIME 187 -#define WLC_GET_SCAN_HOME_TIME 188 -#define WLC_SET_SCAN_HOME_TIME 189 -#define WLC_GET_SCAN_NPROBES 190 -#define WLC_SET_SCAN_NPROBES 191 -#define WLC_GET_PRB_RESP_TIMEOUT 192 -#define WLC_SET_PRB_RESP_TIMEOUT 193 -#define WLC_GET_ATTEN 194 -#define WLC_SET_ATTEN 195 -#define WLC_GET_SHMEM 196 -#define WLC_SET_SHMEM 197 - - -#define WLC_SET_WSEC_TEST 200 -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define WLC_TKIP_COUNTERMEASURES 202 -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_ASSOC_PREFER 205 -#define WLC_GET_ASSOC_PREFER 206 -#define WLC_SET_ROAM_PREFER 207 -#define WLC_GET_ROAM_PREFER 208 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_GET_INTERFERENCE_MODE 211 -#define WLC_SET_INTERFERENCE_MODE 212 -#define WLC_GET_CHANNEL_QA 213 -#define WLC_START_CHANNEL_QA 214 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_PWROUT_PERCENTAGE 220 -#define WLC_SET_PWROUT_PERCENTAGE 221 -#define WLC_SET_BAD_FRAME_PREEMPT 222 -#define WLC_GET_BAD_FRAME_PREEMPT 223 -#define WLC_SET_LEAP_LIST 224 -#define WLC_GET_LEAP_LIST 225 -#define WLC_GET_CWMIN 226 -#define WLC_SET_CWMIN 227 -#define WLC_GET_CWMAX 228 -#define WLC_SET_CWMAX 229 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_PUB 232 - - -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 - -#define WLC_GET_ACI_ARGS 238 -#define WLC_SET_ACI_ARGS 239 -#define WLC_UNSET_CALLBACK 240 -#define WLC_SET_CALLBACK 241 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 -#define WLC_WDS_GET_WPA_SUP 247 -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_MEASURE_REQUEST 250 -#define WLC_INIT 251 -#define WLC_SEND_QUIET 252 -#define WLC_KEEPALIVE 253 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_UPGRADE_STATUS 255 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_SCAN_PASSIVE_TIME 257 -#define WLC_SET_SCAN_PASSIVE_TIME 258 -#define WLC_LEGACY_LINK_BEHAVIOR 259 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 -#define WLC_SET_VAR 263 -#define WLC_NVRAM_GET 264 -#define WLC_NVRAM_SET 265 -#define WLC_NVRAM_DUMP 266 -#define WLC_REBOOT 267 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_GET_WAKEENTRY 271 -#define WLC_SET_WAKEENTRY 272 -#define WLC_NDCONFIG_ITEM 273 -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_IOV_BLOCK_GET 276 -#define WLC_IOV_MODULES_GET 277 -#define WLC_SOFT_RESET 278 -#define WLC_GET_ALLOW_MODE 279 -#define WLC_SET_ALLOW_MODE 280 -#define WLC_GET_DESIRED_BSSID 281 -#define WLC_SET_DESIRED_BSSID 282 -#define WLC_DISASSOC_MYAP 283 -#define WLC_GET_NBANDS 284 -#define WLC_GET_BANDSTATES 285 -#define WLC_GET_WLC_BSS_INFO 286 -#define WLC_GET_ASSOC_INFO 287 -#define WLC_GET_OID_PHY 288 -#define WLC_SET_OID_PHY 289 -#define WLC_SET_ASSOC_TIME 290 -#define WLC_GET_DESIRED_SSID 291 -#define WLC_GET_CHANSPEC 292 -#define WLC_GET_ASSOC_STATE 293 -#define WLC_SET_PHY_STATE 294 -#define WLC_GET_SCAN_PENDING 295 -#define WLC_GET_SCANREQ_PENDING 296 -#define WLC_GET_PREV_ROAM_REASON 297 -#define WLC_SET_PREV_ROAM_REASON 298 -#define WLC_GET_BANDSTATES_PI 299 -#define WLC_GET_PHY_STATE 300 -#define WLC_GET_BSS_WPA_RSN 301 -#define WLC_GET_BSS_WPA2_RSN 302 -#define WLC_GET_BSS_BCN_TS 303 -#define WLC_GET_INT_DISASSOC 304 -#define WLC_SET_NUM_PEERS 305 -#define WLC_GET_NUM_BSS 306 -#define WLC_LAST 307 - - - -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) - - -#define WL_TXPWR_OVERRIDE (1U<<31) - -#define WL_PHY_PAVARS_LEN 6 - - -#define WL_DIAG_INTERRUPT 1 -#define WL_DIAG_LOOPBACK 2 -#define WL_DIAG_MEMORY 3 -#define WL_DIAG_LED 4 -#define WL_DIAG_REG 5 -#define WL_DIAG_SROM 6 -#define WL_DIAG_DMA 7 - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 -#define WL_DIAGERR_NOT_SUPPORTED 2 -#define WL_DIAGERR_INTERRUPT_FAIL 3 -#define WL_DIAGERR_LOOPBACK_FAIL 4 -#define WL_DIAGERR_SROM_FAIL 5 -#define WL_DIAGERR_SROM_BADCRC 6 -#define WL_DIAGERR_REG_FAIL 7 -#define WL_DIAGERR_MEMORY_FAIL 8 -#define WL_DIAGERR_NOMEM 9 -#define WL_DIAGERR_DMA_FAIL 10 - -#define WL_DIAGERR_MEMORY_TIMEOUT 11 -#define WL_DIAGERR_MEMORY_BADPATTERN 12 - - -#define WLC_BAND_AUTO 0 -#define WLC_BAND_5G 1 -#define WLC_BAND_2G 2 -#define WLC_BAND_ALL 3 - - -#define WL_CHAN_FREQ_RANGE_2G 0 -#define WL_CHAN_FREQ_RANGE_5GL 1 -#define WL_CHAN_FREQ_RANGE_5GM 2 -#define WL_CHAN_FREQ_RANGE_5GH 3 - - -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_NULL 0xf - - -#define WLC_MACMODE_DISABLED 0 -#define WLC_MACMODE_DENY 1 -#define WLC_MACMODE_ALLOW 2 - - -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - - -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - - -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 -#define WLC_PROTECTION_MMHDR_ONLY 2 -#define WLC_PROTECTION_CTS_ONLY 3 - - -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - - -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_OPTIONAL 1 -#define WLC_N_PROTECTION_20IN40 2 -#define WLC_N_PROTECTION_MIXEDMODE 3 - - -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 - - -#define WLC_N_BW_20ALL 0 -#define WLC_N_BW_40ALL 1 -#define WLC_N_BW_20IN2G_40IN5G 2 - - -#define WLC_N_TXRX_CHAIN0 0 -#define WLC_N_TXRX_CHAIN1 1 - - -#define WLC_N_SGI_20 0x01 -#define WLC_N_SGI_40 0x02 - - -#define PM_OFF 0 -#define PM_MAX 1 -#define PM_FAST 2 - -#define LISTEN_INTERVAL 10 - -#define INTERFERE_NONE 0 -#define NON_WLAN 1 -#define WLAN_MANUAL 2 -#define WLAN_AUTO 3 -#define AUTO_ACTIVE (1 << 7) - -typedef struct wl_aci_args { - int enter_aci_thresh; - int exit_aci_thresh; - int usec_spin; - int glitch_delay; - uint16 nphy_adcpwr_enter_thresh; - uint16 nphy_adcpwr_exit_thresh; - uint16 nphy_repeat_ctr; - uint16 nphy_num_samples; - uint16 nphy_undetect_window_sz; - uint16 nphy_b_energy_lo_aci; - uint16 nphy_b_energy_md_aci; - uint16 nphy_b_energy_hi_aci; -} wl_aci_args_t; - -#define WL_ACI_ARGS_LEGACY_LENGTH 16 - - - -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 -#define WL_PRHDRS_VAL 0x00000004 -#define WL_PRPKT_VAL 0x00000008 -#define WL_INFORM_VAL 0x00000010 -#define WL_TMP_VAL 0x00000020 -#define WL_OID_VAL 0x00000040 -#define WL_RATE_VAL 0x00000080 -#define WL_ASSOC_VAL 0x00000100 -#define WL_PRUSR_VAL 0x00000200 -#define WL_PS_VAL 0x00000400 -#define WL_TXPWR_VAL 0x00000800 -#define WL_PORT_VAL 0x00001000 -#define WL_DUAL_VAL 0x00002000 -#define WL_WSEC_VAL 0x00004000 -#define WL_WSEC_DUMP_VAL 0x00008000 -#define WL_LOG_VAL 0x00010000 -#define WL_NRSSI_VAL 0x00020000 -#define WL_LOFT_VAL 0x00040000 -#define WL_REGULATORY_VAL 0x00080000 -#define WL_PHYCAL_VAL 0x00100000 -#define WL_RADAR_VAL 0x00200000 -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_MBSS_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 - - -#define WL_DPT_VAL 0x00000001 -#define WL_SCAN_VAL 0x00000002 -#define WL_WOWL_VAL 0x00000004 -#define WL_COEX_VAL 0x00000008 -#define WL_RTDC_VAL 0x00000010 -#define WL_BTA_VAL 0x00000040 - - -#define WL_LED_NUMGPIO 16 - - -#define WL_LED_OFF 0 -#define WL_LED_ON 1 -#define WL_LED_ACTIVITY 2 -#define WL_LED_RADIO 3 -#define WL_LED_ARADIO 4 -#define WL_LED_BRADIO 5 -#define WL_LED_BGMODE 6 -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 -#define WL_LED_INACTIVE 11 -#define WL_LED_ASSOCACT 12 -#define WL_LED_NUMBEHAVIOR 13 - - -#define WL_LED_BEH_MASK 0x7f -#define WL_LED_AL_MASK 0x80 - - -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 - - -#define WL_WDS_WPA_ROLE_AUTH 0 -#define WL_WDS_WPA_ROLE_SUP 1 -#define WL_WDS_WPA_ROLE_AUTO 255 - - -#define WL_EVENTING_MASK_LEN 16 - - -#define VNDR_IE_CMD_LEN 4 - - -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 -#define VNDR_IE_PRBREQ_FLAG 0x10 -#define VNDR_IE_ASSOCREQ_FLAG 0x20 -#define VNDR_IE_CUSTOM_FLAG 0x100 - -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) - -typedef struct { - uint32 pktflag; - vndr_ie_t vndr_ie_data; -} vndr_ie_info_t; - -typedef struct { - int iecount; - vndr_ie_info_t vndr_ie_list[1]; -} vndr_ie_buf_t; - -typedef struct { - char cmd[VNDR_IE_CMD_LEN]; - vndr_ie_buf_t vndr_ie_buffer; -} vndr_ie_setbuf_t; - - - - -#define WL_JOIN_PREF_RSSI 1 -#define WL_JOIN_PREF_WPA 2 -#define WL_JOIN_PREF_BAND 3 - - -#define WLJP_BAND_ASSOC_PREF 255 - - -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" - -struct tsinfo_arg { - uint8 octets[3]; -}; - - -#define NFIFO 6 - -#define WL_CNT_T_VERSION 5 -#define WL_CNT_EXT_T_VERSION 1 - -typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txerror; - uint32 txctl; - uint32 txprshort; - uint32 txserr; - uint32 txnobuf; - uint32 txnoassoc; - uint32 txrunt; - uint32 txchit; - uint32 txcmiss; - - - uint32 txuflo; - uint32 txphyerr; - uint32 txphycrs; - - - uint32 rxframe; - uint32 rxbyte; - uint32 rxerror; - uint32 rxctl; - uint32 rxnobuf; - uint32 rxnondata; - uint32 rxbadds; - uint32 rxbadcm; - uint32 rxfragerr; - uint32 rxrunt; - uint32 rxgiant; - uint32 rxnoscb; - uint32 rxbadproto; - uint32 rxbadsrcmac; - uint32 rxbadda; - uint32 rxfilter; - - - uint32 rxoflo; - uint32 rxuflo[NFIFO]; - - uint32 d11cnt_txrts_off; - uint32 d11cnt_rxcrc_off; - uint32 d11cnt_txnocts_off; - - - uint32 dmade; - uint32 dmada; - uint32 dmape; - uint32 reset; - uint32 tbtt; - uint32 txdmawar; - uint32 pkt_callback_reg_fail; - - - uint32 txallfrm; - uint32 txrtsfrm; - uint32 txctsfrm; - uint32 txackfrm; - uint32 txdnlfrm; - uint32 txbcnfrm; - uint32 txfunfl[8]; - uint32 txtplunfl; - uint32 txphyerror; - uint32 rxfrmtoolong; - uint32 rxfrmtooshrt; - uint32 rxinvmachdr; - uint32 rxbadfcs; - uint32 rxbadplcp; - uint32 rxcrsglitch; - uint32 rxstrt; - uint32 rxdfrmucastmbss; - uint32 rxmfrmucastmbss; - uint32 rxcfrmucast; - uint32 rxrtsucast; - uint32 rxctsucast; - uint32 rxackucast; - uint32 rxdfrmocast; - uint32 rxmfrmocast; - uint32 rxcfrmocast; - uint32 rxrtsocast; - uint32 rxctsocast; - uint32 rxdfrmmcast; - uint32 rxmfrmmcast; - uint32 rxcfrmmcast; - uint32 rxbeaconmbss; - uint32 rxdfrmucastobss; - uint32 rxbeaconobss; - uint32 rxrsptmout; - uint32 bcntxcancl; - uint32 rxf0ovfl; - uint32 rxf1ovfl; - uint32 rxf2ovfl; - uint32 txsfovfl; - uint32 pmqovfl; - uint32 rxcgprqfrm; - uint32 rxcgprsqovfl; - uint32 txcgprsfail; - uint32 txcgprssuc; - uint32 prs_timeout; - uint32 rxnack; - uint32 frmscons; - uint32 txnack; - uint32 txglitch_nack; - uint32 txburst; - - - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; - - - uint32 tkipmicfaill; - uint32 tkipcntrmsr; - uint32 tkipreplay; - uint32 ccmpfmterr; - uint32 ccmpreplay; - uint32 ccmpundec; - uint32 fourwayfail; - uint32 wepundec; - uint32 wepicverr; - uint32 decsuccess; - uint32 tkipicverr; - uint32 wepexcluded; - - uint32 txchanrej; - uint32 psmwds; - uint32 phywatchdog; - - - uint32 prq_entries_handled; - uint32 prq_undirected_entries; - uint32 prq_bad_entries; - uint32 atim_suppress_count; - uint32 bcn_template_not_ready; - uint32 bcn_template_not_ready_done; - uint32 late_tbtt_dpc; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; - - uint32 pktengrxducast; - uint32 pktengrxdmcast; -} wl_cnt_t; - -typedef struct { - uint16 version; - uint16 length; - - uint32 rxampdu_sgi; - uint32 rxampdu_stbc; - uint32 rxmpdu_sgi; - uint32 rxmpdu_stbc; - uint32 rxmcs0_40M; - uint32 rxmcs1_40M; - uint32 rxmcs2_40M; - uint32 rxmcs3_40M; - uint32 rxmcs4_40M; - uint32 rxmcs5_40M; - uint32 rxmcs6_40M; - uint32 rxmcs7_40M; - uint32 rxmcs32_40M; - - uint32 txfrmsnt_20Mlo; - uint32 txfrmsnt_20Mup; - uint32 txfrmsnt_40M; - - uint32 rx_20ul; -} wl_cnt_ext_t; - -#define WL_RXDIV_STATS_T_VERSION 1 -typedef struct { - uint16 version; - uint16 length; - - uint32 rxant[4]; -} wl_rxdiv_stats_t; - -#define WL_DELTA_STATS_T_VERSION 1 - -typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txfail; - - - uint32 rxframe; - uint32 rxbyte; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; -} wl_delta_stats_t; - -#define WL_WME_CNT_VERSION 1 - -typedef struct { - uint32 packets; - uint32 bytes; -} wl_traffic_stats_t; - -typedef struct { - uint16 version; - uint16 length; - - wl_traffic_stats_t tx[AC_COUNT]; - wl_traffic_stats_t tx_failed[AC_COUNT]; - wl_traffic_stats_t rx[AC_COUNT]; - wl_traffic_stats_t rx_failed[AC_COUNT]; - - wl_traffic_stats_t forward[AC_COUNT]; - - wl_traffic_stats_t tx_expired[AC_COUNT]; - -} wl_wme_cnt_t; - - - -#define WLC_ROAM_TRIGGER_DEFAULT 0 -#define WLC_ROAM_TRIGGER_BANDWIDTH 1 -#define WLC_ROAM_TRIGGER_DISTANCE 2 -#define WLC_ROAM_TRIGGER_MAX_VALUE 2 - - -enum { - PFN_LIST_ORDER, - PFN_RSSI -}; - -enum { - DISABLE, - ENABLE -}; - -#define SORT_CRITERIA_BIT 0 -#define AUTO_NET_SWITCH_BIT 1 -#define ENABLE_BKGRD_SCAN_BIT 2 -#define IMMEDIATE_SCAN_BIT 3 -#define AUTO_CONNECT_BIT 4 -#define ENABLE_BD_SCAN_BIT 5 -#define ENABLE_ADAPTSCAN_BIT 6 - -#define SORT_CRITERIA_MASK 0x01 -#define AUTO_NET_SWITCH_MASK 0x02 -#define ENABLE_BKGRD_SCAN_MASK 0x04 -#define IMMEDIATE_SCAN_MASK 0x08 -#define AUTO_CONNECT_MASK 0x10 -#define ENABLE_BD_SCAN_MASK 0x20 -#define ENABLE_ADAPTSCAN_MASK 0x40 - -#define PFN_VERSION 1 - -#define MAX_PFN_LIST_COUNT 16 - - -typedef struct wl_pfn_param { - int32 version; - int32 scan_freq; - int32 lost_network_timeout; - int16 flags; - int16 rssi_margin; - int32 repeat_scan; - int32 max_freq_adjust; -} wl_pfn_param_t; - -typedef struct wl_pfn { - wlc_ssid_t ssid; - int32 bss_type; - int32 infra; - int32 auth; - uint32 wpa_auth; - int32 wsec; -} wl_pfn_t; - -#define PNO_SCAN_MAX_FW 508*1000 -#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 -#define PNO_SCAN_MIN_FW_SEC 10 - - -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 - - -#define TOE_ERRTEST_TX_CSUM 0x00000001 -#define TOE_ERRTEST_RX_CSUM 0x00000002 -#define TOE_ERRTEST_RX_CSUM2 0x00000004 - -struct toe_ol_stats_t { - - uint32 tx_summed; - - - uint32 tx_iph_fill; - uint32 tx_tcp_fill; - uint32 tx_udp_fill; - uint32 tx_icmp_fill; - - - uint32 rx_iph_good; - uint32 rx_iph_bad; - uint32 rx_tcp_good; - uint32 rx_tcp_bad; - uint32 rx_udp_good; - uint32 rx_udp_bad; - uint32 rx_icmp_good; - uint32 rx_icmp_bad; - - - uint32 tx_tcp_errinj; - uint32 tx_udp_errinj; - uint32 tx_icmp_errinj; - - - uint32 rx_tcp_errinj; - uint32 rx_udp_errinj; - uint32 rx_icmp_errinj; -}; - - -#define ARP_OL_AGENT 0x00000001 -#define ARP_OL_SNOOP 0x00000002 -#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -#define ARP_OL_PEER_AUTO_REPLY 0x00000008 - - -#define ARP_ERRTEST_REPLY_PEER 0x1 -#define ARP_ERRTEST_REPLY_HOST 0x2 - -#define ARP_MULTIHOMING_MAX 8 - - -struct arp_ol_stats_t { - uint32 host_ip_entries; - uint32 host_ip_overflow; - - uint32 arp_table_entries; - uint32 arp_table_overflow; - - uint32 host_request; - uint32 host_reply; - uint32 host_service; - - uint32 peer_request; - uint32 peer_request_drop; - uint32 peer_reply; - uint32 peer_reply_drop; - uint32 peer_service; -}; - - - - - -typedef struct wl_keep_alive_pkt { - uint32 period_msec; - uint16 len_bytes; - uint8 data[1]; -} wl_keep_alive_pkt_t; - -#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) - - - - - -typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH -} wl_pkt_filter_type_t; - -#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t - - -typedef struct wl_pkt_filter_pattern { - uint32 offset; - uint32 size_bytes; - uint8 mask_and_pattern[1]; -} wl_pkt_filter_pattern_t; - - -typedef struct wl_pkt_filter { - uint32 id; - uint32 type; - uint32 negate_match; - union { - wl_pkt_filter_pattern_t pattern; - } u; -} wl_pkt_filter_t; - -#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) - - -typedef struct wl_pkt_filter_enable { - uint32 id; - uint32 enable; -} wl_pkt_filter_enable_t; - - -typedef struct wl_pkt_filter_list { - uint32 num; - wl_pkt_filter_t filter[1]; -} wl_pkt_filter_list_t; - -#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) - - -typedef struct wl_pkt_filter_stats { - uint32 num_pkts_matched; - uint32 num_pkts_forwarded; - uint32 num_pkts_discarded; -} wl_pkt_filter_stats_t; - - -typedef struct wl_seq_cmd_ioctl { - uint32 cmd; - uint32 len; -} wl_seq_cmd_ioctl_t; - -#define WL_SEQ_CMD_ALIGN_BYTES 4 - - -#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ - (((cmd) == WLC_GET_MAGIC) || \ - ((cmd) == WLC_GET_VERSION) || \ - ((cmd) == WLC_GET_AP) || \ - ((cmd) == WLC_GET_INSTANCE)) - - - -#define WL_PKTENG_PER_TX_START 0x01 -#define WL_PKTENG_PER_TX_STOP 0x02 -#define WL_PKTENG_PER_RX_START 0x04 -#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -#define WL_PKTENG_PER_RX_STOP 0x08 -#define WL_PKTENG_PER_MASK 0xff - -#define WL_PKTENG_SYNCHRONOUS 0x100 - -typedef struct wl_pkteng { - uint32 flags; - uint32 delay; - uint32 nframes; - uint32 length; - uint8 seqno; - struct ether_addr dest; - struct ether_addr src; -} wl_pkteng_t; - -#define NUM_80211b_RATES 4 -#define NUM_80211ag_RATES 8 -#define NUM_80211n_RATES 32 -#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) -typedef struct wl_pkteng_stats { - uint32 lostfrmcnt; - int32 rssi; - int32 snr; - uint16 rxpktcnt[NUM_80211_RATES+1]; -} wl_pkteng_stats_t; - -#define WL_WOWL_MAGIC (1 << 0) -#define WL_WOWL_NET (1 << 1) -#define WL_WOWL_DIS (1 << 2) -#define WL_WOWL_RETR (1 << 3) -#define WL_WOWL_BCN (1 << 4) -#define WL_WOWL_TST (1 << 5) -#define WL_WOWL_BCAST (1 << 15) - -#define MAGIC_PKT_MINLEN 102 - -typedef struct { - uint masksize; - uint offset; - uint patternoffset; - uint patternsize; - - -} wl_wowl_pattern_t; - -typedef struct { - uint count; - wl_wowl_pattern_t pattern[1]; -} wl_wowl_pattern_list_t; - -typedef struct { - uint8 pci_wakeind; - uint16 ucode_wakeind; -} wl_wowl_wakeind_t; - - -typedef struct wl_txrate_class { - uint8 init_rate; - uint8 min_rate; - uint8 max_rate; -} wl_txrate_class_t; - - - - -#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 100 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 - - -typedef struct wl_obss_scan_arg { - int16 passive_dwell; - int16 active_dwell; - int16 bss_widthscan_interval; - int16 passive_total; - int16 active_total; - int16 chanwidth_transition_delay; - int16 activity_threshold; -} wl_obss_scan_arg_t; -#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -#define WL_MIN_NUM_OBSS_SCAN_ARG 7 - -#define WL_COEX_INFO_MASK 0x07 -#define WL_COEX_INFO_REQ 0x01 -#define WL_COEX_40MHZ_INTOLERANT 0x02 -#define WL_COEX_WIDTH20 0x04 - -typedef struct wl_action_obss_coex_req { - uint8 info; - uint8 num; - uint8 ch_list[1]; -} wl_action_obss_coex_req_t; - - -#define MAX_RSSI_LEVELS 8 - - -typedef struct wl_rssi_event { - - uint32 rate_limit_msec; - - uint8 num_rssi_levels; - - int8 rssi_levels[MAX_RSSI_LEVELS]; -} wl_rssi_event_t; - - - -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - - - -#include - - -#include - - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { - struct ether_addr staAddr; - uint16 ieLen; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { - sta_prbreq_wps_ie_hdr_t hdr; - uint8 ieData[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; - -typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { - uint32 totLen; - uint8 ieDataList[1]; -} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; - - -#include - -#endif diff --git a/drivers/net/wireless/bcm4329/linux_osl.c b/drivers/net/wireless/bcm4329/linux_osl.c deleted file mode 100644 index 3a026eed516e..000000000000 --- a/drivers/net/wireless/bcm4329/linux_osl.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Linux OS Independent Layer - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: linux_osl.c,v 1.125.12.3.8.7 2010/05/04 21:10:04 Exp $ - */ - - -#define LINUX_OSL - -#include -#include -#include -#include -#include -#include -#include -#include - -#define PCI_CFG_RETRY 10 - -#define OS_HANDLE_MAGIC 0x1234abcd -#define BCM_MEM_FILENAME_LEN 24 - -#ifdef DHD_USE_STATIC_BUF -#define MAX_STATIC_BUF_NUM 16 -#define STATIC_BUF_SIZE (PAGE_SIZE*2) -#define STATIC_BUF_TOTAL_LEN (MAX_STATIC_BUF_NUM*STATIC_BUF_SIZE) -typedef struct bcm_static_buf { - struct semaphore static_sem; - unsigned char *buf_ptr; - unsigned char buf_use[MAX_STATIC_BUF_NUM]; -} bcm_static_buf_t; - -static bcm_static_buf_t *bcm_static_buf = 0; - -#define MAX_STATIC_PKT_NUM 8 -typedef struct bcm_static_pkt { - struct sk_buff *skb_4k[MAX_STATIC_PKT_NUM]; - struct sk_buff *skb_8k[MAX_STATIC_PKT_NUM]; - struct semaphore osl_pkt_sem; - unsigned char pkt_use[MAX_STATIC_PKT_NUM*2]; -} bcm_static_pkt_t; -static bcm_static_pkt_t *bcm_static_skb = 0; - -#endif -typedef struct bcm_mem_link { - struct bcm_mem_link *prev; - struct bcm_mem_link *next; - uint size; - int line; - char file[BCM_MEM_FILENAME_LEN]; -} bcm_mem_link_t; - -struct osl_info { - osl_pubinfo_t pub; - uint magic; - void *pdev; - uint malloced; - uint failed; - uint bustype; - bcm_mem_link_t *dbgmem_list; -}; - -static int16 linuxbcmerrormap[] = -{ 0, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -E2BIG, - -E2BIG, - -EBUSY, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EFAULT, - -ENOMEM, - -EOPNOTSUPP, - -EMSGSIZE, - -EINVAL, - -EPERM, - -ENOMEM, - -EINVAL, - -ERANGE, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EINVAL, - -EIO, - -ENODEV, - -EINVAL, - -EIO, - -EIO, - -EINVAL, - -EINVAL, - - - -#if BCME_LAST != -41 -#error "You need to add a OS error translation in the linuxbcmerrormap \ - for new error code defined in bcmutils.h" -#endif -}; - - -int -osl_error(int bcmerror) -{ - if (bcmerror > 0) - bcmerror = 0; - else if (bcmerror < BCME_LAST) - bcmerror = BCME_ERROR; - - - return linuxbcmerrormap[-bcmerror]; -} - -void * dhd_os_prealloc(int section, unsigned long size); -osl_t * -osl_attach(void *pdev, uint bustype, bool pkttag) -{ - osl_t *osh; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh = kmalloc(sizeof(osl_t), flags); - ASSERT(osh); - - bzero(osh, sizeof(osl_t)); - - - ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); - - osh->magic = OS_HANDLE_MAGIC; - osh->malloced = 0; - osh->failed = 0; - osh->dbgmem_list = NULL; - osh->pdev = pdev; - osh->pub.pkttag = pkttag; - osh->bustype = bustype; - - switch (bustype) { - case PCI_BUS: - case SI_BUS: - case PCMCIA_BUS: - osh->pub.mmbus = TRUE; - break; - case JTAG_BUS: - case SDIO_BUS: - case USB_BUS: - case SPI_BUS: - osh->pub.mmbus = FALSE; - break; - default: - ASSERT(FALSE); - break; - } - -#ifdef DHD_USE_STATIC_BUF - - - if (!bcm_static_buf) { - if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(3, STATIC_BUF_SIZE+ - STATIC_BUF_TOTAL_LEN))) { - printk("can not alloc static buf!\n"); - } - else { - /* printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); */ - } - - init_MUTEX(&bcm_static_buf->static_sem); - - - bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; - - } - - if (!bcm_static_skb) - { - int i; - void *skb_buff_ptr = 0; - bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); - skb_buff_ptr = dhd_os_prealloc(4, 0); - - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); - for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) - bcm_static_skb->pkt_use[i] = 0; - - init_MUTEX(&bcm_static_skb->osl_pkt_sem); - } -#endif - return osh; -} - -void -osl_detach(osl_t *osh) -{ - if (osh == NULL) - return; - -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) { - bcm_static_buf = 0; - } - if (bcm_static_skb) { - bcm_static_skb = 0; - } -#endif - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); -} - - -void* -osl_pktget(osl_t *osh, uint len) -{ - struct sk_buff *skb; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((skb = __dev_alloc_skb(len, flags))) { - skb_put(skb, len); - skb->priority = 0; - - - osh->pub.pktalloced++; - } - - return ((void*) skb); -} - - -void -osl_pktfree(osl_t *osh, void *p, bool send) -{ - struct sk_buff *skb, *nskb; - - skb = (struct sk_buff*) p; - - if (send && osh->pub.tx_fn) - osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); - - - while (skb) { - nskb = skb->next; - skb->next = NULL; - - - if (skb->destructor) { - - dev_kfree_skb_any(skb); - } else { - - dev_kfree_skb(skb); - } - - osh->pub.pktalloced--; - - skb = nskb; - } -} - -#ifdef DHD_USE_STATIC_BUF -void* -osl_pktget_static(osl_t *osh, uint len) -{ - int i = 0; - struct sk_buff *skb; - - - if (len > (PAGE_SIZE*2)) - { - printk("Do we really need this big skb??\n"); - return osl_pktget(osh, len); - } - - - down(&bcm_static_skb->osl_pkt_sem); - if (len <= PAGE_SIZE) - { - - for (i = 0; i < MAX_STATIC_PKT_NUM; i++) - { - if (bcm_static_skb->pkt_use[i] == 0) - break; - } - - if (i != MAX_STATIC_PKT_NUM) - { - bcm_static_skb->pkt_use[i] = 1; - up(&bcm_static_skb->osl_pkt_sem); - - skb = bcm_static_skb->skb_4k[i]; - skb->tail = skb->data + len; - skb->len = len; - - return skb; - } - } - - - for (i = 0; i < MAX_STATIC_PKT_NUM; i++) - { - if (bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] == 0) - break; - } - - if (i != MAX_STATIC_PKT_NUM) - { - bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] = 1; - up(&bcm_static_skb->osl_pkt_sem); - skb = bcm_static_skb->skb_8k[i]; - skb->tail = skb->data + len; - skb->len = len; - - return skb; - } - - - - up(&bcm_static_skb->osl_pkt_sem); - printk("all static pkt in use!\n"); - return osl_pktget(osh, len); -} - - -void -osl_pktfree_static(osl_t *osh, void *p, bool send) -{ - int i; - - for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) - { - if (p == bcm_static_skb->skb_4k[i]) - { - down(&bcm_static_skb->osl_pkt_sem); - bcm_static_skb->pkt_use[i] = 0; - up(&bcm_static_skb->osl_pkt_sem); - - - return; - } - } - return osl_pktfree(osh, p, send); -} -#endif -uint32 -osl_pci_read_config(osl_t *osh, uint offset, uint size) -{ - uint val = 0; - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_read_config_dword(osh->pdev, offset, &val); - if (val != 0xffffffff) - break; - } while (retry--); - - - return (val); -} - -void -osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) -{ - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - - ASSERT(size == 4); - - do { - pci_write_config_dword(osh->pdev, offset, val); - if (offset != PCI_BAR0_WIN) - break; - if (osl_pci_read_config(osh, offset, size) == val) - break; - } while (retry--); - -} - - -uint -osl_pci_bus(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return ((struct pci_dev *)osh->pdev)->bus->number; -} - - -uint -osl_pci_slot(osl_t *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -} - -static void -osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -{ -} - -void -osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -} - -void -osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -{ - osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -} - - - -void* -osl_malloc(osl_t *osh, uint size) -{ - void *addr; - gfp_t flags; - - if (osh) - ASSERT(osh->magic == OS_HANDLE_MAGIC); - -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) - { - int i = 0; - if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) - { - down(&bcm_static_buf->static_sem); - - for (i = 0; i < MAX_STATIC_BUF_NUM; i++) - { - if (bcm_static_buf->buf_use[i] == 0) - break; - } - - if (i == MAX_STATIC_BUF_NUM) - { - up(&bcm_static_buf->static_sem); - printk("all static buff in use!\n"); - goto original; - } - - bcm_static_buf->buf_use[i] = 1; - up(&bcm_static_buf->static_sem); - - bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); - if (osh) - osh->malloced += size; - - return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); - } - } -original: -#endif - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((addr = kmalloc(size, flags)) == NULL) { - if (osh) - osh->failed++; - return (NULL); - } - if (osh) - osh->malloced += size; - - return (addr); -} - -void -osl_mfree(osl_t *osh, void *addr, uint size) -{ -#ifdef DHD_USE_STATIC_BUF - if (bcm_static_buf) - { - if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr - <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) - { - int buf_idx = 0; - - buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; - - down(&bcm_static_buf->static_sem); - bcm_static_buf->buf_use[buf_idx] = 0; - up(&bcm_static_buf->static_sem); - - if (osh) { - ASSERT(osh->magic == OS_HANDLE_MAGIC); - osh->malloced -= size; - } - return; - } - } -#endif - if (osh) { - ASSERT(osh->magic == OS_HANDLE_MAGIC); - osh->malloced -= size; - } - kfree(addr); -} - -uint -osl_malloced(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (osh->malloced); -} - -uint -osl_malloc_failed(osl_t *osh) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - return (osh->failed); -} - -void* -osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -} - -void -osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -} - -uint -osl_dma_map(osl_t *osh, void *va, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - return (pci_map_single(osh->pdev, va, size, dir)); -} - -void -osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - pci_unmap_single(osh->pdev, (uint32)pa, size, dir); -} - - -void -osl_delay(uint usec) -{ - uint d; - - while (usec > 0) { - d = MIN(usec, 1000); - udelay(d); - usec -= d; - } -} - - - -void * -osl_pktdup(osl_t *osh, void *skb) -{ - void * p; - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((p = skb_clone((struct sk_buff*)skb, flags)) == NULL) - return NULL; - - - if (osh->pub.pkttag) - bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); - - - osh->pub.pktalloced++; - return (p); -} diff --git a/drivers/net/wireless/bcm4329/miniopt.c b/drivers/net/wireless/bcm4329/miniopt.c deleted file mode 100644 index 6a184a75f06b..000000000000 --- a/drivers/net/wireless/bcm4329/miniopt.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Description. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * $Id: miniopt.c,v 1.1.6.4 2009/09/25 00:32:01 Exp $ - */ - -/* ---- Include Files ---------------------------------------------------- */ - -#include -#include -#include -#include -#include "miniopt.h" - - -/* ---- Public Variables ------------------------------------------------- */ -/* ---- Private Constants and Types -------------------------------------- */ - - - -/* ---- Private Variables ------------------------------------------------ */ -/* ---- Private Function Prototypes -------------------------------------- */ -/* ---- Functions -------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- */ -void -miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags) -{ - static const char *null_flags = ""; - - memset(t, 0, sizeof(miniopt_t)); - t->name = name; - if (flags == NULL) - t->flags = null_flags; - else - t->flags = flags; - t->longflags = longflags; -} - - -/* ----------------------------------------------------------------------- */ -int -miniopt(miniopt_t *t, char **argv) -{ - int keylen; - char *p, *eq, *valstr, *endptr = NULL; - int err = 0; - - t->consumed = 0; - t->positional = FALSE; - memset(t->key, 0, MINIOPT_MAXKEY); - t->opt = '\0'; - t->valstr = NULL; - t->good_int = FALSE; - valstr = NULL; - - if (*argv == NULL) { - err = -1; - goto exit; - } - - p = *argv++; - t->consumed++; - - if (!t->opt_end && !strcmp(p, "--")) { - t->opt_end = TRUE; - if (*argv == NULL) { - err = -1; - goto exit; - } - p = *argv++; - t->consumed++; - } - - if (t->opt_end) { - t->positional = TRUE; - valstr = p; - } - else if (!strncmp(p, "--", 2)) { - eq = strchr(p, '='); - if (eq == NULL && !t->longflags) { - fprintf(stderr, - "%s: missing \" = \" in long param \"%s\"\n", t->name, p); - err = 1; - goto exit; - } - keylen = eq ? (eq - (p + 2)) : (int)strlen(p) - 2; - if (keylen > 63) keylen = 63; - memcpy(t->key, p + 2, keylen); - - if (eq) { - valstr = eq + 1; - if (*valstr == '\0') { - fprintf(stderr, - "%s: missing value after \" = \" in long param \"%s\"\n", - t->name, p); - err = 1; - goto exit; - } - } - } - else if (!strncmp(p, "-", 1)) { - t->opt = p[1]; - if (strlen(p) > 2) { - fprintf(stderr, - "%s: only single char options, error on param \"%s\"\n", - t->name, p); - err = 1; - goto exit; - } - if (strchr(t->flags, t->opt)) { - /* this is a flag option, no value expected */ - valstr = NULL; - } else { - if (*argv == NULL) { - fprintf(stderr, - "%s: missing value parameter after \"%s\"\n", t->name, p); - err = 1; - goto exit; - } - valstr = *argv; - argv++; - t->consumed++; - } - } else { - t->positional = TRUE; - valstr = p; - } - - /* parse valstr as int just in case */ - if (valstr) { - t->uval = (uint)strtoul(valstr, &endptr, 0); - t->val = (int)t->uval; - t->good_int = (*endptr == '\0'); - } - - t->valstr = valstr; - -exit: - if (err == 1) - t->opt = '?'; - - return err; -} diff --git a/drivers/net/wireless/bcm4329/sbutils.c b/drivers/net/wireless/bcm4329/sbutils.c deleted file mode 100644 index 46cd51010b78..000000000000 --- a/drivers/net/wireless/bcm4329/sbutils.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: sbutils.c,v 1.662.4.10.2.7.4.2 2010/04/19 05:48:48 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -/* local prototypes */ -static uint _sb_coreidx(si_info_t *sii, uint32 sba); -static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, - uint ncores); -static uint32 _sb_coresba(si_info_t *sii); -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); - -#define SET_SBREG(sii, r, mask, val) \ - W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) -#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) - -/* sonicsrev */ -#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) - -#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr)) -#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v)) -#define AND_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v))) -#define OR_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v))) - -static uint32 -sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr) -{ - uint8 tmp; - uint32 val, intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - val = R_REG(sii->osh, sbr); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } - - return (val); -} - -static void -sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) -{ - uint8 tmp; - volatile uint32 dummy; - uint32 intr_val = 0; - - - /* - * compact flash only has 11 bits address, while we needs 12 bits address. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if (PCMCIA(sii)) { - INTR_OFF(sii, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ - } - - if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { -#ifdef IL_BIGENDIAN - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); -#else - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); - dummy = R_REG(sii->osh, sbr); - W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -#endif /* IL_BIGENDIAN */ - } else - W_REG(sii->osh, sbr, v); - - if (PCMCIA(sii)) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(sii, intr_val); - } -} - -uint -sb_coreid(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -} - -uint -sb_flag(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return R_SBREG(sii, &sb->sbtpsflag) & SBTPS_NUM0_MASK; -} - -void -sb_setint(si_t *sih, int siflag) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 vec; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - if (siflag == -1) - vec = 0; - else - vec = 1 << siflag; - W_SBREG(sii, &sb->sbintvec, vec); -} - -/* return core index of the core with address 'sba' */ -static uint -_sb_coreidx(si_info_t *sii, uint32 sba) -{ - uint i; - - for (i = 0; i < sii->numcores; i ++) - if (sba == sii->common_info->coresba[i]) - return i; - return BADIDX; -} - -/* return core address of the current core */ -static uint32 -_sb_coresba(si_info_t *sii) -{ - uint32 sbaddr; - - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: { - sbconfig_t *sb = REGS2SB(sii->curmap); - sbaddr = sb_base(R_SBREG(sii, &sb->sbadmatch0)); - break; - } - - case PCI_BUS: - sbaddr = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - break; - - case PCMCIA_BUS: { - uint8 tmp = 0; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - sbaddr = (uint32)tmp << 12; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - sbaddr |= (uint32)tmp << 16; - OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - sbaddr |= (uint32)tmp << 24; - break; - } - - case SPI_BUS: - case SDIO_BUS: - sbaddr = (uint32)(uintptr)sii->curmap; - break; - - - default: - sbaddr = BADCOREADDR; - break; - } - - return sbaddr; -} - -uint -sb_corevendor(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -} - -uint -sb_corerev(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - uint sbidh; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - sbidh = R_SBREG(sii, &sb->sbidhigh); - - return (SBCOREREV(sbidh)); -} - -/* set core-specific control flags */ -void -sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); -} - -/* set/clear core-specific control flags */ -uint32 -sb_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | - (val << SBTML_SICF_SHIFT); - W_SBREG(sii, &sb->sbtmstatelow, w); - } - - /* return the new value - * for write operation, the following readback ensures the completion of write opration. - */ - return (R_SBREG(sii, &sb->sbtmstatelow) >> SBTML_SICF_SHIFT); -} - -/* set/clear core-specific status flags */ -uint32 -sb_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - sbconfig_t *sb; - uint32 w; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sii, &sb->sbtmstatehigh) & ~(mask << SBTMH_SISF_SHIFT)) | - (val << SBTMH_SISF_SHIFT); - W_SBREG(sii, &sb->sbtmstatehigh, w); - } - - /* return the new value */ - return (R_SBREG(sii, &sb->sbtmstatehigh) >> SBTMH_SISF_SHIFT); -} - -bool -sb_iscoreup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return ((R_SBREG(sii, &sb->sbtmstatelow) & - (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) == - (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint -sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - uint32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = FALSE; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (BUSTYPE(sii->pub.bustype) == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = TRUE; - /* map if does not exist */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = - REG_MAP(sii->common_info->coresba[coreidx], SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - r = (uint32 *)((uchar *)sii->common_info->regs[coreidx] + regoff); - } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->common_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = TRUE; - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = TRUE; - if (SI_FAST(sii)) - r = (uint32 *)((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + regoff); - else - r = (uint32 *)((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - if (regoff >= SBCONFIGOFF) { - w = (R_SBREG(sii, r) & ~mask) | val; - W_SBREG(sii, r, w); - } else { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); - } - } - - /* readback */ - if (regoff >= SBCONFIGOFF) - w = R_SBREG(sii, r); - else { - if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) && - (coreidx == SI_CC_IDX) && - (regoff == OFFSETOF(chipcregs_t, watchdog))) { - w = val; - } else - w = R_REG(sii->osh, r); - } - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - sb_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return (w); -} - -/* Scan the enumeration space to find all cores starting from the given - * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba' - * is the default core address at chip POR time and 'regs' is the virtual - * address that the default core is mapped at. 'ncores' is the number of - * cores expected on bus 'sbba'. It returns the total number of cores - * starting from bus 'sbba', inclusive. - */ -#define SB_MAXBUSES 2 -static uint -_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores) -{ - uint next; - uint ncc = 0; - uint i; - - if (bus >= SB_MAXBUSES) { - SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to scan\n", sbba, bus)); - return 0; - } - SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores)); - - /* Scan all cores on the bus starting from core 0. - * Core addresses must be contiguous on each bus. - */ - for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) { - sii->common_info->coresba[next] = sbba + (i * SI_CORE_SIZE); - - /* keep and reuse the initial register mapping */ - if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && - (sii->common_info->coresba[next] == sba)) { - SI_MSG(("_sb_scan: reuse mapped regs %p for core %u\n", regs, next)); - sii->common_info->regs[next] = regs; - } - - /* change core to 'next' and read its coreid */ - sii->curmap = _sb_setcoreidx(sii, next); - sii->curidx = next; - - sii->common_info->coreid[next] = sb_coreid(&sii->pub); - - /* core specific processing... */ - /* chipc provides # cores */ - if (sii->common_info->coreid[next] == CC_CORE_ID) { - chipcregs_t *cc = (chipcregs_t *)sii->curmap; - uint32 ccrev = sb_corerev(&sii->pub); - - /* determine numcores - this is the total # cores in the chip */ - if (((ccrev == 4) || (ccrev >= 6))) - numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> - CID_CC_SHIFT; - else { - /* Older chips */ - uint chip = sii->pub.chip; - - if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ - numcores = 6; - else if (chip == BCM4704_CHIP_ID) - numcores = 9; - else if (chip == BCM5365_CHIP_ID) - numcores = 7; - else { - SI_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", - chip)); - ASSERT(0); - numcores = 1; - } - } - SI_MSG(("_sb_scan: there are %u cores in the chip %s\n", numcores, - sii->pub.issim ? "QT" : "")); - } - /* scan bridged SB(s) and add results to the end of the list */ - else if (sii->common_info->coreid[next] == OCP_CORE_ID) { - sbconfig_t *sb = REGS2SB(sii->curmap); - uint32 nsbba = R_SBREG(sii, &sb->sbadmatch1); - uint nsbcc; - - sii->numcores = next + 1; - - if ((nsbba & 0xfff00000) != SI_ENUM_BASE) - continue; - nsbba &= 0xfffff000; - if (_sb_coreidx(sii, nsbba) != BADIDX) - continue; - - nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16; - nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); - if (sbba == SI_ENUM_BASE) - numcores -= nsbcc; - ncc += nsbcc; - } - } - - SI_MSG(("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba)); - - sii->numcores = i + ncc; - return sii->numcores; -} - -/* scan the sb enumerated space to identify all cores */ -void -sb_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii; - uint32 origsba; - - sii = SI_INFO(sih); - - /* Save the current core info and validate it later till we know - * for sure what is good and what is bad. - */ - origsba = _sb_coresba(sii); - - /* scan all SB(s) starting from SI_ENUM_BASE */ - sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -sb_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (coreidx >= sii->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); - - sii->curmap = _sb_setcoreidx(sii, coreidx); - sii->curidx = coreidx; - - return (sii->curmap); -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -static void * -_sb_setcoreidx(si_info_t *sii, uint coreidx) -{ - uint32 sbaddr = sii->common_info->coresba[coreidx]; - void *regs; - - switch (BUSTYPE(sii->pub.bustype)) { - case SI_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = REG_MAP(sbaddr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - regs = sii->common_info->regs[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, sbaddr); - regs = sii->curmap; - break; - - case PCMCIA_BUS: { - uint8 tmp = (sbaddr >> 12) & 0x0f; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); - tmp = (sbaddr >> 16) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); - tmp = (sbaddr >> 24) & 0xff; - OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); - regs = sii->curmap; - break; - } - case SPI_BUS: - case SDIO_BUS: - /* map new one */ - if (!sii->common_info->regs[coreidx]) { - sii->common_info->regs[coreidx] = (void *)(uintptr)sbaddr; - ASSERT(GOODREGS(sii->common_info->regs[coreidx])); - } - regs = sii->common_info->regs[coreidx]; - break; - - - default: - ASSERT(0); - regs = NULL; - break; - } - - return regs; -} - -/* Return the address of sbadmatch0/1/2/3 register */ -static volatile uint32 * -sb_admatch(si_info_t *sii, uint asidx) -{ - sbconfig_t *sb; - volatile uint32 *addrm; - - sb = REGS2SB(sii->curmap); - - switch (asidx) { - case 0: - addrm = &sb->sbadmatch0; - break; - - case 1: - addrm = &sb->sbadmatch1; - break; - - case 2: - addrm = &sb->sbadmatch2; - break; - - case 3: - addrm = &sb->sbadmatch3; - break; - - default: - SI_ERROR(("%s: Address space index (%d) out of range\n", __FUNCTION__, asidx)); - return 0; - } - - return (addrm); -} - -/* Return the number of address spaces in current core */ -int -sb_numaddrspaces(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - /* + 1 because of enumeration space */ - return ((R_SBREG(sii, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT) + 1; -} - -/* Return the address of the nth address space in the current core */ -uint32 -sb_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_base(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - -/* Return the size of the nth address space in the current core */ -uint32 -sb_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx)))); -} - - -/* do buffered registers update */ -void -sb_commit(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sii = SI_INFO(sih); - - origidx = sii->curidx; - ASSERT(GOODIDX(origidx)); - - INTR_OFF(sii, intr_val); - - /* switch over to chipcommon core if there is one, else use pci */ - if (sii->pub.ccrev != NOREV) { - chipcregs_t *ccregs = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - - /* do the buffer registers update */ - W_REG(sii->osh, &ccregs->broadcastaddress, SB_COMMIT); - W_REG(sii->osh, &ccregs->broadcastdata, 0x0); - } else - ASSERT(0); - - /* restore core index */ - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); -} - -void -sb_core_disable(si_t *sih, uint32 bits) -{ - si_info_t *sii; - volatile uint32 dummy; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* if core is already in reset, just return */ - if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET) - return; - - /* if clocks are not enabled, put into reset and return */ - if ((R_SBREG(sii, &sb->sbtmstatelow) & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0) - goto disable; - - /* set target reject and spin until busy is clear (preserve core-specific bits) */ - OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) - SI_ERROR(("%s: target state still busy\n", __FUNCTION__)); - - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { - OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); - dummy = R_SBREG(sii, &sb->sbimstate); - OSL_DELAY(1); - SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); - } - - /* set reset and reject while enabling the clocks */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_REJ | SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(10); - - /* don't forget to clear the initiator reject bit */ - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) - AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ); - -disable: - /* leave reset and reject asserted */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - OSL_DELAY(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void -sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - si_info_t *sii; - sbconfig_t *sb; - volatile uint32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - sb_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - - /* set reset while enabling the clock and forcing them on throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) { - W_SBREG(sii, &sb->sbtmstatehigh, 0); - } - if ((dummy = R_SBREG(sii, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { - AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - } - - /* clear reset and allow it to propagate throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); - - /* leave clock enabled */ - W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - OSL_DELAY(1); -} - -void -sb_core_tofixup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - if ((BUSTYPE(sii->pub.bustype) != PCI_BUS) || PCIE(sii) || - (PCI(sii) && (sii->pub.buscorerev >= 5))) - return; - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - if (BUSTYPE(sii->pub.bustype) == SI_BUS) { - SET_SBREG(sii, &sb->sbimconfiglow, - SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x5 << SBIMCL_RTO_SHIFT) | 0x3); - } else { - if (sb_coreid(sih) == PCI_CORE_ID) { - SET_SBREG(sii, &sb->sbimconfiglow, - SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x3 << SBIMCL_RTO_SHIFT) | 0x2); - } else { - SET_SBREG(sii, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); - } - } - - sb_commit(sih); -} - -/* - * Set the initiator timeout for the "master core". - * The master core is defined to be the core in control - * of the chip and so it issues accesses to non-memory - * locations (Because of dma *any* core can access memeory). - * - * The routine uses the bus to decide who is the master: - * SI_BUS => mips - * JTAG_BUS => chipc - * PCI_BUS => pci or pcie - * PCMCIA_BUS => pcmcia - * SDIO_BUS => pcmcia - * - * This routine exists so callers can disable initiator - * timeouts so accesses to very slow devices like otp - * won't cause an abort. The routine allows arbitrary - * settings of the service and request timeouts, though. - * - * Returns the timeout state before changing it or -1 - * on error. - */ - -#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) - -uint32 -sb_set_initiator_to(si_t *sih, uint32 to, uint idx) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - uint32 tmp, ret = 0xffffffff; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - if ((to & ~TO_MASK) != 0) - return ret; - - /* Figure out the master core */ - if (idx == BADIDX) { - switch (BUSTYPE(sii->pub.bustype)) { - case PCI_BUS: - idx = sii->pub.buscoreidx; - break; - case JTAG_BUS: - idx = SI_CC_IDX; - break; - case PCMCIA_BUS: - case SDIO_BUS: - idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0); - break; - case SI_BUS: - idx = si_findcoreidx(sih, MIPS33_CORE_ID, 0); - break; - default: - ASSERT(0); - } - if (idx == BADIDX) - return ret; - } - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - sb = REGS2SB(sb_setcoreidx(sih, idx)); - - tmp = R_SBREG(sii, &sb->sbimconfiglow); - ret = tmp & TO_MASK; - W_SBREG(sii, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); - - sb_commit(sih); - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); - return ret; -} - -uint32 -sb_base(uint32 admatch) -{ - uint32 base; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - base = 0; - - if (type == 0) { - base = admatch & SBAM_BASE0_MASK; - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE1_MASK; - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE2_MASK; - } - - return (base); -} - -uint32 -sb_size(uint32 admatch) -{ - uint32 size; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - size = 0; - - if (type == 0) { - size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); - } - - return (size); -} diff --git a/drivers/net/wireless/bcm4329/siutils.c b/drivers/net/wireless/bcm4329/siutils.c deleted file mode 100644 index 1814db0f9dd6..000000000000 --- a/drivers/net/wireless/bcm4329/siutils.c +++ /dev/null @@ -1,1527 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: siutils.c,v 1.662.4.4.4.16.4.28 2010/06/23 21:37:54 Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "siutils_priv.h" - -/* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz); -static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); -static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs); - - -/* global variable to indicate reservation/release of gpio's */ -static uint32 si_gpioreservation = 0; -static void *common_info_alloced = NULL; - -/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ - -/* - * Allocate a si handle. - * devid - pci device id (used to determine chip#) - * osh - opaque OS handle - * regs - virtual address of initial core registers - * bustype - pci/pcmcia/sb/sdio/etc - * vars - pointer to a pointer area for "environment" variables - * varsz - pointer to int to return the size of the vars - */ -si_t * -si_attach(uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - si_info_t *sii; - - /* alloc si_info_t */ - if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { - SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); - return (NULL); - } - - if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { - if (NULL != sii->common_info) - MFREE(osh, sii->common_info, sizeof(si_common_info_t)); - MFREE(osh, sii, sizeof(si_info_t)); - return (NULL); - } - sii->vars = vars ? *vars : NULL; - sii->varsz = varsz ? *varsz : 0; - - return (si_t *)sii; -} - -/* global kernel resource */ -static si_info_t ksii; - -static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */ - -/* generic kernel variant of si_attach() */ -si_t * -si_kattach(osl_t *osh) -{ - static bool ksii_attached = FALSE; - - if (!ksii_attached) { - void *regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - - if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, - SI_BUS, NULL, - osh != SI_OSH ? &ksii.vars : NULL, - osh != SI_OSH ? &ksii.varsz : NULL) == NULL) { - if (NULL != ksii.common_info) - MFREE(osh, ksii.common_info, sizeof(si_common_info_t)); - SI_ERROR(("si_kattach: si_doattach failed\n")); - REG_UNMAP(regs); - return NULL; - } - REG_UNMAP(regs); - - /* save ticks normalized to ms for si_watchdog_ms() */ - if (PMUCTL_ENAB(&ksii.pub)) { - /* based on 32KHz ILP clock */ - wd_msticks = 32; - } else { - wd_msticks = ALP_CLOCK / 1000; - } - - ksii_attached = TRUE; - SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n", - ksii.pub.ccrev, wd_msticks)); - } - - return &ksii.pub; -} - - -static bool -si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) -{ - /* need to set memseg flag for CF card first before any sb registers access */ - if (BUSTYPE(bustype) == PCMCIA_BUS) - sii->memseg = TRUE; - - - if (BUSTYPE(bustype) == SDIO_BUS) { - int err; - uint8 clkset; - - /* Try forcing SDIO core to do ALPAvail request only */ - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); - if (!err) { - uint8 clkval; - - /* If register supported, wait for ALPAvail and then force ALP */ - clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); - if ((clkval & ~SBSDIO_AVBITS) == clkset) { - SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), - PMU_MAX_TRANSITION_DLY); - if (!SBSDIO_ALPAV(clkval)) { - SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", - clkval)); - return FALSE; - } - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); - OSL_DELAY(65); - } - } - - /* Also, disable the extra SDIO pull-ups */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); - } - - - return TRUE; -} - -static bool -si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, - uint *origidx, void *regs) -{ - bool pci, pcie; - uint i; - uint pciidx, pcieidx, pcirev, pcierev; - - cc = si_setcoreidx(&sii->pub, SI_CC_IDX); - ASSERT((uintptr)cc); - - /* get chipcommon rev */ - sii->pub.ccrev = (int)si_corerev(&sii->pub); - - /* get chipcommon chipstatus */ - if (sii->pub.ccrev >= 11) - sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); - - /* get chipcommon capabilites */ - sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); - - /* get pmu rev and caps */ - if (sii->pub.cccaps & CC_CAP_PMU) { - sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); - sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; - } - - SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", - sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, - sii->pub.pmucaps)); - - /* figure out bus/orignal core idx */ - sii->pub.buscoretype = NODEV_CORE_ID; - sii->pub.buscorerev = NOREV; - sii->pub.buscoreidx = BADIDX; - - pci = pcie = FALSE; - pcirev = pcierev = NOREV; - pciidx = pcieidx = BADIDX; - - for (i = 0; i < sii->numcores; i++) { - uint cid, crev; - - si_setcoreidx(&sii->pub, i); - cid = si_coreid(&sii->pub); - crev = si_corerev(&sii->pub); - - /* Display cores found */ - SI_MSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", - i, cid, crev, sii->common_info->coresba[i], sii->common_info->regs[i])); - - if (BUSTYPE(bustype) == PCI_BUS) { - if (cid == PCI_CORE_ID) { - pciidx = i; - pcirev = crev; - pci = TRUE; - } else if (cid == PCIE_CORE_ID) { - pcieidx = i; - pcierev = crev; - pcie = TRUE; - } - } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && - (cid == PCMCIA_CORE_ID)) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - else if (((BUSTYPE(bustype) == SDIO_BUS) || - (BUSTYPE(bustype) == SPI_BUS)) && - ((cid == PCMCIA_CORE_ID) || - (cid == SDIOD_CORE_ID))) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } - - /* find the core idx before entering this func. */ - if ((savewin && (savewin == sii->common_info->coresba[i])) || - (regs == sii->common_info->regs[i])) - *origidx = i; - } - - - SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, - sii->pub.buscorerev)); - - if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) && - (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (sii->pub.chiprev <= 3)) - OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL); - - - /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was - * already running. - */ - if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) { - if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || - si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) - si_core_disable(&sii->pub, 0); - } - - /* return to the original core */ - si_setcoreidx(&sii->pub, *origidx); - - return TRUE; -} - - - -static si_info_t * -si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz) -{ - struct si_pub *sih = &sii->pub; - uint32 w, savewin; - chipcregs_t *cc; - char *pvars = NULL; - uint origidx; - - ASSERT(GOODREGS(regs)); - - bzero((uchar*)sii, sizeof(si_info_t)); - - - { - if (NULL == (common_info_alloced = (void *)MALLOC(osh, sizeof(si_common_info_t)))) { - SI_ERROR(("si_doattach: malloc failed! malloced %dbytes\n", MALLOCED(osh))); - return (NULL); - } - bzero((uchar*)(common_info_alloced), sizeof(si_common_info_t)); - } - sii->common_info = (si_common_info_t *)common_info_alloced; - sii->common_info->attach_count++; - - savewin = 0; - - sih->buscoreidx = BADIDX; - - sii->curmap = regs; - sii->sdh = sdh; - sii->osh = osh; - - - /* find Chipcommon address */ - if (bustype == PCI_BUS) { - savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); - if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) - savewin = SI_ENUM_BASE; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); - cc = (chipcregs_t *)regs; - } else - if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { - cc = (chipcregs_t *)sii->curmap; - } else { - cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - } - - sih->bustype = bustype; - if (bustype != BUSTYPE(bustype)) { - SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", - bustype, BUSTYPE(bustype))); - return NULL; - } - - /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, sdh)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); - return NULL; - } - - /* ChipID recognition. - * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. - */ - w = R_REG(osh, &cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - /* Might as wll fill in chip id rev & pkg */ - sih->chip = w & CID_ID_MASK; - sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; - sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chippkg != BCM4329_289PIN_PKG_ID)) - sih->chippkg = BCM4329_182PIN_PKG_ID; - sih->issim = IS_SIM(sih->chippkg); - - /* scan for cores */ - if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { - SI_MSG(("Found chip type SB (0x%08x)\n", w)); - sb_scan(&sii->pub, regs, devid); - } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { - SI_MSG(("Found chip type AI (0x%08x)\n", w)); - /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)cc, devid); - } else { - SI_ERROR(("Found chip of unkown type (0x%08x)\n", w)); - return NULL; - } - /* no cores found, bail out */ - if (sii->numcores == 0) { - SI_ERROR(("si_doattach: could not find any cores\n")); - return NULL; - } - /* bus/core/clk setup */ - origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { - SI_ERROR(("si_doattach: si_buscore_setup failed\n")); - return NULL; - } - - pvars = NULL; - - - - if (sii->pub.ccrev >= 20) { - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); - si_setcoreidx(sih, origidx); - } - - /* Skip PMU initialization from the Dongle Host. - * Firmware will take care of it when it comes up. - */ - - - - return (sii); -} - -/* may be called with core in reset */ -void -si_detach(si_t *sih) -{ - si_info_t *sii; - uint idx; - - sii = SI_INFO(sih); - - if (sii == NULL) - return; - - if (BUSTYPE(sih->bustype) == SI_BUS) - for (idx = 0; idx < SI_MAXCORES; idx++) - if (sii->common_info->regs[idx]) { - REG_UNMAP(sii->common_info->regs[idx]); - sii->common_info->regs[idx] = NULL; - } - - - if (1 == sii->common_info->attach_count--) { - MFREE(sii->osh, sii->common_info, sizeof(si_common_info_t)); - common_info_alloced = NULL; - } - -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) - if (sii != &ksii) -#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ - MFREE(sii->osh, sii, sizeof(si_info_t)); -} - -void * -si_osh(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->osh; -} - -void -si_setosh(si_t *sih, osl_t *osh) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sii->osh != NULL) { - SI_ERROR(("osh is already set....\n")); - ASSERT(!sii->osh); - } - sii->osh = osh; -} - -/* register driver interrupt disabling and restoring callback functions */ -void -si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intr_arg = intr_arg; - sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn; - sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn; - sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn; - /* save current core id. when this function called, the current core - * must be the core which provides driver functions(il, et, wl, etc.) - */ - sii->dev_coreid = sii->common_info->coreid[sii->curidx]; -} - -void -si_deregister_intr_callback(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - sii->intrsoff_fn = NULL; -} - -uint -si_intflag(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - if (CHIPTYPE(sih->socitype) == SOCI_SB) { - sbconfig_t *ccsbr = (sbconfig_t *)((uintptr)((ulong) - (sii->common_info->coresba[SI_CC_IDX]) + SBCONFIGOFF)); - return R_REG(sii->osh, &ccsbr->sbflagst); - } else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return R_REG(sii->osh, ((uint32 *)(uintptr) - (sii->common_info->oob_router + OOB_STATUSA))); - else { - ASSERT(0); - return 0; - } -} - -uint -si_flag(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_flag(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_flag(sih); - else { - ASSERT(0); - return 0; - } -} - -void -si_setint(si_t *sih, int siflag) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_setint(sih, siflag); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_setint(sih, siflag); - else - ASSERT(0); -} - -uint -si_coreid(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->common_info->coreid[sii->curidx]; -} - -uint -si_coreidx(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->curidx; -} - -/* return the core-type instantiation # of the current core */ -uint -si_coreunit(si_t *sih) -{ - si_info_t *sii; - uint idx; - uint coreid; - uint coreunit; - uint i; - - sii = SI_INFO(sih); - coreunit = 0; - - idx = sii->curidx; - - ASSERT(GOODREGS(sii->curmap)); - coreid = si_coreid(sih); - - /* count the cores of our type */ - for (i = 0; i < idx; i++) - if (sii->common_info->coreid[i] == coreid) - coreunit++; - - return (coreunit); -} - -uint -si_corevendor(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corevendor(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corevendor(sih); - else { - ASSERT(0); - return 0; - } -} - -bool -si_backplane64(si_t *sih) -{ - return ((sih->cccaps & CC_CAP_BKPLN64) != 0); -} - -uint -si_corerev(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corerev(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corerev(sih); - else { - ASSERT(0); - return 0; - } -} - -/* return index of coreid or BADIDX if not found */ -uint -si_findcoreidx(si_t *sih, uint coreid, uint coreunit) -{ - si_info_t *sii; - uint found; - uint i; - - sii = SI_INFO(sih); - - found = 0; - - for (i = 0; i < sii->numcores; i++) - if (sii->common_info->coreid[i] == coreid) { - if (found == coreunit) - return (i); - found++; - } - - return (BADIDX); -} - -/* return list of found cores */ -uint -si_corelist(si_t *sih, uint coreid[]) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - bcopy((uchar*)sii->common_info->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); - return (sii->numcores); -} - -/* return current register mapping */ -void * -si_coreregs(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - - return (sii->curmap); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void * -si_setcore(si_t *sih, uint coreid, uint coreunit) -{ - uint idx; - - idx = si_findcoreidx(sih, coreid, coreunit); - if (!GOODIDX(idx)) - return (NULL); - - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, idx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, idx); - else { - ASSERT(0); - return NULL; - } -} - -void * -si_setcoreidx(si_t *sih, uint coreidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_setcoreidx(sih, coreidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_setcoreidx(sih, coreidx); - else { - ASSERT(0); - return NULL; - } -} - -/* Turn off interrupt as required by sb_setcore, before switch core */ -void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) -{ - void *cc; - si_info_t *sii; - - sii = SI_INFO(sih); - - INTR_OFF(sii, *intr_val); - *origidx = sii->curidx; - cc = si_setcore(sih, coreid, 0); - ASSERT(cc != NULL); - - return cc; -} - -/* restore coreidx and restore interrupt */ -void si_restore_core(si_t *sih, uint coreid, uint intr_val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - si_setcoreidx(sih, coreid); - INTR_RESTORE(sii, intr_val); -} - -int -si_numaddrspaces(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_numaddrspaces(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_numaddrspaces(sih); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspace(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspace(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspace(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_addrspacesize(si_t *sih, uint asidx) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_addrspacesize(sih, asidx); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_addrspacesize(sih, asidx); - else { - ASSERT(0); - return 0; - } -} - -uint32 -si_core_cflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_cflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_cflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_cflags_wo(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_cflags_wo(sih, mask, val); - else - ASSERT(0); -} - -uint32 -si_core_sflags(si_t *sih, uint32 mask, uint32 val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_core_sflags(sih, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_core_sflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } -} - -bool -si_iscoreup(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_iscoreup(sih); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_iscoreup(sih); - else { - ASSERT(0); - return FALSE; - } -} - -void -si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val) -{ - /* only for 4319, no requirement for SOCI_SB */ - if (CHIPTYPE(sih->socitype) == SOCI_AI) { - ai_write_wrap_reg(sih, offset, val); - } - else - return; - - return; -} - -uint -si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - return sb_corereg(sih, coreidx, regoff, mask, val); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - return ai_corereg(sih, coreidx, regoff, mask, val); - else { - ASSERT(0); - return 0; - } -} - -void -si_core_disable(si_t *sih, uint32 bits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_disable(sih, bits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_disable(sih, bits); -} - -void -si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_reset(sih, bits, resetbits); - else if (CHIPTYPE(sih->socitype) == SOCI_AI) - ai_core_reset(sih, bits, resetbits); -} - -void -si_core_tofixup(si_t *sih) -{ - if (CHIPTYPE(sih->socitype) == SOCI_SB) - sb_core_tofixup(sih); -} - -/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ -int -si_corebist(si_t *sih) -{ - uint32 cflags; - int result = 0; - - /* Read core control flags */ - cflags = si_core_cflags(sih, 0, 0); - - /* Set bist & fgc */ - si_core_cflags(sih, 0, (SICF_BIST_EN | SICF_FGC)); - - /* Wait for bist done */ - SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); - - if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) - result = BCME_ERROR; - - /* Reset core control flags */ - si_core_cflags(sih, 0xffff, cflags); - - return result; -} - -static uint32 -factor6(uint32 x) -{ - switch (x) { - case CC_F6_2: return 2; - case CC_F6_3: return 3; - case CC_F6_4: return 4; - case CC_F6_5: return 5; - case CC_F6_6: return 6; - case CC_F6_7: return 7; - default: return 0; - } -} - -/* calculate the speed the SI would run at given a set of clockcontrol values */ -uint32 -si_clock_rate(uint32 pll_type, uint32 n, uint32 m) -{ - uint32 n1, n2, clock, m1, m2, m3, mc; - - n1 = n & CN_N1_MASK; - n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; - - if (pll_type == PLL_TYPE6) { - if (m & CC_T6_MMASK) - return CC_T6_M1; - else - return CC_T6_M0; - } else if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - n1 = factor6(n1); - n2 += CC_F5_BIAS; - } else if (pll_type == PLL_TYPE2) { - n1 += CC_T2_BIAS; - n2 += CC_T2_BIAS; - ASSERT((n1 >= 2) && (n1 <= 7)); - ASSERT((n2 >= 5) && (n2 <= 23)); - } else if (pll_type == PLL_TYPE5) { - return (100000000); - } else - ASSERT(0); - /* PLL types 3 and 7 use BASE2 (25Mhz) */ - if ((pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE7)) { - clock = CC_CLOCK_BASE2 * n1 * n2; - } else - clock = CC_CLOCK_BASE1 * n1 * n2; - - if (clock == 0) - return 0; - - m1 = m & CC_M1_MASK; - m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; - m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; - mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; - - if ((pll_type == PLL_TYPE1) || - (pll_type == PLL_TYPE3) || - (pll_type == PLL_TYPE4) || - (pll_type == PLL_TYPE7)) { - m1 = factor6(m1); - if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) - m2 += CC_F5_BIAS; - else - m2 = factor6(m2); - m3 = factor6(m3); - - switch (mc) { - case CC_MC_BYPASS: return (clock); - case CC_MC_M1: return (clock / m1); - case CC_MC_M1M2: return (clock / (m1 * m2)); - case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); - case CC_MC_M1M3: return (clock / (m1 * m3)); - default: return (0); - } - } else { - ASSERT(pll_type == PLL_TYPE2); - - m1 += CC_T2_BIAS; - m2 += CC_T2M2_BIAS; - m3 += CC_T2_BIAS; - ASSERT((m1 >= 2) && (m1 <= 7)); - ASSERT((m2 >= 3) && (m2 <= 10)); - ASSERT((m3 >= 2) && (m3 <= 7)); - - if ((mc & CC_T2MC_M1BYP) == 0) - clock /= m1; - if ((mc & CC_T2MC_M2BYP) == 0) - clock /= m2; - if ((mc & CC_T2MC_M3BYP) == 0) - clock /= m3; - - return (clock); - } -} - - -/* set chip watchdog reset timer to fire in 'ticks' */ -void -si_watchdog(si_t *sih, uint ticks) -{ - if (PMUCTL_ENAB(sih)) { - - if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) && (ticks != 0)) { - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); - si_setcore(sih, USB20D_CORE_ID, 0); - si_core_disable(sih, 1); - si_setcore(sih, CC_CORE_ID, 0); - } - - if (ticks == 1) - ticks = 2; - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks); - } else { - /* instant NMI */ - si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); - } -} - -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) -/* trigger watchdog reset after ms milliseconds */ -void -si_watchdog_ms(si_t *sih, uint32 ms) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - si_watchdog(sih, wd_msticks * ms); -} -#endif - - - -/* initialize the sdio core */ -void -si_sdio_init(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - - if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) || - (sih->buscoretype == SDIOD_CORE_ID)) { - uint idx; - sdpcmd_regs_t *sdpregs; - - /* get the current core index */ - idx = sii->curidx; - ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0)); - - /* switch to sdio core */ - if (!(sdpregs = (sdpcmd_regs_t *)si_setcore(sih, PCMCIA_CORE_ID, 0))) - sdpregs = (sdpcmd_regs_t *)si_setcore(sih, SDIOD_CORE_ID, 0); - ASSERT(sdpregs); - - SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " - "through SD core %d (%p)\n", - sih->buscorerev, idx, sii->curidx, sdpregs)); - - /* enable backplane error and core interrupts */ - W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT); - W_REG(sii->osh, &sdpregs->sbintmask, (I_SB_SERR | I_SB_RESPERR | (1 << idx))); - - /* switch back to previous core */ - si_setcoreidx(sih, idx); - } - - /* enable interrupts */ - bcmsdh_intr_enable(sii->sdh); - -} - - -/* change logical "focus" to the gpio core for optimized access */ -void * -si_gpiosetcore(si_t *sih) -{ - return (si_setcoreidx(sih, SI_CC_IDX)); -} - -/* mask&set gpiocontrol bits */ -uint32 -si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiocontrol); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output enable bits */ -uint32 -si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioouten); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio output bits */ -uint32 -si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - uint regoff; - - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpioout); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* reserve one gpio */ -uint32 -si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return -1; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return -1; - } - - /* already reserved */ - if (si_gpioreservation & gpio_bitmask) - return -1; - /* set reservation */ - si_gpioreservation |= gpio_bitmask; - - return si_gpioreservation; -} - -/* release one gpio */ -/* - * releasing the gpio doesn't change the current value on the GPIO last write value - * persists till some one overwrites it - */ - -uint32 -si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - /* only cores on SI_BUS share GPIO's and only applcation users need to - * reserve/release GPIO - */ - if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { - ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); - return -1; - } - /* make sure only one bit is set */ - if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { - ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); - return -1; - } - - /* already released */ - if (!(si_gpioreservation & gpio_bitmask)) - return -1; - - /* clear reservation */ - si_gpioreservation &= ~gpio_bitmask; - - return si_gpioreservation; -} - -/* return the current gpioin register value */ -uint32 -si_gpioin(si_t *sih) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - regoff = OFFSETOF(chipcregs_t, gpioin); - return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); -} - -/* mask&set gpio interrupt polarity bits */ -uint32 -si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointpolarity); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* mask&set gpio interrupt mask bits */ -uint32 -si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) -{ - si_info_t *sii; - uint regoff; - - sii = SI_INFO(sih); - regoff = 0; - - /* gpios could be shared on router platforms */ - if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); - val &= mask; - } - - regoff = OFFSETOF(chipcregs_t, gpiointmask); - return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -} - -/* assign the gpio to an led */ -uint32 -si_gpioled(si_t *sih, uint32 mask, uint32 val) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - if (sih->ccrev < 16) - return -1; - - /* gpio led powersave reg */ - return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); -} - -/* mask&set gpio timer val */ -uint32 -si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (sih->ccrev < 16) - return -1; - - return (si_corereg(sih, SI_CC_IDX, - OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); -} - -uint32 -si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 20) - return -1; - - offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup)); - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -uint32 -si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return -1; - - if (regtype == GPIO_REGEVT) - offs = OFFSETOF(chipcregs_t, gpioevent); - else if (regtype == GPIO_REGEVT_INTMSK) - offs = OFFSETOF(chipcregs_t, gpioeventintmask); - else if (regtype == GPIO_REGEVT_INTPOL) - offs = OFFSETOF(chipcregs_t, gpioeventintpolarity); - else - return -1; - - return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -} - -void * -si_gpio_handler_register(si_t *sih, uint32 event, - bool level, gpio_handler_t cb, void *arg) -{ - si_info_t *sii; - gpioh_item_t *gi; - - ASSERT(event); - ASSERT(cb != NULL); - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return NULL; - - if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL) - return NULL; - - bzero(gi, sizeof(gpioh_item_t)); - gi->event = event; - gi->handler = cb; - gi->arg = arg; - gi->level = level; - - gi->next = sii->gpioh_head; - sii->gpioh_head = gi; - - return (void *)(gi); -} - -void -si_gpio_handler_unregister(si_t *sih, void *gpioh) -{ - si_info_t *sii; - gpioh_item_t *p, *n; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return; - - ASSERT(sii->gpioh_head != NULL); - if ((void*)sii->gpioh_head == gpioh) { - sii->gpioh_head = sii->gpioh_head->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } else { - p = sii->gpioh_head; - n = p->next; - while (n) { - if ((void*)n == gpioh) { - p->next = n->next; - MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); - return; - } - p = n; - n = n->next; - } - } - - ASSERT(0); /* Not found in list */ -} - -void -si_gpio_handler_process(si_t *sih) -{ - si_info_t *sii; - gpioh_item_t *h; - uint32 status; - uint32 level = si_gpioin(sih); - uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0); - - sii = SI_INFO(sih); - for (h = sii->gpioh_head; h != NULL; h = h->next) { - if (h->handler) { - status = (h->level ? level : edge); - - if (status & h->event) - h->handler(status, h->arg); - } - } - - si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */ -} - -uint32 -si_gpio_int_enable(si_t *sih, bool enable) -{ - si_info_t *sii; - uint offs; - - sii = SI_INFO(sih); - if (sih->ccrev < 11) - return -1; - - offs = OFFSETOF(chipcregs_t, intmask); - return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0))); -} - - -/* Return the RAM size of the SOCRAM core */ -uint32 -si_socram_size(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sbsocramregs_t *regs; - bool wasup; - uint corerev; - uint32 coreinfo; - uint memsize = 0; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - /* Get info for determining size */ - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - corerev = si_corerev(sih); - coreinfo = R_REG(sii->osh, ®s->coreinfo); - - /* Calculate size from coreinfo based on rev */ - if (corerev == 0) - memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); - else if (corerev < 3) { - memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); - memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - } else { - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - uint bsz = (coreinfo & SRCI_SRBSZ_MASK); - uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; - if (lss != 0) - nb --; - memsize = nb * (1 << (bsz + SR_BSZ_BASE)); - if (lss != 0) - memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); - - return memsize; -} - - -void -si_btcgpiowar(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - chipcregs_t *cc; - - sii = SI_INFO(sih); - - /* Make sure that there is ChipCommon core present && - * UART_TX is strapped to 1 - */ - if (!(sih->cccaps & CC_CAP_UARTGPIO)) - return; - - /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */ - INTR_OFF(sii, intr_val); - - origidx = si_coreidx(sih); - - cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); - ASSERT(cc != NULL); - - W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04); - - /* restore the original index */ - si_setcoreidx(sih, origidx); - - INTR_RESTORE(sii, intr_val); -} - -/* check if the device is removed */ -bool -si_deviceremoved(si_t *sih) -{ - uint32 w; - si_info_t *sii; - - sii = SI_INFO(sih); - - switch (BUSTYPE(sih->bustype)) { - case PCI_BUS: - ASSERT(sii->osh != NULL); - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32)); - if ((w & 0xFFFF) != VENDOR_BROADCOM) - return TRUE; - else - return FALSE; - default: - return FALSE; - } - return FALSE; -} diff --git a/drivers/net/wireless/bcm4329/siutils_priv.h b/drivers/net/wireless/bcm4329/siutils_priv.h deleted file mode 100644 index e8ad7e50958a..000000000000 --- a/drivers/net/wireless/bcm4329/siutils_priv.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Include file private to the SOC Interconnect support files. - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: siutils_priv.h,v 1.3.10.5.4.2 2009/09/22 13:28:16 Exp $ - */ - -#ifndef _siutils_priv_h_ -#define _siutils_priv_h_ - -/* debug/trace */ -#define SI_ERROR(args) - -#define SI_MSG(args) - -#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) - -typedef uint32 (*si_intrsoff_t)(void *intr_arg); -typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); -typedef bool (*si_intrsenabled_t)(void *intr_arg); - -typedef struct gpioh_item { - void *arg; - bool level; - gpio_handler_t handler; - uint32 event; - struct gpioh_item *next; -} gpioh_item_t; - -/* misc si info needed by some of the routines */ -typedef struct si_common_info { - void *regs[SI_MAXCORES]; /* other regs va */ - void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ - uint coreid[SI_MAXCORES]; /* id of each core */ - uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ - uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ - uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ - uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ - uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ - void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ - uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ - uint32 oob_router; /* oob router registers for axi */ - uint8 attach_count; -} si_common_info_t; - -typedef struct si_info { - struct si_pub pub; /* back plane public state (must be first field) */ - - void *osh; /* osl os handle */ - void *sdh; /* bcmsdh handle */ - void *pch; /* PCI/E core handle */ - uint dev_coreid; /* the core provides driver functions */ - void *intr_arg; /* interrupt callback function arg */ - si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ - si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ - si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ - - - gpioh_item_t *gpioh_head; /* GPIO event handlers list */ - - bool memseg; /* flag to toggle MEM_SEG register */ - - char *vars; - uint varsz; - - void *curmap; /* current regs va */ - - uint curidx; /* current core index */ - uint numcores; /* # discovered cores */ - void *curwrap; /* current wrapper va */ - si_common_info_t *common_info; /* Common information for all the cores in a chip */ -} si_info_t; - -#define SI_INFO(sih) (si_info_t *)(uintptr)sih - -#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ - ISALIGNED((x), SI_CORE_SIZE)) -#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) -#define BADCOREADDR 0 -#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -#define BADIDX (SI_MAXCORES + 1) -#define NOREV -1 /* Invalid rev */ - -#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ - ((si)->pub.buscoretype == PCIE_CORE_ID)) -#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) - -/* Newer chips can access PCI/PCIE and CC core without requiring to change - * PCI BAR0 WIN - */ -#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ - (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) - -#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) - -/* - * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ - * after core switching to avoid invalid register accesss inside ISR. - */ -#define INTR_OFF(si, intr_val) \ - if ((si)->intrsoff_fn && (si)->common_info->coreid[(si)->curidx] == (si)->dev_coreid) { \ - intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -#define INTR_RESTORE(si, intr_val) \ - if ((si)->intrsrestore_fn && (si)->common_info->coreid[(si)->curidx] == (si)->dev_coreid) {\ - (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } - -/* dynamic clock control defines */ -#define LPOMINFREQ 25000 /* low power oscillator min */ -#define LPOMAXFREQ 43000 /* low power oscillator max */ -#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -#define PCIMINFREQ 25000000 /* 25 MHz */ -#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ - -#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ - -#define PCI_FORCEHT(si) \ - (((PCIE(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ - ((PCI(si) || PCIE(si)) && (si->pub.chip == BCM4321_CHIP_ID))) - -/* GPIO Based LED powersave defines */ -#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ - -#ifndef DEFAULT_GPIOTIMERVAL -#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -#endif - -/* Silicon Backplane externs */ -extern void sb_scan(si_t *sih, void *regs, uint devid); -extern uint sb_coreid(si_t *sih); -extern uint sb_flag(si_t *sih); -extern void sb_setint(si_t *sih, int siflag); -extern uint sb_corevendor(si_t *sih); -extern uint sb_corerev(si_t *sih); -extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern bool sb_iscoreup(si_t *sih); -extern void *sb_setcoreidx(si_t *sih, uint coreidx); -extern uint32 sb_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 sb_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern void sb_commit(si_t *sih); -extern uint32 sb_base(uint32 admatch); -extern uint32 sb_size(uint32 admatch); -extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void sb_core_tofixup(si_t *sih); -extern void sb_core_disable(si_t *sih, uint32 bits); -extern uint32 sb_addrspace(si_t *sih, uint asidx); -extern uint32 sb_addrspacesize(si_t *sih, uint asidx); -extern int sb_numaddrspaces(si_t *sih); - -extern uint32 sb_set_initiator_to(si_t *sih, uint32 to, uint idx); - - - -/* Wake-on-wireless-LAN (WOWL) */ -extern bool sb_pci_pmecap(si_t *sih); -struct osl_info; -extern bool sb_pci_fastpmecap(struct osl_info *osh); -extern bool sb_pci_pmeclr(si_t *sih); -extern void sb_pci_pmeen(si_t *sih); -extern uint sb_pcie_readreg(void *sih, uint addrtype, uint offset); - -/* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(osl_t *osh); -extern void ai_scan(si_t *sih, void *regs, uint devid); - -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); -extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -extern void ai_core_disable(si_t *sih, uint32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern uint32 ai_addrspace(si_t *sih, uint asidx); -extern uint32 ai_addrspacesize(si_t *sih, uint asidx); -extern void ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val); - - -#endif /* _siutils_priv_h_ */ diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c deleted file mode 100644 index 230619d901ec..000000000000 --- a/drivers/net/wireless/bcm4329/wl_iw.c +++ /dev/null @@ -1,8441 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.78 2011/02/11 21:27:52 Exp $ - */ - - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -typedef void wlc_info_t; -typedef void wl_info_t; -typedef const struct si_pub si_t; -#include - -#include -#include -#include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) -#define WL_ASSOC(x) -#define WL_INFORM(x) -#define WL_WSEC(x) -#define WL_SCAN(x) -#define WL_PNO(x) -#define WL_TRACE_COEX(x) - -#include - - - -#ifndef IW_ENCODE_ALG_SM4 -#define IW_ENCODE_ALG_SM4 0x20 -#endif - -#ifndef IW_AUTH_WAPI_ENABLED -#define IW_AUTH_WAPI_ENABLED 0x20 -#endif - -#ifndef IW_AUTH_WAPI_VERSION_1 -#define IW_AUTH_WAPI_VERSION_1 0x00000008 -#endif - -#ifndef IW_AUTH_CIPHER_SMS4 -#define IW_AUTH_CIPHER_SMS4 0x00000020 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK -#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT -#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 -#endif - - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) - -#include -#include - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 - -#if defined(SOFTAP) -#define WL_SOFTAP(x) printk x -static struct net_device *priv_dev; -static bool ap_cfg_running = FALSE; -bool ap_fw_loaded = FALSE; -static long ap_cfg_pid = -1; -struct net_device *ap_net_dev = NULL; -struct semaphore ap_eth_sema; -static struct completion ap_cfg_exited; -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap); -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac); -#endif - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; -static struct mutex wl_cache_lock; - -extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, - uint32 reason, char* stringBuf, uint buflen); -#include -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern uint dhd_dev_reset(struct net_device *dev, uint8 flag); -extern void dhd_dev_init_ioctl(struct net_device *dev); -int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val); - -uint wl_msg_level = WL_ERROR_VAL; - -#define MAX_WLIW_IOCTL_LEN 1024 - - -#if defined(IL_BIGENDIAN) -#include -#define htod32(i) (bcmswap32(i)) -#define htod16(i) (bcmswap16(i)) -#define dtoh32(i) (bcmswap32(i)) -#define dtoh16(i) (bcmswap16(i)) -#define htodchanspec(i) htod16(i) -#define dtohchanspec(i) dtoh16(i) -#else -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i -#endif - -#ifdef CONFIG_WIRELESS_EXT - -extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -extern int dhd_wait_pend8021x(struct net_device *dev); -#endif - -#if WIRELESS_EXT < 19 -#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -#endif - -static void *g_scan = NULL; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -bool btcoex_is_sco_active(struct net_device *dev); -static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; -#if defined(CONFIG_FIRST_SCAN) -static volatile uint g_first_broadcast_scan; -static volatile uint g_first_counter_scans; -#define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3 -#endif - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) -static void wl_iw_free_ss_cache(void); -static int wl_iw_run_ss_cache_timer(int kick_off); -#endif -#if defined(CONFIG_FIRST_SCAN) -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -#endif -static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len); -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf * next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; - -typedef struct iscan_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - int iscan_state; - iscan_buf_t * list_hdr; - iscan_buf_t * list_cur; - - - long sysioc_pid; - struct semaphore sysioc_sem; - struct completion sysioc_exited; - - uint32 scan_flag; -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else - char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; -} iscan_info_t; -#define COEX_DHCP 1 - -#define BT_DHCP_eSCO_FIX -#define BT_DHCP_USE_FLAGS -#define BT_DHCP_OPPORTUNITY_WINDOW_TIME 2500 -#define BT_DHCP_FLAG_FORCE_TIME 5500 -static void wl_iw_bt_flag_set(struct net_device *dev, bool set); -static void wl_iw_bt_release(void); - -typedef enum bt_coex_status { - BT_DHCP_IDLE = 0, - BT_DHCP_START, - BT_DHCP_OPPORTUNITY_WINDOW, - BT_DHCP_FLAG_FORCE_TIMEOUT -} coex_status_t; - -typedef struct bt_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - bool dhcp_done; - int bt_state; - - long bt_pid; - struct semaphore bt_sem; - struct completion bt_exited; -} bt_info_t; - -bt_info_t *g_bt = NULL; -static void wl_iw_bt_timerfunc(ulong data); -iscan_info_t *g_iscan = NULL; -static void wl_iw_timerfunc(ulong data); -static void wl_iw_set_event_mask(struct net_device *dev); -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -#endif -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -#ifndef CSCAN -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -); - -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size -); -#endif - -static void swap_key_from_BE( - wl_wsec_key_t *key -) -{ - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); -} - -static void swap_key_to_BE( - wl_wsec_key_t *key -) -{ - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); -} - -static int -dev_wlc_ioctl( - struct net_device *dev, - int cmd, - void *arg, - int len -) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return ret; - } - - net_os_wake_lock(dev); - - WL_INFORM(("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n", - __FUNCTION__, current->pid, cmd, arg, len)); - - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t) &ioc; - - ret = dev_open(dev); - if (ret) { - WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret)); - net_os_wake_unlock(dev); - return ret; - } - - fs = get_fs(); - set_fs(get_ds()); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) - ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#else - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#endif - set_fs(fs); - } - else { - WL_TRACE(("%s: call after driver stop : ignored\n", __FUNCTION__)); - } - - net_os_wake_unlock(dev); - - return ret; -} - - -static int -dev_wlc_intvar_get_reg( - struct net_device *dev, - char *name, - uint reg, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - len = bcm_mkiovar(name, (char *)(®), sizeof(reg), (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - return (error); -} - - -static int -dev_wlc_intvar_set_reg( - struct net_device *dev, - char *name, - char *addr, - char * val) -{ - char reg_addr[8]; - - memset(reg_addr, 0, sizeof(reg_addr)); - memcpy((char *)®_addr[0], (char *)addr, 4); - memcpy((char *)®_addr[4], (char *)val, 4); - - return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -} - - -static int -dev_wlc_intvar_set( - struct net_device *dev, - char *name, - int val) -{ - char buf[WLC_IOCTL_SMLEN]; - uint len; - - val = htod32(val); - len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); - ASSERT(len); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len)); -} - -#if defined(WL_IW_USE_ISCAN) -static int -dev_iw_iovar_setbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - if (iolen == 0) - return 0; - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen)); -} - -static int -dev_iw_iovar_getbuf( - struct net_device *dev, - char *iovar, - void *param, - int paramlen, - void *bufptr, - int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen)); -} -#endif - - -#if WIRELESS_EXT > 17 -static int -dev_wlc_bufvar_set( - struct net_device *dev, - char *name, - char *buf, int len) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - uint buflen; - - buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(buflen); - - return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen)); -} -#endif - - -static int -dev_wlc_bufvar_get( - struct net_device *dev, - char *name, - char *buf, int buflen) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - int error; - uint len; - - len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); - if (!error) - bcopy(ioctlbuf, buf, buflen); - - return (error); -} - - - -static int -dev_wlc_intvar_get( - struct net_device *dev, - char *name, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - uint data_null; - - len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - - return (error); -} - - -#if WIRELESS_EXT > 12 -static int -wl_iw_set_active_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int as = 0; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) -#endif - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); -#if defined(WL_IW_USE_ISCAN) - else - g_iscan->scan_flag = as; -#endif - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_passive_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int ps = 1; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) { -#endif - - - if (g_scan_specified_ssid == 0) { - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &ps, sizeof(ps)); - } -#if defined(WL_IW_USE_ISCAN) - } - else - g_iscan->scan_flag = ps; -#endif - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - return error; -} - - -static int -wl_iw_set_txpower( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - int txpower = -1; - - txpower = bcm_atoi(extra + strlen(TXPOWER_SET_CMD) + 1); - if ((txpower >= 0) && (txpower <= 127)) { - txpower |= WL_TXPWR_OVERRIDE; - txpower = htod32(txpower); - - error = dev_wlc_intvar_set(dev, "qtxpower", txpower); - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set TXpower 0x%X is OK\n", __FUNCTION__, txpower)); - } else { - WL_ERROR(("%s: set tx power failed\n", __FUNCTION__)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_get_macaddr( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - char buf[128]; - struct ether_addr *id; - char *p = extra; - - - strcpy(buf, "cur_etheraddr"); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)); - id = (struct ether_addr *) buf; - p += snprintf(p, MAX_WX_STRING, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - wrqu->data.length = p - extra + 1; - - return error; -} - - -static int -wl_iw_set_country( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - char country_code[WLC_CNTRY_BUF_SZ]; - int error = 0; - char *p = extra; - int country_offset; - int country_code_size; - wl_country_t cspec = {{0}, 0, {0}}; - char smbuf[WLC_IOCTL_SMLEN]; - - cspec.rev = -1; - memset(country_code, 0, sizeof(country_code)); - memset(smbuf, 0, sizeof(smbuf)); - - country_offset = strcspn(extra, " "); - country_code_size = strlen(extra) - country_offset; - - if (country_offset != 0) { - strncpy(country_code, extra + country_offset +1, - MIN(country_code_size, sizeof(country_code))); - - - memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); - - get_customized_country_code((char *)&cspec.country_abbrev, &cspec); - - if ((error = dev_iw_iovar_setbuf(dev, "country", &cspec, \ - sizeof(cspec), smbuf, sizeof(smbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_ERROR(("%s: set country for %s as %s rev %d is OK\n", \ - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - dhd_bus_country_set(dev, &cspec); - goto exit; - } - } - - WL_ERROR(("%s: set country for %s as %s rev %d failed\n", \ - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - return error; -} - -#ifdef CUSTOMER_HW2 -static int -wl_iw_set_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int pm = PM_FAST; - int pm_local = PM_OFF; - char powermode_val = 0; - - WL_TRACE_COEX(("%s: DHCP session cmd:%s\n", __FUNCTION__, extra)); - - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); - - /* Disable packet filtering if necessary */ - net_os_set_packet_filter(dev, 0); - - g_bt->dhcp_done = false; - WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n", - __FUNCTION__, pm, pm_local)); - - } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { - - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - - /* Enable packet filtering if was turned off */ - net_os_set_packet_filter(dev, 1); - - g_bt->dhcp_done = true; - - } else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} -#endif - - -bool btcoex_is_sco_active(struct net_device *dev) -{ - int ioc_res = 0; - bool res = false; - int sco_id_cnt = 0; - int param27; - int i; - - for (i = 0; i < 12; i++) { - - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - - WL_TRACE_COEX(("%s, sample[%d], btc params: 27:%x\n", - __FUNCTION__, i, param27)); - - if (ioc_res < 0) { - WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); - break; - } - - if ((param27 & 0x6) == 2) { - sco_id_cnt++; - } - - if (sco_id_cnt > 2) { - WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", - __FUNCTION__, sco_id_cnt, i)); - res = true; - break; - } - - msleep(5); - } - - return res; -} - -#if defined(BT_DHCP_eSCO_FIX) - -static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -{ - static bool saved_status = false; - - char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; - char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg50; - static uint32 saved_reg51; - static uint32 saved_reg64; - static uint32 saved_reg65; - static uint32 saved_reg71; - - if (trump_sco) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { - - saved_status = TRUE; - WL_TRACE_COEX(("%s saved bt_params[50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - __FUNCTION__, saved_reg50, saved_reg51, - saved_reg64, saved_reg65, saved_reg71)); - - } else { - WL_ERROR((":%s: save btc_params failed\n", - __FUNCTION__)); - saved_status = false; - return -1; - } - - WL_TRACE_COEX(("override with [50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - *(u32 *)(buf_reg50va_dhcp_on+4), - *(u32 *)(buf_reg51va_dhcp_on+4), - *(u32 *)(buf_reg64va_dhcp_on+4), - *(u32 *)(buf_reg65va_dhcp_on+4), - *(u32 *)(buf_reg71va_dhcp_on+4))); - - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8); - - saved_status = true; - - } else if (saved_status) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - regaddr = 50; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg50); - regaddr = 51; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg51); - regaddr = 64; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg64); - regaddr = 65; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg65); - regaddr = 71; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg71); - - WL_TRACE_COEX(("restore bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, saved_reg64, - saved_reg65, saved_reg71)); - - saved_status = false; - } else { - WL_ERROR((":%s att to restore not saved BTCOEX params\n", - __FUNCTION__)); - return -1; - } - return 0; -} -#endif - -static int -wl_iw_get_power_mode( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - char *p = extra; - int pm_local = PM_FAST; - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local)); - if (!error) { - WL_TRACE(("%s: Powermode = %d\n", __func__, pm_local)); - if (pm_local == PM_OFF) - pm_local = 1; /* Active */ - else - pm_local = 0; /* Auto */ - p += snprintf(p, MAX_WX_STRING, "powermode = %d", pm_local); - } - else { - WL_TRACE(("%s: Error = %d\n", __func__, error)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - wrqu->data.length = p - extra + 1; - return error; -} - -static int -wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; -#ifndef CUSTOMER_HW2 - static int pm = PM_FAST; - int pm_local = PM_OFF; -#endif - char powermode_val = 0; - char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; - char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; - char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg66; - static uint32 saved_reg41; - static uint32 saved_reg68; - static bool saved_status = FALSE; - - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; - -#ifdef CUSTOMER_HW2 - strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") + 1, 1); -#else - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1); -#endif - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE_COEX(("%s: DHCP session start, cmd:%s\n", __FUNCTION__, extra)); - - if ((saved_status == FALSE) && -#ifndef CUSTOMER_HW2 - (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) && -#endif - (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { - WL_TRACE_COEX(("save regs {66,41,68} ->: 0x%x 0x%x 0x%x\n", \ - saved_reg66, saved_reg41, saved_reg68)); - -#ifndef CUSTOMER_HW2 - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); -#endif - - if (btcoex_is_sco_active(dev)) { - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg66va_dhcp_on[0], \ - sizeof(buf_reg66va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg41va_dhcp_on[0], \ - sizeof(buf_reg41va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", \ - (char *)&buf_reg68va_dhcp_on[0], \ - sizeof(buf_reg68va_dhcp_on)); - saved_status = TRUE; - - g_bt->bt_state = BT_DHCP_START; - g_bt->timer_on = 1; - mod_timer(&g_bt->timer, g_bt->timer.expires); - WL_TRACE_COEX(("%s enable BT DHCP Timer\n", \ - __FUNCTION__)); - } - } - else if (saved_status == TRUE) { - WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); - } - } -#ifdef CUSTOMER_HW2 - else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { -#else - else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { -#endif - -#ifndef CUSTOMER_HW2 - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); -#endif - - WL_TRACE_COEX(("%s disable BT DHCP Timer\n", __FUNCTION__)); - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - - if (g_bt->bt_state != BT_DHCP_IDLE) { - WL_TRACE_COEX(("%s bt->bt_state:%d\n", - __FUNCTION__, g_bt->bt_state)); - - up(&g_bt->bt_sem); - } - } - - if (saved_status == TRUE) { - dev_wlc_bufvar_set(dev, "btc_flags", \ - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); - - regaddr = 66; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg66); - regaddr = 41; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg41); - regaddr = 68; - dev_wlc_intvar_set_reg(dev, "btc_params", \ - (char *)®addr, (char *)&saved_reg68); - - WL_TRACE_COEX(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", \ - saved_reg66, saved_reg41, saved_reg68)); - } - saved_status = FALSE; - } - else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - -static int -wl_iw_set_suspend( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int suspend_flag; - int ret_now; - int ret = 0; - - suspend_flag = *(extra + strlen(SETSUSPEND_CMD) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now))) - WL_ERROR(("%s: Suspend Flag %d -> %d\n", \ - __FUNCTION__, ret_now, suspend_flag)); - else - WL_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } - - return ret; -} - - -int -wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len) -{ - int i, c; - char *p = ssid_buf; - - if (ssid_len > 32) ssid_len = 32; - - for (i = 0; i < ssid_len; i++) { - c = (int)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += sprintf(p, "\\x%02X", c); - } - } - *p = '\0'; - - return p - ssid_buf; -} - -static int -wl_iw_get_link_speed( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - static int link_speed; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &link_speed, sizeof(link_speed)); - link_speed *= 500000; - } - - p += snprintf(p, MAX_WX_STRING, "LinkSpeed %d", link_speed/1000000); - - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - memset(iovbuf, 0, sizeof(iovbuf)); - strcpy(iovbuf, "bcn_li_dtim"); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - - p += snprintf(p, MAX_WX_STRING, "Dtim_skip %d", iovbuf[0]); - WL_TRACE(("%s: get dtim_skip = %d\n", __FUNCTION__, iovbuf[0])); - wrqu->data.length = p - extra + 1; - } - else - WL_ERROR(("%s: get dtim_skip failed code %d\n", \ - __FUNCTION__, error)); - } - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_dtim_skip( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int bcn_li_dtim; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - bcn_li_dtim = htod32((uint)*(extra + strlen(DTIM_SKIP_SET_CMD) + 1) - '0'); - - if ((bcn_li_dtim >= 0) || ((bcn_li_dtim <= 5))) { - - memset(iovbuf, 0, sizeof(iovbuf)); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - - net_os_set_dtim_skip(dev, bcn_li_dtim); - - WL_TRACE(("%s: set dtim_skip %d OK\n", __FUNCTION__, \ - bcn_li_dtim)); - goto exit; - } - else WL_ERROR(("%s: set dtim_skip %d failed code %d\n", \ - __FUNCTION__, bcn_li_dtim, error)); - } - else WL_ERROR(("%s Incorrect dtim_skip setting %d, ignored\n", \ - __FUNCTION__, bcn_li_dtim)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_get_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - static int band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_BAND, &band, sizeof(band)); - - p += snprintf(p, MAX_WX_STRING, "Band %d", band); - - wrqu->data.length = p - extra + 1; - } - - net_os_wake_unlock(dev); - return error; -} - - -static int -wl_iw_set_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - uint band; - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_ON) { - - band = htod32((uint)*(extra + strlen(BAND_SET_CMD) + 1) - '0'); - - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { - - if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND, - &band, sizeof(band))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set band %d OK\n", __FUNCTION__, band)); - goto exit; - } - else WL_ERROR(("%s: set band %d failed code %d\n", __FUNCTION__, \ - band, error)); - } - else WL_ERROR(("%s Incorrect band setting %d, ignored\n", __FUNCTION__, band)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - -#ifdef PNO_SUPPORT - -static int -wl_iw_set_pno_reset( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - - net_os_wake_lock(dev); - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_reset(dev)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_enable( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - int pfn_enabled; - - net_os_wake_lock(dev); - pfn_enabled = htod32((uint)*(extra + strlen(PNOENABLE_SET_CMD) + 1) - '0'); - - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { - - if ((error = dhd_dev_pno_enable(dev, pfn_enabled)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } - - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} - - - -static int -wl_iw_set_pno_set( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time; - int pno_repeat; - int pno_freq_expo_max; - -#ifdef PNO_SET_DEBUG - int i; - char pno_in_example[] = {'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', \ - 'S', '1', '2', '0', - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '1','E', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - if (wrqu->data.length < (strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, \ - wrqu->data.length, strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))); - goto exit_proc; - } - -#ifdef PNO_SET_DEBUG - if (!(extra = kmalloc(sizeof(pno_in_example) +100, GFP_KERNEL))) { - res = -ENOMEM; - goto exit_proc; - } - memcpy(extra, pno_in_example, sizeof(pno_in_example)); - wrqu->data.length = sizeof(pno_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; -#ifdef PNO_SET_DEBUG - str_ptr += strlen("PNOSETUP "); - tlv_size_left = wrqu->data.length - strlen("PNOSETUP "); -#else - str_ptr += strlen(PNOSETUP_SET_CMD); - tlv_size_left = wrqu->data.length - strlen(PNOSETUP_SET_CMD); -#endif - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - pno_repeat = pno_freq_expo_max = 0; - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && \ - (cmd_tlv_temp->version == PNO_TLV_VERSION) && \ - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) - { - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, \ - MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - WL_ERROR(("%s scan duration corrupted field size %d\n", \ - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - WL_ERROR(("%s pno repeat : corrupted field\n", \ - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - WL_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", \ - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_freq_expo_max=%d\n", \ - __FUNCTION__, pno_freq_expo_max)); - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} -#endif - -static int -wl_iw_get_rssi( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - static int rssi = 0; - static wlc_ssid_t ssid = {0}; - int error = 0; - char *p = extra; - static char ssidbuf[SSID_FMT_BUF_LEN]; - scb_val_t scb_val; - - net_os_wake_lock(dev); - - bzero(&scb_val, sizeof(scb_val_t)); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (error) { - WL_ERROR(("%s: Fails %d\n", __FUNCTION__, error)); - } else { - rssi = dtoh32(scb_val.val); - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (!error) { - ssid.SSID_len = dtoh32(ssid.SSID_len); - wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len)); - } - } - } - - WL_ASSOC(("%s ssid_len:%d, rssi:%d\n", __FUNCTION__, ssid.SSID_len, rssi)); - - if (error || (ssid.SSID_len == 0)) { - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } else { - p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi); - } - wrqu->data.length = p - extra + 1; - - net_os_wake_unlock(dev); - return error; -} - -int -wl_iw_send_priv_event( - struct net_device *dev, - char *flag -) -{ - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd; - - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - if (strlen(flag) > sizeof(extra)) - return -1; - - strcpy(extra, flag); - wrqu.data.length = strlen(extra); - wireless_send_event(dev, cmd, &wrqu, extra); - net_os_wake_lock_timeout_enable(dev); - WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); - - return 0; -} - - -int -wl_control_wl_start(struct net_device *dev) -{ - int ret = 0; - wl_iw_t *iw; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; - } - dhd_os_start_lock(iw->pub); - - if (g_onoff == G_WLAN_SET_OFF) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 0); -#endif - - ret = dhd_dev_reset(dev, 0); - - if (ret == BCME_OK) { -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 1); -#endif - dhd_dev_init_ioctl(dev); - g_onoff = G_WLAN_SET_ON; - } - } - WL_TRACE(("Exited %s \n", __FUNCTION__)); - - dhd_os_start_unlock(iw->pub); - return ret; -} - - -static int -wl_iw_control_wl_off( - struct net_device *dev, - struct iw_request_info *info -) -{ - int ret = 0; - wl_iw_t *iw; - - WL_TRACE(("Enter %s\n", __FUNCTION__)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - iw = *(wl_iw_t **)netdev_priv(dev); - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - dhd_os_start_lock(iw->pub); - -#ifdef SOFTAP - ap_cfg_running = FALSE; -#endif - - if (g_onoff == G_WLAN_SET_ON) { - g_onoff = G_WLAN_SET_OFF; -#if defined(WL_IW_USE_ISCAN) - g_iscan->iscan_state = ISCAN_STATE_IDLE; -#endif - - dhd_dev_reset(dev, 1); - -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - - g_ss_cache_ctrl.m_link_down = 1; -#endif - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; -#endif -#endif - -#if defined(BCMLXSDMMC) - sdioh_stop(NULL); -#endif - - net_os_set_dtim_skip(dev, 0); - - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - - wl_iw_send_priv_event(dev, "STOP"); - } - - dhd_os_start_unlock(iw->pub); - - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - return ret; -} - -static int -wl_iw_control_wl_on( - struct net_device *dev, - struct iw_request_info *info -) -{ - int ret = 0; - - WL_TRACE(("Enter %s \n", __FUNCTION__)); - - if ((ret = wl_control_wl_start(dev)) != BCME_OK) { - WL_ERROR(("%s failed first attemp\n", __FUNCTION__)); - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - if ((ret = wl_control_wl_start(dev)) != BCME_OK) { - WL_ERROR(("%s failed second attemp\n", __FUNCTION__)); - net_os_send_hang_message(dev); - return ret; - } - } - - wl_iw_send_priv_event(dev, "START"); - -#ifdef SOFTAP - if (!ap_fw_loaded) { - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - } -#else - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); -#endif - - WL_TRACE(("Exited %s \n", __FUNCTION__)); - - return ret; -} - -#ifdef SOFTAP -static struct ap_profile my_ap; -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap); -static int get_assoc_sta_list(struct net_device *dev, char *buf, int len); -static int set_ap_mac_list(struct net_device *dev, void *buf); - -#define PTYPE_STRING 0 -#define PTYPE_INTDEC 1 -#define PTYPE_INTHEX 2 -#define PTYPE_STR_HEX 3 -int get_parmeter_from_string( - char **str_ptr, const char *token, int param_type, void *dst, int param_max_len); - -#endif - -int hex2num(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 -1; -} - -int hex2byte(const char *hex) -{ - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; -} - - - -int hstr_2_buf(const char *txt, u8 *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) { - int a, b; - - a = hex2num(*txt++); - if (a < 0) - return -1; - b = hex2num(*txt++); - if (b < 0) - return -1; - *buf++ = (a << 4) | b; - } - - return 0; -} - -#if defined(SOFTAP) && defined(SOFTAP_TLV_CFG) - -static int wl_iw_softap_cfg_tlv( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - char *str_ptr; - int tlv_size_left; - - -#define SOFTAP_TLV_DEBUG 1 -#ifdef SOFTAP_TLV_DEBUG -char softap_cmd_example[] = { - - 'S', 'O', 'F', 'T', 'A', 'P', 'S', 'E', 'T', ' ', - - SOFTAP_TLV_PREFIX, SOFTAP_TLV_VERSION, - SOFTAP_TLV_SUBVERSION, SOFTAP_TLV_RESERVED, - - TLV_TYPE_SSID, 9, 'B', 'R', 'C', 'M', ',', 'G', 'O', 'O', 'G', - - TLV_TYPE_SECUR, 4, 'O', 'P', 'E', 'N', - - TLV_TYPE_KEY, 4, 0x31, 0x32, 0x33, 0x34, - - TLV_TYPE_CHANNEL, 4, 0x06, 0x00, 0x00, 0x00 -}; -#endif - - -#ifdef SOFTAP_TLV_DEBUG - { - int i; - if (!(extra = kmalloc(sizeof(softap_cmd_example) +10, GFP_KERNEL))) - return -ENOMEM; - memcpy(extra, softap_cmd_example, sizeof(softap_cmd_example)); - wrqu->data.length = sizeof(softap_cmd_example); - print_buf(extra, wrqu->data.length, 16); - for (i = 0; i < wrqu->data.length; i++) - printf("%c ", extra[i]); - printf("\n"); - } -#endif - - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - - if (wrqu->data.length < (strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, strlen(SOFTAP_SET_CMD) + sizeof(cmd_tlv_t))); - return -1; - } - - str_ptr = extra + strlen(SOFTAP_SET_CMD)+1; - tlv_size_left = wrqu->data.length - (strlen(SOFTAP_SET_CMD)+1); - - memset(&my_ap, 0, sizeof(my_ap)); - - return res; -} -#endif - - -#ifdef SOFTAP -int init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg) -{ - char *str_ptr = param_str; - char sub_cmd[16]; - int ret = 0; - - memset(sub_cmd, 0, sizeof(sub_cmd)); - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=", - PTYPE_STRING, sub_cmd, SSID_LEN) != 0) { - return -1; - } - if (strncmp(sub_cmd, "AP_CFG", 6)) { - WL_ERROR(("ERROR: sub_cmd:%s != 'AP_CFG'!\n", sub_cmd)); - return -1; - } - - ret = get_parmeter_from_string(&str_ptr, "SSID=", PTYPE_STRING, ap_cfg->ssid, SSID_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "SEC=", PTYPE_STRING, ap_cfg->sec, SEC_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "KEY=", PTYPE_STRING, ap_cfg->key, KEY_LEN); - - ret |= get_parmeter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5); - - get_parmeter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5); - - get_parmeter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC, &ap_cfg->max_scb, 5); - - get_parmeter_from_string(&str_ptr, "HIDDEN=", PTYPE_INTDEC, &ap_cfg->closednet, 5); - - get_parmeter_from_string(&str_ptr, "COUNTRY=", PTYPE_STRING, &ap_cfg->country_code, 3); - - return ret; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_set_ap_config(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *extra = NULL; - struct ap_profile *ap_cfg = &my_ap; - - WL_TRACE(("%s: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - __FUNCTION__, - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got str param in iw_point:\n %s\n", extra)); - - memset(ap_cfg, 0, sizeof(struct ap_profile)); - - str_ptr = extra; - - if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) { - WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res)); - kfree(extra); - return -1; - } - - } else { - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; - } - - if ((res = set_ap_cfg(dev, ap_cfg)) < 0) - WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res)); - - kfree(extra); - - return res; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_get_assoc_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *p_iwrq, - char *extra) -{ - int i, ret = 0; - char mac_buf[256]; - struct maclist *sta_maclist = (struct maclist *)mac_buf; - - char mac_lst[384]; - char *p_mac_str; - char *p_mac_str_end; - - if ((!dev) || (!extra)) { - return -EINVAL; - } - - net_os_wake_lock(dev); - - WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d, \ - iwp.len:%p, iwp.flags:%x \n", __FUNCTION__, info->cmd, info->flags, \ - extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags)); - - memset(sta_maclist, 0, sizeof(mac_buf)); - - sta_maclist->count = 8; - - WL_SOFTAP(("%s: net device:%s, buf_sz:%d\n", - __FUNCTION__, dev->name, sizeof(mac_buf))); - - if ((ret = get_assoc_sta_list(dev, mac_buf, sizeof(mac_buf))) < 0) { - WL_ERROR(("%s: sta list ioctl error:%d\n", - __FUNCTION__, ret)); - goto func_exit; - } - - WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__, - sta_maclist->count)); - - memset(mac_lst, 0, sizeof(mac_lst)); - p_mac_str = mac_lst; - p_mac_str_end = &mac_lst[sizeof(mac_lst)-1]; - - for (i = 0; i < 8; i++) { - struct ether_addr *id = &sta_maclist->ea[i]; - if (!ETHER_ISNULLADDR(id->octet)) { - scb_val_t scb_val; - int rssi = 0; - - bzero(&scb_val, sizeof(scb_val_t)); - - if ((p_mac_str_end - p_mac_str) <= 36) { - WL_ERROR(("%s: mac list buf is < 36 for item[%i] item\n", - __FUNCTION__, i)); - break; - } - - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "\nMac[%d]=%02X:%02X:%02X:%02X:%02X:%02X,", i, - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - - bcopy(id->octet, &scb_val.ea, 6); - ret = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (ret < 0) { - snprintf(p_mac_str, MAX_WX_STRING, "RSSI:ERR"); - WL_ERROR(("%s: RSSI ioctl error:%d\n", - __FUNCTION__, ret)); - break; - } - - rssi = dtoh32(scb_val.val); - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "RSSI:%d", rssi); - } - } - - p_iwrq->data.length = strlen(mac_lst) + 1; - - WL_SOFTAP(("%s: data to user:\n%s\n usr_ptr:%p\n", __FUNCTION__, - mac_lst, p_iwrq->data.pointer)); - - if (p_iwrq->data.length) { - bcopy(mac_lst, extra, p_iwrq->data.length); - } - -func_exit: - net_os_wake_unlock(dev); - - WL_TRACE(("Exited %s \n", __FUNCTION__)); - return ret; -} -#endif - - -#ifdef SOFTAP -#define MAC_FILT_MAX 8 -static int iwpriv_set_mac_filters(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int i, ret = -1; - char * extra = NULL; - int mac_cnt = 0; - int mac_mode = 0; - struct ether_addr *p_ea; - struct mac_list_set mflist_set; - - WL_SOFTAP((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x, \ - info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra)); - - memset(&mflist_set, 0, sizeof(mflist_set)); - - str_ptr = extra; - - if (get_parmeter_from_string(&str_ptr, "MAC_MODE=", - PTYPE_INTDEC, &mac_mode, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_MODE=' token is missing\n")); - goto exit_proc; - } - - p_ea = &mflist_set.mac_list.ea[0]; - - if (get_parmeter_from_string(&str_ptr, "MAC_CNT=", - PTYPE_INTDEC, &mac_cnt, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_CNT=' token param is missing \n")); - goto exit_proc; - } - - if (mac_cnt > MAC_FILT_MAX) { - WL_ERROR(("ERROR: number of MAC filters > MAX\n")); - goto exit_proc; - } - - for (i=0; i < mac_cnt; i++) - if (get_parmeter_from_string(&str_ptr, "MAC=", - PTYPE_STR_HEX, &p_ea[i], 12) != 0) { - WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i)); - goto exit_proc; - } - - WL_SOFTAP(("MAC_MODE=:%d, MAC_CNT=%d, MACs:..\n", mac_mode, mac_cnt)); - for (i = 0; i < mac_cnt; i++) { - WL_SOFTAP(("mac_filt[%d]:", i)); - print_buf(&p_ea[i], 6, 0); - } - - mflist_set.mode = mac_mode; - mflist_set.mac_list.count = mac_cnt; - set_ap_mac_list(dev, &mflist_set); - - wrqu->data.pointer = NULL; - wrqu->data.length = 0; - ret = 0; - - } else { - WL_ERROR(("IWPRIV argument len is 0\n")); - return -1; - } - - exit_proc: - kfree(extra); - return ret; -} -#endif - - -#ifdef SOFTAP -static int iwpriv_set_ap_sta_disassoc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char sta_mac[6] = {0, 0, 0, 0, 0, 0}; - char cmd_buf[256]; - char *str_ptr = cmd_buf; - - WL_SOFTAP((">>%s called\n args: info->cmd:%x," - " info->flags:%x, u.data.p:%p, u.data.len:%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (copy_from_user(cmd_buf, wrqu->data.pointer, wrqu->data.length)) { - return -EFAULT; - } - - if (get_parmeter_from_string(&str_ptr, - "MAC=", PTYPE_STR_HEX, sta_mac, 12) == 0) { - res = wl_iw_softap_deassoc_stations(dev, sta_mac); - } else { - WL_ERROR(("ERROR: STA_MAC= token not found\n")); - } - } - - return res; -} -#endif - -#endif - - -#if WIRELESS_EXT < 13 -struct iw_request_info -{ - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler)(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra); -#endif - -static int -wl_iw_config_commit( - struct net_device *dev, - struct iw_request_info *info, - void *zwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) - return error; - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - if (!ssid.SSID_len) - return 0; - - bzero(&bssid, sizeof(struct sockaddr)); - if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { - WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __FUNCTION__, ssid.SSID)); - return error; - } - - return 0; -} - -static int -wl_iw_get_name( - struct net_device *dev, - struct iw_request_info *info, - char *cwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); - - strcpy(cwrq, "IEEE 802.11-DS"); - - return 0; -} - -static int -wl_iw_set_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - int error, chan; - uint sf = 0; - - WL_TRACE(("%s %s: SIOCSIWFREQ\n", __FUNCTION__, dev->name)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s:>> not executed, 'SOFT_AP is active' \n", __FUNCTION__)); - return 0; - } -#endif - - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } - - - else { - - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; - } - - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; - - chan = wf_mhz2channel(fwrq->m, sf); - } - chan = htod32(chan); - if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) - return error; - - g_wl_iw_params.target_channel = chan; - - return -EINPROGRESS; -} - -static int -wl_iw_get_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - channel_info_t ci; - int error; - - WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - - fwrq->m = dtoh32(ci.hw_channel); - fwrq->e = dtoh32(0); - return 0; -} - -static int -wl_iw_set_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int infra = 0, ap = 0, error = 0; - - WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); - - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: - return -EINVAL; - } - infra = htod32(infra); - ap = htod32(ap); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) - return error; - - - return -EINPROGRESS; -} - -static int -wl_iw_get_mode( - struct net_device *dev, - struct iw_request_info *info, - __u32 *uwrq, - char *extra -) -{ - int error, infra = 0, ap = 0; - - WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) - return error; - - infra = dtoh32(infra); - ap = dtoh32(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; - - return 0; -} - -static int -wl_iw_get_range( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - struct iw_range *range = (struct iw_range *) extra; - wl_uint32_list_t *list; - wl_rateset_t rateset; - int8 *channels; - int error, i, k; - uint sf, ch; - - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - uint8 nrate_list2copy = 0; - uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300}}; - - WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL+1)*4, GFP_KERNEL); - if (!channels) { - WL_ERROR(("Could not alloc channels\n")); - return -ENOMEM; - } - list = (wl_uint32_list_t *)channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(range)); - - range->min_nwid = range->max_nwid = 0; - - list->count = htod32(MAXCHANNEL); - if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, (MAXCHANNEL+1)*4))) { - kfree(channels); - return error; - } - for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { - range->freq[i].i = dtoh32(list->element[i]); - - ch = dtoh32(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) - sf = WF_CHAN_FACTOR_2_4_G; - else - sf = WF_CHAN_FACTOR_5_G; - - range->freq[i].m = wf_channel2mhz(ch, sf); - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - range->max_qual.qual = 5; - - range->max_qual.level = 0x100 - 200; - - range->max_qual.noise = 0x100 - 200; - - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - - range->avg_qual.qual = 3; - - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - - range->avg_qual.noise = 0x100 - 75; -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) { - kfree(channels); - return error; - } - rateset.count = dtoh32(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i]& 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); - ci.hw_channel = dtoh32(ci.hw_channel); - - if (bw_cap == 0 || - (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || - (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - - range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) { - kfree(channels); - return error; - } - i = dtoh32(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WEP1_KEY_SIZE; - range->encoding_size[1] = WEP128_KEY_SIZE; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = TKIP_KEY_SIZE; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = AES_KEY_SIZE; - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - - range->min_retry = 1; - range->max_retry = 255; - - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; -#ifdef BCMWPA2 - range->enc_capa |= IW_ENC_CAPA_WPA2; -#endif - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); -#ifdef BCMWPA2 - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif -#endif - - kfree(channels); - - return 0; -} - -static int -rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - int i; - - WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; - int i; - - WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - - WL_TRACE(("%s join_params->params.chanspec_list[0]= %X\n", \ - __FUNCTION__, join_params->params.chanspec_list[0])); - } - return 1; -} - -static int -wl_iw_set_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR(("Invalid Header...sa_family\n")); - return -EINVAL; - } - - - if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { - scb_val_t scbval; - - bzero(&scbval, sizeof(scb_val_t)); - - (void) dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - return 0; - } - - - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN); - - WL_ASSOC(("%s target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel)); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("%s Invalid ioctl data=%d\n", __FUNCTION__, error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_ASSOC(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__, \ - g_ssid.SSID, MAC2STR((u8 *)awrq->sa_data), \ - g_wl_iw_params.target_channel)); - } - - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETHER_ADDR_LEN); - - - (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE(("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name)); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - } - else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, - sizeof(scb_val_t)); - } - else { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - return error; -} -#endif - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - list = kmalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - memset(list, 0, buflen); - list->buflen = htod32(buflen); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { - WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); - kfree(list); - return error; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s: list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - if ((dtoh32(bi->length) > buflen) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + buflen))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - kfree(list); - return -E2BIG; - } - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - return 0; -} -#endif - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - iscan_buf_t * buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - return 0; - } - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - - if ((dtoh32(bi->length) > WLC_IW_ISCAN_MAXLEN) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + WLC_IW_ISCAN_MAXLEN))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - return -E2BIG; - } - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - return 0; -} - -static int -wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - params->passive_time = 30; -#endif - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(action); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - WL_SCAN(("%s : nprobes=%d\n", __FUNCTION__, iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type)); - - if ((err = dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \ - iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - - return err; -} - -static void -wl_iw_timerfunc(ulong data) -{ - iscan_info_t *iscan = (iscan_info_t *)data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_SCAN(("timer trigger\n")); - up(&iscan->sysioc_sem); - } - } -} -static void wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static uint32 -wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t * buf; - iscan_buf_t * ptr; - wl_iscan_results_t * list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - uint32 status; - int res; - - mutex_lock(&wl_cache_lock); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } - else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR(("%s can't alloc iscan_buf_t : going to abort currect iscan\n", \ - __FUNCTION__)); - mutex_unlock(&wl_cache_lock); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf( - iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, - WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); - WL_SCAN(("results->count = %d\n", results->count)); - - WL_SCAN(("results->buflen = %d\n", results->buflen)); - status = dtoh32(list_buf->status); - } else { - WL_ERROR(("%s returns error %d\n", __FUNCTION__, res)); - status = WL_SCAN_RESULTS_NO_MEM; - } - mutex_unlock(&wl_cache_lock); - return status; -} - -static void wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_SCAN(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - (void) dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void wl_iw_send_scan_complete(iscan_info_t *iscan) -{ -#ifndef SANDGATE2G - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY; -#endif - WL_SCAN(("Send Event ISCAN complete\n")); -#endif -} - -static int -_iscan_sysioc_thread(void *data) -{ - uint32 status; - iscan_info_t *iscan = (iscan_info_t *)data; - static bool iscan_pass_abort = FALSE; - - DAEMONIZE("iscan_sysioc"); - - status = WL_SCAN_RESULTS_PARTIAL; - while (down_interruptible(&iscan->sysioc_sem) == 0) { - - net_os_wake_lock(iscan->dev); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_SCAN(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__)); - net_os_wake_unlock(iscan->dev); - continue; - } -#endif - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - status = wl_iw_iscan_get(iscan); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - if (g_scan_specified_ssid && (iscan_pass_abort == TRUE)) { - WL_SCAN(("%s Get results from specific scan status=%d\n", __FUNCTION__, status)); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = FALSE; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_SCAN(("iscanresults incomplete\n")); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_SCAN(("iscanresults complete\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_SCAN(("iscanresults pending\n")); - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_SCAN(("iscanresults aborted\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = TRUE; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_SCAN(("iscanresults can't alloc memory: skip\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_SCAN(("iscanresults returned unknown status %d\n", status)); - break; - } - - net_os_wake_unlock(iscan->dev); - } - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - - complete_and_exit(&iscan->sysioc_exited, 0); -} -#endif - -#if !defined(CSCAN) - -static void -wl_iw_set_ss_cache_timer_flag(void) -{ - g_ss_cache_ctrl.m_timer_expired = 1; - WL_TRACE(("%s called\n", __FUNCTION__)); -} - -static int -wl_iw_init_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - g_ss_cache_ctrl.m_prev_scan_mode = 0; - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - g_ss_cache_ctrl.m_cache_head = NULL; - g_ss_cache_ctrl.m_link_down = 0; - g_ss_cache_ctrl.m_timer_expired = 0; - memset(g_ss_cache_ctrl.m_active_bssid, 0, ETHER_ADDR_LEN); - - g_ss_cache_ctrl.m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); - if (!g_ss_cache_ctrl.m_timer) { - return -ENOMEM; - } - g_ss_cache_ctrl.m_timer->function = (void *)wl_iw_set_ss_cache_timer_flag; - init_timer(g_ss_cache_ctrl.m_timer); - - return 0; -} - - - -static void -wl_iw_free_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - WL_TRACE(("%s called\n", __FUNCTION__)); - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - - for (;node;) { - WL_TRACE(("%s : SSID - %s\n", __FUNCTION__, node->bss_info->SSID)); - cur = node; - node = cur->next; - kfree(cur); - } - *spec_scan_head = NULL; - mutex_unlock(&wl_cache_lock); -} - - - -static int -wl_iw_run_ss_cache_timer(int kick_off) -{ - struct timer_list **timer; - - timer = &g_ss_cache_ctrl.m_timer; - - if (*timer) { - if (kick_off) { - (*timer)->expires = jiffies + 30000 * HZ / 1000; - add_timer(*timer); - WL_TRACE(("%s : timer starts \n", __FUNCTION__)); - } else { - del_timer_sync(*timer); - WL_TRACE(("%s : timer stops \n", __FUNCTION__)); - } - } - - return 0; -} - - -void -wl_iw_release_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - if (g_ss_cache_ctrl.m_timer) { - kfree(g_ss_cache_ctrl.m_timer); - } -} - - - -static void -wl_iw_reset_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *prev, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - - for (;node;) { - WL_TRACE(("%s : node SSID %s \n", __FUNCTION__, node->bss_info->SSID)); - if (!node->dirty) { - cur = node; - if (cur == *spec_scan_head) { - *spec_scan_head = cur->next; - prev = *spec_scan_head; - } - else { - prev->next = cur->next; - } - node = cur->next; - - WL_TRACE(("%s : Del node : SSID %s\n", __FUNCTION__, cur->bss_info->SSID)); - kfree(cur); - continue; - } - - node->dirty = 0; - prev = node; - node = node->next; - } - mutex_unlock(&wl_cache_lock); -} - - -static int -wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) -{ - - wl_iw_ss_cache_t *node, *prev, *leaf; - wl_iw_ss_cache_t **spec_scan_head; - wl_bss_info_t *bi = NULL; - int i; - - if (!ss_list->count) { - return 0; - } - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - - for (i = 0; i < ss_list->count; i++) { - - node = *spec_scan_head; - prev = node; - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - - WL_TRACE(("%s : find %d with specific SSID %s\n", __FUNCTION__, i, bi->SSID)); - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - - WL_TRACE(("dirty marked : SSID %s\n", bi->SSID)); - node->dirty = 1; - break; - } - prev = node; - node = node->next; - } - - if (node) { - continue; - } - leaf = kmalloc(bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); - if (!leaf) { - WL_ERROR(("Memory alloc failure %d\n", \ - bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); - mutex_unlock(&wl_cache_lock); - return -ENOMEM; - } - - memcpy(leaf->bss_info, bi, bi->length); - leaf->next = NULL; - leaf->dirty = 1; - leaf->count = 1; - leaf->version = ss_list->version; - - if (!prev) { - *spec_scan_head = leaf; - } - else { - prev->next = leaf; - } - } - mutex_unlock(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_merge_scan_cache(struct iw_request_info *info, char *extra, uint buflen_from_user, -__u16 *merged_len) -{ - wl_iw_ss_cache_t *node; - wl_scan_results_t *list_merge; - - mutex_lock(&wl_cache_lock); - node = g_ss_cache_ctrl.m_cache_head; - for (;node;) { - list_merge = (wl_scan_results_t *)&node->buflen; - WL_TRACE(("%s: Cached Specific APs list=%d\n", __FUNCTION__, list_merge->count)); - if (buflen_from_user - *merged_len > 0) { - *merged_len += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + *merged_len, buflen_from_user - *merged_len); - } - else { - WL_TRACE(("%s: exit with break\n", __FUNCTION__)); - break; - } - node = node->next; - } - mutex_unlock(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_delete_bss_from_ss_cache(void *addr) -{ - - wl_iw_ss_cache_t *node, *prev; - wl_iw_ss_cache_t **spec_scan_head; - - mutex_lock(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, addr, ETHER_ADDR_LEN)) { - if (node == *spec_scan_head) { - *spec_scan_head = node->next; - } - else { - prev->next = node->next; - } - - WL_TRACE(("%s : Del node : %s\n", __FUNCTION__, node->bss_info->SSID)); - kfree(node); - break; - } - - prev = node; - node = node->next; - } - - memset(addr, 0, ETHER_ADDR_LEN); - mutex_unlock(&wl_cache_lock); - return 0; -} - -#endif - - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - WL_TRACE(("%s dev:%s: SIOCSIWSCAN : SCAN\n", __FUNCTION__, dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan != BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - WL_ERROR(("%s Ignoring SC %s first BC is not done = %d\n", \ - __FUNCTION__, req->essid, \ - g_first_broadcast_scan)); - return -EBUSY; - } -#endif - if (g_scan_specified_ssid) { - WL_SCAN(("%s Specific SCAN is not done ignore scan for = %s \n", \ - __FUNCTION__, req->essid)); - return -EBUSY; - } - else { - g_specific_ssid.SSID_len = MIN(sizeof(g_specific_ssid.SSID), \ - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = htod32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE(("### Specific scan ssid=%s len=%d\n", \ - g_specific_ssid.SSID, g_specific_ssid.SSID_len)); - } - } - } -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)))) { - WL_SCAN(("Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error)); - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int -wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_IDLE) { - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_STARTED; - WL_SCAN(("%s: First Brodcast scan was forced\n", __FUNCTION__)); - } - else if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) { - WL_SCAN(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__)); - return 0; - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_lock(); -#endif - - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &iscan->scan_flag, sizeof(iscan->scan_flag)); - wl_iw_set_event_mask(dev); - - WL_SCAN(("+++: Set Broadcast ISCAN\n")); - - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - int ret = 0; - - WL_SCAN(("%s: SIOCSIWSCAN : ISCAN\n", dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - - net_os_wake_lock(dev); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_SCAN(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - goto set_scan_end; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_SCAN(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto set_scan_end; - } - -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_SCAN(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - goto set_scan_end; - } - - if (g_scan_specified_ssid) { - WL_SCAN(("%s Specific SCAN already running ignoring BC scan\n", \ - __FUNCTION__)); - ret = EBUSY; - goto set_scan_end; - } - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int as = 0; - struct iw_scan_req *req = (struct iw_scan_req *)extra; - ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = htod32(ssid.SSID_len); - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); - wl_iw_set_event_mask(dev); - ret = wl_iw_set_scan(dev, info, wrqu, extra); - goto set_scan_end; - } - else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_SCAN(("%s ISCAN already in progress \n", __FUNCTION__)); - goto set_scan_end; - } - } - } -#endif - -#if defined(CONFIG_FIRST_SCAN) && !defined(CSCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", \ - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring Broadcast Scan:First Scan is not done yet %d\n", \ - __FUNCTION__, g_first_counter_scans)); - ret = -EBUSY; - goto set_scan_end; - } - } -#endif - - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - -set_scan_end: - net_os_wake_unlock(dev); - return ret; -} -#endif - -#if WIRELESS_EXT > 17 -static bool -ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) -{ - uint8 *ie = *wpaie; - - if ((ie[1] >= 6) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return TRUE; - } - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} - -static bool -ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) -{ - uint8 *ie = *wpsie; - - if ((ie[1] >= 4) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return TRUE; - } - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} -#endif - -static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, - size_t len, int uppercase) -{ - size_t i; - char *pos = buf, *end = buf + buf_size; - int ret; - if (buf_size == 0) - return 0; - for (i = 0; i < len; i++) { - ret = snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", - data[i]); - if (ret < 0 || ret >= end - pos) { - end[-1] = '\0'; - return pos - buf; - } - pos += ret; - } - end[-1] = '\0'; - return pos - buf; -} - - -int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -{ - return _wpa_snprintf_hex(buf, buf_size, data, len, 0); -} - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - char *buf; - int custom_event_len; - - event = *event_p; - if (bi->ie_length) { - - bcm_tlv_t *ie; - uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - -#ifdef BCMWPA2 - if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - } - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -#endif - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - - if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WAPI_ID))) { - WL_TRACE(("%s: found a WAPI IE...\n", __FUNCTION__)); -#ifdef WAPI_IE_USE_GENIE - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -#else - iwe.cmd = IWEVCUSTOM; - custom_event_len = strlen("wapi_ie=") + 2*(ie->len + 2); - iwe.u.data.length = custom_event_len; - - buf = kmalloc(custom_event_len+1, GFP_KERNEL); - if (buf == NULL) - { - WL_ERROR(("malloc(%d) returned NULL...\n", custom_event_len)); - break; - } - - memcpy(buf, "wapi_ie=", 8); - wpa_snprintf_hex(buf + 8, 2+1, &(ie->id), 1); - wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); - wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); - kfree(buf); -#endif - break; - } - *event_p = event; - } -#endif - - return 0; -} - -#ifndef CSCAN -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - int channel; - - if (!list) { - WL_ERROR(("%s: Null list pointer",__FUNCTION__)); - return ret; - } - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) - { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", \ - __FUNCTION__, list->version)); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - WL_TRACE(("%s : %s\n", __FUNCTION__, bi->SSID)); - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (((event -extra) + IW_EV_LCP_LEN) <= (uintptr)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - if ((ret = (event - extra)) < 0) { - WL_ERROR(("==> Wrong size\n")); - ret = 0; - } - WL_TRACE(("%s: size=%d bytes prepared \n", __FUNCTION__, (unsigned int)(event - extra))); - return (uint)ret; -} - -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if !defined(CSCAN) - __u16 merged_len = 0; -#endif -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; -#if !defined(CSCAN) - uint32 counter = 0; -#endif -#endif - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); - - if (!extra) { - WL_TRACE(("%s: wl_iw_get_scan return -EINVAL\n", dev->name)); - return -EINVAL; - } - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - ci.scan_channel = dtoh32(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if ((!g_scan_specified_ssid && g_ss_cache_ctrl.m_prev_scan_mode) || - g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - if (g_scan_specified_ssid) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - } - else { - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - if (g_scan_specified_ssid) { - - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE(("%s: wl_iw_get_scan return -ENOMEM\n", dev->name)); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = htod32(len); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len))) { - WL_ERROR(("%s: %s : Scan_results ERROR %d\n", dev->name, __FUNCTION__, error)); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - -#if !defined(CSCAN) - if (g_scan_specified_ssid) { - - wl_iw_add_bss_to_ss_cache(list); - kfree(list); - } - - mutex_lock(&wl_cache_lock); -#if defined(WL_IW_USE_ISCAN) - if (g_scan_specified_ssid) - WL_TRACE(("%s: Specified scan APs from scan=%d\n", __FUNCTION__, list->count)); - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - counter += list_merge->count; - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } - WL_TRACE(("%s merged with total Bcast APs=%d\n", __FUNCTION__, counter)); -#else - list_merge = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list_merge, info, extra, buflen_from_user); -#endif - mutex_unlock(&wl_cache_lock); - if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - - wl_iw_merge_scan_cache(info, extra+len_ret, buflen_from_user-len_ret, &merged_len); - len_ret += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#else - - if (g_scan_specified_ssid) { - WL_TRACE(("%s: Specified scan APs in the list =%d\n", __FUNCTION__, list->count)); - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, extra+len_ret, - buflen_from_user -len_ret); -#endif - } - else { - list = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - } -#endif - -#if defined(WL_IW_USE_ISCAN) - - g_scan_specified_ssid = 0; -#endif - - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, list->count)); - return 0; -} -#endif - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; - uint32 counter = 0; - uint8 channel; -#if !defined(CSCAN) - __u16 merged_len = 0; - uint buflen_from_user = dwrq->length; -#endif - - WL_SCAN(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return -EINVAL; - } -#endif - - if (!extra) { - WL_TRACE(("%s: INVALID SIOCGIWSCAN GET bad parameter\n", dev->name)); - return -EINVAL; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_READY) { - WL_TRACE(("%s %s: first ISCAN results are NOT ready yet \n", \ - dev->name, __FUNCTION__)); - return -EAGAIN; - } -#endif - - if ((!iscan) || (iscan->sysioc_pid < 0)) { - WL_ERROR(("%ssysioc_pid\n", __FUNCTION__)); - return -EAGAIN; - } - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if (g_scan_specified_ssid) { - return wl_iw_get_scan(dev, info, dwrq, extra); - } - else { - if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - if (g_ss_cache_ctrl.m_prev_scan_mode || g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - WL_TRACE(("%s: SIOCGIWSCAN GET broadcast results\n", dev->name)); - apcnt = 0; - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - if ((dtoh32(bi->length) > WLC_IW_ISCAN_MAXLEN) || - (((uintptr)bi + dtoh32(bi->length)) > ((uintptr)list + WLC_IW_ISCAN_MAXLEN))) { - WL_ERROR(("%s: Scan results out of bounds: %u\n",__FUNCTION__,dtoh32(bi->length))); - return -E2BIG; - } - - if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN + - IW_EV_QUAL_LEN >= end) - return -E2BIG; - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - -#if !defined(CSCAN) - wl_iw_merge_scan_cache(info, event, buflen_from_user - dwrq->length, &merged_len); - dwrq->length += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#endif /* CSCAN */ -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; -#endif - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter)); - - return 0; -} -#endif - -static int -wl_iw_set_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - int error; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); - - - memset(&g_ssid, 0, sizeof(g_ssid)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length); -#else - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length-1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - } else { - - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = htod32(g_ssid.SSID_len); - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN); - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s ch=%d\n", __FUNCTION__, \ - g_ssid.SSID, g_wl_iw_params.target_channel)); - } - return 0; -} - -static int -wl_iw_get_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { - WL_ERROR(("Error getting the SSID\n")); - return error; - } - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int wl_iw_set_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) - return error; - - rateset.count = dtoh32(rateset.count); - - if (vwrq->value < 0) { - - rate = rateset.rates[rateset.count - 1] & 0x7f; - } else if (vwrq->value < rateset.count) { - - rate = rateset.rates[vwrq->value] & 0x7f; - } else { - - rate = vwrq->value / 500000; - } - - if (vwrq->fixed) { - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return (error_bg | error_a); - } else { - - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return (error_bg | error_a); - - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = htod32(i); - - - if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) - return error; - } - - return 0; -} - -static int wl_iw_get_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rate; - - WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) - return error; - rate = dtoh32(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) - return error; - - return 0; -} - -static int -wl_iw_get_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, frag; - - WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) - return error; - - return 0; -} - -static int -wl_iw_get_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, fragthreshold; - - WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable; - uint16 txpwrmw; - WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); - - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = htod32(disable); - if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) - return error; - - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) txpwrmw = 0xffff; - else txpwrmw = (uint16)vwrq->value; - - - error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable, txpwrdbm; - uint8 result; - - WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || - (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) - return error; - - disable = dtoh32(disable); - result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (int32)bcm_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); - - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - - if (vwrq->flags & IW_RETRY_LIMIT) { - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || - !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) - return error; - } - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || - !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); - - vwrq->disabled = 0; - - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || - (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) - return error; - - lrl = dtoh32(lrl); - srl = dtoh32(srl); - - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif - -static int -wl_iw_set_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name)); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WEP1_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WEP128_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP128; - break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) - case TKIP_KEY_SIZE: - key.algo = CRYPTO_ALGO_TKIP; - break; -#endif - case AES_KEY_SIZE: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - - swap_key_from_BE(&key); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) - return error; - } - - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) - return error; - - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = htod32(val); - if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) - return error; - - return 0; -} - -static int -wl_iw_get_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - - - bzero(&key, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = key.index; - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) - return error; - - swap_key_to_BE(&key); - - wsec = dtoh32(wsec); - auth = dtoh32(auth); - - dwrq->length = MIN(DOT11_MAX_KEY_SIZE, key.len); - - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { - - dwrq->flags |= IW_ENCODE_DISABLED; - } - if (auth) { - - dwrq->flags |= IW_ENCODE_RESTRICTED; - } - - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = htod32(pm); - if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) - return error; - - return 0; -} - -static int -wl_iw_get_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) - return error; - - pm = dtoh32(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - uchar buf[WLC_IOCTL_SMLEN] = {0}; - uchar *p = buf; - int wapi_ie_size; - - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (extra[0] == DOT11_MNG_WAPI_ID) - { - wapi_ie_size = iwp->length; - memcpy(p, extra, iwp->length); - dev_wlc_bufvar_set(dev, "wapiie", buf, wapi_ie_size); - } - else - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_WSEC(("%s: SIOCSIWENCODEEXT\n", dev->name)); - - CHECK_EXTRA_FOR_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - - if (!ETHER_ISMULTI(iwe->addr.sa_data)) - bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); - - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("Changing the the primary Key to %d\n", key.index)); - - key.index = htod32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } - - else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } - else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC(("Setting the key index %d\n", key.index)); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("key is a Primary Key\n")); - key.flags = WL_PRIMARY_KEY; - } - - bcopy((void *)iwe->key, key.data, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - uint8 keybuf[8]; - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); - } - - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - uchar *ivptr; - ivptr = (uchar *)iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = TRUE; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WEP1_KEY_SIZE) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - case IW_ENCODE_ALG_SM4: - key.algo = CRYPTO_ALGO_SMS4; - if (iwe->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - key.flags &= ~WL_PRIMARY_KEY; - } - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -#ifdef BCMWPA2 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID-1]; -} pmkid_list; - -static int -wl_iw_set_pmksa( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - char eabuf[ETHER_ADDR_STR_LEN]; - - WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); - CHECK_EXTRA_FOR_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - bzero((char *)eabuf, ETHER_ADDR_STR_LEN); - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); - bzero((char *)&pmkid_list, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); - - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", - bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkidptr->pmkid[0].PMKID[j])); - WL_WSEC(("\n")); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_list.pmkids.pmkid[i+1].BSSID, - &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&pmkid_list.pmkids.pmkid[i+1].PMKID, - &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } - else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) - break; - if (i < MAXPMKID) { - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } - else - ret = -EINVAL; - - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[k].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j])); - WL_WSEC(("\n")); - } - } - WL_WSEC(("PRINTING pmkid LIST - No of elements %d, ret = %d\n", pmkid_list.pmkids.npmkid, ret)); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC(("PMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[i].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j])); - WL_WSEC(("\n")); - } - WL_WSEC(("\n")); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list)); - return ret; -} -#endif -#endif - -static int -wl_iw_get_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - WL_WSEC(("%s: SIOCGIWENCODEEXT\n", dev->name)); - return 0; -} - -static int -wl_iw_set_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_WSEC(("%s: SIOCSIWAUTH\n", dev->name)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_WSEC(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", - dev->name, paramid, paramval)); - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; -#ifdef BCMWPA2 - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; -#endif - else if (paramval & IW_AUTH_WAPI_VERSION_1) - val = WPA_AUTH_WAPI; - WL_WSEC(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - - - if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - val = WEP_ENABLED; - if (paramval & IW_AUTH_CIPHER_TKIP) - val = TKIP_ENABLED; - if (paramval & IW_AUTH_CIPHER_CCMP) - val = AES_ENABLED; - if (paramval & IW_AUTH_CIPHER_SMS4) - val = SMS4_ENABLED; - - if (paramid == IW_AUTH_CIPHER_PAIRWISE) { - iw->pwsec = val; - val |= iw->gwsec; - } - else { - iw->gwsec = val; - val |= iw->pwsec; - } - - if (iw->privacy_invoked && !val) { - WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " - "we're a WPS enrollee\n", dev->name, __FUNCTION__)); - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { - WL_ERROR(("Failed to set iovar is_WPS_enrollee\n")); - return error; - } - } else if (val) { - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_ERROR(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } - - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { - WL_ERROR(("Failed to set 'wsec'iovar\n")); - return error; - } - - break; - - case IW_AUTH_KEY_MGMT: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) { - WL_ERROR(("Failed to get 'wpa_auth'iovar\n")); - return error; - } - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - } -#ifdef BCMWPA2 - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - } -#endif - if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT)) - val = WPA_AUTH_WAPI; - WL_WSEC(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) { - WL_ERROR(("Failed to set 'wpa_auth'iovar\n")); - return error; - } - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - if ((error = dev_wlc_bufvar_set(dev, "tkip_countermeasures", \ - (char *)¶mval, sizeof(paramval)))) - WL_WSEC(("%s: tkip_countermeasures failed %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_80211_AUTH_ALG: - - WL_WSEC(("Setting the D11auth %d\n", paramval)); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) - return error; - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->pwsec = 0; - iw->gwsec = 0; - if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) { - WL_ERROR(("Failed to get 'wsec'iovar\n")); - return error; - } - if (val & (TKIP_ENABLED | AES_ENABLED)) { - val &= ~(TKIP_ENABLED | AES_ENABLED); - dev_wlc_intvar_set(dev, "wsec", val); - } - val = 0; - - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", - __FUNCTION__, __LINE__, val)); - error = dev_wlc_intvar_set(dev, "wpa_auth", 0); - if (error) - WL_ERROR(("Failed to set 'wpa_auth'iovar\n")); - return error; - } - - - break; - - case IW_AUTH_DROP_UNENCRYPTED: - error = dev_wlc_bufvar_set(dev, "wsec_restrict", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s: wsec_restrict %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - error = dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_WSEC(("%s: rx_unencrypted_eapol %d\n", __FUNCTION__, error)); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: { - int wsec; - - if (paramval == 0) { - iw->privacy_invoked = FALSE; - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } else { - iw->privacy_invoked = TRUE; - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - if (!(IW_WSEC_ENABLED(wsec))) { - - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { - WL_WSEC(("Failed to set iovar is_WPS_enrollee\n")); - return error; - } - } else { - if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { - WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); - return error; - } - } - } - break; - } -#endif - case IW_AUTH_WAPI_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) - return error; - if (paramval) { - val |= SMS4_ENABLED; - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { - WL_ERROR(("%s: setting wsec to 0x%0x returned error %d\n", - __FUNCTION__, val, error)); - return error; - } - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", WPA_AUTH_WAPI))) { - WL_ERROR(("%s: setting wpa_auth(WPA_AUTH_WAPI) returned %d\n", - __FUNCTION__, error)); - return error; - } - } - - break; - default: - break; - } - return 0; -} -#ifdef BCMWPA2 -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) -#else -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK)) -#endif - -static int -wl_iw_get_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev); - - WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) - paramval = IW_AUTH_WPA_VERSION_DISABLED; - else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA; -#ifdef BCMWPA2 - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA2; -#endif - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramid == IW_AUTH_CIPHER_PAIRWISE) - val = iw->pwsec; - else - val = iw->gwsec; - - paramval = 0; - if (val) { - if (val & WEP_ENABLED) - paramval |= (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104); - if (val & TKIP_ENABLED) - paramval |= (IW_AUTH_CIPHER_TKIP); - if (val & AES_ENABLED) - paramval |= (IW_AUTH_CIPHER_CCMP); - } - else - paramval = IW_AUTH_CIPHER_NONE; - break; - case IW_AUTH_KEY_MGMT: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - error = dev_wlc_bufvar_get(dev, "tkip_countermeasures", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get tkip_countermeasures %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - error = dev_wlc_bufvar_get(dev, "wsec_restrict", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get wsec_restrict %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - error = dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", \ - (char *)¶mval, sizeof(paramval)); - if (error) - WL_ERROR(("%s get rx_unencrypted_eapol %d\n", __FUNCTION__, error)); - break; - - case IW_AUTH_80211_AUTH_ALG: - - if ((error = dev_wlc_intvar_get(dev, "auth", &val))) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val) - paramval = TRUE; - else - paramval = FALSE; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; -#endif - } - vwrq->value = paramval; - return 0; -} -#endif - - -#ifdef SOFTAP - -static int ap_macmode = MACLIST_MODE_DISABLED; -static struct mflist ap_black_list; -static int -wl_iw_parse_wep(char *keystr, wl_wsec_key_t *key) -{ - char hex[] = "XX"; - unsigned char *data = key->data; - - switch (strlen(keystr)) { - case 5: - case 13: - case 16: - key->len = strlen(keystr); - memcpy(data, keystr, key->len + 1); - break; - case 12: - case 28: - case 34: - case 66: - if (!strnicmp(keystr, "0x", 2)) - keystr += 2; - else - return -1; - case 10: - case 26: - case 32: - case 64: - key->len = strlen(keystr) / 2; - while (*keystr) { - strncpy(hex, keystr, 2); - *data++ = (char) bcm_strtoul(hex, NULL, 16); - keystr += 2; - } - break; - default: - return -1; - } - - switch (key->len) { - case 5: - key->algo = CRYPTO_ALGO_WEP1; - break; - case 13: - key->algo = CRYPTO_ALGO_WEP128; - break; - case 16: - key->algo = CRYPTO_ALGO_AES_CCM; - break; - case 32: - key->algo = CRYPTO_ALGO_TKIP; - break; - default: - return -1; - } - - key->flags |= WL_PRIMARY_KEY; - - return 0; -} - -#ifdef EXT_WPA_CRYPTO -#define SHA1HashSize 20 -extern void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen); - -#else - -#define SHA1HashSize 20 -int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen) -{ - WL_ERROR(("WARNING: %s is not implemented !!!\n", __FUNCTION__)); - return -1; -} - -#endif - - -int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val) -{ - struct { - int cfg; - int val; - } bss_setbuf; - - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_setbuf.cfg = 1; - bss_setbuf.val = val; - - bss_set_res = dev_iw_iovar_setbuf(dev, "bss", - &bss_setbuf, sizeof(bss_setbuf), smbuf, sizeof(smbuf)); - WL_TRACE(("%s: bss_set_result:%d set with %d\n", __FUNCTION__, bss_set_res, val)); - - return bss_set_res; -} - - -int dev_iw_read_cfg1_bss_var(struct net_device *dev, int *val) -{ - int bsscfg_idx = 1; - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_set_res = dev_iw_iovar_getbuf(dev, "bss", \ - &bsscfg_idx, sizeof(bsscfg_idx), smbuf, sizeof(smbuf)); - *val = *(int*)smbuf; - *val = dtoh32(*val); - WL_TRACE(("%s: status=%d bss_get_result=%d\n", __FUNCTION__, bss_set_res, *val)); - return bss_set_res; -} - - -#ifndef AP_ONLY -static int wl_bssiovar_mkbuf( - const char *iovar, - int bssidx, - void *param, - int paramlen, - void *bufptr, - int buflen, - int *perr) -{ - const char *prefix = "bsscfg:"; - int8 *p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); - namelen = strlen(iovar) + 1; - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - if (buflen < 0 || iolen > (uint)buflen) { - *perr = BCME_BUFTOOSHORT; - return 0; - } - - p = (int8 *)bufptr; - - memcpy(p, prefix, prefixlen); - p += prefixlen; - - memcpy(p, iovar, namelen); - p += namelen; - - bssidx = htod32(bssidx); - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - if (paramlen) - memcpy(p, param, paramlen); - - *perr = 0; - return iolen; -} -#endif - - -int get_user_params(char *user_params, struct iw_point *dwrq) -{ - int ret = 0; - - if (copy_from_user(user_params, dwrq->pointer, dwrq->length)) { - WL_ERROR(("\n%s: no user params: uptr:%p, ulen:%d\n", - __FUNCTION__, dwrq->pointer, dwrq->length)); - return -EFAULT; - } - - WL_TRACE(("\n%s: iwpriv user params:%s\n", __FUNCTION__, user_params)); - - return ret; -} - - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -#if defined(CSCAN) - -static int -wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, int nchan) -{ - int params_size = WL_SCAN_PARAMS_FIXED_SIZE + WL_NUMCHANNELS * sizeof(uint16); - int err = 0; - char *p; - int i; - iscan_info_t *iscan = g_iscan; - - WL_SCAN(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan)); - - if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) { - WL_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - goto exit; - } - -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); - - if (nssid > 0) { - i = OFFSETOF(wl_scan_params_t, channel_list) + nchan * sizeof(uint16); - i = ROUNDUP(i, sizeof(uint32)); - if (i + nssid * sizeof(wlc_ssid_t) > params_size) { - printf("additional ssids exceed params_size\n"); - err = -1; - goto exit; - } - - p = ((char*)&iscan->iscan_ex_params_p->params) + i; - memcpy(p, ssids_local, nssid * sizeof(wlc_ssid_t)); - p += nssid * sizeof(wlc_ssid_t); - } else { - p = (char*)iscan->iscan_ex_params_p->params.channel_list + nchan * sizeof(uint16); - } - - iscan->iscan_ex_params_p->params.channel_num = \ - htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | \ - (nchan & WL_SCAN_PARAMS_COUNT_MASK)); - - nssid = \ - (uint)((iscan->iscan_ex_params_p->params.channel_num >> WL_SCAN_PARAMS_NSSID_SHIFT) & \ - WL_SCAN_PARAMS_COUNT_MASK); - - params_size = (int) (p - (char*)iscan->iscan_ex_params_p + nssid * sizeof(wlc_ssid_t)); - iscan->iscan_ex_param_size = params_size; - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - wl_iw_set_event_mask(dev); - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - -#ifdef SCAN_DUMP - { - int i; - WL_SCAN(("\n### List of SSIDs to scan ###\n")); - for (i = 0; i < nssid; i++) { - if (!ssids_local[i].SSID_len) - WL_SCAN(("%d: Broadcast scan\n", i)); - else - WL_SCAN(("%d: scan for %s size =%d\n", i, \ - ssids_local[i].SSID, ssids_local[i].SSID_len)); - } - WL_SCAN(("### List of channels to scan ###\n")); - for (i = 0; i < nchan; i++) - { - WL_SCAN(("%d ", iscan->iscan_ex_params_p->params.channel_list[i])); - } - WL_SCAN(("\nnprobes=%d\n", iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("\n###################\n")); - } -#endif - - if (params_size > WLC_IOCTL_MEDLEN) { - WL_ERROR(("Set ISCAN for %s due to params_size=%d \n", \ - __FUNCTION__, params_size)); - err = -1; - } - - if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan->iscan_ex_params_p, \ - iscan->iscan_ex_param_size, \ - iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - -exit: - - return err; -} - - -static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info, \ - union iwreq_data *wrqu, char *ext) -{ - int res = 0; - char *extra = NULL; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - - WL_TRACE(("\%s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - -#ifdef PNO_SET_DEBUG - wl_iw_set_pno_set(dev, info, wrqu, extra); - return 0; -#endif - - if (wrqu->data.length != 0) { - - char *str_ptr; - - if (!iscan->iscan_ex_params_p) { - return -EFAULT; - } - - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } - - extra[wrqu->data.length] = 0; - WL_ERROR(("Got str param in iw_point:\n %s\n", extra)); - - str_ptr = extra; - - if (strncmp(str_ptr, GET_SSID, strlen(GET_SSID))) { - WL_ERROR(("%s Error: extracting SSID='' string\n", __FUNCTION__)); - goto exit_proc; - } - str_ptr += strlen(GET_SSID); - nssid = wl_iw_parse_ssid_list(&str_ptr, ssids_local, nssid, \ - WL_SCAN_PARAMS_SSID_MAX); - if (nssid == -1) { - WL_ERROR(("%s wrong ssid list", __FUNCTION__)); - return -1; - } - - if (iscan->iscan_ex_param_size > WLC_IOCTL_MAXLEN) { - WL_ERROR(("%s wrong ex_param_size %d", \ - __FUNCTION__, iscan->iscan_ex_param_size)); - return -1; - } - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - if ((nchan = wl_iw_parse_channel_list(&str_ptr, \ - &iscan->iscan_ex_params_p->params.channel_list[0], \ - WL_NUMCHANNELS)) == -1) { - WL_ERROR(("%s missing channel list\n", __FUNCTION__)); - return -1; - } - - - get_parmeter_from_string(&str_ptr, \ - GET_NPROBE, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.nprobes, 2); - - get_parmeter_from_string(&str_ptr, GET_ACTIVE_ASSOC_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.active_time, 4); - - get_parmeter_from_string(&str_ptr, GET_PASSIVE_ASSOC_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.passive_time, 4); - - get_parmeter_from_string(&str_ptr, GET_HOME_DWELL, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.home_time, 4); - - get_parmeter_from_string(&str_ptr, GET_SCAN_TYPE, PTYPE_INTDEC, \ - &iscan->iscan_ex_params_p->params.scan_type, 1); - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - - } else { - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; - } - -exit_proc: - - kfree(extra); - - return res; -} - - -static int -wl_iw_set_cscan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int res = -1; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - cscan_tlv_t *cscan_tlv_temp; - char type; - char *str_ptr; - int tlv_size_left; -#ifdef TLV_DEBUG - int i; - char tlv_in_example[] = { 'C', 'S', 'C', 'A', 'N', ' ', \ - 0x53, 0x01, 0x00, 0x00, - 'S', - 0x00, - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'C', - 0x06, - 'P', - 0x94, - 0x11, - 'T', - 0x01 - }; -#endif - - WL_TRACE(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - - - if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) { - WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, \ - wrqu->data.length, strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))); - goto exit_proc; - } - -#ifdef TLV_DEBUG - memcpy(extra, tlv_in_example, sizeof(tlv_in_example)); - wrqu->data.length = sizeof(tlv_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; - str_ptr += strlen(CSCAN_COMMAND); - tlv_size_left = wrqu->data.length - strlen(CSCAN_COMMAND); - - cscan_tlv_temp = (cscan_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cscan_tlv_temp->prefix == CSCAN_TLV_PREFIX) && \ - (cscan_tlv_temp->version == CSCAN_TLV_VERSION) && \ - (cscan_tlv_temp->subver == CSCAN_TLV_SUBVERSION)) - { - str_ptr += sizeof(cscan_tlv_t); - tlv_size_left -= sizeof(cscan_tlv_t); - - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, \ - WL_SCAN_PARAMS_SSID_MAX, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - while (tlv_size_left > 0) - { - type = str_ptr[0]; - switch (type) { - case CSCAN_TLV_TYPE_CHANNEL_IE: - - if ((nchan = wl_iw_parse_channel_list_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.channel_list[0], \ - WL_NUMCHANNELS, &tlv_size_left)) == -1) { - WL_ERROR(("%s missing channel list\n", \ - __FUNCTION__)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_NPROBE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.nprobes, \ - sizeof(iscan->iscan_ex_params_p->params.nprobes), \ - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_ACTIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.active_time, \ - sizeof(iscan->iscan_ex_params_p->params.active_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_PASSIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.passive_time, \ - sizeof(iscan->iscan_ex_params_p->params.passive_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_HOME_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.home_time, \ - sizeof(iscan->iscan_ex_params_p->params.home_time), \ - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_STYPE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, \ - &iscan->iscan_ex_params_p->params.scan_type, \ - sizeof(iscan->iscan_ex_params_p->params.scan_type), \ - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", \ - __FUNCTION__, res)); - goto exit_proc; - } - break; - - default : - WL_ERROR(("%s get unkwown type %X\n", \ - __FUNCTION__, type)); - goto exit_proc; - break; - } - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", \ - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring CSCAN : First Scan is not done yet %d\n", \ - __FUNCTION__, g_first_counter_scans)); - res = -EBUSY; - goto exit_proc; - } - } -#endif - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - -exit_proc: - net_os_wake_unlock(dev); - return res; -} - -#endif - -#ifdef SOFTAP -#ifndef AP_ONLY - -static int thr_wait_for_2nd_eth_dev(void *data) -{ - struct net_device *dev = (struct net_device *)data; - wl_iw_t *iw; - int ret = 0; - unsigned long flags; - - net_os_wake_lock(dev); - - DAEMONIZE("wl0_eth_wthread"); - - WL_TRACE(("\n>%s thread started:, PID:%x\n", __FUNCTION__, current->pid)); - iw = *(wl_iw_t **)netdev_priv(dev); - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - ret = -1; - goto fail; - } - -#ifndef BCMSDIOH_STD - if (down_timeout(&ap_eth_sema, msecs_to_jiffies(5000)) != 0) { - WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__)); - ret = -1; - goto fail; - } -#endif - - flags = dhd_os_spin_lock(iw->pub); - if (!ap_net_dev) { - WL_ERROR((" ap_net_dev is null !!!")); - ret = -1; - dhd_os_spin_unlock(iw->pub, flags); - goto fail; - } - - WL_TRACE(("\n>%s: Thread:'softap ethdev IF:%s is detected !!!'\n\n", - __FUNCTION__, ap_net_dev->name)); - - ap_cfg_running = TRUE; - - dhd_os_spin_unlock(iw->pub, flags); - - bcm_mdelay(500); - - wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK"); - -fail: - WL_TRACE(("\n>%s, thread completed\n", __FUNCTION__)); - - net_os_wake_unlock(dev); - - complete_and_exit(&ap_cfg_exited, 0); - return ret; -} -#endif -#ifndef AP_ONLY -static int last_auto_channel = 6; -#endif -static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap) -{ - int chosen = 0; - wl_uint32_list_t request; - int rescan = 0; - int retry = 0; - int updown = 0; - int ret = 0; - wlc_ssid_t null_ssid; - int res = 0; -#ifndef AP_ONLY - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - WL_SOFTAP(("Enter %s\n", __FUNCTION__)); - -#ifndef AP_ONLY - if (ap_cfg_running) { - ap->channel = last_auto_channel; - return res; - } -#endif - memset(&null_ssid, 0, sizeof(wlc_ssid_t)); - res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)); -#ifdef AP_ONLY - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid)); -#else - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&null_ssid), \ - null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen); -#endif - auto_channel_retry: - request.count = htod32(0); - ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request)); - if (ret < 0) { - WL_ERROR(("can't start auto channel scan\n")); - goto fail; - } - - get_channel_retry: - bcm_mdelay(500); - - ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen)); - if (ret < 0 || dtoh32(chosen) == 0) { - if (retry++ < 3) - goto get_channel_retry; - else { - WL_ERROR(("can't get auto channel sel, err = %d, \ - chosen = %d\n", ret, chosen)); - goto fail; - } - } - if ((chosen == 1) && (!rescan++)) - goto auto_channel_retry; - WL_SOFTAP(("Set auto channel = %d\n", chosen)); - ap->channel = chosen; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res)); - goto fail; - } -#ifndef AP_ONLY - if (!res) - last_auto_channel = ap->channel; -#endif - -fail : - return res; -} - - -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap) -{ - int updown = 0; - int channel = 0; - - wlc_ssid_t ap_ssid; - int max_assoc = 8; - - int res = 0; - int apsta_var = 0; -#ifndef AP_ONLY - int mpc = 0; - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - -#ifdef AP_ONLY - if (ap_cfg_running) { - wl_iw_softap_deassoc_stations(dev, NULL); - ap_cfg_running = FALSE; - } -#endif - - if (ap_cfg_running == FALSE) { - -#ifndef AP_ONLY - sema_init(&ap_eth_sema, 0); - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } -#endif - - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set updown\n", __FUNCTION__)); - goto fail; - } - -#ifdef AP_ONLY - apsta_var = 0; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 0\n", __FUNCTION__)); - goto fail; - } - apsta_var = 1; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 1\n", __FUNCTION__)); - goto fail; - } - res = dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var)); -#else - apsta_var = 1; - iolen = wl_bssiovar_mkbuf("apsta", - bsscfg_index, &apsta_var, sizeof(apsta_var)+4, - buf, sizeof(buf), &mkvar_err); - - if (iolen <= 0) - goto fail; - - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res)); -#endif - - updown = 1; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - - } else { - - if (!ap_net_dev) { - WL_ERROR(("%s: ap_net_dev is null\n", __FUNCTION__)); - goto fail; - } - - res = wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - - - if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s fail to set bss down\n", __FUNCTION__)); - goto fail; - } - } - - if (strlen(ap->country_code)) { - WL_ERROR(("%s: Igonored: Country MUST be specified \ - COUNTRY command with \n", __FUNCTION__)); - } else { - WL_SOFTAP(("%s: Country code is not specified," - " will use Radio's default\n", - __FUNCTION__)); - } - - iolen = wl_bssiovar_mkbuf("closednet", - bsscfg_index, &ap->closednet, sizeof(ap->closednet)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s failed to set 'closednet'for apsta \n", __FUNCTION__)); - goto fail; - } - - - if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) { - ap->channel = 1; - WL_ERROR(("%s auto channel failed, pick up channel=%d\n", \ - __FUNCTION__, ap->channel)); - } - - channel = ap->channel; - if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) { - WL_ERROR(("%s fail to set channel\n", __FUNCTION__)); - goto fail; - } - - if (ap_cfg_running == FALSE) { - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set up\n", __FUNCTION__)); - goto fail; - } - } - - max_assoc = ap->max_scb; - if ((res = dev_wlc_intvar_set(dev, "maxassoc", max_assoc))) { - WL_ERROR(("%s fail to set maxassoc\n", __FUNCTION__)); - goto fail; - } - - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - -#ifdef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR(("ERROR:%d in:%s, wl_iw_set_ap_security is skipped\n", \ - res, __FUNCTION__)); - goto fail; - } - wl_iw_send_priv_event(dev, "ASCII_CMD=AP_BSS_START"); - ap_cfg_running = TRUE; -#else - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid), - ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) != 0) { - WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", \ - res, __FUNCTION__)); - goto fail; - } - if (ap_cfg_running == FALSE) { - init_completion(&ap_cfg_exited); - ap_cfg_pid = kernel_thread(thr_wait_for_2nd_eth_dev, dev, 0); - } else { - ap_cfg_pid = -1; - if (ap_net_dev == NULL) { - WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__)); - goto fail; - } - - WL_ERROR(("%s: %s Configure security & restart AP bss \n", \ - __FUNCTION__, ap_net_dev->name)); - - if ((res = wl_iw_set_ap_security(ap_net_dev, &my_ap)) < 0) { - WL_ERROR(("%s fail to set security : %d\n", __FUNCTION__, res)); - goto fail; - } - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) { - WL_ERROR(("%s fail to set bss up\n", __FUNCTION__)); - goto fail; - } - } -#endif -fail: - WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - - -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap) -{ - int wsec = 0; - int wpa_auth = 0; - int res = 0; - int i; - char *ptr; -#ifdef AP_ONLY - int mpc = 0; - wlc_ssid_t ap_ssid; -#endif - wl_wsec_key_t key; - - WL_SOFTAP(("\nsetting SOFTAP security mode:\n")); - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') { - WL_SOFTAP((" key = '%s'\n", ap->key)); - } - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - - if (strnicmp(ap->sec, "open", strlen("open")) == 0) { - wsec = 0; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & wpa_auth set 'OPEN', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - - memset(&key, 0, sizeof(key)); - - wsec = WEP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key.index = 0; - if (wl_iw_parse_wep(ap->key, &key)) { - WL_SOFTAP(("wep key parse err!\n")); - return -1; - } - - key.index = htod32(key.index); - key.len = htod32(key.len); - key.algo = htod32(key.algo); - key.flags = htod32(key.flags); - - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & auth set 'WEP', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wpa2-psk", strlen("wpa2-psk")) == 0) { - wsec_pmk_t psk; - size_t key_len; - - wsec = AES_ENABLED; - dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - - memset(output, 0, sizeof(output)); - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], \ - (uint)output[i*4+1], (uint)output[i*4+2], \ - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - psk.flags = htod16(WSEC_PASSPHRASE); - dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA2_AUTH_PSK; - dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - } else if (strnicmp(ap->sec, "wpa-psk", strlen("wpa-psk")) == 0) { - - wsec_pmk_t psk; - size_t key_len; - - wsec = TKIP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } - - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - bzero(output, 2*SHA1HashSize); - - WL_SOFTAP(("%s: do passhash...\n", __FUNCTION__)); - - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - WL_SOFTAP(("[%02d]: %08x\n", i, *((unsigned int *)&output[i*4]))); - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - - psk.flags = htod16(WSEC_PASSPHRASE); - res |= dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA_AUTH_PSK; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP((" wsec & auth set 'wpa-psk' (TKIP), result:&d %d\n", res)); - } - -#ifdef AP_ONLY - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &ap_ssid, sizeof(ap_ssid)); - mpc = 0; - res |= dev_wlc_intvar_set(dev, "mpc", mpc); - if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } -#endif - return res; -} - - - -int get_parmeter_from_string( - char **str_ptr, const char *token, - int param_type, void *dst, int param_max_len) -{ - char int_str[7] = "0"; - int parm_str_len; - char *param_str_begin; - char *param_str_end; - - if ((*str_ptr) && !strncmp(*str_ptr, token, strlen(token))) { - - strsep(str_ptr, "=,"); - param_str_begin = *str_ptr; - strsep(str_ptr, "=,"); - - if (*str_ptr == NULL) { - parm_str_len = strlen(param_str_begin); - } else { - param_str_end = *str_ptr-1; - parm_str_len = param_str_end - param_str_begin; - } - - WL_TRACE((" 'token:%s', len:%d, ", token, parm_str_len)); - - if (parm_str_len > param_max_len) { - WL_TRACE((" WARNING: extracted param len:%d is > MAX:%d\n", - parm_str_len, param_max_len)); - - parm_str_len = param_max_len; - } - - switch (param_type) { - - case PTYPE_INTDEC: { - int *pdst_int = dst; - char *eptr; - - if (parm_str_len > sizeof(int_str)) - parm_str_len = sizeof(int_str); - - memcpy(int_str, param_str_begin, parm_str_len); - - *pdst_int = simple_strtoul(int_str, &eptr, 10); - - WL_TRACE((" written as integer:%d\n", *pdst_int)); - } - break; - case PTYPE_STR_HEX: { - u8 *buf = dst; - - param_max_len = param_max_len >> 1; - hstr_2_buf(param_str_begin, buf, param_max_len); - print_buf(buf, param_max_len, 0); - } - break; - default: - memcpy(dst, param_str_begin, parm_str_len); - *((char *)dst + parm_str_len) = 0; - WL_TRACE((" written as a string:%s\n", (char *)dst)); - break; - } - - return 0; - } else { - WL_ERROR(("\n %s: No token:%s in str:%s\n", - __FUNCTION__, token, *str_ptr)); - - return -1; - } -} - -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac) -{ - int i; - int res = 0; - char mac_buf[128] = {0}; - char z_mac[6] = {0, 0, 0, 0, 0, 0}; - char *sta_mac; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - bool deauth_all = false; - - if (mac == NULL) { - deauth_all = true; - sta_mac = z_mac; - } else { - sta_mac = mac; - } - - memset(assoc_maclist, 0, sizeof(mac_buf)); - assoc_maclist->count = 8; - - res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128); - if (res != 0) { - WL_SOFTAP(("%s: Error:%d Couldn't get ASSOC List\n", __FUNCTION__, res)); - return res; - } - - if (assoc_maclist->count) { - for (i = 0; i < assoc_maclist->count; i++) { - scb_val_t scbval; - - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN); - - if (deauth_all || (memcmp(&scbval.ea, sta_mac, ETHER_ADDR_LEN) == 0)) { - WL_SOFTAP(("%s, deauth STA:%d \n", __FUNCTION__, i)); - res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } - } - } else { - WL_SOFTAP((" STA ASSOC list is empty\n")); - } - - if (res != 0) { - WL_ERROR(("%s: Error:%d\n", __FUNCTION__, res)); - } else if (assoc_maclist->count) { - bcm_mdelay(200); - } - return res; -} - - -static int iwpriv_softap_stop(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - - WL_SOFTAP(("got iwpriv AP_BSS_STOP\n")); - - if ((!dev) && (!ap_net_dev)) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return res; - } - - net_os_wake_lock(dev); - - if ((ap_cfg_running == TRUE)) { -#ifdef AP_ONLY - wl_iw_softap_deassoc_stations(dev, NULL); -#else - wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - - if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0) - WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res)); -#endif - - bcm_mdelay(100); - - wrqu->data.length = 0; - ap_cfg_running = FALSE; - } - else - WL_ERROR(("%s: was called when SoftAP is OFF : move on\n", __FUNCTION__)); - - WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - - -static int iwpriv_fw_reload(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int ret = -1; - char extra[256]; - char *fwstr = fw_path; - - WL_SOFTAP(("current firmware_path[]=%s\n", fwstr)); - - WL_TRACE((">Got FW_RELOAD cmd:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d, \ - fw_path:%p, len:%d \n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length, fwstr, strlen(fwstr))); - - if ((wrqu->data.length > 4) && (wrqu->data.length < sizeof(extra))) { - - char *str_ptr; - - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit_proc; - } - - extra[wrqu->data.length] = 8; - str_ptr = extra; - - if (get_parmeter_from_string(&str_ptr, "FW_PATH=", PTYPE_STRING, fwstr, 255) != 0) { - WL_ERROR(("Error: extracting FW_PATH='' string\n")); - goto exit_proc; - } - - if (strstr(fwstr, "apsta") != NULL) { - WL_SOFTAP(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - WL_SOFTAP(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; - } - - WL_SOFTAP(("SET firmware_path[]=%s , str_p:%p\n", fwstr, fwstr)); - ret = 0; - } else { - WL_ERROR(("Error: ivalid param len:%d\n", wrqu->data.length)); - } - -exit_proc: - return ret; -} -#endif - -#ifdef SOFTAP -static int iwpriv_wpasupp_loop_tst(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *params = NULL; - - WL_TRACE((">Got IWPRIV wp_supp loopback cmd test:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (wrqu->data.length != 0) { - - if (!(params = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(params, wrqu->data.pointer, wrqu->data.length)) { - kfree(params); - return -EFAULT; - } - - params[wrqu->data.length] = 0; - WL_SOFTAP(("\n>> copied from user:\n %s\n", params)); - } else { - WL_ERROR(("ERROR param length is 0\n")); - return -EFAULT; - } - - res = wl_iw_send_priv_event(dev, params); - kfree(params); - - return res; -} -#endif - - -static int -iwpriv_en_ap_bss( - struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra) -{ - int res = 0; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } - - net_os_wake_lock(dev); - - WL_SOFTAP(("%s: rcvd IWPRIV IOCTL: for dev:%s\n", __FUNCTION__, dev->name)); - -#ifndef AP_ONLY - if (ap_cfg_pid >= 0) { - wait_for_completion(&ap_cfg_exited); - ap_cfg_pid = -1; - } - - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res)); - } - else { - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) - WL_ERROR(("%s fail to set bss up err=%d\n", __FUNCTION__, res)); - else - bcm_mdelay(100); - } - -#endif - WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res)); - - net_os_wake_unlock(dev); - - return res; -} - -static int -get_assoc_sta_list(struct net_device *dev, char *buf, int len) -{ - WL_TRACE(("%s: dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n", - __FUNCTION__, dev, WLC_GET_ASSOCLIST, buf, len)); - - return dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len); - -} - - -void check_error(int res, const char *msg, const char *func, int line) -{ - if (res != 0) - WL_ERROR(("%s, %d function:%s, line:%d\n", msg, res, func, line)); -} - -static int -set_ap_mac_list(struct net_device *dev, void *buf) -{ - struct mac_list_set *mac_list_set = (struct mac_list_set *)buf; - struct maclist *maclist = (struct maclist *)&mac_list_set->mac_list; - int length; - int i; - int mac_mode = mac_list_set->mode; - int ioc_res = 0; - ap_macmode = mac_list_set->mode; - - bzero(&ap_black_list, sizeof(struct mflist)); - - if (mac_mode == MACLIST_MODE_DISABLED) { - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP(("%s: MAC filtering disabled\n", __FUNCTION__)); - } else { - - scb_val_t scbval; - char mac_buf[256] = {0}; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - - bcopy(maclist, &ap_black_list, sizeof(ap_black_list)); - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - - length = sizeof(maclist->count) + maclist->count*ETHER_ADDR_LEN; - dev_wlc_ioctl(dev, WLC_SET_MACLIST, maclist, length); - - WL_SOFTAP(("%s: applied MAC List, mode:%d, length %d:\n", - __FUNCTION__, mac_mode, length)); - for (i = 0; i < maclist->count; i++) - WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n", - i, maclist->ea[i].octet[0], maclist->ea[i].octet[1], \ - maclist->ea[i].octet[2], \ - maclist->ea[i].octet[3], maclist->ea[i].octet[4], \ - maclist->ea[i].octet[5])); - - assoc_maclist->count = 8; - ioc_res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP((" Cur assoc clients:%d\n", assoc_maclist->count)); - - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - int j; - bool assoc_mac_matched = false; - - WL_SOFTAP(("\n Cheking assoc STA: ")); - print_buf(&assoc_maclist->ea[i], 6, 7); - WL_SOFTAP(("with the b/w list:")); - - for (j = 0; j < maclist->count; j++) - if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j], - ETHER_ADDR_LEN)) { - - assoc_mac_matched = true; - break; - } - - if (((mac_mode == MACLIST_MODE_ALLOW) && !assoc_mac_matched) || - ((mac_mode == MACLIST_MODE_DENY) && assoc_mac_matched)) { - - WL_SOFTAP(("b-match or w-mismatch," - " do deauth/disassoc \n")); - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, \ - ETHER_ADDR_LEN); - ioc_res = dev_wlc_ioctl(dev, - WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - check_error(ioc_res, - "ioctl ERROR:", - __FUNCTION__, __LINE__); - - } else { - WL_SOFTAP((" no b/w list hits, let it be\n")); - } - } else { - WL_SOFTAP(("No ASSOC CLIENTS\n")); - } - } - - WL_SOFTAP(("%s iocres:%d\n", __FUNCTION__, ioc_res)); - return ioc_res; -} -#endif - - -#ifdef SOFTAP -int set_macfilt_from_string(struct mflist *pmflist, char **param_str) -{ - return 0; -} -#endif - - -#ifdef SOFTAP -#define PARAM_OFFSET PROFILE_OFFSET - -int wl_iw_process_private_ascii_cmd( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *dwrq, - char *cmd_str) -{ - int ret = 0; - char *sub_cmd = cmd_str + PROFILE_OFFSET + strlen("ASCII_CMD="); - - WL_SOFTAP(("\n %s: ASCII_CMD: offs_0:%s, offset_32:\n'%s'\n", - __FUNCTION__, cmd_str, cmd_str + PROFILE_OFFSET)); - - if (strnicmp(sub_cmd, "AP_CFG", strlen("AP_CFG")) == 0) { - - WL_SOFTAP((" AP_CFG \n")); - - - if (init_ap_profile_from_string(cmd_str+PROFILE_OFFSET, &my_ap) != 0) { - WL_ERROR(("ERROR: SoftAP CFG prams !\n")); - ret = -1; - } else { - ret = set_ap_cfg(dev, &my_ap); - } - - } else if (strnicmp(sub_cmd, "AP_BSS_START", strlen("AP_BSS_START")) == 0) { - - WL_SOFTAP(("\n SOFTAP - ENABLE BSS \n")); - - WL_SOFTAP(("\n!!! got 'WL_AP_EN_BSS' from WPA supplicant, dev:%s\n", dev->name)); - -#ifndef AP_ONLY - if (ap_net_dev == NULL) { - printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n"); - } else { - if ((ret = iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", \ - __FUNCTION__, __LINE__)); - } -#else - if ((ret = iwpriv_en_ap_bss(dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", \ - __FUNCTION__, __LINE__)); -#endif - } else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) { - /* no code yet */ - } else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) { - WL_SOFTAP((" \n temp DOWN SOFTAP\n")); -#ifndef AP_ONLY - if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s line %d fail to set bss down\n", \ - __FUNCTION__, __LINE__)); - } -#endif - } - - return ret; -} -#endif - -static int wl_iw_set_priv( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *ext -) -{ - int ret = 0; - char * extra; - - if (!(extra = kmalloc(dwrq->length, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(extra, dwrq->pointer, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - WL_TRACE(("%s: SIOCSIWPRIV request %s, info->cmd:%x, info->flags:%d\n dwrq->length:%d", - dev->name, extra, info->cmd, info->flags, dwrq->length)); - - net_os_wake_lock(dev); - - if (dwrq->length && extra) { - if (strnicmp(extra, "START", strlen("START")) == 0) { - wl_iw_control_wl_on(dev, info); - WL_TRACE(("%s, Received regular START command\n", __FUNCTION__)); - } - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__)); - kfree(extra); - net_os_wake_unlock(dev); - return -EFAULT; - } - - if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: active scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_active_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - } else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: passive scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_passive_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) - ret = wl_iw_get_rssi(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) - ret = wl_iw_get_link_speed(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) - ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) - ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) - ret = wl_iw_control_wl_off(dev, info); - else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) - ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) - ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) - ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) - ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) - ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) - ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); -#if defined(PNO_SUPPORT) - else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) - ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) - ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) - ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#if defined(CSCAN) - else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) - ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#ifdef CUSTOMER_HW2 - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) { - WL_TRACE_COEX(("%s:got Framwrork cmd: 'BTCOEXMODE'\n", __FUNCTION__)); - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); - } -#else - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) - ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); -#ifdef SOFTAP -#ifdef SOFTAP_TLV_CFG - else if (strnicmp(extra, SOFTAP_SET_CMD, strlen(SOFTAP_SET_CMD)) == 0) { - wl_iw_softap_cfg_tlv(dev, info, (union iwreq_data *)dwrq, extra); - } -#endif - else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { - wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); - } else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { - WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n")); - set_ap_mac_list(dev, (extra + PROFILE_OFFSET)); - } -#endif - else { - WL_TRACE(("Unknown PRIVATE command: %s: ignored\n", extra)); - snprintf(extra, MAX_WX_STRING, "OK"); - dwrq->length = strlen("OK") + 1; - } - } - - net_os_wake_unlock(dev); - - if (extra) { - if (copy_to_user(dwrq->pointer, extra, dwrq->length)) { - kfree(extra); - return -EFAULT; - } - - kfree(extra); - } - - return ret; -} - -static const iw_handler wl_iw_handler[] = -{ - (iw_handler) wl_iw_config_commit, - (iw_handler) wl_iw_get_name, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_freq, - (iw_handler) wl_iw_get_freq, - (iw_handler) wl_iw_set_mode, - (iw_handler) wl_iw_get_mode, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_get_range, - (iw_handler) wl_iw_set_priv, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_spy, - (iw_handler) wl_iw_get_spy, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wap, - (iw_handler) wl_iw_get_wap, -#if WIRELESS_EXT > 17 - (iw_handler) wl_iw_mlme, -#else - (iw_handler) NULL, -#endif -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif -#if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_set_scan, - (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif -#else - (iw_handler) NULL, - (iw_handler) NULL, -#endif - (iw_handler) wl_iw_set_essid, - (iw_handler) wl_iw_get_essid, - (iw_handler) wl_iw_set_nick, - (iw_handler) wl_iw_get_nick, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_rate, - (iw_handler) wl_iw_get_rate, - (iw_handler) wl_iw_set_rts, - (iw_handler) wl_iw_get_rts, - (iw_handler) wl_iw_set_frag, - (iw_handler) wl_iw_get_frag, - (iw_handler) wl_iw_set_txpow, - (iw_handler) wl_iw_get_txpow, -#if WIRELESS_EXT > 10 - (iw_handler) wl_iw_set_retry, - (iw_handler) wl_iw_get_retry, -#endif - (iw_handler) wl_iw_set_encode, - (iw_handler) wl_iw_get_encode, - (iw_handler) wl_iw_set_power, - (iw_handler) wl_iw_get_power, -#if WIRELESS_EXT > 17 - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wpaie, - (iw_handler) wl_iw_get_wpaie, - (iw_handler) wl_iw_set_wpaauth, - (iw_handler) wl_iw_get_wpaauth, - (iw_handler) wl_iw_set_encodeext, - (iw_handler) wl_iw_get_encodeext, -#ifdef BCMWPA2 - (iw_handler) wl_iw_set_pmksa, -#endif -#endif -}; - -#if WIRELESS_EXT > 12 -static const iw_handler wl_iw_priv_handler[] = { - NULL, - (iw_handler)wl_iw_set_active_scan, - NULL, - (iw_handler)wl_iw_get_rssi, - NULL, - (iw_handler)wl_iw_set_passive_scan, - NULL, - (iw_handler)wl_iw_get_link_speed, - NULL, - (iw_handler)wl_iw_get_macaddr, - NULL, - (iw_handler)wl_iw_control_wl_off, - NULL, - (iw_handler)wl_iw_control_wl_on, -#ifdef SOFTAP - NULL, - (iw_handler)iwpriv_set_ap_config, - - NULL, - (iw_handler)iwpriv_get_assoc_list, - - NULL, - (iw_handler)iwpriv_set_mac_filters, - - NULL, - (iw_handler)iwpriv_en_ap_bss, - - NULL, - (iw_handler)iwpriv_wpasupp_loop_tst, - - NULL, - (iw_handler)iwpriv_softap_stop, - - NULL, - (iw_handler)iwpriv_fw_reload, - - NULL, - (iw_handler)iwpriv_set_ap_sta_disassoc, -#endif -#if defined(CSCAN) - - NULL, - (iw_handler)iwpriv_set_cscan -#endif -}; - -static const struct iw_priv_args wl_iw_priv_args[] = { - { - WL_IW_SET_ACTIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-ACTIVE" - }, - { - WL_IW_GET_RSSI, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "RSSI" - }, - { - WL_IW_SET_PASSIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-PASSIVE" - }, - { - WL_IW_GET_LINK_SPEED, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "LINKSPEED" - }, - { - WL_IW_GET_CURR_MACADDR, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "Macaddr" - }, - { - WL_IW_SET_STOP, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "STOP" - }, - { - WL_IW_SET_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "START" - }, - -#ifdef SOFTAP - { - WL_SET_AP_CFG, - IW_PRIV_TYPE_CHAR | 256, - 0, - "AP_SET_CFG" - }, - - { - WL_AP_STA_LIST, - IW_PRIV_TYPE_CHAR | 0, - IW_PRIV_TYPE_CHAR | 1024, - "AP_GET_STA_LIST" - }, - - { - WL_AP_MAC_FLTR, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_SET_MAC_FLTR" - }, - - { - WL_AP_BSS_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "AP_BSS_START" - }, - - { - AP_LPB_CMD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_LPB_CMD" - }, - - { - WL_AP_STOP, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_BSS_STOP" - }, - - { - WL_FW_RELOAD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "WL_FW_RELOAD" - }, - - { - WL_AP_STA_DISASSOC, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | 0, - "AP_STA_DISASSOC" - }, -#endif -#if defined(CSCAN) - { - WL_COMBO_SCAN, - IW_PRIV_TYPE_CHAR | 1024, - 0, - "CSCAN" - }, -#endif -}; - -const struct iw_handler_def wl_iw_handler_def = -{ - .num_standard = ARRAYSIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = ARRAYSIZE(wl_iw_priv_handler), - .num_private_args = ARRAY_SIZE(wl_iw_priv_args), - .private = (iw_handler *)wl_iw_priv_handler, - .private_args = (void *) wl_iw_priv_args, - -#if WIRELESS_EXT >= 19 - get_wireless_stats: dhd_get_wireless_stats, -#endif -}; -#endif - - -int wl_iw_ioctl( - struct net_device *dev, - struct ifreq *rq, - int cmd -) -{ - struct iwreq *wrq = (struct iwreq *) rq; - struct iw_request_info info; - iw_handler handler; - char *extra = NULL; - int token_size = 1, max_tokens = 0, ret = 0; - - net_os_wake_lock(dev); - - WL_TRACE(("%s: cmd:%x alled via dhd->do_ioctl()entry point\n", __FUNCTION__, cmd)); - if (cmd < SIOCIWFIRST || - IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) || - !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) { - WL_ERROR(("%s: error in cmd=%x : not supported\n", __FUNCTION__, cmd)); - net_os_wake_unlock(dev); - return -EOPNOTSUPP; - } - - switch (cmd) { - - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - max_tokens = IW_ESSID_MAX_SIZE + 1; - break; - - case SIOCSIWENCODE: - case SIOCGIWENCODE: -#if WIRELESS_EXT > 17 - case SIOCSIWENCODEEXT: - case SIOCGIWENCODEEXT: -#endif - max_tokens = wrq->u.data.length; - break; - - case SIOCGIWRANGE: - max_tokens = sizeof(struct iw_range) + 500; - break; - - case SIOCGIWAPLIST: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_AP; - break; - -#if WIRELESS_EXT > 13 - case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) - if (g_iscan) - max_tokens = wrq->u.data.length; - else -#endif - max_tokens = IW_SCAN_MAX_DATA; - break; -#endif - - case SIOCSIWSPY: - token_size = sizeof(struct sockaddr); - max_tokens = IW_MAX_SPY; - break; - - case SIOCGIWSPY: - token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_SPY; - break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; - break; - } - - if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", \ - __FUNCTION__, cmd, wrq->u.data.length, max_tokens)); - ret = -E2BIG; - goto wl_iw_ioctl_done; - } - if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) { - ret = -ENOMEM; - goto wl_iw_ioctl_done; - } - - if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - } - - info.cmd = cmd; - info.flags = 0; - - ret = handler(dev, &info, &wrq->u, extra); - - if (extra) { - if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) { - kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; - } - - kfree(extra); - } - -wl_iw_ioctl_done: - - net_os_wake_unlock(dev); - - return ret; -} - - -bool -wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, - char* stringBuf, uint buflen) -{ - typedef struct conn_fail_event_map_t { - uint32 inEvent; - uint32 inStatus; - uint32 inReason; - const char* outName; - const char* outCause; - } conn_fail_event_map_t; - - -# define WL_IW_DONT_CARE 9999 - const conn_fail_event_map_t event_map [] = { - - - {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, - "Conn", "Success"}, - {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, - "Conn", "NoNetworks"}, - {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ConfigMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, - "Conn", "EncrypMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, - "Conn", "RsnMismatch"}, - {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "AuthTimeout"}, - {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "AuthFail"}, - {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, - "Conn", "AuthNoAck"}, - {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ReassocFail"}, - {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "ReassocTimeout"}, - {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, - "Conn", "ReassocAbort"}, - {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, - "Sup", "ConnSuccess"}, - {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Sup", "WpaHandshakeFail"}, - {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Deauth"}, - {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "DisassocInd"}, - {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Disassoc"} - }; - - const char* name = ""; - const char* cause = NULL; - int i; - - - for (i = 0; i < sizeof(event_map)/sizeof(event_map[0]); i++) { - const conn_fail_event_map_t* row = &event_map[i]; - if (row->inEvent == event_type && - (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) && - (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) { - name = row->outName; - cause = row->outCause; - break; - } - } - - - if (cause) { - memset(stringBuf, 0, buflen); - snprintf(stringBuf, buflen, "%s %s %02d %02d", - name, cause, status, reason); - WL_INFORM(("Connection status: %s\n", stringBuf)); - return TRUE; - } else { - return FALSE; - } -} - -#if WIRELESS_EXT > 14 - -static bool -wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) -{ - uint32 event = ntoh32(e->event_type); - uint32 status = ntoh32(e->status); - uint32 reason = ntoh32(e->reason); - - if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { - return TRUE; - } - else - return FALSE; -} -#endif - -#ifndef IW_CUSTOM_MAX -#define IW_CUSTOM_MAX 256 -#endif - -void -wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) -{ -#if WIRELESS_EXT > 13 - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd = 0; - uint32 event_type = ntoh32(e->event_type); - uint16 flags = ntoh16(e->flags); - uint32 datalen = ntoh32(e->datalen); - uint32 status = ntoh32(e->status); - uint32 toto; -#if defined(ROAM_NOT_USED) - static uint32 roam_no_success = 0; - static bool roam_no_success_send = FALSE; -#endif - memset(&wrqu, 0, sizeof(wrqu)); - memset(extra, 0, sizeof(extra)); - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return; - } - - net_os_wake_lock(dev); - - WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type)); - - switch (event_type) { - - case WLC_E_RELOAD: - WL_ERROR(("%s: Firmware ERROR %d\n", __FUNCTION__, status)); - net_os_send_hang_message(dev); - goto wl_iw_event_end; - -#if defined(SOFTAP) - case WLC_E_PRUNE: - if (ap_cfg_running) { - char *macaddr = (char *)&e->addr; - WL_SOFTAP(("PRUNE received, %02X:%02X:%02X:%02X:%02X:%02X!\n", - macaddr[0], macaddr[1], macaddr[2], macaddr[3], \ - macaddr[4], macaddr[5])); - - if (ap_macmode) { - int i; - for (i = 0; i < ap_black_list.count; i++) { - if (!bcmp(macaddr, &ap_black_list.ea[i], \ - sizeof(struct ether_addr))) { - WL_SOFTAP(("mac in black list, ignore it\n")); - break; - } - } - - if (i == ap_black_list.count) { - char mac_buf[32] = {0}; - sprintf(mac_buf, "STA_BLOCK %02X:%02X:%02X:%02X:%02X:%02X", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); - wl_iw_send_priv_event(priv_dev, mac_buf); - } - } - } - break; -#endif - case WLC_E_TXFAIL: - cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; -#if WIRELESS_EXT > 14 - case WLC_E_JOIN: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA connect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_JOIN"); - goto wl_iw_event_end; - } -#endif - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = IWEVREGISTERED; - break; - case WLC_E_ROAM: - if (status == WLC_E_STATUS_SUCCESS) { - memcpy(wrqu.addr.sa_data, &e->addr.octet, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = SIOCGIWAP; - } -#if defined(ROAM_NOT_USED) - else if (status == WLC_E_STATUS_NO_NETWORKS) { - roam_no_success++; - if ((roam_no_success == 5) && (roam_no_success_send == FALSE)) { - roam_no_success_send = TRUE; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); - cmd = SIOCGIWAP; - WL_ERROR(("%s ROAMING did not succeeded , send Link Down\n", \ - __FUNCTION__)); - } else { - WL_TRACE(("##### ROAMING did not succeeded %d\n", roam_no_success)); - goto wl_iw_event_end; - } - } -#endif - break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA disconnect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_LEAVE"); - goto wl_iw_event_end; - } -#endif - cmd = SIOCGIWAP; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - bzero(&extra, ETHER_ADDR_LEN); - break; - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - cmd = SIOCGIWAP; - if (!(flags & WLC_EVENT_MSG_LINK)) { -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - WL_SOFTAP(("AP DOWN %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } else { - WL_TRACE(("STA_Link Down\n")); - g_ss_cache_ctrl.m_link_down = 1; - } -#else - g_ss_cache_ctrl.m_link_down = 1; -#endif - WL_TRACE(("Link Down\n")); - - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); - } - else { - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - g_ss_cache_ctrl.m_link_down = 0; - - memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN); - -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - WL_SOFTAP(("AP UP %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_UP"); - } else { - WL_TRACE(("STA_LINK_UP\n")); -#if defined(ROAM_NOT_USED) - roam_no_success_send = FALSE; - roam_no_success = 0; -#endif - } -#endif - WL_TRACE(("Link UP\n")); - - } - net_os_wake_lock_timeout_enable(dev); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; - case WLC_E_ACTION_FRAME: - cmd = IWEVCUSTOM; - if (datalen + 1 <= sizeof(extra)) { - wrqu.data.length = datalen + 1; - extra[0] = WLC_E_ACTION_FRAME; - memcpy(&extra[1], data, datalen); - WL_TRACE(("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length)); - } - break; - - case WLC_E_ACTION_FRAME_COMPLETE: - cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); - if (sizeof(status) + 1 <= sizeof(extra)) { - wrqu.data.length = sizeof(status) + 1; - extra[0] = WLC_E_ACTION_FRAME_COMPLETE; - memcpy(&extra[1], &status, sizeof(status)); - printf("wl_iw_event status %d PacketId %d \n", status, toto); - printf("WLC_E_ACTION_FRAME_COMPLETE len %d \n", wrqu.data.length); - } - break; -#endif -#if WIRELESS_EXT > 17 - case WLC_E_MIC_ERROR: { - struct iw_michaelmicfailure *micerrevt = (struct iw_michaelmicfailure *)&extra; - cmd = IWEVMICHAELMICFAILURE; - wrqu.data.length = sizeof(struct iw_michaelmicfailure); - if (flags & WLC_EVENT_MSG_GROUP) - micerrevt->flags |= IW_MICFAILURE_GROUP; - else - micerrevt->flags |= IW_MICFAILURE_PAIRWISE; - memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN); - micerrevt->src_addr.sa_family = ARPHRD_ETHER; - - break; - } -#ifdef BCMWPA2 - case WLC_E_PMKID_CACHE: { - if (data) - { - struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; - bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, - ETHER_ADDR_LEN); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - pmkidcand++; - count--; - } - } - goto wl_iw_event_end; - } -#endif -#endif - - case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if ((g_iscan) && (g_iscan->sysioc_pid >= 0) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) - { - up(&g_iscan->sysioc_sem); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", \ - g_iscan->iscan_state)); - } -#else - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE\n")); -#endif - break; - - case WLC_E_PFN_NET_FOUND: - { - wlc_ssid_t * ssid; - ssid = (wlc_ssid_t *)data; - WL_TRACE(("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", \ - __FUNCTION__, PNO_EVENT_UP, ssid->SSID, ssid->SSID_len)); - net_os_wake_lock_timeout_enable(dev); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; - - default: - - WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); - break; - } -#ifndef SANDGATE2G - if (cmd) { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else -#endif - wireless_send_event(dev, cmd, &wrqu, extra); - } -#endif - -#if WIRELESS_EXT > 14 - - memset(extra, 0, sizeof(extra)); - if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { - cmd = IWEVCUSTOM; - wrqu.data.length = strlen(extra); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - } -#endif -wl_iw_event_end: - net_os_wake_unlock(dev); -#endif -} - -int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) -{ - int res = 0; - wl_cnt_t cnt; - int phy_noise; - int rssi; - scb_val_t scb_val; - - phy_noise = 0; - if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise)))) - goto done; - - phy_noise = dtoh32(phy_noise); - WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); - - bzero(&scb_val, sizeof(scb_val_t)); - if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) - goto done; - - rssi = dtoh32(scb_val.val); - WL_TRACE(("wl_iw_get_wireless_stats rssi=%d\n", rssi)); - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - wstats->qual.qual = 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - wstats->qual.qual = 1; - else if (rssi <= WL_IW_RSSI_LOW) - wstats->qual.qual = 2; - else if (rssi <= WL_IW_RSSI_GOOD) - wstats->qual.qual = 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - wstats->qual.qual = 4; - else - wstats->qual.qual = 5; - - - wstats->qual.level = 0x100 + rssi; - wstats->qual.noise = 0x100 + phy_noise; -#if WIRELESS_EXT > 18 - wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM); -#else - wstats->qual.updated |= 7; -#endif - -#if WIRELESS_EXT > 11 - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n", (int)sizeof(wl_cnt_t))); - - memset(&cnt, 0, sizeof(wl_cnt_t)); - res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); - if (res) - { - WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d\n", res)); - goto done; - } - - cnt.version = dtoh16(cnt.version); - if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE(("\tIncorrect version of counters struct: expected %d; got %d\n", - WL_CNT_T_VERSION, cnt.version)); - goto done; - } - - wstats->discard.nwid = 0; - wstats->discard.code = dtoh32(cnt.rxundec); - wstats->discard.fragment = dtoh32(cnt.rxfragerr); - wstats->discard.retries = dtoh32(cnt.txfail); - wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); - wstats->miss.beacon = 0; - - WL_TRACE(("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - dtoh32(cnt.txframe), dtoh32(cnt.txbyte))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr))); - WL_TRACE(("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant))); - -#endif - -done: - return res; -} -static void -wl_iw_bt_flag_set( - struct net_device *dev, - bool set) -{ -#if defined(BT_DHCP_USE_FLAGS) - char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - -#if defined(BT_DHCP_eSCO_FIX) - set_btc_esco_params(dev, set); -#endif - -#if defined(BT_DHCP_USE_FLAGS) - WL_TRACE_COEX(("WI-FI priority boost via bt flags, set:%d\n", set)); - if (set == TRUE) { - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); - } - else { - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void -wl_iw_bt_timerfunc(ulong data) -{ - bt_info_t *bt_local = (bt_info_t *)data; - bt_local->timer_on = 0; - WL_TRACE(("%s\n", __FUNCTION__)); - - up(&bt_local->bt_sem); -} - -static int -_bt_dhcp_sysioc_thread(void *data) -{ - DAEMONIZE("dhcp_sysioc"); - - while (down_interruptible(&g_bt->bt_sem) == 0) { - - net_os_wake_lock(g_bt->dev); - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - - switch (g_bt->bt_state) { - case BT_DHCP_START: - WL_TRACE_COEX(("%s bt_dhcp stm: started \n", __FUNCTION__)); - g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW; - mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIME*HZ/1000); - g_bt->timer_on = 1; - break; - - case BT_DHCP_OPPORTUNITY_WINDOW: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T1 expiration\n", \ - __FUNCTION__)); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } - - WL_TRACE_COEX(("%s DHCP T1:%d expired\n", \ - __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIME)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE); - g_bt->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; - mod_timer(&g_bt->timer, jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000); - g_bt->timer_on = 1; - break; - - case BT_DHCP_FLAG_FORCE_TIMEOUT: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T2 expiration\n", \ - __FUNCTION__)); - } else { - WL_TRACE_COEX(("%s DHCP wait interval T2:%d msec expired\n", - __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME)); - } - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - - default: - WL_ERROR(("%s error g_status=%d !!!\n", __FUNCTION__, \ - g_bt->bt_state)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } - - net_os_wake_unlock(g_bt->dev); - } - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } - - complete_and_exit(&g_bt->bt_exited, 0); -} - -static void -wl_iw_bt_release(void) -{ - bt_info_t *bt_local = g_bt; - - if (!bt_local) { - return; - } - - if (bt_local->bt_pid >= 0) { - KILL_PROC(bt_local->bt_pid, SIGTERM); - wait_for_completion(&bt_local->bt_exited); - } - kfree(bt_local); - g_bt = NULL; -} - -static int -wl_iw_bt_init(struct net_device *dev) -{ - bt_info_t *bt_dhcp = NULL; - - bt_dhcp = kmalloc(sizeof(bt_info_t), GFP_KERNEL); - if (!bt_dhcp) - return -ENOMEM; - - memset(bt_dhcp, 0, sizeof(bt_info_t)); - bt_dhcp->bt_pid = -1; - g_bt = bt_dhcp; - bt_dhcp->dev = dev; - bt_dhcp->bt_state = BT_DHCP_IDLE; - - - bt_dhcp->timer_ms = 10; - init_timer(&bt_dhcp->timer); - bt_dhcp->timer.data = (ulong)bt_dhcp; - bt_dhcp->timer.function = wl_iw_bt_timerfunc; - - sema_init(&bt_dhcp->bt_sem, 0); - init_completion(&bt_dhcp->bt_exited); - bt_dhcp->bt_pid = kernel_thread(_bt_dhcp_sysioc_thread, bt_dhcp, 0); - if (bt_dhcp->bt_pid < 0) { - WL_ERROR(("Failed in %s\n", __FUNCTION__)); - return -ENOMEM; - } - - return 0; -} - -int wl_iw_attach(struct net_device *dev, void *dhdp) -{ - int params_size; - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = NULL; -#endif - - mutex_init(&wl_cache_lock); - -#if defined(WL_IW_USE_ISCAN) - if (!dev) - return 0; - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - -#ifdef CSCAN - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(uint16)) + WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); -#endif - iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); - if (!iscan) - return -ENOMEM; - memset(iscan, 0, sizeof(iscan_info_t)); - - iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) - return -ENOMEM; - iscan->iscan_ex_param_size = params_size; - iscan->sysioc_pid = -1; - - g_iscan = iscan; - iscan->dev = dev; - iscan->iscan_state = ISCAN_STATE_IDLE; -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; - g_iscan->scan_flag = 0; -#endif - - iscan->timer_ms = 8000; - init_timer(&iscan->timer); - iscan->timer.data = (ulong)iscan; - iscan->timer.function = wl_iw_timerfunc; - - sema_init(&iscan->sysioc_sem, 0); - init_completion(&iscan->sysioc_exited); - iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); - if (iscan->sysioc_pid < 0) - return -ENOMEM; -#endif - - iw = *(wl_iw_t **)netdev_priv(dev); - iw->pub = (dhd_pub_t *)dhdp; -#ifdef SOFTAP - priv_dev = dev; -#endif - g_scan = NULL; - - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) - return -ENOMEM; - - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; - -#if !defined(CSCAN) - wl_iw_init_ss_cache_ctrl(); -#endif - - wl_iw_bt_init(dev); - - return 0; -} - -void wl_iw_detach(void) -{ -#if defined(WL_IW_USE_ISCAN) - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - if (!iscan) - return; - if (iscan->sysioc_pid >= 0) { - KILL_PROC(iscan->sysioc_pid, SIGTERM); - wait_for_completion(&iscan->sysioc_exited); - } - mutex_lock(&wl_cache_lock); - while (iscan->list_hdr) { - buf = iscan->list_hdr->next; - kfree(iscan->list_hdr); - iscan->list_hdr = buf; - } - kfree(iscan->iscan_ex_params_p); - kfree(iscan); - g_iscan = NULL; - mutex_unlock(&wl_cache_lock); -#endif - - if (g_scan) - kfree(g_scan); - - g_scan = NULL; -#if !defined(CSCAN) - wl_iw_release_ss_cache_ctrl(); -#endif - wl_iw_bt_release(); -#ifdef SOFTAP - if (ap_cfg_running) { - WL_TRACE(("\n%s AP is going down\n", __FUNCTION__)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } -#endif -} diff --git a/drivers/net/wireless/bcm4329/wl_iw.h b/drivers/net/wireless/bcm4329/wl_iw.h deleted file mode 100644 index d94bdb432723..000000000000 --- a/drivers/net/wireless/bcm4329/wl_iw.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Linux Wireless Extensions support - * - * Copyright (C) 1999-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 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * 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. - * - * $Id: wl_iw.h,v 1.5.34.1.6.36.4.18 2011/02/10 19:33:12 Exp $ - */ - - -#ifndef _wl_iw_h_ -#define _wl_iw_h_ - -#include - -#include -#include -#include - -#define WL_SCAN_PARAMS_SSID_MAX 10 -#define GET_SSID "SSID=" -#define GET_CHANNEL "CH=" -#define GET_NPROBE "NPROBE=" -#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -#define GET_HOME_DWELL "HOME=" -#define GET_SCAN_TYPE "TYPE=" - -#define BAND_GET_CMD "GETBAND" -#define BAND_SET_CMD "SETBAND" -#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -#define SETSUSPEND_CMD "SETSUSPENDOPT" -#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" -#define PNOSETUP_SET_CMD "PNOSETUP " -#define PNOENABLE_SET_CMD "PNOFORCE" -#define PNODEBUG_SET_CMD "PNODEBUG" -#define TXPOWER_SET_CMD "TXPOWER" - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - - -typedef struct wl_iw_extra_params { - int target_channel; -} wl_iw_extra_params_t; - -struct cntry_locales_custom { - char iso_abbrev[WLC_CNTRY_BUF_SZ]; - char custom_locale[WLC_CNTRY_BUF_SZ]; - int32 custom_locale_rev; -}; - -#define WL_IW_RSSI_MINVAL -200 -#define WL_IW_RSSI_NO_SIGNAL -91 -#define WL_IW_RSSI_VERY_LOW -80 -#define WL_IW_RSSI_LOW -70 -#define WL_IW_RSSI_GOOD -68 -#define WL_IW_RSSI_VERY_GOOD -58 -#define WL_IW_RSSI_EXCELLENT -57 -#define WL_IW_RSSI_INVALID 0 -#define MAX_WX_STRING 80 -#define isprint(c) bcm_isprint(c) -#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31) - -#define G_SCAN_RESULTS (8*1024) -#define WE_ADD_EVENT_FIX 0x80 -#define G_WLAN_SET_ON 0 -#define G_WLAN_SET_OFF 1 - -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ -} - -typedef struct wl_iw { - char nickname[IW_ESSID_MAX_SIZE]; - - struct iw_statistics wstats; - - int spy_num; - uint32 pwsec; - uint32 gwsec; - bool privacy_invoked; - - struct ether_addr spy_addr[IW_MAX_SPY]; - struct iw_quality spy_qual[IW_MAX_SPY]; - void *wlinfo; - dhd_pub_t * pub; -} wl_iw_t; - -#define WLC_IW_SS_CACHE_MAXLEN 2048 -#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 -#define WLC_IW_BSS_INFO_MAXLEN \ - (WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN) - -typedef struct wl_iw_ss_cache { - struct wl_iw_ss_cache *next; - int dirty; - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_iw_ss_cache_t; - -typedef struct wl_iw_ss_cache_ctrl { - wl_iw_ss_cache_t *m_cache_head; - int m_link_down; - int m_timer_expired; - char m_active_bssid[ETHER_ADDR_LEN]; - uint m_prev_scan_mode; - uint m_cons_br_scan_cnt; - struct timer_list *m_timer; -} wl_iw_ss_cache_ctrl_t; - -typedef enum broadcast_first_scan { - BROADCAST_SCAN_FIRST_IDLE = 0, - BROADCAST_SCAN_FIRST_STARTED, - BROADCAST_SCAN_FIRST_RESULT_READY, - BROADCAST_SCAN_FIRST_RESULT_CONSUMED -} broadcast_first_scan_t; -#ifdef SOFTAP -#define SSID_LEN 33 -#define SEC_LEN 16 -#define KEY_LEN 65 -#define PROFILE_OFFSET 32 -struct ap_profile { - uint8 ssid[SSID_LEN]; - uint8 sec[SEC_LEN]; - uint8 key[KEY_LEN]; - uint32 channel; - uint32 preamble; - uint32 max_scb; - uint32 closednet; - char country_code[WLC_CNTRY_BUF_SZ]; -}; - - -#define MACLIST_MODE_DISABLED 0 -#define MACLIST_MODE_DENY 1 -#define MACLIST_MODE_ALLOW 2 -struct mflist { - uint count; - struct ether_addr ea[16]; -}; - -struct mac_list_set { - uint32 mode; - struct mflist mac_list; -}; -#endif - -#if WIRELESS_EXT > 12 -#include -extern const struct iw_handler_def wl_iw_handler_def; -#endif - -extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data); -extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); -int wl_iw_attach(struct net_device *dev, void * dhdp); -void wl_iw_detach(void); -int wl_control_wl_start(struct net_device *dev); - -extern int net_os_wake_lock(struct net_device *dev); -extern int net_os_wake_unlock(struct net_device *dev); -extern int net_os_wake_lock_timeout(struct net_device *dev); -extern int net_os_wake_lock_timeout_enable(struct net_device *dev); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern int net_os_set_packet_filter(struct net_device *dev, int val); -extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); -extern char *dhd_bus_country_get(struct net_device *dev); -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(info, stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(info, event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(info, stream, ends, iwe, extra) -#else -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(stream, ends, iwe, extra) -#endif - -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, \ - ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, \ - int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); -extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' -#define PNO_EVENT_UP "PNO_EVENT" - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; - -#ifdef SOFTAP_TLV_CFG -#define SOFTAP_SET_CMD "SOFTAPSET " -#define SOFTAP_TLV_PREFIX 'A' -#define SOFTAP_TLV_VERSION '1' -#define SOFTAP_TLV_SUBVERSION '0' -#define SOFTAP_TLV_RESERVED '0' - -#define TLV_TYPE_SSID 'S' -#define TLV_TYPE_SECUR 'E' -#define TLV_TYPE_KEY 'K' -#define TLV_TYPE_CHANNEL 'C' -#endif - -#if defined(CSCAN) - -typedef struct cscan_tlv { - char prefix; - char version; - char subver; - char reserved; -} cscan_tlv_t; - -#define CSCAN_COMMAND "CSCAN " -#define CSCAN_TLV_PREFIX 'S' -#define CSCAN_TLV_VERSION 1 -#define CSCAN_TLV_SUBVERSION 0 -#define CSCAN_TLV_TYPE_SSID_IE 'S' -#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' -#define CSCAN_TLV_TYPE_NPROBE_IE 'N' -#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' -#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' -#define CSCAN_TLV_TYPE_HOME_IE 'H' -#define CSCAN_TLV_TYPE_STYPE_IE 'T' - -extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, \ - int channel_num, int *bytes_left); - -extern int wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, \ - const char token, int input_size, int *bytes_left); - -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, \ - int max, int *bytes_left); - -extern int wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max); - -extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num); - -#endif - -#endif diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 42dad59cadb0..b50fedcef8ac 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 __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) -#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) +#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 TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) struct netfront_info { diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 010725117dbb..dc0ae4d14dff 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c @@ -21,7 +21,6 @@ #include "oprof.h" static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer); -static int ctr_running; static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer) { @@ -34,9 +33,6 @@ static void __oprofile_hrtimer_start(void *unused) { struct hrtimer *hrtimer = &__get_cpu_var(oprofile_hrtimer); - if (!ctr_running) - return; - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer->function = oprofile_hrtimer_notify; @@ -46,10 +42,7 @@ static void __oprofile_hrtimer_start(void *unused) static int oprofile_hrtimer_start(void) { - get_online_cpus(); - ctr_running = 1; on_each_cpu(__oprofile_hrtimer_start, NULL, 1); - put_online_cpus(); return 0; } @@ -57,9 +50,6 @@ static void __oprofile_hrtimer_stop(int cpu) { struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu); - if (!ctr_running) - return; - hrtimer_cancel(hrtimer); } @@ -67,11 +57,8 @@ static void oprofile_hrtimer_stop(void) { int cpu; - get_online_cpus(); for_each_online_cpu(cpu) __oprofile_hrtimer_stop(cpu); - ctr_running = 0; - put_online_cpus(); } static int __cpuinit oprofile_cpu_notify(struct notifier_block *self, diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index a286959db67e..0a19708074c2 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -1414,11 +1414,6 @@ 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/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 4835a02ec017..b5a7d9bfcb24 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -705,21 +705,17 @@ void pci_remove_legacy_files(struct pci_bus *b) #ifdef HAVE_PCI_MMAP -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, - enum pci_mmap_api mmap_api) +int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) { - unsigned long nr, start, size, pci_start; + unsigned long nr, start, size; - if (pci_resource_len(pdev, resno) == 0) - return 0; nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; - pci_start = (mmap_api == PCI_MMAP_PROCFS) ? - pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; - if (start >= pci_start && start < pci_start + size && - start + nr <= pci_start + size) + if (start < size && size - start >= nr) return 1; + WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", + current->comm, start, start+nr, pci_name(pdev), resno, size); return 0; } @@ -749,14 +745,8 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; - if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { - WARN(1, "process \"%s\" tried to map 0x%08lx bytes " - "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", - current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, - pci_name(pdev), i, - pci_resource_start(pdev, i), pci_resource_len(pdev, i)); + if (!pci_mmap_fits(pdev, i, vma)) return -EINVAL; - } /* pci_mmap_page_range() expects the same kind of entry as coming * from /proc/bus/pci/ which is a "user visible" value. If this is diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1001b1d7e041..6beb11b617a9 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -22,13 +22,8 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev); #endif extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP -enum pci_mmap_api { - PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ - PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ -}; extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vmai, - enum pci_mmap_api mmap_api); + struct vm_area_struct *vma); #endif int pci_probe_reset_function(struct pci_dev *dev); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 4aae016c79d0..01f0306525a5 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -260,7 +260,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) /* Make sure the caller is mapping a real resource for this device */ for (i = 0; i < PCI_ROM_RESOURCE; i++) { - if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) + if (pci_mmap_fits(dev, i, vma)) break; } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 32ae8188c094..857ae01734a6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2714,29 +2714,6 @@ 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/soc_common.c b/drivers/pcmcia/soc_common.c index fd4c25ac18ec..6f1a86b43c60 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -65,7 +65,6 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, va_end(args); } } -EXPORT_SYMBOL(soc_pcmcia_debug); #endif diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e8acb1c7b194..b756e07d41b4 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1065,9 +1065,9 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, */ static int asus_gps_rfkill_set(void *data, bool blocked) { - struct asus_laptop *asus = data; + acpi_handle handle = data; - return asus_gps_switch(asus, !blocked); + return asus_gps_switch(handle, !blocked); } static const struct rfkill_ops asus_gps_rfkill_ops = { @@ -1094,7 +1094,7 @@ static int asus_rfkill_init(struct asus_laptop *asus) asus->gps_rfkill = rfkill_alloc("asus-gps", &asus->platform_device->dev, RFKILL_TYPE_GPS, - &asus_gps_rfkill_ops, asus); + &asus_gps_rfkill_ops, NULL); if (!asus->gps_rfkill) return -EINVAL; diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index f0b3ad13c273..c44a5e8b8b82 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -75,7 +75,6 @@ #include #include #include -#include "intel_ips.h" #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 @@ -246,7 +245,6 @@ #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 */ @@ -341,9 +339,6 @@ 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 @@ -522,7 +517,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(ips)) + if (!ips->gpu_turbo_enabled) return false; return ips->gpu_busy(); @@ -537,7 +532,7 @@ static bool ips_gpu_busy(struct ips_driver *ips) */ static void ips_gpu_raise(struct ips_driver *ips) { - if (!ips_gpu_turbo_enabled(ips)) + if (!ips->gpu_turbo_enabled) return; if (!ips->gpu_raise()) @@ -554,7 +549,7 @@ static void ips_gpu_raise(struct ips_driver *ips) */ static void ips_gpu_lower(struct ips_driver *ips) { - if (!ips_gpu_turbo_enabled(ips)) + if (!ips->gpu_turbo_enabled) return; if (!ips->gpu_lower()) @@ -1459,31 +1454,6 @@ 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 deleted file mode 100644 index 73299beff5b3..000000000000 --- a/drivers/platform/x86/intel_ips.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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/wmi.c b/drivers/platform/x86/wmi.c index 677783475d84..b2978a04317f 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -801,7 +801,7 @@ static bool guid_already_parsed(const char *guid_string) wblock = list_entry(p, struct wmi_block, list); gblock = &wblock->gblock; - if (memcmp(gblock->guid, guid_string, 16) == 0) + if (strncmp(gblock->guid, guid_string, 16) == 0) return true; } return false; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 0d943eea1c2d..dc4e32e031e9 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -28,7 +28,7 @@ #include "../base.h" #include "pnpacpi.h" -static int num; +static int num = 0; /* We need only to blacklist devices that have already an acpi driver that * can't use pnp layer. We don't need to blacklist device that are directly @@ -180,24 +180,11 @@ struct pnp_protocol pnpacpi_protocol = { }; EXPORT_SYMBOL(pnpacpi_protocol); -static char *pnpacpi_get_id(struct acpi_device *device) -{ - struct acpi_hardware_id *id; - - list_for_each_entry(id, &device->pnp.ids, list) { - if (ispnpidacpi(id->id)) - return id->id; - } - - return NULL; -} - static int __init pnpacpi_add_device(struct acpi_device *device) { acpi_handle temp = NULL; acpi_status status; struct pnp_dev *dev; - char *pnpid; struct acpi_hardware_id *id; /* @@ -205,17 +192,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device) * driver should not be loaded. */ status = acpi_get_handle(device->handle, "_CRS", &temp); - if (ACPI_FAILURE(status)) - return 0; - - pnpid = pnpacpi_get_id(device); - if (!pnpid) - return 0; - - if (is_exclusive_device(device) || !device->status.present) + if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || + is_exclusive_device(device) || (!device->status.present)) return 0; - dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid); + dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); if (!dev) return -ENOMEM; @@ -246,7 +227,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) pnpacpi_parse_resource_option_data(dev); list_for_each_entry(id, &device->pnp.ids, list) { - if (!strcmp(id->id, pnpid)) + if (!strcmp(id->id, acpi_device_hid(device))) continue; if (!ispnpidacpi(id->id)) continue; diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 5cb348f382c2..dd3bc824ef4c 100755 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -83,13 +83,6 @@ config BATTERY_DS2760 help Say Y here to enable support for batteries with ds2760 chip. -config BATTERY_DS2781 - tristate "DS2781 battery driver" - select W1 - select W1_SLAVE_DS2781 - help - Say Y here to enable support for batteries with ds2781 chip. - config BATTERY_DS2782 tristate "DS2782/DS2786 standalone gas-gauge" depends on I2C @@ -130,11 +123,6 @@ config BATTERY_WM97XX help Say Y to enable support for battery measured by WM97xx aux port. -config CHARGER_BQ24617 - tristate "BQ24617 Charger Driver" - help - Say Y to include support for BQ24617 Main Battery Charger. - config BATTERY_BQ27x00 tristate "BQ27x00 battery driver" depends on I2C diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 70184898195e..4ed46e2e40c9 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -24,14 +24,12 @@ obj-$(CONFIG_WM8350_POWER) += wm8350_power.o obj-$(CONFIG_TEST_POWER) += test_power.o obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o -obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o -obj-$(CONFIG_CHARGER_BQ24617) += bq24617_charger.o obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o diff --git a/drivers/power/bq24617_charger.c b/drivers/power/bq24617_charger.c deleted file mode 100644 index 825e2d7b6ebf..000000000000 --- a/drivers/power/bq24617_charger.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct bq24617_data { - int stat1_irq; - int stat2_irq; - int detect_irq; - - struct power_supply ac; - int ac_online; - - struct delayed_work work; - - bool stat_irq_en; - spinlock_t stat_irq_lock; -}; - -static int bq24617_stat1_value = 1; /* 0 = charging in progress */ -static int bq24617_stat2_value = 1; /* 0 = charge complete */ - -static char *bq24617_supply_list[] = { - "battery", -}; - -static enum power_supply_property bq24617_power_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -int is_ac_charging(void) -{ - return (!bq24617_stat1_value || !bq24617_stat2_value); -} - -int is_ac_charge_complete(void) -{ - return !bq24617_stat2_value; -} - -static int power_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct bq24617_data *bq_data = - container_of(psy, struct bq24617_data, ac); - - if (psp != POWER_SUPPLY_PROP_ONLINE) - return -EINVAL; - - val->intval = bq_data->ac_online; - return 0; -} - -static void bq24617_read_status(struct bq24617_data *bq_data) -{ - int detect = 0; - - /* STAT1 indicates charging, STAT2 indicates charge complete */ - bq24617_stat1_value = gpio_get_value(irq_to_gpio(bq_data->stat1_irq)); - bq24617_stat2_value = gpio_get_value(irq_to_gpio(bq_data->stat2_irq)); - - if (bq_data->detect_irq >= 0) - detect = gpio_get_value(irq_to_gpio(bq_data->detect_irq)); - - if (!bq24617_stat1_value || !bq24617_stat2_value || detect) - bq_data->ac_online = 1; - else - bq_data->ac_online = 0; - - pr_debug("%s: ac_online=%d (stat1=%d, stat2=%d, detect=%d)\n", __func__, - bq_data->ac_online, bq24617_stat1_value, bq24617_stat2_value, - detect); - - power_supply_changed(&bq_data->ac); -} - -static irqreturn_t bq24617_stat_isr(int irq, void *data) -{ - struct bq24617_data *bq_data = data; - - bq24617_read_status(bq_data); - return IRQ_HANDLED; -} - -static irqreturn_t bq24617_detect_isr(int irq, void *data) -{ - struct bq24617_data *bq_data = data; - unsigned long flags; - - cancel_delayed_work(&bq_data->work); - - spin_lock_irqsave(&bq_data->stat_irq_lock, flags); - if (bq_data->stat_irq_en) { - disable_irq(bq_data->stat1_irq); - disable_irq(bq_data->stat2_irq); - bq_data->stat_irq_en = false; - } - spin_unlock_irqrestore(&bq_data->stat_irq_lock, flags); - - /* The STAT lines cannot be trusted immediately after a charger - * insertion. Default the STAT lines to their "not charging" values. - */ - bq24617_stat1_value = 1; - bq24617_stat2_value = 1; - - bq_data->ac_online = gpio_get_value(irq_to_gpio(bq_data->detect_irq)); - pr_debug("%s: ac_online=%d\n", __func__, bq_data->ac_online); - - power_supply_changed(&bq_data->ac); - - /* Give time for STAT lines to settle before enabling the IRQs. */ - if (bq_data->ac_online) - schedule_delayed_work(&bq_data->work, msecs_to_jiffies(500)); - - return IRQ_HANDLED; -} - -static void bq24617_work(struct work_struct *work) -{ - struct bq24617_data *bq_data = - container_of(work, struct bq24617_data, work.work); - unsigned long flags; - - spin_lock_irqsave(&bq_data->stat_irq_lock, flags); - enable_irq(bq_data->stat1_irq); - enable_irq(bq_data->stat2_irq); - bq_data->stat_irq_en = true; - spin_unlock_irqrestore(&bq_data->stat_irq_lock, flags); -} - -static int bq24617_probe(struct platform_device *pdev) -{ - struct bq24617_data *bq_data; - int retval; - unsigned int flags; - - bq_data = kzalloc(sizeof(*bq_data), GFP_KERNEL); - if (bq_data == NULL) - return -ENOMEM; - - INIT_DELAYED_WORK(&bq_data->work, bq24617_work); - bq_data->stat_irq_en = true; - spin_lock_init(&bq_data->stat_irq_lock); - platform_set_drvdata(pdev, bq_data); - - bq_data->stat1_irq = platform_get_irq_byname(pdev, "stat1"); - bq_data->stat2_irq = platform_get_irq_byname(pdev, "stat2"); - if ((bq_data->stat1_irq < 0) || (bq_data->stat2_irq < 0)) { - dev_err(&pdev->dev, "Resources not set properly\n"); - retval = -ENODEV; - goto free_mem; - } - - flags = IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; - - retval = request_irq(bq_data->stat1_irq, bq24617_stat_isr, flags, - "bq24617_stat1", bq_data); - if (retval) { - dev_err(&pdev->dev, "Failed requesting STAT1 IRQ\n"); - goto free_mem; - } - - retval = request_irq(bq_data->stat2_irq, bq24617_stat_isr, flags, - "bq24617_stat2", bq_data); - if (retval) { - dev_err(&pdev->dev, "Failed requesting STAT2 IRQ\n"); - goto free_stat1; - } - - enable_irq_wake(bq_data->stat1_irq); - enable_irq_wake(bq_data->stat2_irq); - - bq_data->ac.name = "ac"; - bq_data->ac.type = POWER_SUPPLY_TYPE_MAINS; - bq_data->ac.supplied_to = bq24617_supply_list; - bq_data->ac.num_supplicants = ARRAY_SIZE(bq24617_supply_list); - bq_data->ac.properties = bq24617_power_props; - bq_data->ac.num_properties = ARRAY_SIZE(bq24617_power_props); - bq_data->ac.get_property = power_get_property; - - retval = power_supply_register(&pdev->dev, &bq_data->ac); - if (retval) { - dev_err(&pdev->dev, "Failed registering power supply\n"); - goto free_stat2; - } - - bq_data->detect_irq = platform_get_irq_byname(pdev, "detect"); - if (bq_data->detect_irq < 0) - dev_info(&pdev->dev, "Only using STAT lines for detection.\n"); - else { - dev_info(&pdev->dev, "Using STAT and DETECT for detection.\n"); - - retval = request_irq(bq_data->detect_irq, bq24617_detect_isr, - flags, "bq24617_detect", bq_data); - if (retval) { - dev_err(&pdev->dev, "Failed requesting DETECT IRQ\n"); - goto free_all; - } - - enable_irq_wake(bq_data->detect_irq); - } - - bq24617_read_status(bq_data); - - return 0; - -free_all: - power_supply_unregister(&bq_data->ac); -free_stat2: - free_irq(bq_data->stat2_irq, bq_data); -free_stat1: - free_irq(bq_data->stat1_irq, bq_data); -free_mem: - kfree(bq_data); - - return retval; -} - -static int bq24617_remove(struct platform_device *pdev) -{ - struct bq24617_data *bq_data = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&bq_data->work); - - power_supply_unregister(&bq_data->ac); - - free_irq(bq_data->stat1_irq, bq_data); - free_irq(bq_data->stat2_irq, bq_data); - if (bq_data->detect_irq >= 0) - free_irq(bq_data->detect_irq, bq_data); - - kfree(bq_data); - - return 0; -} - -static int bq24617_resume(struct device *dev) -{ - struct bq24617_data *bq_data = dev_get_drvdata(dev); - int stat1; - int stat2; - - if (delayed_work_pending(&bq_data->work)) { - pr_debug("%s: STAT check skipped\n", __func__); - return 0; - } - - stat1 = gpio_get_value(irq_to_gpio(bq_data->stat1_irq)); - stat2 = gpio_get_value(irq_to_gpio(bq_data->stat2_irq)); - - if ((stat1 != bq24617_stat1_value) || (stat2 != bq24617_stat2_value)) { - pr_debug("%s: STAT pins changed while suspended\n", __func__); - bq24617_read_status(bq_data); - } - - return 0; -} - -static struct dev_pm_ops bq24617_pm_ops = { - .resume = bq24617_resume, -}; - -static struct platform_driver bq24617_pdrv = { - .driver = { - .name = "bq24617", - .pm = &bq24617_pm_ops, - }, - .probe = bq24617_probe, - .remove = bq24617_remove, -}; - -static int __init bq24617_init(void) -{ - return platform_driver_register(&bq24617_pdrv); -} - -static void __exit bq24617_exit(void) -{ - platform_driver_unregister(&bq24617_pdrv); -} - -module_init(bq24617_init); -module_exit(bq24617_exit); - -MODULE_ALIAS("platform:bq24617_charger"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Motorola"); -MODULE_DESCRIPTION("bq24617 charger driver"); diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c deleted file mode 100644 index 0b2d78a416c3..000000000000 --- a/drivers/power/ds2781_battery.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (C) 2010 Motorola, 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. - * - * Based on ds2784_battery.c which is: - * Copyright (C) 2009 HTC Corporation - * Copyright (C) 2009 Google, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../w1/w1.h" -#include "../w1/slaves/w1_ds2781.h" - -extern int is_ac_charging(void); -extern int is_ac_charge_complete(void); - -struct battery_status { - int timestamp; - - int voltage_uV; /* units of uV */ - int current_uA; /* units of uA */ - int current_avg_uA; - int charge_uAh; - - short temp_C; /* units of 0.1 C */ - - u8 percentage; /* battery percentage */ - u8 age_scalar; /* converted to percent */ - u8 charge_source; - u8 status_reg; - u8 battery_full; /* battery full (don't charge) */ - - u8 cooldown; /* was overtemp */ -}; - - -#define TEMP_HOT 450 /* 45.0 degrees Celcius */ - -/* On power up, a sanity check is performed on the reported capacity. If the - * capacity is less than THRES_PERCENT, but the battery voltage is above - * THRES_BATT (when battery powered) or THRES_CHRG (when on a charger), the - * ACR will be reset to a reasonable value. - */ -#define THRES_PERCENT 3 -#define THRES_BATT 7500000 -#define THRES_CHRG 7750000 - -/* When charge complete is reached, a sanity check is performed on the reported - * capacity. If the capacity is less than 100, but the battery voltage is above - * THRES_100_RESET, the ACR will be reset to full capacity. - */ -#define THRES_100_RESET 8320000 - -#define BATTERY_LOG_MAX 1024 -#define BATTERY_LOG_MASK (BATTERY_LOG_MAX - 1) - -/* When we're awake or running on wall power, sample the battery - * gauge every FAST_POLL seconds. If we're asleep and on battery - * power, sample every SLOW_POLL seconds - */ -#define FAST_POLL (1 * 60) -#define SLOW_POLL (20 * 60) - -static DEFINE_MUTEX(battery_log_lock); -static struct battery_status battery_log[BATTERY_LOG_MAX]; -static unsigned battery_log_head; -static unsigned battery_log_tail; - -static int battery_log_en; -module_param(battery_log_en, int, S_IRUGO | S_IWUSR | S_IWGRP); - -void battery_log_status(struct battery_status *s) -{ - unsigned n; - mutex_lock(&battery_log_lock); - n = battery_log_head; - memcpy(battery_log + n, s, sizeof(struct battery_status)); - n = (n + 1) & BATTERY_LOG_MASK; - if (n == battery_log_tail) - battery_log_tail = (battery_log_tail + 1) & BATTERY_LOG_MASK; - battery_log_head = n; - mutex_unlock(&battery_log_lock); -} - -static const char *battery_source[2] = { "none", " ac" }; - -static int battery_log_print(struct seq_file *sf, void *private) -{ - unsigned n; - mutex_lock(&battery_log_lock); - seq_printf(sf, "timestamp mV mA avg mA uAh dC %% src reg full\n"); - for (n = battery_log_tail; n != battery_log_head; n = (n + 1) & BATTERY_LOG_MASK) { - struct battery_status *s = battery_log + n; - seq_printf(sf, "%9d %5d %6d %6d %8d %4d %3d %s 0x%02x %d\n", - s->timestamp, s->voltage_uV / 1000, - s->current_uA / 1000, s->current_avg_uA / 1000, - s->charge_uAh, s->temp_C, - s->percentage, - battery_source[s->charge_source], - s->status_reg, s->battery_full); - } - mutex_unlock(&battery_log_lock); - return 0; -} - - -struct ds2781_device_info { - struct device *dev; - - /* DS2781 data, valid after calling ds2781_battery_read_status() */ - char raw[DS2781_DATA_SIZE]; /* raw DS2781 data */ - - struct battery_status status; - struct mutex status_lock; - - struct power_supply bat; - struct device *w1_dev; - struct workqueue_struct *monitor_wqueue; - struct work_struct monitor_work; - struct alarm alarm; - struct wake_lock work_wake_lock; - - u8 slow_poll; - ktime_t last_poll; -}; - -#define psy_to_dev_info(x) container_of((x), struct ds2781_device_info, bat) - -static enum power_supply_property battery_properties[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_CYCLE_COUNT, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CHARGE_COUNTER, -}; - -#define to_ds2781_device_info(x) container_of((x), struct ds2781_device_info, \ - bat); - -static void ds2781_parse_data(u8 *raw, struct battery_status *s) -{ - short n; - - /* Get status reg */ - s->status_reg = raw[DS2781_REG_STATUS]; - - /* Get Level */ - s->percentage = raw[DS2781_REG_RARC]; - - /* Get Voltage: Unit=9.76mV, range is 0V to 9.9902V */ - n = (((raw[DS2781_REG_VOLT_MSB] << 8) | - (raw[DS2781_REG_VOLT_LSB])) >> 5); - - s->voltage_uV = n * 9760; - - /* Get Current: Unit= 1.5625uV x Rsnsp */ - n = ((raw[DS2781_REG_CURR_MSB]) << 8) | - raw[DS2781_REG_CURR_LSB]; - s->current_uA = ((n * 15625) / 10000) * raw[DS2781_REG_RSNSP]; - - n = ((raw[DS2781_REG_AVG_CURR_MSB]) << 8) | - raw[DS2781_REG_AVG_CURR_LSB]; - s->current_avg_uA = ((n * 15625) / 10000) * raw[DS2781_REG_RSNSP]; - - /* Get Temperature: - * Unit=0.125 degree C,therefore, give up LSB , - * just caculate MSB for temperature only. - */ - n = (((signed char)raw[DS2781_REG_TEMP_MSB]) << 3) | - (raw[DS2781_REG_TEMP_LSB] >> 5); - - s->temp_C = n + (n / 4); - - /* RAAC is in units of 1.6mAh */ - s->charge_uAh = ((raw[DS2781_REG_RAAC_MSB] << 8) | - raw[DS2781_REG_RAAC_LSB]) * 1600; - - /* Get Age: Unit=0.78125%, range is 49.2% to 100% */ - n = raw[DS2781_REG_AGE_SCALAR]; - s->age_scalar = (n * 78125) / 100000; -} - -static int ds2781_battery_read_status(struct ds2781_device_info *di) -{ - int ret; - int start; - int count; - char first_time; - struct battery_status *s = &di->status; - - /* The first time we read the entire contents of SRAM/EEPROM, - * but after that we just read the interesting bits that change. */ - if (di->raw[DS2781_REG_RSNSP] == 0x00) { - start = DS2781_REG_STATUS; - count = DS2781_DATA_SIZE - start; - first_time = 1; - } else { - start = DS2781_REG_STATUS; - count = DS2781_REG_AGE_SCALAR - start + 1; - first_time = 0; - } - - ret = w1_ds2781_read(di->w1_dev, di->raw + start, start, count); - if (ret != count) { - dev_warn(di->dev, "call to w1_ds2781_read failed (0x%p)\n", - di->w1_dev); - return 1; - } - - ds2781_parse_data(di->raw, s); - - if (first_time && (s->percentage < THRES_PERCENT) && - (s->voltage_uV > (s->charge_source ? THRES_CHRG : THRES_BATT))) { - dev_err(di->dev, "Battery capacity is obviously wrong\n"); - dev_err(di->dev, "Reset ACR registers to ~1300mAh\n"); - - di->raw[DS2781_REG_ACCUMULATE_CURR_MSB] = 0x08; - di->raw[DS2781_REG_ACCUMULATE_CURR_LSB] = 0x25; - w1_ds2781_write(di->w1_dev, - di->raw + DS2781_REG_ACCUMULATE_CURR_MSB, - DS2781_REG_ACCUMULATE_CURR_MSB, 2); - - /* Give time for registers to update, then read again */ - msleep(450); - return ds2781_battery_read_status(di); - } - - return 0; -} - -static int battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct ds2781_device_info *di = psy_to_dev_info(psy); - int retval = 0; - - mutex_lock(&di->status_lock); - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - if (is_ac_charging()) { - if (di->status.battery_full) - val->intval = POWER_SUPPLY_STATUS_FULL; - else - val->intval = POWER_SUPPLY_STATUS_CHARGING; - } else - val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; - break; - case POWER_SUPPLY_PROP_HEALTH: - if (di->status.temp_C >= TEMP_HOT) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - else - val->intval = POWER_SUPPLY_HEALTH_GOOD; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = 1; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; - break; - case POWER_SUPPLY_PROP_CYCLE_COUNT: - val->intval = di->status.age_scalar; - break; - case POWER_SUPPLY_PROP_CAPACITY: - if (di->status.battery_full) - val->intval = 100; - else - val->intval = di->status.percentage; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = di->status.voltage_uV; - break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = di->status.temp_C; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = di->status.current_uA; - break; - case POWER_SUPPLY_PROP_CURRENT_AVG: - val->intval = di->status.current_avg_uA; - break; - case POWER_SUPPLY_PROP_CHARGE_COUNTER: - val->intval = di->status.charge_uAh; - break; - default: - retval = -EINVAL; - } - - mutex_unlock(&di->status_lock); - - return retval; -} - -static void ds2781_battery_update_status(struct ds2781_device_info *di) -{ - u8 last_level; - last_level = di->status.percentage; - - mutex_lock(&di->status_lock); - ds2781_battery_read_status(di); - - if (battery_log_en) - pr_info("batt: %3d%%, %d mV, %d mA (%d avg), %d.%d C, %d mAh\n", - di->status.percentage, - di->status.voltage_uV / 1000, - di->status.current_uA / 1000, - di->status.current_avg_uA / 1000, - di->status.temp_C / 10, di->status.temp_C % 10, - di->status.charge_uAh / 1000); - mutex_unlock(&di->status_lock); - - if ((last_level != di->status.percentage) || - (di->status.temp_C >= TEMP_HOT)) - power_supply_changed(&di->bat); -} - -static void ds2781_program_alarm(struct ds2781_device_info *di, int seconds) -{ - ktime_t low_interval = ktime_set(seconds - 10, 0); - ktime_t slack = ktime_set(20, 0); - ktime_t next; - - next = ktime_add(di->last_poll, low_interval); - - alarm_cancel(&di->alarm); - alarm_start_range(&di->alarm, next, ktime_add(next, slack)); -} - -static void ds2781_battery_work(struct work_struct *work) -{ - struct ds2781_device_info *di = - container_of(work, struct ds2781_device_info, monitor_work); - struct timespec ts; - - ds2781_battery_update_status(di); - - di->last_poll = alarm_get_elapsed_realtime(); - - ts = ktime_to_timespec(di->last_poll); - di->status.timestamp = ts.tv_sec; - - if (battery_log_en) - battery_log_status(&di->status); - - ds2781_program_alarm(di, FAST_POLL); - wake_unlock(&di->work_wake_lock); -} - -static void ds2781_battery_alarm(struct alarm *alarm) -{ - struct ds2781_device_info *di = - container_of(alarm, struct ds2781_device_info, alarm); - wake_lock(&di->work_wake_lock); - queue_work(di->monitor_wqueue, &di->monitor_work); -} - -static void ds2781_reset_if_necessary(struct ds2781_device_info *di) -{ - /* If we have read from the DS2781 and the percentage is not 100%, - * the ACR should be reset. */ - if (di->raw[DS2781_REG_RSNSP] && (di->status.percentage < 100) && - (di->status.voltage_uV > THRES_100_RESET)) { - dev_err(di->dev, "Charge complete before 100 percent.\n"); - dev_err(di->dev, "Resetting ACR registers to Full 40 value.\n"); - - di->raw[DS2781_REG_ACCUMULATE_CURR_MSB] = - di->raw[DS2781_REG_FULL_40_MSB]; - di->raw[DS2781_REG_ACCUMULATE_CURR_LSB] = - di->raw[DS2781_REG_FULL_40_LSB]; - w1_ds2781_write(di->w1_dev, - di->raw + DS2781_REG_ACCUMULATE_CURR_MSB, - DS2781_REG_ACCUMULATE_CURR_MSB, 2); - } -} - -static void battery_ext_power_changed(struct power_supply *psy) -{ - struct ds2781_device_info *di; - int got_power; - - di = psy_to_dev_info(psy); - got_power = power_supply_am_i_supplied(psy); - - mutex_lock(&di->status_lock); - if (got_power) { - di->status.charge_source = 1; - if (is_ac_charge_complete()) { - di->status.battery_full = 1; - ds2781_reset_if_necessary(di); - } - } else { - di->status.charge_source = 0; - di->status.battery_full = 0; - } - mutex_unlock(&di->status_lock); - - power_supply_changed(psy); -} - -static int ds2781_battery_probe(struct platform_device *pdev) -{ - int rc; - struct ds2781_device_info *di; - - di = kzalloc(sizeof(*di), GFP_KERNEL); - if (!di) - return -ENOMEM; - - platform_set_drvdata(pdev, di); - - di->dev = &pdev->dev; - di->w1_dev = pdev->dev.parent; - mutex_init(&di->status_lock); - - di->bat.name = "battery"; - di->bat.type = POWER_SUPPLY_TYPE_BATTERY; - di->bat.properties = battery_properties; - di->bat.num_properties = ARRAY_SIZE(battery_properties); - di->bat.external_power_changed = battery_ext_power_changed; - di->bat.get_property = battery_get_property; - - rc = power_supply_register(&pdev->dev, &di->bat); - if (rc) - goto fail_register; - - INIT_WORK(&di->monitor_work, ds2781_battery_work); - di->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev)); - - /* init to something sane */ - di->last_poll = alarm_get_elapsed_realtime(); - - if (!di->monitor_wqueue) { - rc = -ESRCH; - goto fail_workqueue; - } - wake_lock_init(&di->work_wake_lock, WAKE_LOCK_SUSPEND, - "ds2781-battery"); - alarm_init(&di->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, - ds2781_battery_alarm); - wake_lock(&di->work_wake_lock); - - /* Check for charger since it could have been detected already. */ - battery_ext_power_changed(&di->bat); - - queue_work(di->monitor_wqueue, &di->monitor_work); - return 0; - -fail_workqueue: - power_supply_unregister(&di->bat); -fail_register: - kfree(di); - return rc; -} - -static int ds2781_suspend(struct device *dev) -{ - struct ds2781_device_info *di = dev_get_drvdata(dev); - - /* If on battery, reduce update rate until next resume. */ - if ((!di->status.charge_source) && - (di->status.temp_C < TEMP_HOT)) { - ds2781_program_alarm(di, SLOW_POLL); - di->slow_poll = 1; - } - return 0; -} - -static int ds2781_resume(struct device *dev) -{ - struct ds2781_device_info *di = dev_get_drvdata(dev); - - /* We might be on a slow sample cycle. If we're - * resuming we should resample the battery state - * if it's been over a minute since we last did - * so, and move back to sampling every minute until - * we suspend again. - */ - if (di->slow_poll) { - ds2781_program_alarm(di, FAST_POLL); - di->slow_poll = 0; - } - return 0; -} - -static struct dev_pm_ops ds2781_pm_ops = { - .suspend = ds2781_suspend, - .resume = ds2781_resume, -}; - -static struct platform_driver ds2781_battery_driver = { - .driver = { - .name = "ds2781-battery", - .pm = &ds2781_pm_ops, - }, - .probe = ds2781_battery_probe, -}; - -static int battery_log_open(struct inode *inode, struct file *file) -{ - return single_open(file, battery_log_print, NULL); -} - -static struct file_operations battery_log_fops = { - .open = battery_log_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init ds2781_battery_init(void) -{ - debugfs_create_file("battery_log", 0444, NULL, NULL, &battery_log_fops); - return platform_driver_register(&ds2781_battery_driver); -} - -module_init(ds2781_battery_init); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Motorola"); -MODULE_DESCRIPTION("ds2781 battery driver"); diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 5bc1dcf7785e..aafc1c506eda 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -271,14 +271,14 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; + val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32; break; case POWER_SUPPLY_PROP_CURRENT_AVG: ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 15625L / 120; + val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120; break; case POWER_SUPPLY_PROP_CAPACITY: ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); @@ -299,7 +299,7 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; break; case POWER_SUPPLY_PROP_TEMP_AMBIENT: ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); @@ -313,7 +313,7 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 6250 / 15; + val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15; break; case POWER_SUPPLY_PROP_SERIAL_NUMBER: ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 127617195629..91606bb55318 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -41,40 +41,23 @@ static int __power_supply_changed_work(struct device *dev, void *data) static void power_supply_changed_work(struct work_struct *work) { - unsigned long flags; struct power_supply *psy = container_of(work, struct power_supply, changed_work); dev_dbg(psy->dev, "%s\n", __func__); - spin_lock_irqsave(&psy->changed_lock, flags); - if (psy->changed) { - psy->changed = false; - spin_unlock_irqrestore(&psy->changed_lock, flags); + class_for_each_device(power_supply_class, NULL, psy, + __power_supply_changed_work); - class_for_each_device(power_supply_class, NULL, psy, - __power_supply_changed_work); + power_supply_update_leds(psy); - power_supply_update_leds(psy); - - kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); - spin_lock_irqsave(&psy->changed_lock, flags); - } - if (!psy->changed) - wake_unlock(&psy->work_wake_lock); - spin_unlock_irqrestore(&psy->changed_lock, flags); + kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); } void power_supply_changed(struct power_supply *psy) { - unsigned long flags; - dev_dbg(psy->dev, "%s\n", __func__); - spin_lock_irqsave(&psy->changed_lock, flags); - psy->changed = true; - wake_lock(&psy->work_wake_lock); - spin_unlock_irqrestore(&psy->changed_lock, flags); schedule_work(&psy->changed_work); } EXPORT_SYMBOL_GPL(power_supply_changed); @@ -197,8 +180,6 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto device_add_failed; INIT_WORK(&psy->changed_work, power_supply_changed_work); - spin_lock_init(&psy->changed_lock); - wake_lock_init(&psy->work_wake_lock, WAKE_LOCK_SUSPEND, "power-supply"); rc = power_supply_create_triggers(psy); if (rc) @@ -209,7 +190,6 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto success; create_triggers_failed: - wake_lock_destroy(&psy->work_wake_lock); device_unregister(psy->dev); kobject_set_name_failed: device_add_failed: @@ -223,7 +203,6 @@ void power_supply_unregister(struct power_supply *psy) { flush_scheduled_work(); power_supply_remove_triggers(psy); - wake_lock_destroy(&psy->work_wake_lock); device_unregister(psy->dev); } EXPORT_SYMBOL_GPL(power_supply_unregister); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index b463b679100c..0d19d0d866cc 100755 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -264,11 +264,5 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. -config REGULATOR_CPCAP - tristate "CPCAP regulator driver" - depends on MFD_CPCAP - help - Say Y here to support the voltage regulators on CPCAP - endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 085384e7e27e..8285fd832e16 100755 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o -obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c deleted file mode 100644 index 4163f2b9177e..000000000000 --- a/drivers/regulator/cpcap-regulator.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (C) 2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define CPCAP_REGULATOR(_name, _id) \ - { \ - .name = _name, \ - .id = _id, \ - .ops = &cpcap_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - } - - -#define SW2_SW4_VAL_TBL_SIZE 69 -#define SW2_SW4_VAL_TBL_STEP 12500 - -static int sw2_sw4_val_tbl[SW2_SW4_VAL_TBL_SIZE]; -static const int sw5_val_tbl[] = {0, 5050000}; -static const int vcam_val_tbl[] = {2600000, 2700000, 2800000, 2900000}; -static const int vcsi_val_tbl[] = {1200000, 1800000}; -static const int vdac_val_tbl[] = {1200000, 1500000, 1800000, 2500000}; -static const int vdig_val_tbl[] = {1200000, 1350000, 1500000, 1875000}; -static const int vfuse_val_tbl[] = {1500000, 1600000, 1700000, 1800000, 1900000, - 2000000, 2100000, 2200000, 2300000, 2400000, - 2500000, 2600000, 2700000, 3150000}; -static const int vhvio_val_tbl[] = {2775000}; -static const int vsdio_val_tbl[] = {1500000, 1600000, 1800000, 2600000, - 2700000, 2800000, 2900000, 3000000}; -static const int vpll_val_tbl[] = {1200000, 1300000, 1400000, 1800000}; -static const int vrf1_val_tbl[] = {2775000, 2500000}; /* Yes, this is correct */ -static const int vrf2_val_tbl[] = {0, 2775000}; -static const int vrfref_val_tbl[] = {2500000, 2775000}; -static const int vwlan1_val_tbl[] = {1800000, 1900000}; -static const int vwlan2_val_tbl[] = {2775000, 3000000, 3300000, 3300000}; -static const int vsim_val_tbl[] = {1800000, 2900000}; -static const int vsimcard_val_tbl[] = {1800000, 2900000}; -static const int vvib_val_tbl[] = {1300000, 1800000, 2000000, 3000000}; -static const int vusb_val_tbl[] = {0, 3300000}; -static const int vaudio_val_tbl[] = {0, 2775000}; - -static struct { - const enum cpcap_reg reg; - const unsigned short mode_mask; - const unsigned short volt_mask; - const unsigned char volt_shft; - unsigned short mode_val; - unsigned short off_mode_val; - const int val_tbl_sz; - const int *val_tbl; - unsigned int mode_cntr; - const unsigned int volt_trans_time; /* in micro seconds */ - const unsigned int turn_on_time; /* in micro seconds */ -} cpcap_regltr_data[CPCAP_NUM_REGULATORS] = { - [CPCAP_SW2] = {CPCAP_REG_S2C1, - 0x0F00, - 0x007F, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(sw2_sw4_val_tbl), - sw2_sw4_val_tbl, - 0, - 120, - 1500}, - - [CPCAP_SW4] = {CPCAP_REG_S4C1, - 0x0F00, - 0x007F, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(sw2_sw4_val_tbl), - sw2_sw4_val_tbl, - 0, - 100, - 1500}, - - [CPCAP_SW5] = {CPCAP_REG_S5C, - 0x002A, - 0x0000, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(sw5_val_tbl), - sw5_val_tbl, - 0, - 0, - 1500}, - - [CPCAP_VCAM] = {CPCAP_REG_VCAMC, - 0x0087, - 0x0030, - 4, - 0x0000, - 0x0000, - ARRAY_SIZE(vcam_val_tbl), - vcam_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VCSI] = {CPCAP_REG_VCSIC, - 0x0047, - 0x0010, - 4, - 0x0000, - 0x0000, - ARRAY_SIZE(vcsi_val_tbl), - vcsi_val_tbl, - 0, - 350, - 1000}, - - [CPCAP_VDAC] = {CPCAP_REG_VDACC, - 0x0087, - 0x0030, - 4, - 0x0000, - 0x0000, - ARRAY_SIZE(vdac_val_tbl), - vdac_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VDIG] = {CPCAP_REG_VDIGC, - 0x0087, - 0x0030, - 4, - 0x0000, - 0x0000, - ARRAY_SIZE(vdig_val_tbl), - vdig_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VFUSE] = {CPCAP_REG_VFUSEC, - 0x0080, - 0x000F, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(vfuse_val_tbl), - vfuse_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VHVIO] = {CPCAP_REG_VHVIOC, - 0x0017, - 0x0000, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(vhvio_val_tbl), - vhvio_val_tbl, - 0, - 0, - 1000}, - - [CPCAP_VSDIO] = {CPCAP_REG_VSDIOC, - 0x0087, - 0x0038, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vsdio_val_tbl), - vsdio_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VPLL] = {CPCAP_REG_VPLLC, - 0x0043, - 0x0018, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vpll_val_tbl), - vpll_val_tbl, - 0, - 420, - 100}, - - [CPCAP_VRF1] = {CPCAP_REG_VRF1C, - 0x00AC, - 0x0002, - 1, - 0x0000, - 0x0000, - ARRAY_SIZE(vrf1_val_tbl), - vrf1_val_tbl, - 0, - 10, - 1000}, - - [CPCAP_VRF2] = {CPCAP_REG_VRF2C, - 0x0023, - 0x0008, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vrf2_val_tbl), - vrf2_val_tbl, - 0, - 10, - 1000}, - - [CPCAP_VRFREF] = {CPCAP_REG_VRFREFC, - 0x0023, - 0x0008, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vrfref_val_tbl), - vrfref_val_tbl, - 0, - 420, - 100}, - - [CPCAP_VWLAN1] = {CPCAP_REG_VWLAN1C, - 0x0047, - 0x0010, - 4, - 0x0000, - 0x0000, - ARRAY_SIZE(vwlan1_val_tbl), - vwlan1_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VWLAN2] = {CPCAP_REG_VWLAN2C, - 0x020C, - 0x00C0, - 6, - 0x0000, - 0x0000, - ARRAY_SIZE(vwlan2_val_tbl), - vwlan2_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VSIM] = {CPCAP_REG_VSIMC, - 0x0023, - 0x0008, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vsim_val_tbl), - vsim_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VSIMCARD] = {CPCAP_REG_VSIMC, - 0x1E80, - 0x0008, - 3, - 0x0000, - 0x0000, - ARRAY_SIZE(vsimcard_val_tbl), - vsimcard_val_tbl, - 0, - 420, - 1000}, - - [CPCAP_VVIB] = {CPCAP_REG_VVIBC, - 0x0001, - 0x000C, - 2, - 0x0000, - 0x0000, - ARRAY_SIZE(vvib_val_tbl), - vvib_val_tbl, - 0, - 500, - 500}, - - [CPCAP_VUSB] = {CPCAP_REG_VUSBC, - 0x011C, - 0x0040, - 6, - 0x0000, - 0x0000, - ARRAY_SIZE(vusb_val_tbl), - vusb_val_tbl, - 0, - 0, - 1000}, - - [CPCAP_VAUDIO] = {CPCAP_REG_VAUDIOC, - 0x0016, - 0x0001, - 0, - 0x0000, - 0x0000, - ARRAY_SIZE(vaudio_val_tbl), - vaudio_val_tbl, - 0, - 0, - 1000}, -}; - -static int cpcap_regulator_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct cpcap_device *cpcap; - int regltr_id; - int retval; - enum cpcap_reg regnr; - int i; - - cpcap = rdev_get_drvdata(rdev); - - regltr_id = rdev_get_id(rdev); - if (regltr_id >= CPCAP_NUM_REGULATORS) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - if (regltr_id == CPCAP_VRF1) { - if (min_uV > 2500000) - i = 0; - else - i = cpcap_regltr_data[regltr_id].volt_mask; - } else { - for (i = 0; i < cpcap_regltr_data[regltr_id].val_tbl_sz; i++) - if (cpcap_regltr_data[regltr_id].val_tbl[i] >= min_uV) - break; - - if (i >= cpcap_regltr_data[regltr_id].val_tbl_sz) - i--; - - i <<= cpcap_regltr_data[regltr_id].volt_shft; - } - - retval = cpcap_regacc_write(cpcap, regnr, i, - cpcap_regltr_data[regltr_id].volt_mask); - - if ((cpcap_regltr_data[regltr_id].volt_trans_time) && (retval == 0)) - udelay(cpcap_regltr_data[regltr_id].volt_trans_time); - - return retval; -} - -static int cpcap_regulator_get_voltage(struct regulator_dev *rdev) -{ - struct cpcap_device *cpcap; - int regltr_id; - unsigned short volt_bits; - enum cpcap_reg regnr; - unsigned int shift; - - cpcap = rdev_get_drvdata(rdev); - - regltr_id = rdev_get_id(rdev); - if (regltr_id >= CPCAP_NUM_REGULATORS) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - if (cpcap_regacc_read(cpcap, regnr, &volt_bits) < 0) - return -1; - - if (!(volt_bits & cpcap_regltr_data[regltr_id].mode_mask)) - return 0; - - volt_bits &= cpcap_regltr_data[regltr_id].volt_mask; - shift = cpcap_regltr_data[regltr_id].volt_shft; - - return cpcap_regltr_data[regltr_id].val_tbl[volt_bits >> shift]; -} - -static int cpcap_regulator_enable(struct regulator_dev *rdev) -{ - struct cpcap_device *cpcap = rdev_get_drvdata(rdev); - int regltr_id; - int retval; - enum cpcap_reg regnr; - - regltr_id = rdev_get_id(rdev); - if (regltr_id >= CPCAP_NUM_REGULATORS) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - retval = cpcap_regacc_write(cpcap, regnr, - cpcap_regltr_data[regltr_id].mode_val, - cpcap_regltr_data[regltr_id].mode_mask); - - if ((cpcap_regltr_data[regltr_id].turn_on_time) && (retval == 0)) - udelay(cpcap_regltr_data[regltr_id].turn_on_time); - - return retval; -} - -static int cpcap_regulator_disable(struct regulator_dev *rdev) -{ - struct cpcap_device *cpcap = rdev_get_drvdata(rdev); - int regltr_id; - enum cpcap_reg regnr; - - regltr_id = rdev_get_id(rdev); - if (regltr_id >= CPCAP_NUM_REGULATORS) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - return cpcap_regacc_write(cpcap, regnr, - cpcap_regltr_data[regltr_id].off_mode_val, - cpcap_regltr_data[regltr_id].mode_mask); -} - -static int cpcap_regulator_is_enabled(struct regulator_dev *rdev) -{ - struct cpcap_device *cpcap = rdev_get_drvdata(rdev); - int regltr_id; - enum cpcap_reg regnr; - unsigned short value; - - regltr_id = rdev_get_id(rdev); - if (regltr_id >= CPCAP_NUM_REGULATORS) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - if (cpcap_regacc_read(cpcap, regnr, &value)) - return -1; - - return (value & cpcap_regltr_data[regltr_id].mode_mask) ? 1 : 0; -} - -static int cpcap_regulator_set_mode(struct regulator_dev *rdev, - unsigned int mode) -{ - struct cpcap_device *cpcap = rdev_get_drvdata(rdev); - int regltr_id; - enum cpcap_reg regnr; - int ret = 0; - - regltr_id = rdev_get_id(rdev); - if (regltr_id != CPCAP_VAUDIO) - return -EINVAL; - - regnr = cpcap_regltr_data[regltr_id].reg; - - if (mode == REGULATOR_MODE_NORMAL) { - if (cpcap_regltr_data[regltr_id].mode_cntr == 0) { - ret = cpcap_regacc_write(cpcap, regnr, - 0, - CPCAP_BIT_AUDIO_LOW_PWR); - } - if (ret == 0) - cpcap_regltr_data[regltr_id].mode_cntr++; - } else if (mode == REGULATOR_MODE_STANDBY) { - if (cpcap_regltr_data[regltr_id].mode_cntr == 1) { - ret = cpcap_regacc_write(cpcap, regnr, - CPCAP_BIT_AUDIO_LOW_PWR, - CPCAP_BIT_AUDIO_LOW_PWR); - } else if (WARN((cpcap_regltr_data[regltr_id].mode_cntr == 0), - "Unbalanced modes for supply vaudio\n")) - ret = -EIO; - - if (ret == 0) - cpcap_regltr_data[regltr_id].mode_cntr--; - } - - return ret; -} - -static struct regulator_ops cpcap_regulator_ops = { - .set_voltage = cpcap_regulator_set_voltage, - .get_voltage = cpcap_regulator_get_voltage, - .enable = cpcap_regulator_enable, - .disable = cpcap_regulator_disable, - .is_enabled = cpcap_regulator_is_enabled, - .set_mode = cpcap_regulator_set_mode, -}; - -static struct regulator_desc regulators[] = { - [CPCAP_SW2] = CPCAP_REGULATOR("sw2", CPCAP_SW2), - [CPCAP_SW4] = CPCAP_REGULATOR("sw4", CPCAP_SW4), - [CPCAP_SW5] = CPCAP_REGULATOR("sw5", CPCAP_SW5), - [CPCAP_VCAM] = CPCAP_REGULATOR("vcam", CPCAP_VCAM), - [CPCAP_VCSI] = CPCAP_REGULATOR("vcsi", CPCAP_VCSI), - [CPCAP_VDAC] = CPCAP_REGULATOR("vdac", CPCAP_VDAC), - [CPCAP_VDIG] = CPCAP_REGULATOR("vdig", CPCAP_VDIG), - [CPCAP_VFUSE] = CPCAP_REGULATOR("vfuse", CPCAP_VFUSE), - [CPCAP_VHVIO] = CPCAP_REGULATOR("vhvio", CPCAP_VHVIO), - [CPCAP_VSDIO] = CPCAP_REGULATOR("vsdio", CPCAP_VSDIO), - [CPCAP_VPLL] = CPCAP_REGULATOR("vpll", CPCAP_VPLL), - [CPCAP_VRF1] = CPCAP_REGULATOR("vrf1", CPCAP_VRF1), - [CPCAP_VRF2] = CPCAP_REGULATOR("vrf2", CPCAP_VRF2), - [CPCAP_VRFREF] = CPCAP_REGULATOR("vrfref", CPCAP_VRFREF), - [CPCAP_VWLAN1] = CPCAP_REGULATOR("vwlan1", CPCAP_VWLAN1), - [CPCAP_VWLAN2] = CPCAP_REGULATOR("vwlan2", CPCAP_VWLAN2), - [CPCAP_VSIM] = CPCAP_REGULATOR("vsim", CPCAP_VSIM), - [CPCAP_VSIMCARD] = CPCAP_REGULATOR("vsimcard", CPCAP_VSIMCARD), - [CPCAP_VVIB] = CPCAP_REGULATOR("vvib", CPCAP_VVIB), - [CPCAP_VUSB] = CPCAP_REGULATOR("vusb", CPCAP_VUSB), - [CPCAP_VAUDIO] = CPCAP_REGULATOR("vaudio", CPCAP_VAUDIO), -}; - -static int __devinit cpcap_regulator_probe(struct platform_device *pdev) -{ - struct regulator_dev *rdev; - struct cpcap_device *cpcap; - struct cpcap_platform_data *data; - struct regulator_init_data *init; - int i; - - /* Already set by core driver */ - cpcap = platform_get_drvdata(pdev); - data = cpcap->spi->controller_data; - init = pdev->dev.platform_data; - - for (i = 0; i < CPCAP_NUM_REGULATORS; i++) { - cpcap_regltr_data[i].mode_val = data->regulator_mode_values[i]; - cpcap_regltr_data[i].off_mode_val = - data->regulator_off_mode_values[i]; - } - - rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - init, cpcap); - if (IS_ERR(rdev)) - return PTR_ERR(rdev); - /* this is ok since the cpcap is still reachable from the rdev */ - platform_set_drvdata(pdev, rdev); - - return 0; -} - -static int __devexit cpcap_regulator_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - - regulator_unregister(rdev); - - return 0; -} - -static struct platform_driver cpcap_regulator_driver = { - .driver = { - .name = "cpcap-regltr", - }, - .probe = cpcap_regulator_probe, - .remove = __devexit_p(cpcap_regulator_remove), -}; - -static int __init cpcap_regulator_init(void) -{ - int i; - - for (i = 0; i < SW2_SW4_VAL_TBL_SIZE; i++) - sw2_sw4_val_tbl[i] = 600000 + (i * SW2_SW4_VAL_TBL_STEP); - - return platform_driver_register(&cpcap_regulator_driver); -} -subsys_initcall(cpcap_regulator_init); - -static void __exit cpcap_regulator_exit(void) -{ - platform_driver_unregister(&cpcap_regulator_driver); -} -module_exit(cpcap_regulator_exit); - -MODULE_ALIAS("platform:cpcap-regulator"); -MODULE_DESCRIPTION("CPCAP regulator driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 6300c521da5e..6b60a9c0366b 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -17,20 +17,8 @@ #include #include - -/* Voltage ranges for three variants of the max8649 */ -#define MAX8649_CHIP_ID2_VAL 0x0E #define MAX8649_DCDC_VMIN 750000 /* uV */ #define MAX8649_DCDC_VMAX 1380000 /* uV */ - -#define MAX8649S_CHIP_ID2_VAL 0x0A -#define MAX8649S_DCDC_VMIN 770000 /* uV */ -#define MAX8649S_DCDC_VMAX 1400000 /* uV */ - -#define MAX8952_CHIP_ID2_VAL 0x1A -#define MAX8952_DCDC_VMIN 770000 /* uV */ -#define MAX8952_DCDC_VMAX 1400000 /* uV */ - #define MAX8649_DCDC_STEP 10000 /* uV */ #define MAX8649_VOL_MASK 0x3f @@ -64,8 +52,6 @@ struct max8649_regulator_info { struct i2c_client *i2c; struct device *dev; struct mutex io_lock; - unsigned dcdc_vmin; /* uV */ - unsigned dcdc_vmax; /* uV */ int vol_reg; unsigned mode:2; /* bit[1:0] = VID1, VID0 */ @@ -142,10 +128,9 @@ out: return ret; } -static inline int check_range(struct max8649_regulator_info *info, - int min_uV, int max_uV) +static inline int check_range(int min_uV, int max_uV) { - if ((min_uV < info->dcdc_vmin) || (max_uV > info->dcdc_vmax) + if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX) || (min_uV > max_uV)) return -EINVAL; return 0; @@ -153,8 +138,7 @@ static inline int check_range(struct max8649_regulator_info *info, static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index) { - struct max8649_regulator_info *info = rdev_get_drvdata(rdev); - return info->dcdc_vmin + index * MAX8649_DCDC_STEP; + return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP); } static int max8649_get_voltage(struct regulator_dev *rdev) @@ -176,12 +160,12 @@ static int max8649_set_voltage(struct regulator_dev *rdev, struct max8649_regulator_info *info = rdev_get_drvdata(rdev); unsigned char data, mask; - if (check_range(info, min_uV, max_uV)) { + if (check_range(min_uV, max_uV)) { dev_err(info->dev, "invalid voltage range (%d, %d) uV\n", min_uV, max_uV); return -EINVAL; } - data = (min_uV - info->dcdc_vmin + MAX8649_DCDC_STEP - 1) + data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) / MAX8649_DCDC_STEP; mask = MAX8649_VOL_MASK; @@ -236,7 +220,7 @@ static int max8649_enable_time(struct regulator_dev *rdev) ret = (ret & MAX8649_RAMP_MASK) >> 5; rate = (32 * 1000) >> ret; /* uV/uS */ - return voltage / rate; + return (voltage / rate); } static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) @@ -269,27 +253,17 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; } -static int max8649_set_suspend_voltage(struct regulator_dev *rdev, int uV) -{ - struct max8649_regulator_info *info = rdev_get_drvdata(rdev); - - dev_info(info->dev, "%d uV suspend voltage\n", uV); - return max8649_set_voltage(rdev, uV, uV); -} - static struct regulator_ops max8649_dcdc_ops = { - .set_voltage = max8649_set_voltage, - .get_voltage = max8649_get_voltage, - .list_voltage = max8649_list_voltage, - .enable = max8649_enable, - .disable = max8649_disable, - .is_enabled = max8649_is_enabled, - .enable_time = max8649_enable_time, - .set_mode = max8649_set_mode, - .get_mode = max8649_get_mode, - .set_suspend_voltage = max8649_set_suspend_voltage, - .set_suspend_enable = max8649_enable, - .set_suspend_disable = max8649_disable, + .set_voltage = max8649_set_voltage, + .get_voltage = max8649_get_voltage, + .list_voltage = max8649_list_voltage, + .enable = max8649_enable, + .disable = max8649_disable, + .is_enabled = max8649_is_enabled, + .enable_time = max8649_enable_time, + .set_mode = max8649_set_mode, + .get_mode = max8649_get_mode, + }; static struct regulator_desc dcdc_desc = { @@ -306,7 +280,6 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, struct max8649_platform_data *pdata = client->dev.platform_data; struct max8649_regulator_info *info = NULL; unsigned char data; - int id1, id2; int ret; info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL); @@ -338,47 +311,13 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, break; } - id1 = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1); - if (id1 < 0) { - dev_err(info->dev, "Failed to detect ID1 of MAX8649:%d\n", id1); - ret = id1; + ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1); + if (ret < 0) { + dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", + ret); goto out; } - - id2 = max8649_reg_read(info->i2c, MAX8649_CHIP_ID2); - if (id2 < 0) { - dev_err(info->dev, "Failed to detect ID2 of MAX8649:%d\n", id2); - ret = id2; - goto out; - } - - switch (id2) { - case MAX8649S_CHIP_ID2_VAL: - dev_info(info->dev, "Detected MAX8649S (ID: 0x%02x%02x)\n", - id1, id2); - info->dcdc_vmin = MAX8649S_DCDC_VMIN; - info->dcdc_vmax = MAX8649S_DCDC_VMAX; - break; - case MAX8952_CHIP_ID2_VAL: - dev_info(info->dev, "Detected MAX8952 (ID: 0x%02x%02x)\n", - id1, id2); - info->dcdc_vmin = MAX8952_DCDC_VMIN; - info->dcdc_vmax = MAX8952_DCDC_VMAX; - break; - case MAX8649_CHIP_ID2_VAL: - dev_info(info->dev, "Detected MAX8649 (ID: 0x%02x%02x)\n", - id1, id2); - info->dcdc_vmin = MAX8649_DCDC_VMIN; - info->dcdc_vmax = MAX8649_DCDC_VMAX; - break; - default: - dev_info(info->dev, "Detected Unknown (ID: 0x%02x%02x)" - " - defaulting to max8649 settings\n", - id1, id2); - info->dcdc_vmin = MAX8649_DCDC_VMIN; - info->dcdc_vmax = MAX8649_DCDC_VMAX; - break; - } + dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret); /* enable VID0 & VID1 */ max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_VID_MASK, 0); diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 6d20b0454a1d..51237fbb1bbb 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -231,7 +231,8 @@ static int tps6586x_dvm_voltages[] = { }; #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1) \ + ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ +{ \ .desc = { \ .name = "REG-" #_id, \ .ops = &tps6586x_regulator_##_ops, \ @@ -247,26 +248,18 @@ static int tps6586x_dvm_voltages[] = { .enable_bit[0] = (ebit0), \ .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ .enable_bit[1] = (ebit1), \ - .voltages = tps6586x_##vdata##_voltages, - -#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ - .go_reg = TPS6586X_##goreg, \ - .go_bit = (gobit), + .voltages = tps6586x_##vdata##_voltages, \ +} #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) \ -} + ereg0, ebit0, ereg1, ebit1, 0, 0) #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) \ - TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ -} + ereg0, ebit0, ereg1, ebit1, goreg, gobit) static struct tps6586x_regulator tps6586x_regulator[] = { TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), @@ -274,11 +267,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, SUPPLYV2, 5, 3, ENC, 6, END, 6), + TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 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, V4, 7, V4, 7), + TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), - TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), + TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), 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), @@ -297,10 +290,6 @@ 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; @@ -309,14 +298,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent, if (ret) return ret; - if (!(val2 & (1 << ri->enable_bit[1]))) + if (!(val2 & 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 & (1 << ri->enable_bit[0]))) { + if (!(val1 & ri->enable_bit[0])) { ret = tps6586x_set_bits(parent, ri->enable_reg[0], 1 << ri->enable_bit[0]); if (ret) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9c9228fbab61..48ca7132cc05 100755 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -109,31 +109,6 @@ config RTC_INTF_DEV_UIE_EMUL clock several times per second, please enable this option only if you know that you really need it. -config RTC_INTF_ALARM - bool "Android alarm driver" - depends on RTC_CLASS - default y - help - Provides non-wakeup and rtc backed wakeup alarms based on rtc or - elapsed realtime, and a non-wakeup alarm on the monotonic clock. - Also provides an interface to set the wall time which must be used - for elapsed realtime to work. - -config RTC_INTF_ALARM_DEV - bool "Android alarm device" - depends on RTC_INTF_ALARM - default y - help - Exports the alarm interface to user-space. - -config RTC_INTF_CPCAP_SECCLKD - bool "Secure Clock Daemon support" - depends on RTC_DRV_CPCAP - default n - help - CPCAP RTC driver support for secure clock daemon by maintaining a - counter to keep track of changes in RTC time. - config RTC_DRV_TEST tristate "Test driver/device" help @@ -311,13 +286,6 @@ config RTC_DRV_DM355EVM help Supports the RTC firmware in the MSP430 on the DM355 EVM. -config RTC_DRV_TPS6586X - tristate "TI TPS6586X RTC" - depends on I2C - select MFD_TPS6586X - help - This driver supports TPS6586X RTC - config RTC_DRV_TWL92330 boolean "TI TWL92330/Menelaus" depends on MENELAUS @@ -686,13 +654,6 @@ config RTC_DRV_NUC900 If you say yes here you get support for the RTC subsystem of the NUC910/NUC920 used in embedded systems. -config RTC_DRV_CPCAP - depends on MFD_CPCAP - tristate "CPCAP RTC" - help - If you say yes here you get support for the RTC subsystem of the - CPCAP used in embedded systems. - comment "on-CPU RTC drivers" config RTC_DRV_DAVINCI diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 1849ff0b5963..0f207b3b5833 100755 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -11,8 +11,6 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o rtc-core-y := class.o interface.o -obj-$(CONFIG_RTC_INTF_ALARM) += alarm.o -obj-$(CONFIG_RTC_INTF_ALARM_DEV) += alarm-dev.o rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o @@ -93,7 +91,6 @@ obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o @@ -101,4 +98,3 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o -obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o diff --git a/drivers/rtc/alarm-dev.c b/drivers/rtc/alarm-dev.c deleted file mode 100644 index 686e6f7ed480..000000000000 --- a/drivers/rtc/alarm-dev.c +++ /dev/null @@ -1,286 +0,0 @@ -/* drivers/rtc/alarm-dev.c - * - * Copyright (C) 2007-2009 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ANDROID_ALARM_PRINT_INFO (1U << 0) -#define ANDROID_ALARM_PRINT_IO (1U << 1) -#define ANDROID_ALARM_PRINT_INT (1U << 2) - -static int debug_mask = ANDROID_ALARM_PRINT_INFO; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old usespace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -static int alarm_opened; -static DEFINE_SPINLOCK(alarm_slock); -static struct wake_lock alarm_wake_lock; -static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); -static uint32_t alarm_pending; -static uint32_t alarm_enabled; -static uint32_t wait_pending; - -static struct alarm alarms[ANDROID_ALARM_TYPE_COUNT]; - -static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int rv = 0; - unsigned long flags; - struct timespec new_alarm_time; - struct timespec new_rtc_time; - struct timespec tmp_time; - enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); - uint32_t alarm_type_mask = 1U << alarm_type; - - if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) - return -EINVAL; - - if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - return -EPERM; - if (file->private_data == NULL && - cmd != ANDROID_ALARM_SET_RTC) { - spin_lock_irqsave(&alarm_slock, flags); - if (alarm_opened) { - spin_unlock_irqrestore(&alarm_slock, flags); - return -EBUSY; - } - alarm_opened = 1; - file->private_data = (void *)1; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - - switch (ANDROID_ALARM_BASE_CMD(cmd)) { - case ANDROID_ALARM_CLEAR(0): - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d clear\n", alarm_type); - alarm_try_to_cancel(&alarms[alarm_type]); - if (alarm_pending) { - alarm_pending &= ~alarm_type_mask; - if (!alarm_pending && !wait_pending) - wake_unlock(&alarm_wake_lock); - } - alarm_enabled &= ~alarm_type_mask; - spin_unlock_irqrestore(&alarm_slock, flags); - break; - - case ANDROID_ALARM_SET_OLD: - case ANDROID_ALARM_SET_AND_WAIT_OLD: - if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { - rv = -EFAULT; - goto err1; - } - new_alarm_time.tv_nsec = 0; - goto from_old_alarm_set; - - case ANDROID_ALARM_SET_AND_WAIT(0): - case ANDROID_ALARM_SET(0): - if (copy_from_user(&new_alarm_time, (void __user *)arg, - sizeof(new_alarm_time))) { - rv = -EFAULT; - goto err1; - } -from_old_alarm_set: - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, - new_alarm_time.tv_sec, new_alarm_time.tv_nsec); - alarm_enabled |= alarm_type_mask; - alarm_start_range(&alarms[alarm_type], - timespec_to_ktime(new_alarm_time), - timespec_to_ktime(new_alarm_time)); - spin_unlock_irqrestore(&alarm_slock, flags); - if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) - && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) - break; - /* fall though */ - case ANDROID_ALARM_WAIT: - spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm wait\n"); - if (!alarm_pending && wait_pending) { - wake_unlock(&alarm_wake_lock); - wait_pending = 0; - } - spin_unlock_irqrestore(&alarm_slock, flags); - rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); - if (rv) - goto err1; - spin_lock_irqsave(&alarm_slock, flags); - rv = alarm_pending; - wait_pending = 1; - alarm_pending = 0; - spin_unlock_irqrestore(&alarm_slock, flags); - break; - case ANDROID_ALARM_SET_RTC: - if (copy_from_user(&new_rtc_time, (void __user *)arg, - sizeof(new_rtc_time))) { - rv = -EFAULT; - goto err1; - } - rv = alarm_set_rtc(new_rtc_time); - spin_lock_irqsave(&alarm_slock, flags); - alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; - wake_up(&alarm_wait_queue); - spin_unlock_irqrestore(&alarm_slock, flags); - if (rv < 0) - goto err1; - break; - case ANDROID_ALARM_GET_TIME(0): - switch (alarm_type) { - case ANDROID_ALARM_RTC_WAKEUP: - case ANDROID_ALARM_RTC: - getnstimeofday(&tmp_time); - break; - case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: - case ANDROID_ALARM_ELAPSED_REALTIME: - tmp_time = - ktime_to_timespec(alarm_get_elapsed_realtime()); - break; - case ANDROID_ALARM_TYPE_COUNT: - case ANDROID_ALARM_SYSTEMTIME: - ktime_get_ts(&tmp_time); - break; - } - if (copy_to_user((void __user *)arg, &tmp_time, - sizeof(tmp_time))) { - rv = -EFAULT; - goto err1; - } - break; - - default: - rv = -EINVAL; - goto err1; - } -err1: - return rv; -} - -static int alarm_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - return 0; -} - -static int alarm_release(struct inode *inode, struct file *file) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - if (file->private_data != 0) { - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { - uint32_t alarm_type_mask = 1U << i; - if (alarm_enabled & alarm_type_mask) { - pr_alarm(INFO, "alarm_release: clear alarm, " - "pending %d\n", - !!(alarm_pending & alarm_type_mask)); - alarm_enabled &= ~alarm_type_mask; - } - spin_unlock_irqrestore(&alarm_slock, flags); - alarm_cancel(&alarms[i]); - spin_lock_irqsave(&alarm_slock, flags); - } - if (alarm_pending | wait_pending) { - if (alarm_pending) - pr_alarm(INFO, "alarm_release: clear " - "pending alarms %x\n", alarm_pending); - wake_unlock(&alarm_wake_lock); - wait_pending = 0; - alarm_pending = 0; - } - alarm_opened = 0; - } - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - -static void alarm_triggered(struct alarm *alarm) -{ - unsigned long flags; - uint32_t alarm_type_mask = 1U << alarm->type; - - pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); - spin_lock_irqsave(&alarm_slock, flags); - if (alarm_enabled & alarm_type_mask) { - wake_lock_timeout(&alarm_wake_lock, 5 * HZ); - alarm_enabled &= ~alarm_type_mask; - alarm_pending |= alarm_type_mask; - wake_up(&alarm_wait_queue); - } - spin_unlock_irqrestore(&alarm_slock, flags); -} - -static const struct file_operations alarm_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = alarm_ioctl, - .open = alarm_open, - .release = alarm_release, -}; - -static struct miscdevice alarm_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "alarm", - .fops = &alarm_fops, -}; - -static int __init alarm_dev_init(void) -{ - int err; - int i; - - err = misc_register(&alarm_device); - if (err) - return err; - - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - alarm_init(&alarms[i], i, alarm_triggered); - wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); - - return 0; -} - -static void __exit alarm_dev_exit(void) -{ - misc_deregister(&alarm_device); - wake_lock_destroy(&alarm_wake_lock); -} - -module_init(alarm_dev_init); -module_exit(alarm_dev_exit); - diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c deleted file mode 100644 index b445a8675850..000000000000 --- a/drivers/rtc/alarm.c +++ /dev/null @@ -1,590 +0,0 @@ -/* drivers/rtc/alarm.c - * - * Copyright (C) 2007-2009 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ANDROID_ALARM_PRINT_ERROR (1U << 0) -#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) -#define ANDROID_ALARM_PRINT_TSET (1U << 2) -#define ANDROID_ALARM_PRINT_CALL (1U << 3) -#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) -#define ANDROID_ALARM_PRINT_INT (1U << 5) -#define ANDROID_ALARM_PRINT_FLOW (1U << 6) - -static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ - ANDROID_ALARM_PRINT_INIT_STATUS; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old usespace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -struct alarm_queue { - struct rb_root alarms; - struct rb_node *first; - struct hrtimer timer; - ktime_t delta; - bool stopped; - ktime_t stopped_time; -}; - -static struct rtc_device *alarm_rtc_dev; -static DEFINE_SPINLOCK(alarm_slock); -static DEFINE_MUTEX(alarm_setrtc_mutex); -static struct wake_lock alarm_rtc_wake_lock; -static struct platform_device *alarm_platform_dev; -struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; -static bool suspended; - -static void update_timer_locked(struct alarm_queue *base, bool head_removed) -{ - struct alarm *alarm; - bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || - base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - - if (base->stopped) { - pr_alarm(FLOW, "changed alarm while setting the wall time\n"); - return; - } - - if (is_wakeup && !suspended && head_removed) - wake_unlock(&alarm_rtc_wake_lock); - - if (!base->first) - return; - - alarm = container_of(base->first, struct alarm, node); - - pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (is_wakeup && suspended) { - pr_alarm(FLOW, "changed alarm while suspened\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); - return; - } - - hrtimer_try_to_cancel(&base->timer); - base->timer._expires = ktime_add(base->delta, alarm->expires); - base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); - hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); -} - -static void alarm_enqueue_locked(struct alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - struct rb_node **link = &base->alarms.rb_node; - struct rb_node *parent = NULL; - struct alarm *entry; - int leftmost = 1; - bool was_first = false; - - pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - was_first = true; - } - if (!RB_EMPTY_NODE(&alarm->node)) { - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - } - - while (*link) { - parent = *link; - entry = rb_entry(parent, struct alarm, node); - /* - * We dont care about collisions. Nodes with - * the same expiry time stay together. - */ - if (alarm->expires.tv64 < entry->expires.tv64) { - link = &(*link)->rb_left; - } else { - link = &(*link)->rb_right; - leftmost = 0; - } - } - if (leftmost) - base->first = &alarm->node; - if (leftmost || was_first) - update_timer_locked(base, was_first); - - rb_link_node(&alarm->node, parent, link); - rb_insert_color(&alarm->node, &base->alarms); -} - -/** - * alarm_init - initialize an alarm - * @alarm: the alarm to be initialized - * @type: the alarm type to be used - * @function: alarm callback function - */ -void alarm_init(struct alarm *alarm, - enum android_alarm_type type, void (*function)(struct alarm *)) -{ - RB_CLEAR_NODE(&alarm->node); - alarm->type = type; - alarm->function = function; - - pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); -} - - -/** - * alarm_start_range - (re)start an alarm - * @alarm: the alarm to be added - * @start: earliest expiry time - * @end: expiry time - */ -void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) -{ - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - alarm->softexpires = start; - alarm->expires = end; - alarm_enqueue_locked(alarm); - spin_unlock_irqrestore(&alarm_slock, flags); -} - -/** - * alarm_try_to_cancel - try to deactivate an alarm - * @alarm: alarm to stop - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - * -1 when the alarm may currently be excuting the callback function and - * cannot be stopped (it may also be inactive) - */ -int alarm_try_to_cancel(struct alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - unsigned long flags; - bool first = false; - int ret = 0; - - spin_lock_irqsave(&alarm_slock, flags); - if (!RB_EMPTY_NODE(&alarm->node)) { - pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires)); - ret = 1; - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - first = true; - } - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - if (first) - update_timer_locked(base, true); - } else - pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", - alarm->type, alarm->function); - spin_unlock_irqrestore(&alarm_slock, flags); - if (!ret && hrtimer_callback_running(&base->timer)) - ret = -1; - return ret; -} - -/** - * alarm_cancel - cancel an alarm and wait for the handler to finish. - * @alarm: the alarm to be cancelled - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - */ -int alarm_cancel(struct alarm *alarm) -{ - for (;;) { - int ret = alarm_try_to_cancel(alarm); - if (ret >= 0) - return ret; - cpu_relax(); - } -} - -/** - * alarm_set_rtc - set the kernel and rtc walltime - * @new_time: timespec value containing the new time - */ -int alarm_set_rtc(struct timespec new_time) -{ - int i; - int ret; - unsigned long flags; - struct rtc_time rtc_new_rtc_time; - struct timespec tmp_time; - - rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); - - pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", - new_time.tv_sec, new_time.tv_nsec, - rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, - rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, - rtc_new_rtc_time.tm_mday, - rtc_new_rtc_time.tm_year + 1900); - - mutex_lock(&alarm_setrtc_mutex); - spin_lock_irqsave(&alarm_slock, flags); - wake_lock(&alarm_rtc_wake_lock); - getnstimeofday(&tmp_time); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_try_to_cancel(&alarms[i].timer); - alarms[i].stopped = true; - alarms[i].stopped_time = timespec_to_ktime(tmp_time); - } - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, - timespec_to_ktime(timespec_sub(tmp_time, new_time))); - spin_unlock_irqrestore(&alarm_slock, flags); - ret = do_settimeofday(&new_time); - spin_lock_irqsave(&alarm_slock, flags); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - alarms[i].stopped = false; - update_timer_locked(&alarms[i], false); - } - spin_unlock_irqrestore(&alarm_slock, flags); - if (ret < 0) { - pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); - goto err; - } - if (!alarm_rtc_dev) { - pr_alarm(ERROR, - "alarm_set_rtc: no RTC, time will be lost on reboot\n"); - goto err; - } - ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); - if (ret < 0) - pr_alarm(ERROR, "alarm_set_rtc: " - "Failed to set RTC, time will be lost on reboot\n"); -err: - wake_unlock(&alarm_rtc_wake_lock); - mutex_unlock(&alarm_setrtc_mutex); - return ret; -} - -/** - * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format - * - * returns the time in ktime_t format - */ -ktime_t alarm_get_elapsed_realtime(void) -{ - ktime_t now; - unsigned long flags; - struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; - - spin_lock_irqsave(&alarm_slock, flags); - now = base->stopped ? base->stopped_time : ktime_get_real(); - now = ktime_sub(now, base->delta); - spin_unlock_irqrestore(&alarm_slock, flags); - return now; -} - -static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) -{ - struct alarm_queue *base; - struct alarm *alarm; - unsigned long flags; - ktime_t now; - - spin_lock_irqsave(&alarm_slock, flags); - - base = container_of(timer, struct alarm_queue, timer); - now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); - now = ktime_sub(now, base->delta); - - pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", - base - alarms, ktime_to_ns(now)); - - while (base->first) { - alarm = container_of(base->first, struct alarm, node); - if (alarm->softexpires.tv64 > now.tv64) { - pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", - alarm->function, ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - break; - } - base->first = rb_next(&alarm->node); - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - spin_unlock_irqrestore(&alarm_slock, flags); - alarm->function(alarm); - spin_lock_irqsave(&alarm_slock, flags); - } - if (!base->first) - pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); - update_timer_locked(base, true); - spin_unlock_irqrestore(&alarm_slock, flags); - return HRTIMER_NORESTART; -} - -static void alarm_triggered_func(void *p) -{ - struct rtc_device *rtc = alarm_rtc_dev; - if (!(rtc->irq_data & RTC_AF)) - return; - pr_alarm(INT, "rtc alarm triggered\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); -} - -static int alarm_suspend(struct platform_device *pdev, pm_message_t state) -{ - int err = 0; - unsigned long flags; - struct rtc_wkalrm rtc_alarm; - struct rtc_time rtc_current_rtc_time; - unsigned long rtc_current_time; - unsigned long rtc_alarm_time; - struct timespec rtc_delta; - struct timespec wall_time; - struct alarm_queue *wakeup_queue = NULL; - struct alarm_queue *tmp_queue = NULL; - - pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = true; - spin_unlock_irqrestore(&alarm_slock, flags); - - hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); - hrtimer_cancel(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK].timer); - - tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; - if (tmp_queue->first) - wakeup_queue = tmp_queue; - tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - if (tmp_queue->first && (!wakeup_queue || - hrtimer_get_expires(&tmp_queue->timer).tv64 < - hrtimer_get_expires(&wakeup_queue->timer).tv64)) - wakeup_queue = tmp_queue; - if (wakeup_queue) { - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - getnstimeofday(&wall_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - set_normalized_timespec(&rtc_delta, - wall_time.tv_sec - rtc_current_time, - wall_time.tv_nsec); - - rtc_alarm_time = timespec_sub(ktime_to_timespec( - hrtimer_get_expires(&wakeup_queue->timer)), - rtc_delta).tv_sec; - - rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); - rtc_alarm.enabled = 1; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - pr_alarm(SUSPEND, - "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", - rtc_alarm_time, rtc_current_time, - rtc_delta.tv_sec, rtc_delta.tv_nsec); - if (rtc_current_time + 1 >= rtc_alarm_time) { - pr_alarm(SUSPEND, "alarm about to go off\n"); - memset(&rtc_alarm, 0, sizeof(rtc_alarm)); - rtc_alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], - false); - update_timer_locked(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); - err = -EBUSY; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - return err; -} - -static int alarm_resume(struct platform_device *pdev) -{ - struct rtc_wkalrm alarm; - unsigned long flags; - - pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); - - memset(&alarm, 0, sizeof(alarm)); - alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); - update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], - false); - spin_unlock_irqrestore(&alarm_slock, flags); - - return 0; -} - -static struct rtc_task alarm_rtc_task = { - .func = alarm_triggered_func -}; - -static int rtc_alarm_add_device(struct device *dev, - struct class_interface *class_intf) -{ - int err; - struct rtc_device *rtc = to_rtc_device(dev); - - mutex_lock(&alarm_setrtc_mutex); - - if (alarm_rtc_dev) { - err = -EBUSY; - goto err1; - } - - alarm_platform_dev = - platform_device_register_simple("alarm", -1, NULL, 0); - if (IS_ERR(alarm_platform_dev)) { - err = PTR_ERR(alarm_platform_dev); - goto err2; - } - err = rtc_irq_register(rtc, &alarm_rtc_task); - if (err) - goto err3; - alarm_rtc_dev = rtc; - pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); - mutex_unlock(&alarm_setrtc_mutex); - - return 0; - -err3: - platform_device_unregister(alarm_platform_dev); -err2: -err1: - mutex_unlock(&alarm_setrtc_mutex); - return err; -} - -static void rtc_alarm_remove_device(struct device *dev, - struct class_interface *class_intf) -{ - if (dev == &alarm_rtc_dev->dev) { - pr_alarm(INIT_STATUS, "lost rtc device for alarms"); - rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); - platform_device_unregister(alarm_platform_dev); - alarm_rtc_dev = NULL; - } -} - -static struct class_interface rtc_alarm_interface = { - .add_dev = &rtc_alarm_add_device, - .remove_dev = &rtc_alarm_remove_device, -}; - -static struct platform_driver alarm_driver = { - .suspend = alarm_suspend, - .resume = alarm_resume, - .driver = { - .name = "alarm" - } -}; - -static int __init alarm_late_init(void) -{ - unsigned long flags; - struct timespec tmp_time, system_time; - - /* this needs to run after the rtc is read at boot */ - spin_lock_irqsave(&alarm_slock, flags); - /* We read the current rtc and system time so we can later calulate - * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == - * (rtc - (boot_rtc - boot_systemtime)) - */ - getnstimeofday(&tmp_time); - ktime_get_ts(&system_time); - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - timespec_to_ktime(timespec_sub(tmp_time, system_time)); - - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - -static int __init alarm_driver_init(void) -{ - int err; - int i; - - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_init(&alarms[i].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - alarms[i].timer.function = alarm_timer_triggered; - } - hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; - err = platform_driver_register(&alarm_driver); - if (err < 0) - goto err1; - wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); - rtc_alarm_interface.class = rtc_class; - err = class_interface_register(&rtc_alarm_interface); - if (err < 0) - goto err2; - - return 0; - -err2: - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -err1: - return err; -} - -static void __exit alarm_exit(void) -{ - class_interface_unregister(&rtc_alarm_interface); - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -} - -late_initcall(alarm_late_init); -module_init(alarm_driver_init); -module_exit(alarm_exit); - diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 11d7ab90a67c..565562ba6ac9 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -41,32 +41,25 @@ static void rtc_device_release(struct device *dev) */ static struct timespec delta; -static struct timespec delta_delta; static time_t oldtime; static int rtc_suspend(struct device *dev, pm_message_t mesg) { struct rtc_device *rtc = to_rtc_device(dev); struct rtc_time tm; - struct timespec ts; - struct timespec new_delta; + struct timespec ts = current_kernel_time(); if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) return 0; - getnstimeofday(&ts); rtc_read_time(rtc, &tm); rtc_tm_to_time(&tm, &oldtime); /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ - set_normalized_timespec(&new_delta, + set_normalized_timespec(&delta, ts.tv_sec - oldtime, ts.tv_nsec - (NSEC_PER_SEC >> 1)); - /* prevent 1/2 sec errors from accumulating */ - delta_delta = timespec_sub(new_delta, delta); - if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) - delta = new_delta; return 0; } @@ -86,8 +79,6 @@ static int rtc_resume(struct device *dev) return 0; } rtc_tm_to_time(&tm, &newtime); - if (delta_delta.tv_sec < -1) - newtime++; if (newtime <= oldtime) { if (newtime < oldtime) pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c deleted file mode 100644 index 7e9c7051fce1..000000000000 --- a/drivers/rtc/rtc-cpcap.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 2009 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef RTC_INTF_CPCAP_SECCLKD -#include - -#define CNT_MASK 0xFFFF -#endif -#define SECS_PER_DAY 86400 -#define DAY_MASK 0x7FFF -#define TOD1_MASK 0x00FF -#define TOD2_MASK 0x01FF - -#ifdef RTC_INTF_CPCAP_SECCLKD -static int cpcap_rtc_open(struct inode *inode, struct file *file); -static int cpcap_rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); -static unsigned int cpcap_rtc_poll(struct file *file, poll_table *wait); -static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm); -#endif - -struct cpcap_time { - unsigned short day; - unsigned short tod1; - unsigned short tod2; -}; - -struct cpcap_rtc { - struct cpcap_device *cpcap; - struct rtc_device *rtc_dev; - int alarm_enabled; - int second_enabled; -#ifdef RTC_INTF_CPCAP_SECCLKD - struct device *dev; - struct mutex lock; /* protect access to flags */ - wait_queue_head_t wait; - bool data_pending; - bool reset_flag; -#endif -}; - -#ifdef RTC_INTF_CPCAP_SECCLKD -static const struct file_operations cpcap_rtc_fops = { - .owner = THIS_MODULE, - .open = cpcap_rtc_open, - .ioctl = cpcap_rtc_ioctl, - .poll = cpcap_rtc_poll, -}; - -static struct cpcap_rtc *rtc_ptr; - -static struct miscdevice cpcap_rtc_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "cpcap_mot_rtc", - .fops = &cpcap_rtc_fops, -}; - -static int cpcap_rtc_open(struct inode *inode, struct file *file) -{ - file->private_data = rtc_ptr; - return 0; -} - -static int cpcap_rtc_ioctl(struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) -{ - struct cpcap_rtc *rtc = file->private_data; - struct cpcap_rtc_time_cnt local_val; - int ret = 0; - - mutex_lock(&rtc->lock); - switch (cmd) { - case CPCAP_IOCTL_GET_RTC_TIME_COUNTER: - ret = cpcap_rtc_read_time(rtc->dev, &local_val.time); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_VAL2, - &local_val.count); - - if (ret) - break; - - if (rtc->reset_flag) { - rtc->reset_flag = 0; - local_val.count = 0; - } - - /* Copy the result back to the user. */ - if (copy_to_user((struct cpcap_rtc_time_cnt *)arg, &local_val, - sizeof(struct cpcap_rtc_time_cnt)) == 0) { - if (local_val.count == 0) { - ret = cpcap_regacc_write(rtc->cpcap, - CPCAP_REG_VAL2, 0x0001, - CNT_MASK); - if (ret) - break; - } - rtc->data_pending = 0; - } else - ret = -EFAULT; - break; - - default: - ret = -ENOTTY; - - } - - mutex_unlock(&rtc->lock); - return ret; -} - -static unsigned int cpcap_rtc_poll(struct file *file, poll_table *wait) -{ - struct cpcap_rtc *rtc = file->private_data; - unsigned int ret = 0; - - poll_wait(file, &rtc->wait, wait); - - if (rtc->data_pending) - ret = (POLLIN | POLLRDNORM); - - return ret; -} -#endif - -static void cpcap2rtc_time(struct rtc_time *rtc, struct cpcap_time *cpcap) -{ - unsigned long int tod; - unsigned long int time; - - tod = (cpcap->tod1 & TOD1_MASK) | ((cpcap->tod2 & TOD2_MASK) << 8); - time = tod + ((cpcap->day & DAY_MASK) * SECS_PER_DAY); - - rtc_time_to_tm(time, rtc); -} - -static void rtc2cpcap_time(struct cpcap_time *cpcap, struct rtc_time *rtc) -{ - unsigned long time; - - rtc_tm_to_time(rtc, &time); - - cpcap->day = time / SECS_PER_DAY; - time %= SECS_PER_DAY; - cpcap->tod2 = (time >> 8) & TOD2_MASK; - cpcap->tod1 = time & TOD1_MASK; -} - -static int -cpcap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct cpcap_rtc *rtc = dev_get_drvdata(dev); - int err; - - if (enabled) - err = cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_TODA); - else - err = cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA); - - if (err < 0) - return err; - - rtc->alarm_enabled = enabled; - - return 0; -} - -static int -cpcap_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct cpcap_rtc *rtc = dev_get_drvdata(dev); - int err; - - if (enabled) - err = cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_1HZ); - else - err = cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ); - - if (err < 0) - return err; - - rtc->second_enabled = enabled; - - return 0; -} - -static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct cpcap_rtc *rtc; - struct cpcap_time cpcap_tm; - unsigned short temp_tod2; - int ret; - - rtc = dev_get_drvdata(dev); - - ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD2, &temp_tod2); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAY, &cpcap_tm.day); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD1, &cpcap_tm.tod1); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD2, &cpcap_tm.tod2); - if (temp_tod2 > cpcap_tm.tod2) - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAY, - &cpcap_tm.day); - - if (ret) { - dev_err(dev, "Failed to read time\n"); - return -EIO; - } - - cpcap2rtc_time(tm, &cpcap_tm); - - dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", - tm->tm_mday, tm->tm_mon, tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return rtc_valid_tm(tm); -} - -static int cpcap_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct cpcap_rtc *rtc; - struct cpcap_time cpcap_tm; - int second_masked; - int alarm_masked; - int ret = 0; -#ifdef RTC_INTF_CPCAP_SECCLKD - unsigned short local_cnt; -#endif - - rtc = dev_get_drvdata(dev); - - dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", - tm->tm_mday, tm->tm_mon, tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - rtc2cpcap_time(&cpcap_tm, tm); - - second_masked = cpcap_irq_mask_get(rtc->cpcap, CPCAP_IRQ_1HZ); - alarm_masked = cpcap_irq_mask_get(rtc->cpcap, CPCAP_IRQ_TODA); - - if (!second_masked) - cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ); - if (!alarm_masked) - cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA); - -#ifdef RTC_INTF_CPCAP_SECCLKD - /* Increment the counter and update validity 2 register */ - ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_VAL2, &local_cnt); - - if (local_cnt == 0) - rtc->reset_flag = 1; - - if (local_cnt == CNT_MASK) - local_cnt = 0x0001; - else - local_cnt++; - - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_VAL2, local_cnt, - CNT_MASK); -#endif - - if (rtc->cpcap->vendor == CPCAP_VENDOR_ST) { - /* The TOD1 and TOD2 registers MUST be written in this order - * for the change to properly set. */ - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1, - cpcap_tm.tod1, TOD1_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD2, - cpcap_tm.tod2, TOD2_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAY, - cpcap_tm.day, DAY_MASK); - } else { - /* Clearing the upper lower 8 bits of the TOD guarantees that - * the upper half of TOD (TOD2) will not increment for 0xFF RTC - * ticks (255 seconds). During this time we can safely write - * to DAY, TOD2, then TOD1 (in that order) and expect RTC to be - * synchronized to the exact time requested upon the final write - * to TOD1. */ - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1, - 0, TOD1_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAY, - cpcap_tm.day, DAY_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD2, - cpcap_tm.tod2, TOD2_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1, - cpcap_tm.tod1, TOD1_MASK); - } - - if (!second_masked) - cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_1HZ); - if (!alarm_masked) - cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_TODA); - -#ifdef RTC_INTF_CPCAP_SECCLKD - mutex_lock(&rtc->lock); - rtc->data_pending = 1; - mutex_unlock(&rtc->lock); - wake_up_interruptible(&rtc->wait); -#endif - - return ret; -} - -static int cpcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct cpcap_rtc *rtc; - struct cpcap_time cpcap_tm; - int ret; - - rtc = dev_get_drvdata(dev); - - alrm->enabled = rtc->alarm_enabled; - - ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAYA, &cpcap_tm.day); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TODA2, &cpcap_tm.tod2); - ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TODA1, &cpcap_tm.tod1); - - if (ret) { - dev_err(dev, "Failed to read time\n"); - return -EIO; - } - - cpcap2rtc_time(&alrm->time, &cpcap_tm); - return rtc_valid_tm(&alrm->time); -} - -static int cpcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct cpcap_rtc *rtc; - struct cpcap_time cpcap_tm; - int ret; - - rtc = dev_get_drvdata(dev); - - rtc2cpcap_time(&cpcap_tm, &alrm->time); - - if (rtc->alarm_enabled) - cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA); - - ret = cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAYA, cpcap_tm.day, - DAY_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TODA2, cpcap_tm.tod2, - TOD2_MASK); - ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TODA1, cpcap_tm.tod1, - TOD1_MASK); - - ret |= cpcap_rtc_alarm_irq_enable(dev, alrm->enabled); - - return ret; -} - -static struct rtc_class_ops cpcap_rtc_ops = { - .read_time = cpcap_rtc_read_time, - .set_time = cpcap_rtc_set_time, - .read_alarm = cpcap_rtc_read_alarm, - .set_alarm = cpcap_rtc_set_alarm, - .alarm_irq_enable = cpcap_rtc_alarm_irq_enable, - .update_irq_enable = cpcap_rtc_update_irq_enable, -}; - -static void cpcap_rtc_irq(enum cpcap_irqs irq, void *data) -{ - struct cpcap_rtc *rtc = data; - - switch (irq) { - case CPCAP_IRQ_TODA: - rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); - break; - case CPCAP_IRQ_1HZ: - rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); - break; - default: - break; - } -} - -static int __devinit cpcap_rtc_probe(struct platform_device *pdev) -{ - struct cpcap_rtc *rtc; -#ifdef RTC_INTF_CPCAP_SECCLKD - int ret = 0; -#endif - - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); - if (!rtc) - return -ENOMEM; - - rtc->cpcap = pdev->dev.platform_data; - platform_set_drvdata(pdev, rtc); - rtc->rtc_dev = rtc_device_register("cpcap_rtc", &pdev->dev, - &cpcap_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc->rtc_dev)) { - kfree(rtc); - return PTR_ERR(rtc->rtc_dev); - } - -#ifdef RTC_INTF_CPCAP_SECCLKD - rtc->dev = &pdev->dev; - ret = misc_register(&cpcap_rtc_dev); - if (ret != 0) { - rtc_device_unregister(rtc->rtc_dev); - kfree(rtc); - return ret; - } - - mutex_init(&rtc->lock); - init_waitqueue_head(&rtc->wait); - rtc_ptr = rtc; -#endif - cpcap_irq_register(rtc->cpcap, CPCAP_IRQ_TODA, cpcap_rtc_irq, rtc); - cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA); - - cpcap_irq_clear(rtc->cpcap, CPCAP_IRQ_1HZ); - cpcap_irq_register(rtc->cpcap, CPCAP_IRQ_1HZ, cpcap_rtc_irq, rtc); - cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ); - - return 0; -} - -static int __devexit cpcap_rtc_remove(struct platform_device *pdev) -{ - struct cpcap_rtc *rtc; - - rtc = platform_get_drvdata(pdev); - - cpcap_irq_free(rtc->cpcap, CPCAP_IRQ_TODA); - cpcap_irq_free(rtc->cpcap, CPCAP_IRQ_1HZ); - -#ifdef RTC_INTF_CPCAP_SECCLKD - misc_deregister(&cpcap_rtc_dev); -#endif - rtc_device_unregister(rtc->rtc_dev); - kfree(rtc); - - return 0; -} - -static struct platform_driver cpcap_rtc_driver = { - .driver = { - .name = "cpcap_rtc", - }, - .probe = cpcap_rtc_probe, - .remove = __devexit_p(cpcap_rtc_remove), -}; - -static int __init cpcap_rtc_init(void) -{ - return platform_driver_register(&cpcap_rtc_driver); -} -module_init(cpcap_rtc_init); - -static void __exit cpcap_rtc_exit(void) -{ - platform_driver_unregister(&cpcap_rtc_driver); -} -module_exit(cpcap_rtc_exit); - -MODULE_ALIAS("platform:cpcap_rtc"); -MODULE_DESCRIPTION("CPCAP RTC driver"); -MODULE_AUTHOR("Motorola"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index dd14e202c2c8..90cf0a6ff23e 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[7]; + unsigned char buf[8]; int addr; dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c deleted file mode 100644 index ca6138bbda4b..000000000000 --- a/drivers/rtc/rtc-tps6586x.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * drivers/rtc/rtc-tps6586x.c - * - * RTC driver for TI TPS6586x - * - * Copyright (c) 2010, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define TPS_EPOCH 2009 - -#define RTC_CTRL 0xc0 -# define RTC_ENABLE (1 << 5) /* enables tick updates */ -# define RTC_HIRES (1 << 4) /* 1Khz or 32Khz updates */ -#define RTC_ALARM1_HI 0xc1 -#define RTC_COUNT4 0xc6 - -struct tps6586x_rtc { - unsigned long epoch_start; - int irq; - bool irq_en; - struct rtc_device *rtc; -}; - -static inline struct device *to_tps6586x_dev(struct device *dev) -{ - return dev->parent; -} - -static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - struct device *tps_dev = to_tps6586x_dev(dev); - unsigned long long ticks = 0; - unsigned long seconds; - u8 buff[5]; - int err; - int i; - - err = tps6586x_reads(tps_dev, RTC_COUNT4, sizeof(buff), buff); - if (err < 0) { - dev_err(dev, "failed to read counter\n"); - return err; - } - - for (i = 0; i < sizeof(buff); i++) { - ticks <<= 8; - ticks |= buff[i]; - } - - seconds = ticks >> 10; - - seconds += rtc->epoch_start; - rtc_time_to_tm(seconds, tm); - return rtc_valid_tm(tm); -} - -static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - struct device *tps_dev = to_tps6586x_dev(dev); - unsigned long long ticks; - unsigned long seconds; - u8 buff[5]; - int err; - - rtc_tm_to_time(tm, &seconds); - - if (WARN_ON(seconds < rtc->epoch_start)) { - dev_err(dev, "requested time unsupported\n"); - return -EINVAL; - } - - seconds -= rtc->epoch_start; - - ticks = (unsigned long long)seconds << 10; - buff[0] = (ticks >> 32) & 0xff; - buff[1] = (ticks >> 24) & 0xff; - buff[2] = (ticks >> 16) & 0xff; - buff[3] = (ticks >> 8) & 0xff; - buff[4] = ticks & 0xff; - - err = tps6586x_clr_bits(tps_dev, RTC_CTRL, RTC_ENABLE); - if (err < 0) { - dev_err(dev, "failed to clear RTC_ENABLE\n"); - return err; - } - - err = tps6586x_writes(tps_dev, RTC_COUNT4, sizeof(buff), buff); - if (err < 0) { - dev_err(dev, "failed to program new time\n"); - return err; - } - - err = tps6586x_set_bits(tps_dev, RTC_CTRL, RTC_ENABLE); - if (err < 0) { - dev_err(dev, "failed to set RTC_ENABLE\n"); - return err; - } - - return 0; -} - -static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - struct device *tps_dev = to_tps6586x_dev(dev); - unsigned long seconds; - unsigned long ticks; - u8 buff[3]; - int err; - - if (rtc->irq == -1) - return -EIO; - - rtc_tm_to_time(&alrm->time, &seconds); - - if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { - dev_err(dev, "can't set alarm to requested time\n"); - return -EINVAL; - } - - if (rtc->irq_en && rtc->irq_en && (rtc->irq != -1)) { - disable_irq(rtc->irq); - rtc->irq_en = false; - } - - seconds -= rtc->epoch_start; - ticks = (unsigned long long)seconds << 10; - - buff[0] = (ticks >> 16) & 0xff; - buff[1] = (ticks >> 8) & 0xff; - buff[2] = ticks & 0xff; - - err = tps6586x_writes(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); - if (err) { - dev_err(tps_dev, "unable to program alarm\n"); - return err; - } - - if (alrm->enabled && (rtc->irq != -1)) { - enable_irq(rtc->irq); - rtc->irq_en = true; - } - - return err; -} - -static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - struct device *tps_dev = to_tps6586x_dev(dev); - unsigned long ticks; - unsigned long seconds; - u8 buff[3]; - int err; - - err = tps6586x_reads(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); - if (err) - return err; - - ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2]; - seconds = ticks >> 10; - seconds += rtc->epoch_start; - - rtc_time_to_tm(seconds, &alrm->time); - alrm->enabled = rtc->irq_en; - - return 0; -} - -static int tps6586x_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - - if (rtc->irq == -1) - return -EIO; - - enabled = !!enabled; - if (enabled == rtc->irq_en) - return 0; - - if (enabled) - enable_irq(rtc->irq); - else - disable_irq(rtc->irq); - - rtc->irq_en = enabled; - return 0; -} - -static const struct rtc_class_ops tps6586x_rtc_ops = { - .read_time = tps6586x_rtc_read_time, - .set_time = tps6586x_rtc_set_time, - .set_alarm = tps6586x_rtc_set_alarm, - .read_alarm = tps6586x_rtc_read_alarm, - .update_irq_enable = tps6586x_rtc_update_irq_enable, -}; - -static irqreturn_t tps6586x_rtc_irq(int irq, void *data) -{ - struct device *dev = data; - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); - - rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); - return IRQ_HANDLED; -} - -static int __devinit tps6586x_rtc_probe(struct platform_device *pdev) -{ - struct tps6586x_rtc_platform_data *pdata = pdev->dev.platform_data; - struct device *tps_dev = to_tps6586x_dev(&pdev->dev); - struct tps6586x_rtc *rtc; - int err; - - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); - - if (!rtc) - return -ENOMEM; - - rtc->irq = -1; - if (!pdata || (pdata->irq < 0)) - dev_warn(&pdev->dev, "no IRQ specified, wakeup is disabled\n"); - - rtc->epoch_start = mktime(TPS_EPOCH, 1, 1, 0, 0, 0); - - rtc->rtc = rtc_device_register("tps6586x-rtc", &pdev->dev, - &tps6586x_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc->rtc)) { - err = PTR_ERR(rtc->rtc); - goto fail; - } - - /* disable high-res mode, enable tick counting */ - err = tps6586x_update(tps_dev, RTC_CTRL, - (RTC_ENABLE | RTC_HIRES), RTC_ENABLE); - if (err < 0) { - dev_err(&pdev->dev, "unable to start counter\n"); - goto fail; - } - - dev_set_drvdata(&pdev->dev, rtc); - if (pdata && (pdata->irq >= 0)) { - rtc->irq = pdata->irq; - err = request_threaded_irq(pdata->irq, NULL, tps6586x_rtc_irq, - IRQF_ONESHOT, "tps6586x-rtc", - &pdev->dev); - if (err) { - dev_warn(&pdev->dev, "unable to request IRQ\n"); - rtc->irq = -1; - } else { - device_init_wakeup(&pdev->dev, 1); - disable_irq(rtc->irq); - enable_irq_wake(rtc->irq); - } - } - - return 0; - -fail: - if (!IS_ERR_OR_NULL(rtc->rtc)) - rtc_device_unregister(rtc->rtc); - kfree(rtc); - return err; -} - -static int __devexit tps6586x_rtc_remove(struct platform_device *pdev) -{ - struct tps6586x_rtc *rtc = dev_get_drvdata(&pdev->dev); - - if (rtc->irq != -1) - free_irq(rtc->irq, rtc); - rtc_device_unregister(rtc->rtc); - kfree(rtc); - return 0; -} - -static struct platform_driver tps6586x_rtc_driver = { - .driver = { - .name = "tps6586x-rtc", - .owner = THIS_MODULE, - }, - .probe = tps6586x_rtc_probe, - .remove = __devexit_p(tps6586x_rtc_remove), -}; - -static int __init tps6586x_rtc_init(void) -{ - return platform_driver_register(&tps6586x_rtc_driver); -} -module_init(tps6586x_rtc_init); - -static void __exit tps6586x_rtc_exit(void) -{ - platform_driver_unregister(&tps6586x_rtc_driver); -} -module_exit(tps6586x_rtc_exit); - -MODULE_DESCRIPTION("TI TPS6586x RTC driver"); -MODULE_AUTHOR("NVIDIA Corporation"); -MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 4cf7ffa2dad3..b860d650a563 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4175,14 +4175,6 @@ static int ioc_general(void __user *arg, char *cmnd) ha = gdth_find_ha(gen.ionode); if (!ha) return -EFAULT; - - if (gen.data_len > INT_MAX) - return -EINVAL; - if (gen.sense_len > INT_MAX) - return -EINVAL; - if (gen.data_len + gen.sense_len > INT_MAX) - return -EINVAL; - if (gen.data_len + gen.sense_len != 0) { if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, &paddr))) diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index ddbade7beec9..042153cbbde1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -347,7 +347,6 @@ static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in, static struct ata_port_operations sas_sata_ops = { .phy_reset = sas_ata_phy_reset, .post_internal_cmd = sas_ata_post_internal, - .qc_defer = ata_std_qc_defer, .qc_prep = ata_noop_qc_prep, .qc_issue = sas_ata_qc_issue, .qc_fill_rtf = sas_ata_qc_fill_rtf, diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index dd78f9e8eb9b..6cfa0145a1d7 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -568,6 +568,7 @@ struct pmcraid_cmd { struct pmcraid_control_block *ioa_cb; dma_addr_t ioa_cb_bus_addr; dma_addr_t dma_handle; + u8 *sense_buffer; /* pointer to mid layer structure of SCSI commands */ struct scsi_cmnd *scsi_cmd; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 16df82ac1b26..1a1b281cea33 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -92,7 +92,6 @@ extern int ql2xshiftctondsd; extern int ql2xdbwr; extern int ql2xdontresethba; extern int ql2xasynctmfenable; -extern int ql2xgffidenable; extern int ql2xenabledif; extern int ql2xenablehba_err_chk; extern int ql2xtargetreset; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 49e7b0916364..9c383baebe27 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3258,9 +3258,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, continue; /* Bypass ports whose FCP-4 type is not FCP_SCSI */ - if (ql2xgffidenable && - (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI && - new_fcport->fc4_type != FC4_TYPE_UNKNOWN)) + if (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI && + new_fcport->fc4_type != FC4_TYPE_UNKNOWN) continue; /* Locate matching device in database. */ diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index de844996743c..579f02854665 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1061,7 +1061,6 @@ 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_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 424cf189af27..0a71cc71eab2 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -2740,7 +2740,6 @@ 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)); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 202a31ab2f18..1e4bff695254 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -160,11 +160,6 @@ MODULE_PARM_DESC(ql2xtargetreset, "Enable target reset." "Default is 1 - use hw defaults."); -int ql2xgffidenable; -module_param(ql2xgffidenable, int, S_IRUGO|S_IRUSR); -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); @@ -2095,7 +2090,6 @@ 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; diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 449256f2c5f8..5d4a3822382d 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -5,7 +5,6 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ #include -#include #include #include "ql4_def.h" #include "ql4_glbl.h" diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5bff8a2396e4..ee02d3838a0a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1632,8 +1632,9 @@ 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) - q->limits.cluster = 0; + queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); /* * set a reasonable default alignment on word boundaries: the @@ -2427,8 +2428,7 @@ scsi_internal_device_unblock(struct scsi_device *sdev) sdev->sdev_state = SDEV_RUNNING; else if (sdev->sdev_state == SDEV_CREATED_BLOCK) sdev->sdev_state = SDEV_CREATED; - else if (sdev->sdev_state != SDEV_CANCEL && - sdev->sdev_state != SDEV_OFFLINE) + else return -EINVAL; spin_lock_irqsave(q->queue_lock, flags); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 7a0ca6fdbd79..c3f67373a4f8 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -962,11 +962,10 @@ static void __scsi_remove_target(struct scsi_target *starget) list_for_each_entry(sdev, &shost->__devices, siblings) { if (sdev->channel != starget->channel || sdev->id != starget->id || - scsi_device_get(sdev)) + sdev->sdev_state == SDEV_DEL) continue; spin_unlock_irqrestore(shost->host_lock, flags); scsi_remove_device(sdev); - scsi_device_put(sdev); spin_lock_irqsave(shost->host_lock, flags); goto restart; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0eb0af56db97..ffa0689ee840 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2252,10 +2252,11 @@ static void sd_probe_async(void *data, async_cookie_t cookie) index = sdkp->index; dev = &sdp->sdev_gendev; - gd->major = sd_major((index & 0xf0) >> 4); - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); - gd->minors = SD_MINORS; - + if (index < SD_MAX_DISKS) { + gd->major = sd_major((index & 0xf0) >> 4); + gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); + gd->minors = SD_MINORS; + } gd->fops = &sd_fops; gd->private_data = &sdkp->driver; gd->queue = sdkp->device->request_queue; @@ -2345,12 +2346,6 @@ static int sd_probe(struct device *dev) if (error) goto out_put; - if (index >= SD_MAX_DISKS) { - error = -ENODEV; - sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n"); - goto out_free_index; - } - error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); if (error) goto out_free_index; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 3053d8d8cd89..12900f7083b0 100755 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -542,14 +542,6 @@ config SERIAL_S5PV210 help Serial port support for Samsung's S5P Family of SoC's -config SERIAL_TEGRA - boolean "High speed serial support for NVIDIA Tegra SoCs" - depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA - select SERIAL_CORE - help - Support for the on-chip UARTs on NVIDIA Tegra SoC, providing - /dev/ttyHSx, where x is determined by the number of UARTs on the - platform config SERIAL_MAX3100 tristate "MAX3100 support" diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index f0faee6ec05a..1ca4fd599ffe 100755 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o -obj-$(CONFIG_SERIAL_TEGRA) += tegra_hsuart.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c index f083f7c90c29..5dff45c76d32 100644 --- a/drivers/serial/mfd.c +++ b/drivers/serial/mfd.c @@ -892,7 +892,8 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; - u32 ps, mul; + u32 mul = 0x3600; + u32 ps = 0x10; switch (termios->c_cflag & CSIZE) { case CS5: @@ -936,19 +937,20 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, ps = 0xC; quot = 1; break; + case 2500000: + mul = 0x2710; + ps = 0x10; + quot = 1; + break; case 18432000: mul = 0x2400; ps = 0x10; quot = 1; break; - case 3000000: - case 2500000: - case 2000000: case 1500000: - case 1000000: - case 500000: - /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */ - mul = baud / 500000 * 0x9C4; + mul = 0x1D4C; + ps = 0xc; + quot = 1; break; default: ; diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 076cfd1546d4..cd8511298bcb 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -94,9 +94,6 @@ static void __uart_start(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; - if (port->ops->wake_peer) - port->ops->wake_peer(port); - if (!uart_circ_empty(&state->xmit) && state->xmit.buf && !tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); diff --git a/drivers/serial/tegra_hsuart.c b/drivers/serial/tegra_hsuart.c deleted file mode 100644 index 61d38bfcaa59..000000000000 --- a/drivers/serial/tegra_hsuart.c +++ /dev/null @@ -1,1393 +0,0 @@ -/* - * drivers/serial/tegra_hsuart.c - * - * High-speed serial driver for NVIDIA Tegra SoCs - * - * Copyright (C) 2009 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/*#define DEBUG 1*/ -/*#define VERBOSE_DEBUG 1*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) - -#define BYTES_TO_ALIGN(x) ((unsigned long)(ALIGN((x), sizeof(u32))) - \ - (unsigned long)(x)) - -#define UART_RX_DMA_BUFFER_SIZE (2048*4) - -#define UART_LSR_FIFOE 0x80 -#define UART_IER_EORD 0x20 -#define UART_MCR_RTS_EN 0x40 -#define UART_MCR_CTS_EN 0x20 -#define UART_LSR_ANY (UART_LSR_OE | UART_LSR_BI | \ - UART_LSR_PE | UART_LSR_FE) - -#define TX_FORCE_PIO 0 -#define RX_FORCE_PIO 0 - -const int dma_req_sel[] = { - TEGRA_DMA_REQ_SEL_UARTA, - TEGRA_DMA_REQ_SEL_UARTB, - TEGRA_DMA_REQ_SEL_UARTC, - TEGRA_DMA_REQ_SEL_UARTD, - TEGRA_DMA_REQ_SEL_UARTE, -}; - -#define TEGRA_TX_PIO 1 -#define TEGRA_TX_DMA 2 - -#define TEGRA_UART_MIN_DMA 16 -#define TEGRA_UART_FIFO_SIZE 8 - -/* Tx fifo trigger level setting in tegra uart is in - * reverse way then conventional uart */ -#define TEGRA_UART_TX_TRIG_16B 0x00 -#define TEGRA_UART_TX_TRIG_8B 0x10 -#define TEGRA_UART_TX_TRIG_4B 0x20 -#define TEGRA_UART_TX_TRIG_1B 0x30 - -struct tegra_uart_port { - struct uart_port uport; - char port_name[32]; - - /* Module info */ - unsigned long size; - struct clk *clk; - unsigned int baud; - - /* Register shadow */ - unsigned char fcr_shadow; - unsigned char mcr_shadow; - unsigned char lcr_shadow; - unsigned char ier_shadow; - bool use_cts_control; - bool rts_active; - - int tx_in_progress; - unsigned int tx_bytes; - - dma_addr_t xmit_dma_addr; - - /* TX DMA */ - struct tegra_dma_req tx_dma_req; - struct tegra_dma_channel *tx_dma; - struct work_struct tx_work; - - /* RX DMA */ - struct tegra_dma_req rx_dma_req; - struct tegra_dma_channel *rx_dma; - - bool use_rx_dma; - bool use_tx_dma; - - bool rx_timeout; - int rx_in_progress; - - /* optional callback to exit low power mode */ - void (*exit_lpm_cb)(struct uart_port *); - /* optional callback to indicate rx is done */ - void (*rx_done_cb)(struct uart_port *); - -}; - -static inline u8 uart_readb(struct tegra_uart_port *t, unsigned long reg) -{ - u8 val = readb(t->uport.membase + (reg << t->uport.regshift)); - dev_vdbg(t->uport.dev, "%s: %p %03lx = %02x\n", __func__, - t->uport.membase, reg << t->uport.regshift, val); - return val; -} - -static inline void uart_writeb(struct tegra_uart_port *t, u8 val, - unsigned long reg) -{ - dev_vdbg(t->uport.dev, "%s: %p %03lx %02x\n", - __func__, t->uport.membase, reg << t->uport.regshift, val); - writeb(val, t->uport.membase + (reg << t->uport.regshift)); -} - -static inline void uart_writel(struct tegra_uart_port *t, u32 val, - unsigned long reg) -{ - dev_vdbg(t->uport.dev, "%s: %p %03lx %08x\n", - __func__, t->uport.membase, reg << t->uport.regshift, val); - writel(val, t->uport.membase + (reg << t->uport.regshift)); -} - -static void tegra_set_baudrate(struct tegra_uart_port *t, unsigned int baud); -static void tegra_set_mctrl(struct uart_port *u, unsigned int mctrl); -static void do_handle_rx_pio(struct tegra_uart_port *t); -static void do_handle_rx_dma(struct tegra_uart_port *t); -static void set_rts(struct tegra_uart_port *t, bool active); -static void set_dtr(struct tegra_uart_port *t, bool active); - -static void fill_tx_fifo(struct tegra_uart_port *t, int max_bytes) -{ - int i; - struct circ_buf *xmit = &t->uport.state->xmit; - - for (i = 0; i < max_bytes; i++) { - BUG_ON(uart_circ_empty(xmit)); - uart_writeb(t, xmit->buf[xmit->tail], UART_TX); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - t->uport.icount.tx++; - } -} - -static void tegra_start_pio_tx(struct tegra_uart_port *t, unsigned int bytes) -{ - if (bytes > TEGRA_UART_FIFO_SIZE) - bytes = TEGRA_UART_FIFO_SIZE; - - t->fcr_shadow &= ~UART_FCR_T_TRIG_11; - t->fcr_shadow |= TEGRA_UART_TX_TRIG_8B; - uart_writeb(t, t->fcr_shadow, UART_FCR); - t->tx_in_progress = TEGRA_TX_PIO; - t->tx_bytes = bytes; - t->ier_shadow |= UART_IER_THRI; - uart_writeb(t, t->ier_shadow, UART_IER); -} - -static void tegra_start_dma_tx(struct tegra_uart_port *t, unsigned long bytes) -{ - struct circ_buf *xmit; - xmit = &t->uport.state->xmit; - - dma_sync_single_for_device(t->uport.dev, t->xmit_dma_addr, - UART_XMIT_SIZE, DMA_TO_DEVICE); - - t->fcr_shadow &= ~UART_FCR_T_TRIG_11; - t->fcr_shadow |= TEGRA_UART_TX_TRIG_4B; - uart_writeb(t, t->fcr_shadow, UART_FCR); - - t->tx_bytes = bytes & ~(sizeof(u32)-1); - t->tx_dma_req.source_addr = t->xmit_dma_addr + xmit->tail; - t->tx_dma_req.size = t->tx_bytes; - - t->tx_in_progress = TEGRA_TX_DMA; - - tegra_dma_enqueue_req(t->tx_dma, &t->tx_dma_req); -} - -/* Called with u->lock taken */ -static void tegra_start_next_tx(struct tegra_uart_port *t) -{ - unsigned long tail; - unsigned long count; - - struct circ_buf *xmit; - - xmit = &t->uport.state->xmit; - tail = (unsigned long)&xmit->buf[xmit->tail]; - count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); - - - dev_vdbg(t->uport.dev, "+%s %lu %d\n", __func__, count, - t->tx_in_progress); - - if (count == 0) - goto out; - - if (!t->use_tx_dma || count < TEGRA_UART_MIN_DMA) - tegra_start_pio_tx(t, count); - else if (BYTES_TO_ALIGN(tail) > 0) - tegra_start_pio_tx(t, BYTES_TO_ALIGN(tail)); - else - tegra_start_dma_tx(t, count); - -out: - dev_vdbg(t->uport.dev, "-%s", __func__); -} - -/* Called by serial core driver with u->lock taken. */ -static void tegra_start_tx(struct uart_port *u) -{ - struct tegra_uart_port *t; - struct circ_buf *xmit; - - t = container_of(u, struct tegra_uart_port, uport); - xmit = &u->state->xmit; - - if (t->exit_lpm_cb) - t->exit_lpm_cb(u); - - if (!uart_circ_empty(xmit) && !t->tx_in_progress) - tegra_start_next_tx(t); -} - -static int tegra_start_dma_rx(struct tegra_uart_port *t) -{ - wmb(); - if (tegra_dma_enqueue_req(t->rx_dma, &t->rx_dma_req)) { - dev_err(t->uport.dev, "Could not enqueue Rx DMA req\n"); - return -EINVAL; - } - return 0; -} - -static void tegra_rx_dma_threshold_callback(struct tegra_dma_req *req) -{ - struct tegra_uart_port *t = req->dev; - unsigned long flags; - - spin_lock_irqsave(&t->uport.lock, flags); - - do_handle_rx_dma(t); - - spin_unlock_irqrestore(&t->uport.lock, flags); -} - -/* must be called with uart lock held */ -static void tegra_rx_dma_complete_req(struct tegra_uart_port *t, - struct tegra_dma_req *req) -{ - struct uart_port *u = &t->uport; - struct tty_struct *tty = u->state->port.tty; - - /* If we are here, DMA is stopped */ - - dev_dbg(t->uport.dev, "%s: %d %d\n", __func__, req->bytes_transferred, - req->status); - if (req->bytes_transferred) { - t->uport.icount.rx += req->bytes_transferred; - tty_insert_flip_string(tty, - ((unsigned char *)(req->virt_addr)), - req->bytes_transferred); - } - - do_handle_rx_pio(t); - - /* Push the read data later in caller place. */ - if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED) - return; - - tty_flip_buffer_push(u->state->port.tty); - - if (t->rx_done_cb) - t->rx_done_cb(u); -} - -static void tegra_rx_dma_complete_callback(struct tegra_dma_req *req) -{ - struct tegra_uart_port *t = req->dev; - unsigned long flags; - - /* - * should never get called, dma should be dequeued during threshold - * callback - */ - - dev_warn(t->uport.dev, "possible rx overflow\n"); - - spin_lock_irqsave(&t->uport.lock, flags); - tegra_rx_dma_complete_req(t, req); - spin_unlock_irqrestore(&t->uport.lock, flags); -} - -/* Lock already taken */ -static void do_handle_rx_dma(struct tegra_uart_port *t) -{ - struct uart_port *u = &t->uport; - if (t->rts_active) - set_rts(t, false); - if (!tegra_dma_dequeue_req(t->rx_dma, &t->rx_dma_req)) - tegra_rx_dma_complete_req(t, &t->rx_dma_req); - - tty_flip_buffer_push(u->state->port.tty); - if (t->rx_done_cb) - t->rx_done_cb(u); - /* enqueue the request again */ - tegra_start_dma_rx(t); - if (t->rts_active) - set_rts(t, true); -} - -/* Wait for a symbol-time. */ -static void wait_sym_time(struct tegra_uart_port *t, unsigned int syms) -{ - - /* Definitely have a start bit. */ - unsigned int bits = 1; - switch (t->lcr_shadow & 3) { - case UART_LCR_WLEN5: - bits += 5; - break; - case UART_LCR_WLEN6: - bits += 6; - break; - case UART_LCR_WLEN7: - bits += 7; - break; - default: - bits += 8; - break; - } - - /* Technically 5 bits gets 1.5 bits of stop... */ - if (t->lcr_shadow & UART_LCR_STOP) { - bits += 2; - } else { - bits++; - } - - if (t->lcr_shadow & UART_LCR_PARITY) - bits++; - - if (likely(t->baud)) - udelay(DIV_ROUND_UP(syms * bits * 1000000, t->baud)); -} - -/* Flush desired FIFO. */ -static void tegra_fifo_reset(struct tegra_uart_port *t, u8 fcr_bits) -{ - unsigned char fcr = t->fcr_shadow; - fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - uart_writeb(t, fcr, UART_FCR); - uart_readb(t, UART_SCR); /* Dummy read to ensure the write is posted */ - wait_sym_time(t, 1); /* Wait for the flush to propagate. */ -} - -static char do_decode_rx_error(struct tegra_uart_port *t, u8 lsr) -{ - char flag = TTY_NORMAL; - - if (unlikely(lsr & UART_LSR_ANY)) { - if (lsr & UART_LSR_OE) { - /* Overrrun error */ - flag |= TTY_OVERRUN; - t->uport.icount.overrun++; - dev_err(t->uport.dev, "Got overrun errors\n"); - } else if (lsr & UART_LSR_PE) { - /* Parity error */ - flag |= TTY_PARITY; - t->uport.icount.parity++; - dev_err(t->uport.dev, "Got Parity errors\n"); - } else if (lsr & UART_LSR_FE) { - flag |= TTY_FRAME; - t->uport.icount.frame++; - dev_err(t->uport.dev, "Got frame errors\n"); - } else if (lsr & UART_LSR_BI) { - dev_err(t->uport.dev, "Got Break\n"); - t->uport.icount.brk++; - /* If FIFO read error without any data, reset Rx FIFO */ - if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE)) - tegra_fifo_reset(t, UART_FCR_CLEAR_RCVR); - } - } - return flag; -} - -static void do_handle_rx_pio(struct tegra_uart_port *t) -{ - int count = 0; - do { - char flag = TTY_NORMAL; - unsigned char lsr = 0; - unsigned char ch; - - - lsr = uart_readb(t, UART_LSR); - if (!(lsr & UART_LSR_DR)) - break; - - flag = do_decode_rx_error(t, lsr); - ch = uart_readb(t, UART_RX); - t->uport.icount.rx++; - count++; - - if (!uart_handle_sysrq_char(&t->uport, c)) - uart_insert_char(&t->uport, lsr, UART_LSR_OE, ch, flag); - } while (1); - - dev_dbg(t->uport.dev, "PIO received %d bytes\n", count); - - return; -} - -static void do_handle_modem_signal(struct uart_port *u) -{ - unsigned char msr; - struct tegra_uart_port *t; - - t = container_of(u, struct tegra_uart_port, uport); - msr = uart_readb(t, UART_MSR); - if (msr & UART_MSR_CTS) - dev_dbg(u->dev, "CTS triggered\n"); - if (msr & UART_MSR_DSR) - dev_dbg(u->dev, "DSR enabled\n"); - if (msr & UART_MSR_DCD) - dev_dbg(u->dev, "CD enabled\n"); - if (msr & UART_MSR_RI) - dev_dbg(u->dev, "RI enabled\n"); - return; -} - -static void do_handle_tx_pio(struct tegra_uart_port *t) -{ - struct circ_buf *xmit = &t->uport.state->xmit; - - fill_tx_fifo(t, t->tx_bytes); - - t->tx_in_progress = 0; - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&t->uport); - - tegra_start_next_tx(t); - return; -} - -static void tegra_tx_dma_complete_work(struct work_struct *work) -{ - struct tegra_uart_port *t = - container_of(work, struct tegra_uart_port, tx_work); - struct tegra_dma_req *req = &t->tx_dma_req; - unsigned long flags; - int timeout = 20; - - while ((uart_readb(t, UART_LSR) & TX_EMPTY_STATUS) != TX_EMPTY_STATUS) { - timeout--; - if (timeout == 0) { - dev_err(t->uport.dev, - "timed out waiting for TX FIFO to empty\n"); - return; - } - msleep(1); - } - - spin_lock_irqsave(&t->uport.lock, flags); - - t->tx_in_progress = 0; - - if (req->status != -TEGRA_DMA_REQ_ERROR_ABORTED) - tegra_start_next_tx(t); - - spin_unlock_irqrestore(&t->uport.lock, flags); -} - -/* must be called with uart lock held */ -static void tegra_tx_dma_complete_req(struct tegra_uart_port *t, - struct tegra_dma_req *req) -{ - struct circ_buf *xmit = &t->uport.state->xmit; - int count = req->bytes_transferred; - - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&t->uport); - - schedule_work(&t->tx_work); -} - -static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) -{ - struct tegra_uart_port *t = req->dev; - unsigned long flags; - - dev_vdbg(t->uport.dev, "%s: %d\n", __func__, req->bytes_transferred); - - spin_lock_irqsave(&t->uport.lock, flags); - - tegra_tx_dma_complete_req(t, req); - - spin_unlock_irqrestore(&t->uport.lock, flags); -} - -static irqreturn_t tegra_uart_isr(int irq, void *data) -{ - struct tegra_uart_port *t = data; - struct uart_port *u = &t->uport; - unsigned char iir; - unsigned char ier; - bool is_rx_int = false; - unsigned long flags; - - spin_lock_irqsave(&u->lock, flags); - t = container_of(u, struct tegra_uart_port, uport); - while (1) { - iir = uart_readb(t, UART_IIR); - if (iir & UART_IIR_NO_INT) { - if (likely(t->use_rx_dma) && is_rx_int) { - do_handle_rx_dma(t); - - if (t->rx_in_progress) { - ier = t->ier_shadow; - ier |= (UART_IER_RLSI | UART_IER_RTOIE | UART_IER_EORD); - t->ier_shadow = ier; - uart_writeb(t, ier, UART_IER); - } - } - spin_unlock_irqrestore(&u->lock, flags); - return IRQ_HANDLED; - } - - dev_dbg(u->dev, "tegra_uart_isr iir = 0x%x (%d)\n", iir, - (iir >> 1) & 0x7); - switch ((iir >> 1) & 0x7) { - case 0: /* Modem signal change interrupt */ - do_handle_modem_signal(u); - break; - case 1: /* Transmit interrupt only triggered when using PIO */ - t->ier_shadow &= ~UART_IER_THRI; - uart_writeb(t, t->ier_shadow, UART_IER); - do_handle_tx_pio(t); - break; - case 4: /* End of data */ - case 6: /* Rx timeout */ - case 2: /* Receive */ - if (likely(t->use_rx_dma)) { - if (!is_rx_int) { - is_rx_int = true; - /* Disable interrups */ - ier = t->ier_shadow; - ier |= UART_IER_RDI; - uart_writeb(t, ier, UART_IER); - ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | UART_IER_EORD); - t->ier_shadow = ier; - uart_writeb(t, ier, UART_IER); - } - } else { - do_handle_rx_pio(t); - - spin_unlock_irqrestore(&u->lock, flags); - tty_flip_buffer_push(u->state->port.tty); - spin_lock_irqsave(&u->lock, flags); - if (t->rx_done_cb) - t->rx_done_cb(u); - } - break; - case 3: /* Receive error */ - /* FIXME how to handle this? Why do we get here */ - do_decode_rx_error(t, uart_readb(t, UART_LSR)); - break; - case 5: /* break nothing to handle */ - case 7: /* break nothing to handle */ - break; - } - } -} - -static void tegra_stop_rx(struct uart_port *u) -{ - struct tegra_uart_port *t; - unsigned char ier; - - t = container_of(u, struct tegra_uart_port, uport); - - if (t->rts_active) - set_rts(t, false); - - if (t->rx_in_progress) { - wait_sym_time(t, 1); /* wait a character interval */ - - ier = t->ier_shadow; - ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | UART_IER_EORD); - t->ier_shadow = ier; - uart_writeb(t, ier, UART_IER); - t->rx_in_progress = 0; - - if (t->use_rx_dma && t->rx_dma) { - if (!tegra_dma_dequeue_req(t->rx_dma, &t->rx_dma_req)) - tegra_rx_dma_complete_req(t, &t->rx_dma_req); - } else { - do_handle_rx_pio(t); - } - tty_flip_buffer_push(u->state->port.tty); - if (t->rx_done_cb) - t->rx_done_cb(u); - } - - return; -} - -static void tegra_uart_hw_deinit(struct tegra_uart_port *t) -{ - unsigned long flags; - - flush_work(&t->tx_work); - - /* Disable interrupts */ - uart_writeb(t, 0, UART_IER); - - while ((uart_readb(t, UART_LSR) & UART_LSR_TEMT) != UART_LSR_TEMT); - udelay(200); - - spin_lock_irqsave(&t->uport.lock, flags); - - /* Reset the Rx and Tx FIFOs */ - tegra_fifo_reset(t, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); - - clk_disable(t->clk); - t->baud = 0; - - spin_unlock_irqrestore(&t->uport.lock, flags); -} - -static void tegra_uart_free_rx_dma(struct tegra_uart_port *t) -{ - if (!t->use_rx_dma) - return; - - tegra_dma_free_channel(t->rx_dma); - t->rx_dma = NULL; - - if (likely(t->rx_dma_req.dest_addr)) - dma_free_coherent(t->uport.dev, t->rx_dma_req.size, - t->rx_dma_req.virt_addr, t->rx_dma_req.dest_addr); - t->rx_dma_req.dest_addr = 0; - t->rx_dma_req.virt_addr = NULL; - - t->use_rx_dma = false; -} - -static int tegra_uart_hw_init(struct tegra_uart_port *t) -{ - unsigned char ier; - - dev_vdbg(t->uport.dev, "+tegra_uart_hw_init\n"); - - t->fcr_shadow = 0; - t->mcr_shadow = 0; - t->lcr_shadow = 0; - t->ier_shadow = 0; - t->baud = 0; - - clk_enable(t->clk); - - /* Reset the UART controller to clear all previous status.*/ - tegra_periph_reset_assert(t->clk); - udelay(100); - tegra_periph_reset_deassert(t->clk); - udelay(100); - - t->rx_in_progress = 0; - - /* Set the trigger level - * - * For PIO mode: - * - * For receive, this will interrupt the CPU after that many number of - * bytes are received, for the remaining bytes the receive timeout - * interrupt is received. - * - * Rx high watermark is set to 4. - * - * For transmit, if the trasnmit interrupt is enabled, this will - * interrupt the CPU when the number of entries in the FIFO reaches the - * low watermark. - * - * Tx low watermark is set to 8. - * - * For DMA mode: - * - * Set the Tx trigger to 4. This should match the DMA burst size that - * programmed in the DMA registers. - * */ - t->fcr_shadow = UART_FCR_ENABLE_FIFO; - t->fcr_shadow |= UART_FCR_R_TRIG_01; - t->fcr_shadow |= TEGRA_UART_TX_TRIG_8B; - uart_writeb(t, t->fcr_shadow, UART_FCR); - - if (t->use_rx_dma) { - /* initialize the UART for a simple default configuration - * so that the receive DMA buffer may be enqueued */ - t->lcr_shadow = 3; /* no parity, stop, 8 data bits */ - tegra_set_baudrate(t, 115200); - t->fcr_shadow |= UART_FCR_DMA_SELECT; - uart_writeb(t, t->fcr_shadow, UART_FCR); - if (tegra_start_dma_rx(t)) { - dev_err(t->uport.dev, "Rx DMA enqueue failed\n"); - tegra_uart_free_rx_dma(t); - t->fcr_shadow &= ~UART_FCR_DMA_SELECT; - uart_writeb(t, t->fcr_shadow, UART_FCR); - } - } - else - uart_writeb(t, t->fcr_shadow, UART_FCR); - - t->rx_in_progress = 1; - - /* - * Enable IE_RXS for the receive status interrupts like line errros. - * Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd. - * - * If using DMA mode, enable EORD instead of receive interrupt which - * will interrupt after the UART is done with the receive instead of - * the interrupt when the FIFO "threshold" is reached. - * - * EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when - * the DATA is sitting in the FIFO and couldn't be transferred to the - * DMA as the DMA size alignment(4 bytes) is not met. EORD will be - * triggered when there is a pause of the incomming data stream for 4 - * characters long. - * - * For pauses in the data which is not aligned to 4 bytes, we get - * both the EORD as well as RX_TIMEOUT - SW sees RX_TIMEOUT first - * then the EORD. - * - * Don't get confused, believe in the magic of nvidia hw...:-) - */ - ier = 0; - ier |= UART_IER_RLSI | UART_IER_RTOIE; - if (t->use_rx_dma) - ier |= UART_IER_EORD; - else - ier |= UART_IER_RDI; - t->ier_shadow = ier; - uart_writeb(t, ier, UART_IER); - - dev_vdbg(t->uport.dev, "-tegra_uart_hw_init\n"); - return 0; -} - -static int tegra_uart_init_rx_dma(struct tegra_uart_port *t) -{ - dma_addr_t rx_dma_phys; - void *rx_dma_virt; - - t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS); - if (!t->rx_dma) { - dev_err(t->uport.dev, "%s: failed to allocate RX DMA.\n", __func__); - return -ENODEV; - } - - t->rx_dma_req.size = UART_RX_DMA_BUFFER_SIZE; - rx_dma_virt = dma_alloc_coherent(t->uport.dev, - t->rx_dma_req.size, &rx_dma_phys, GFP_KERNEL); - if (!rx_dma_virt) { - dev_err(t->uport.dev, "DMA buffers allocate failed\n"); - goto fail; - } - t->rx_dma_req.dest_addr = rx_dma_phys; - t->rx_dma_req.virt_addr = rx_dma_virt; - - t->rx_dma_req.source_addr = (unsigned long)t->uport.mapbase; - t->rx_dma_req.source_wrap = 4; - t->rx_dma_req.dest_wrap = 0; - t->rx_dma_req.to_memory = 1; - t->rx_dma_req.source_bus_width = 8; - t->rx_dma_req.dest_bus_width = 32; - t->rx_dma_req.req_sel = dma_req_sel[t->uport.line]; - t->rx_dma_req.complete = tegra_rx_dma_complete_callback; - t->rx_dma_req.threshold = tegra_rx_dma_threshold_callback; - t->rx_dma_req.dev = t; - - return 0; -fail: - tegra_uart_free_rx_dma(t); - return -ENODEV; -} - -static int tegra_startup(struct uart_port *u) -{ - struct tegra_uart_port *t = container_of(u, - struct tegra_uart_port, uport); - int ret = 0; - - t = container_of(u, struct tegra_uart_port, uport); - sprintf(t->port_name, "tegra_uart_%d", u->line); - - t->use_tx_dma = false; - if (!TX_FORCE_PIO) { - t->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); - if (t->tx_dma) - t->use_tx_dma = true; - else - pr_err("%s: failed to allocate TX DMA.\n", __func__); - } - if (t->use_tx_dma) { - t->tx_dma_req.instance = u->line; - t->tx_dma_req.complete = tegra_tx_dma_complete_callback; - t->tx_dma_req.to_memory = 0; - - t->tx_dma_req.dest_addr = (unsigned long)t->uport.mapbase; - t->tx_dma_req.dest_wrap = 4; - t->tx_dma_req.source_wrap = 0; - t->tx_dma_req.source_bus_width = 32; - t->tx_dma_req.dest_bus_width = 8; - t->tx_dma_req.req_sel = dma_req_sel[t->uport.line]; - t->tx_dma_req.dev = t; - t->tx_dma_req.size = 0; - t->xmit_dma_addr = dma_map_single(t->uport.dev, - t->uport.state->xmit.buf, UART_XMIT_SIZE, - DMA_TO_DEVICE); - } - t->tx_in_progress = 0; - - t->use_rx_dma = false; - if (!RX_FORCE_PIO) { - if (!tegra_uart_init_rx_dma(t)) - t->use_rx_dma = true; - } - - ret = tegra_uart_hw_init(t); - if (ret) - goto fail; - - dev_dbg(u->dev, "Requesting IRQ %d\n", u->irq); - msleep(1); - - ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED, - t->port_name, t); - if (ret) { - dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq); - goto fail; - } - dev_dbg(u->dev,"Started UART port %d\n", u->line); - - return 0; -fail: - dev_err(u->dev, "Tegra UART startup failed\n"); - return ret; -} - -static void tegra_shutdown(struct uart_port *u) -{ - struct tegra_uart_port *t; - - t = container_of(u, struct tegra_uart_port, uport); - dev_vdbg(u->dev, "+tegra_shutdown\n"); - - tegra_uart_hw_deinit(t); - - t->rx_in_progress = 0; - t->tx_in_progress = 0; - - tegra_uart_free_rx_dma(t); - if (t->use_tx_dma) { - tegra_dma_free_channel(t->tx_dma); - t->tx_dma = NULL; - t->use_tx_dma = false; - dma_unmap_single(t->uport.dev, t->xmit_dma_addr, UART_XMIT_SIZE, - DMA_TO_DEVICE); - t->xmit_dma_addr = 0; - } - - free_irq(u->irq, t); - dev_vdbg(u->dev, "-tegra_shutdown\n"); -} - -static unsigned int tegra_get_mctrl(struct uart_port *u) -{ - /* RI - Ring detector is active - * CD/DCD/CAR - Carrier detect is always active. For some reason - * linux has different names for carrier detect. - * DSR - Data Set ready is active as the hardware doesn't support it. - * Don't know if the linux support this yet? - * CTS - Clear to send. Always set to active, as the hardware handles - * CTS automatically. - * */ - return TIOCM_RI | TIOCM_CD | TIOCM_DSR | TIOCM_CTS; -} - -static void set_rts(struct tegra_uart_port *t, bool active) -{ - unsigned char mcr; - mcr = t->mcr_shadow; - if (active) - mcr |= UART_MCR_RTS; - else - mcr &= ~UART_MCR_RTS; - if (mcr != t->mcr_shadow) { - uart_writeb(t, mcr, UART_MCR); - t->mcr_shadow = mcr; - } - return; -} - -static void set_dtr(struct tegra_uart_port *t, bool active) -{ - unsigned char mcr; - mcr = t->mcr_shadow; - if (active) - mcr |= UART_MCR_DTR; - else - mcr &= ~UART_MCR_DTR; - if (mcr != t->mcr_shadow) { - uart_writeb(t, mcr, UART_MCR); - t->mcr_shadow = mcr; - } - return; -} - -static void tegra_set_mctrl(struct uart_port *u, unsigned int mctrl) -{ - unsigned char mcr; - struct tegra_uart_port *t; - - dev_dbg(u->dev, "tegra_set_mctrl called with %d\n", mctrl); - t = container_of(u, struct tegra_uart_port, uport); - - mcr = t->mcr_shadow; - if (mctrl & TIOCM_RTS) { - t->rts_active = true; - set_rts(t, true); - } else { - t->rts_active = false; - set_rts(t, false); - } - - if (mctrl & TIOCM_DTR) - set_dtr(t, true); - else - set_dtr(t, false); - return; -} - -static void tegra_break_ctl(struct uart_port *u, int break_ctl) -{ - struct tegra_uart_port *t; - unsigned char lcr; - - t = container_of(u, struct tegra_uart_port, uport); - lcr = t->lcr_shadow; - if (break_ctl) - lcr |= UART_LCR_SBC; - else - lcr &= ~UART_LCR_SBC; - uart_writeb(t, lcr, UART_LCR); - t->lcr_shadow = lcr; -} - -static int tegra_request_port(struct uart_port *u) -{ - return 0; -} - -static void tegra_release_port(struct uart_port *u) -{ - -} - -static unsigned int tegra_tx_empty(struct uart_port *u) -{ - struct tegra_uart_port *t; - unsigned int ret = 0; - unsigned long flags; - - t = container_of(u, struct tegra_uart_port, uport); - dev_vdbg(u->dev, "+tegra_tx_empty\n"); - - spin_lock_irqsave(&u->lock, flags); - if (!t->tx_in_progress) - ret = TIOCSER_TEMT; - spin_unlock_irqrestore(&u->lock, flags); - - dev_vdbg(u->dev, "-tegra_tx_empty\n"); - return ret; -} - -static void tegra_stop_tx(struct uart_port *u) -{ - struct tegra_uart_port *t; - - t = container_of(u, struct tegra_uart_port, uport); - - if (t->use_tx_dma) { - if (!tegra_dma_dequeue_req(t->tx_dma, &t->tx_dma_req)) - tegra_tx_dma_complete_req(t, &t->tx_dma_req); - } - - return; -} - -static void tegra_enable_ms(struct uart_port *u) -{ -} - -#define UART_CLOCK_ACCURACY 5 - -static void tegra_set_baudrate(struct tegra_uart_port *t, unsigned int baud) -{ - unsigned long rate; - unsigned int divisor; - unsigned char lcr; - - if (t->baud == baud) - return; - - rate = clk_get_rate(t->clk); - - divisor = rate; - do_div(divisor, 16); - divisor += baud/2; - do_div(divisor, baud); - - lcr = t->lcr_shadow; - lcr |= UART_LCR_DLAB; - uart_writeb(t, lcr, UART_LCR); - - uart_writel(t, divisor & 0xFF, UART_TX); - uart_writel(t, ((divisor >> 8) & 0xFF), UART_IER); - - lcr &= ~UART_LCR_DLAB; - uart_writeb(t, lcr, UART_LCR); - uart_readb(t, UART_SCR); /* Dummy read to ensure the write is posted */ - - t->baud = baud; - wait_sym_time(t, 2); /* wait two character intervals at new rate */ - dev_dbg(t->uport.dev, "Baud %u clock freq %lu and divisor of %u\n", - baud, rate, divisor); -} - -static void tegra_set_termios(struct uart_port *u, struct ktermios *termios, - struct ktermios *oldtermios) -{ - struct tegra_uart_port *t; - unsigned int baud; - unsigned long flags; - unsigned int lcr; - unsigned int c_cflag = termios->c_cflag; - unsigned char mcr; - - t = container_of(u, struct tegra_uart_port, uport); - dev_vdbg(t->uport.dev, "+tegra_set_termios\n"); - - spin_lock_irqsave(&u->lock, flags); - - /* Changing configuration, it is safe to stop any rx now */ - if (t->rts_active) - set_rts(t, false); - - /* Parity */ - lcr = t->lcr_shadow; - lcr &= ~UART_LCR_PARITY; - if (PARENB == (c_cflag & PARENB)) { - if (CMSPAR == (c_cflag & CMSPAR)) { - /* FIXME What is space parity? */ - /* data |= SPACE_PARITY; */ - } else if (c_cflag & PARODD) { - lcr |= UART_LCR_PARITY; - lcr &= ~UART_LCR_EPAR; - lcr &= ~UART_LCR_SPAR; - } else { - lcr |= UART_LCR_PARITY; - lcr |= UART_LCR_EPAR; - lcr &= ~UART_LCR_SPAR; - } - } - - lcr &= ~UART_LCR_WLEN8; - switch (c_cflag & CSIZE) { - case CS5: - lcr |= UART_LCR_WLEN5; - break; - case CS6: - lcr |= UART_LCR_WLEN6; - break; - case CS7: - lcr |= UART_LCR_WLEN7; - break; - default: - lcr |= UART_LCR_WLEN8; - break; - } - - /* Stop bits */ - if (termios->c_cflag & CSTOPB) - lcr |= UART_LCR_STOP; - else - lcr &= ~UART_LCR_STOP; - - uart_writeb(t, lcr, UART_LCR); - t->lcr_shadow = lcr; - - /* Baud rate. */ - baud = uart_get_baud_rate(u, termios, oldtermios, 200, 4000000); - tegra_set_baudrate(t, baud); - - /* Flow control */ - if (termios->c_cflag & CRTSCTS) { - mcr = t->mcr_shadow; - mcr |= UART_MCR_CTS_EN; - mcr &= ~UART_MCR_RTS_EN; - t->mcr_shadow = mcr; - uart_writeb(t, mcr, UART_MCR); - t->use_cts_control = true; - /* if top layer has asked to set rts active then do so here */ - if (t->rts_active) - set_rts(t, true); - } else { - mcr = t->mcr_shadow; - mcr &= ~UART_MCR_CTS_EN; - mcr &= ~UART_MCR_RTS_EN; - t->mcr_shadow = mcr; - uart_writeb(t, mcr, UART_MCR); - t->use_cts_control = false; - } - - /* update the port timeout based on new settings */ - uart_update_timeout(u, termios->c_cflag, baud); - - spin_unlock_irqrestore(&u->lock, flags); - dev_vdbg(t->uport.dev, "-tegra_set_termios\n"); - return; -} - -/* - * Flush any TX data submitted for DMA. Called when the TX circular - * buffer is reset. - */ -static void tegra_flush_buffer(struct uart_port *u) -{ - struct tegra_uart_port *t; - - dev_vdbg(u->dev, "%s called", __func__); - - t = container_of(u, struct tegra_uart_port, uport); - - if (t->use_tx_dma) { - if (!tegra_dma_dequeue_req(t->tx_dma, &t->tx_dma_req)) - tegra_tx_dma_complete_req(t, &t->tx_dma_req); - t->tx_dma_req.size = 0; - } - return; -} - - -static void tegra_pm(struct uart_port *u, unsigned int state, - unsigned int oldstate) -{ - -} - -static const char *tegra_type(struct uart_port *u) -{ - return 0; -} - -static struct uart_ops tegra_uart_ops = { - .tx_empty = tegra_tx_empty, - .set_mctrl = tegra_set_mctrl, - .get_mctrl = tegra_get_mctrl, - .stop_tx = tegra_stop_tx, - .start_tx = tegra_start_tx, - .stop_rx = tegra_stop_rx, - .flush_buffer = tegra_flush_buffer, - .enable_ms = tegra_enable_ms, - .break_ctl = tegra_break_ctl, - .startup = tegra_startup, - .shutdown = tegra_shutdown, - .set_termios = tegra_set_termios, - .pm = tegra_pm, - .type = tegra_type, - .request_port = tegra_request_port, - .release_port = tegra_release_port, -}; - -static int tegra_uart_probe(struct platform_device *pdev); -static int __devexit tegra_uart_remove(struct platform_device *pdev); -static int tegra_uart_suspend(struct platform_device *pdev, pm_message_t state); -static int tegra_uart_resume(struct platform_device *pdev); - -static struct platform_driver tegra_uart_platform_driver = { - .remove = tegra_uart_remove, - .probe = tegra_uart_probe, - .suspend = tegra_uart_suspend, - .resume = tegra_uart_resume, - .driver = { - .name = "tegra_uart" - } -}; - -static struct uart_driver tegra_uart_driver = -{ - .owner = THIS_MODULE, - .driver_name = "tegra_uart", - .dev_name = "ttyHS", - .cons = 0, - .nr = 5, -}; - -static int tegra_uart_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct tegra_uart_port *t = platform_get_drvdata(pdev); - struct uart_port *u; - - if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) - pr_err("Invalid Uart instance (%d)\n", pdev->id); - - u = &t->uport; - uart_suspend_port(&tegra_uart_driver, u); - - flush_work(&t->tx_work); - return 0; -} - -static int tegra_uart_resume(struct platform_device *pdev) -{ - struct tegra_uart_port *t = platform_get_drvdata(pdev); - struct uart_port *u; - - if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) - pr_err("Invalid Uart instance (%d)\n", pdev->id); - - u = &t->uport; - uart_resume_port(&tegra_uart_driver, u); - return 0; -} - - - -static int __devexit tegra_uart_remove(struct platform_device *pdev) -{ - struct tegra_uart_port *t = platform_get_drvdata(pdev); - struct uart_port *u; - - if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) - pr_err("Invalid Uart instance (%d)\n", pdev->id); - - u = &t->uport; - uart_remove_one_port(&tegra_uart_driver, u); - - platform_set_drvdata(pdev, NULL); - - pr_info("Unregistered UART port %s%d\n", - tegra_uart_driver.dev_name, u->line); - kfree(t); - return 0; -} - -static int tegra_uart_probe(struct platform_device *pdev) -{ - struct tegra_uart_port *t; - struct uart_port *u; - struct resource *resource; - struct tegra_hsuart_platform_data *pdata = pdev->dev.platform_data; - int ret; - char name[64]; - if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) { - pr_err("Invalid Uart instance (%d)\n", pdev->id); - return -ENODEV; - } - - t = kzalloc(sizeof(struct tegra_uart_port), GFP_KERNEL); - if (!t) { - pr_err("%s: Failed to allocate memory\n", __func__); - return -ENOMEM; - } - u = &t->uport; - u->dev = &pdev->dev; - platform_set_drvdata(pdev, u); - u->line = pdev->id; - u->ops = &tegra_uart_ops; - u->type = ~PORT_UNKNOWN; - u->fifosize = 32; - - resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!resource)) - return -ENXIO; - - u->mapbase = resource->start; - u->membase = IO_ADDRESS(u->mapbase); - if (unlikely(!u->membase)) - return -ENOMEM; - - u->irq = platform_get_irq(pdev, 0); - if (unlikely(u->irq < 0)) - return -ENXIO; - - u->regshift = 2; - - if (pdata) { - t->exit_lpm_cb = pdata->exit_lpm_cb; - t->rx_done_cb = pdata->rx_done_cb; - } - - t->clk = clk_get(&pdev->dev, NULL); - if (!t->clk) { - dev_err(&pdev->dev, "Couldn't get the clock\n"); - goto fail; - } - - ret = uart_add_one_port(&tegra_uart_driver, u); - if (ret) { - pr_err("%s: Failed(%d) to add uart port %s%d\n", - __func__, ret, tegra_uart_driver.dev_name, u->line); - kfree(t); - platform_set_drvdata(pdev, NULL); - return ret; - } - - snprintf(name, sizeof(name), "tegra_hsuart_%d", u->line); - pr_info("Registered UART port %s%d\n", - tegra_uart_driver.dev_name, u->line); - - INIT_WORK(&t->tx_work, tegra_tx_dma_complete_work); - return ret; -fail: - kfree(t); - return -ENODEV; -} - -static int __init tegra_uart_init(void) -{ - int ret; - - ret = uart_register_driver(&tegra_uart_driver); - if (unlikely(ret)) { - pr_err("Could not register %s driver\n", - tegra_uart_driver.driver_name); - return ret; - } - - ret = platform_driver_register(&tegra_uart_platform_driver); - if (unlikely(ret)) { - pr_err("Could not register the UART platfrom " - "driver\n"); - uart_unregister_driver(&tegra_uart_driver); - return ret; - } - - pr_info("Initialized tegra uart driver\n"); - return 0; -} - -static void __exit tegra_uart_exit(void) -{ - pr_info("Unloading tegra uart driver\n"); - platform_driver_unregister(&tegra_uart_platform_driver); - uart_unregister_driver(&tegra_uart_driver); -} - -module_init(tegra_uart_init); -module_exit(tegra_uart_exit); -MODULE_DESCRIPTION("High speed UART driver for tegra chipset"); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 61b907b84e1a..0942452ef16b 100755 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -298,13 +298,6 @@ config SPI_STMP3XXX help SPI driver for Freescale STMP37xx/378x SoC SSP interface -config SPI_TEGRA - tristate "Nvidia Tegra SPI controller" - depends on ARCH_TEGRA - select TEGRA_SYSTEM_DMA - help - SPI driver for NVidia Tegra SoCs - config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e3e70d8ef44c..39aa49d0e48b 100755 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -40,7 +40,6 @@ obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o -obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o diff --git a/drivers/spi/spi_tegra.c b/drivers/spi/spi_tegra.c deleted file mode 100644 index 842ac14f745d..000000000000 --- a/drivers/spi/spi_tegra.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Driver for Nvidia TEGRA spi controller. - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define SLINK_COMMAND 0x000 -#define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) -#define SLINK_WORD_SIZE(x) (((x) & 0x1f) << 5) -#define SLINK_BOTH_EN (1 << 10) -#define SLINK_CS_SW (1 << 11) -#define SLINK_CS_VALUE (1 << 12) -#define SLINK_CS_POLARITY (1 << 13) -#define SLINK_IDLE_SDA_DRIVE_LOW (0 << 16) -#define SLINK_IDLE_SDA_DRIVE_HIGH (1 << 16) -#define SLINK_IDLE_SDA_PULL_LOW (2 << 16) -#define SLINK_IDLE_SDA_PULL_HIGH (3 << 16) -#define SLINK_IDLE_SDA_MASK (3 << 16) -#define SLINK_CS_POLARITY1 (1 << 20) -#define SLINK_CK_SDA (1 << 21) -#define SLINK_CS_POLARITY2 (1 << 22) -#define SLINK_CS_POLARITY3 (1 << 23) -#define SLINK_IDLE_SCLK_DRIVE_LOW (0 << 24) -#define SLINK_IDLE_SCLK_DRIVE_HIGH (1 << 24) -#define SLINK_IDLE_SCLK_PULL_LOW (2 << 24) -#define SLINK_IDLE_SCLK_PULL_HIGH (3 << 24) -#define SLINK_IDLE_SCLK_MASK (3 << 24) -#define SLINK_M_S (1 << 28) -#define SLINK_WAIT (1 << 29) -#define SLINK_GO (1 << 30) -#define SLINK_ENB (1 << 31) - -#define SLINK_COMMAND2 0x004 -#define SLINK_LSBFE (1 << 0) -#define SLINK_SSOE (1 << 1) -#define SLINK_SPIE (1 << 4) -#define SLINK_BIDIROE (1 << 6) -#define SLINK_MODFEN (1 << 7) -#define SLINK_INT_SIZE(x) (((x) & 0x1f) << 8) -#define SLINK_CS_ACTIVE_BETWEEN (1 << 17) -#define SLINK_SS_EN_CS(x) (((x) & 0x3) << 18) -#define SLINK_SS_SETUP(x) (((x) & 0x3) << 20) -#define SLINK_FIFO_REFILLS_0 (0 << 22) -#define SLINK_FIFO_REFILLS_1 (1 << 22) -#define SLINK_FIFO_REFILLS_2 (2 << 22) -#define SLINK_FIFO_REFILLS_3 (3 << 22) -#define SLINK_FIFO_REFILLS_MASK (3 << 22) -#define SLINK_WAIT_PACK_INT(x) (((x) & 0x7) << 26) -#define SLINK_SPC0 (1 << 29) -#define SLINK_TXEN (1 << 30) -#define SLINK_RXEN (1 << 31) - -#define SLINK_STATUS 0x008 -#define SLINK_COUNT(val) (((val) >> 0) & 0x1f) -#define SLINK_WORD(val) (((val) >> 5) & 0x1f) -#define SLINK_BLK_CNT(val) (((val) >> 0) & 0xffff) -#define SLINK_MODF (1 << 16) -#define SLINK_RX_UNF (1 << 18) -#define SLINK_TX_OVF (1 << 19) -#define SLINK_TX_FULL (1 << 20) -#define SLINK_TX_EMPTY (1 << 21) -#define SLINK_RX_FULL (1 << 22) -#define SLINK_RX_EMPTY (1 << 23) -#define SLINK_TX_UNF (1 << 24) -#define SLINK_RX_OVF (1 << 25) -#define SLINK_TX_FLUSH (1 << 26) -#define SLINK_RX_FLUSH (1 << 27) -#define SLINK_SCLK (1 << 28) -#define SLINK_ERR (1 << 29) -#define SLINK_RDY (1 << 30) -#define SLINK_BSY (1 << 31) - -#define SLINK_MAS_DATA 0x010 -#define SLINK_SLAVE_DATA 0x014 - -#define SLINK_DMA_CTL 0x018 -#define SLINK_DMA_BLOCK_SIZE(x) (((x) & 0xffff) << 0) -#define SLINK_TX_TRIG_1 (0 << 16) -#define SLINK_TX_TRIG_4 (1 << 16) -#define SLINK_TX_TRIG_8 (2 << 16) -#define SLINK_TX_TRIG_16 (3 << 16) -#define SLINK_TX_TRIG_MASK (3 << 16) -#define SLINK_RX_TRIG_1 (0 << 18) -#define SLINK_RX_TRIG_4 (1 << 18) -#define SLINK_RX_TRIG_8 (2 << 18) -#define SLINK_RX_TRIG_16 (3 << 18) -#define SLINK_RX_TRIG_MASK (3 << 18) -#define SLINK_PACKED (1 << 20) -#define SLINK_PACK_SIZE_4 (0 << 21) -#define SLINK_PACK_SIZE_8 (1 << 21) -#define SLINK_PACK_SIZE_16 (2 << 21) -#define SLINK_PACK_SIZE_32 (3 << 21) -#define SLINK_PACK_SIZE_MASK (3 << 21) -#define SLINK_IE_TXC (1 << 26) -#define SLINK_IE_RXC (1 << 27) -#define SLINK_DMA_EN (1 << 31) - -#define SLINK_STATUS2 0x01c -#define SLINK_TX_FIFO_EMPTY_COUNT(val) (((val) & 0x3f) >> 0) -#define SLINK_RX_FIFO_FULL_COUNT(val) (((val) & 0x3f) >> 16) - -#define SLINK_TX_FIFO 0x100 -#define SLINK_RX_FIFO 0x180 - -static const unsigned long spi_tegra_req_sels[] = { - TEGRA_DMA_REQ_SEL_SL2B1, - TEGRA_DMA_REQ_SEL_SL2B2, - TEGRA_DMA_REQ_SEL_SL2B3, - TEGRA_DMA_REQ_SEL_SL2B4, -}; - -#define BB_LEN 32 - -struct spi_tegra_data { - struct spi_master *master; - struct platform_device *pdev; - spinlock_t lock; - - struct clk *clk; - void __iomem *base; - unsigned long phys; - - u32 cur_speed; - - struct list_head queue; - struct spi_transfer *cur; - unsigned cur_pos; - unsigned cur_len; - unsigned cur_bytes_per_word; - - /* The tegra spi controller has a bug which causes the first word - * in PIO transactions to be garbage. Since packed DMA transactions - * require transfers to be 4 byte aligned we need a bounce buffer - * for the generic case. - */ - struct tegra_dma_req rx_dma_req; - struct tegra_dma_channel *rx_dma; - u32 *rx_bb; - dma_addr_t rx_bb_phys; - bool is_suspended; - unsigned long save_slink_cmd; -}; - - -static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, - unsigned long reg) -{ - return readl(tspi->base + reg); -} - -static inline void spi_tegra_writel(struct spi_tegra_data *tspi, - unsigned long val, - unsigned long reg) -{ - writel(val, tspi->base + reg); -} - -static void spi_tegra_go(struct spi_tegra_data *tspi) -{ - unsigned long val; - - wmb(); - - val = spi_tegra_readl(tspi, SLINK_DMA_CTL); - val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; - val |= SLINK_DMA_BLOCK_SIZE(tspi->rx_dma_req.size / 4 - 1); - spi_tegra_writel(tspi, val, SLINK_DMA_CTL); - - tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req); - - val |= SLINK_DMA_EN; - spi_tegra_writel(tspi, val, SLINK_DMA_CTL); -} - -static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi, - struct spi_transfer *t) -{ - unsigned len = min(t->len - tspi->cur_pos, BB_LEN * - tspi->cur_bytes_per_word); - u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_pos; - int i, j; - unsigned long val; - - val = spi_tegra_readl(tspi, SLINK_COMMAND); - val &= ~SLINK_WORD_SIZE(~0); - val |= SLINK_WORD_SIZE(len / tspi->cur_bytes_per_word - 1); - spi_tegra_writel(tspi, val, SLINK_COMMAND); - - for (i = 0; i < len; i += tspi->cur_bytes_per_word) { - val = 0; - for (j = 0; j < tspi->cur_bytes_per_word; j++) - val |= tx_buf[i + j] << j * 8; - - spi_tegra_writel(tspi, val, SLINK_TX_FIFO); - } - - tspi->rx_dma_req.size = len / tspi->cur_bytes_per_word * 4; - - return len; -} - -static unsigned spi_tegra_drain_rx_fifo(struct spi_tegra_data *tspi, - struct spi_transfer *t) -{ - unsigned len = tspi->cur_len; - u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_pos; - int i, j; - unsigned long val; - - for (i = 0; i < len; i += tspi->cur_bytes_per_word) { - val = tspi->rx_bb[i / tspi->cur_bytes_per_word]; - for (j = 0; j < tspi->cur_bytes_per_word; j++) - rx_buf[i + j] = (val >> (j * 8)) & 0xff; - } - - return len; -} - -static void spi_tegra_start_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); - u32 speed; - u8 bits_per_word; - unsigned long val; - - speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; - bits_per_word = t->bits_per_word ? t->bits_per_word : - spi->bits_per_word; - - tspi->cur_bytes_per_word = (bits_per_word - 1) / 8 + 1; - - if (speed != tspi->cur_speed) - clk_set_rate(tspi->clk, speed); - - if (tspi->cur_speed == 0) - clk_enable(tspi->clk); - - tspi->cur_speed = speed; - - val = spi_tegra_readl(tspi, SLINK_COMMAND2); - val &= ~SLINK_SS_EN_CS(~0) | SLINK_RXEN | SLINK_TXEN; - if (t->rx_buf) - val |= SLINK_RXEN; - if (t->tx_buf) - val |= SLINK_TXEN; - val |= SLINK_SS_EN_CS(spi->chip_select); - val |= SLINK_SPIE; - val |= SLINK_SS_SETUP(3); - spi_tegra_writel(tspi, val, SLINK_COMMAND2); - - val = spi_tegra_readl(tspi, SLINK_COMMAND); - val &= ~SLINK_BIT_LENGTH(~0); - val |= SLINK_BIT_LENGTH(bits_per_word - 1); - - /* FIXME: should probably control CS manually so that we can be sure - * it does not go low between transfer and to support delay_usecs - * correctly. - */ - val &= ~SLINK_IDLE_SCLK_MASK & ~SLINK_CK_SDA & ~SLINK_CS_SW; - - if (spi->mode & SPI_CPHA) - val |= SLINK_CK_SDA; - - if (spi->mode & SPI_CPOL) - val |= SLINK_IDLE_SCLK_DRIVE_HIGH; - else - val |= SLINK_IDLE_SCLK_DRIVE_LOW; - - val |= SLINK_M_S; - - spi_tegra_writel(tspi, val, SLINK_COMMAND); - - spi_tegra_writel(tspi, SLINK_RX_FLUSH | SLINK_TX_FLUSH, SLINK_STATUS); - - tspi->cur = t; - tspi->cur_pos = 0; - tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, t); - - spi_tegra_go(tspi); -} - -static void spi_tegra_start_message(struct spi_device *spi, - struct spi_message *m) -{ - struct spi_transfer *t; - - m->actual_length = 0; - m->status = 0; - - t = list_first_entry(&m->transfers, struct spi_transfer, transfer_list); - spi_tegra_start_transfer(spi, t); -} - -static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) -{ - struct spi_tegra_data *tspi = req->dev; - unsigned long flags; - struct spi_message *m; - struct spi_device *spi; - int timeout = 0; - unsigned long val; - - /* the SPI controller may come back with both the BSY and RDY bits - * set. In this case we need to wait for the BSY bit to clear so - * that we are sure the DMA is finished. 1000 reads was empirically - * determined to be long enough. - */ - while (timeout++ < 1000) { - if (!(spi_tegra_readl(tspi, SLINK_STATUS) & SLINK_BSY)) - break; - } - - spin_lock_irqsave(&tspi->lock, flags); - - val = spi_tegra_readl(tspi, SLINK_STATUS); - val |= SLINK_RDY; - spi_tegra_writel(tspi, val, SLINK_STATUS); - - m = list_first_entry(&tspi->queue, struct spi_message, queue); - - if (timeout >= 1000) - m->status = -EIO; - - spi = m->state; - - tspi->cur_pos += spi_tegra_drain_rx_fifo(tspi, tspi->cur); - m->actual_length += tspi->cur_pos; - - if (tspi->cur_pos < tspi->cur->len) { - tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, tspi->cur); - spi_tegra_go(tspi); - } else if (!list_is_last(&tspi->cur->transfer_list, - &m->transfers)) { - tspi->cur = list_first_entry(&tspi->cur->transfer_list, - struct spi_transfer, - transfer_list); - spi_tegra_start_transfer(spi, tspi->cur); - } else { - list_del(&m->queue); - - m->complete(m->context); - - if (!list_empty(&tspi->queue)) { - m = list_first_entry(&tspi->queue, struct spi_message, - queue); - spi = m->state; - spi_tegra_start_message(spi, m); - } else { - clk_disable(tspi->clk); - tspi->cur_speed = 0; - } - } - - spin_unlock_irqrestore(&tspi->lock, flags); -} - -static int spi_tegra_setup(struct spi_device *spi) -{ - struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); - unsigned long cs_bit; - unsigned long val; - unsigned long flags; - - dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n", - spi->bits_per_word, - spi->mode & SPI_CPOL ? "" : "~", - spi->mode & SPI_CPHA ? "" : "~", - spi->max_speed_hz); - - - switch (spi->chip_select) { - case 0: - cs_bit = SLINK_CS_POLARITY; - break; - - case 1: - cs_bit = SLINK_CS_POLARITY1; - break; - - case 2: - cs_bit = SLINK_CS_POLARITY2; - break; - - case 4: - cs_bit = SLINK_CS_POLARITY3; - break; - - default: - return -EINVAL; - } - - spin_lock_irqsave(&tspi->lock, flags); - - val = spi_tegra_readl(tspi, SLINK_COMMAND); - if (spi->mode & SPI_CS_HIGH) - val |= cs_bit; - else - val &= ~cs_bit; - spi_tegra_writel(tspi, val, SLINK_COMMAND); - - spin_unlock_irqrestore(&tspi->lock, flags); - - return 0; -} - -static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m) -{ - struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); - struct spi_transfer *t; - unsigned long flags; - int was_empty; - - if (list_empty(&m->transfers) || !m->complete) - return -EINVAL; - - list_for_each_entry(t, &m->transfers, transfer_list) { - if (t->bits_per_word < 0 || t->bits_per_word > 32) - return -EINVAL; - - if (t->len == 0) - return -EINVAL; - - if (!t->rx_buf && !t->tx_buf) - return -EINVAL; - } - - spin_lock_irqsave(&tspi->lock, flags); - - if (WARN_ON(tspi->is_suspended)) { - spin_unlock_irqrestore(&tspi->lock, flags); - return -EBUSY; - } - - m->state = spi; - - was_empty = list_empty(&tspi->queue); - list_add_tail(&m->queue, &tspi->queue); - - if (was_empty) - spi_tegra_start_message(spi, m); - - spin_unlock_irqrestore(&tspi->lock, flags); - - return 0; -} - -static int __init spi_tegra_probe(struct platform_device *pdev) -{ - struct spi_master *master; - struct spi_tegra_data *tspi; - struct resource *r; - int ret; - - master = spi_alloc_master(&pdev->dev, sizeof *tspi); - if (master == NULL) { - dev_err(&pdev->dev, "master allocation failed\n"); - return -ENOMEM; - } - - /* the spi->mode bits understood by this driver: */ - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - - master->bus_num = pdev->id; - - master->setup = spi_tegra_setup; - master->transfer = spi_tegra_transfer; - master->num_chipselect = 4; - - dev_set_drvdata(&pdev->dev, master); - tspi = spi_master_get_devdata(master); - tspi->master = master; - tspi->pdev = pdev; - spin_lock_init(&tspi->lock); - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENODEV; - goto err0; - } - - if (!request_mem_region(r->start, (r->end - r->start) + 1, - dev_name(&pdev->dev))) { - ret = -EBUSY; - goto err0; - } - - tspi->phys = r->start; - tspi->base = ioremap(r->start, r->end - r->start + 1); - if (!tspi->base) { - dev_err(&pdev->dev, "can't ioremap iomem\n"); - ret = -ENOMEM; - goto err1; - } - - tspi->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR_OR_NULL(tspi->clk)) { - dev_err(&pdev->dev, "can not get clock\n"); - ret = PTR_ERR(tspi->clk); - goto err2; - } - - INIT_LIST_HEAD(&tspi->queue); - - tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT | - TEGRA_DMA_SHARED); - if (!tspi->rx_dma) { - dev_err(&pdev->dev, "can not allocate rx dma channel\n"); - ret = -ENODEV; - goto err3; - } - - tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, - &tspi->rx_bb_phys, GFP_KERNEL); - if (!tspi->rx_bb) { - dev_err(&pdev->dev, "can not allocate rx bounce buffer\n"); - ret = -ENOMEM; - goto err4; - } - - tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; - tspi->rx_dma_req.to_memory = 1; - tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys; - tspi->rx_dma_req.dest_bus_width = 32; - tspi->rx_dma_req.source_addr = tspi->phys + SLINK_RX_FIFO; - tspi->rx_dma_req.source_bus_width = 32; - tspi->rx_dma_req.source_wrap = 4; - tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; - tspi->rx_dma_req.dev = tspi; - - ret = spi_register_master(master); - - if (ret < 0) - goto err5; - - return ret; - -err5: - dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, - tspi->rx_bb, tspi->rx_bb_phys); -err4: - tegra_dma_free_channel(tspi->rx_dma); -err3: - clk_put(tspi->clk); -err2: - iounmap(tspi->base); -err1: - release_mem_region(r->start, (r->end - r->start) + 1); -err0: - spi_master_put(master); - return ret; -} - -static int __devexit spi_tegra_remove(struct platform_device *pdev) -{ - struct spi_master *master; - struct spi_tegra_data *tspi; - struct resource *r; - - master = dev_get_drvdata(&pdev->dev); - tspi = spi_master_get_devdata(master); - - tegra_dma_free_channel(tspi->rx_dma); - - dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, - tspi->rx_bb, tspi->rx_bb_phys); - - clk_put(tspi->clk); - iounmap(tspi->base); - - spi_master_put(master); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, (r->end - r->start) + 1); - - return 0; -} - -#ifdef CONFIG_PM -static int spi_tegra_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct spi_master *master; - struct spi_tegra_data *tspi; - unsigned long flags; - unsigned limit = 500; - - master = dev_get_drvdata(&pdev->dev); - tspi = spi_master_get_devdata(master); - spin_lock_irqsave(&tspi->lock, flags); - tspi->is_suspended = true; - WARN_ON(!list_empty(&tspi->queue)); - - while (!list_empty(&tspi->queue) && limit--) { - spin_unlock_irqrestore(&tspi->lock, flags); - msleep(10); - spin_lock_irqsave(&tspi->lock, flags); - } - - tspi->save_slink_cmd = spi_tegra_readl(tspi, SLINK_COMMAND); - spin_unlock_irqrestore(&tspi->lock, flags); - return 0; -} - -static int spi_tegra_resume(struct platform_device *pdev) -{ - struct spi_master *master; - struct spi_tegra_data *tspi; - unsigned long flags; - - master = dev_get_drvdata(&pdev->dev); - tspi = spi_master_get_devdata(master); - spin_lock_irqsave(&tspi->lock, flags); - clk_enable(tspi->clk); - spi_tegra_writel(tspi, tspi->save_slink_cmd, SLINK_COMMAND); - clk_disable(tspi->clk); - tspi->cur_speed = 0; - tspi->is_suspended = false; - spin_unlock_irqrestore(&tspi->lock, flags); - return 0; -} -#endif - -MODULE_ALIAS("platform:spi_tegra"); - -static struct platform_driver spi_tegra_driver = { - .driver = { - .name = "spi_tegra", - .owner = THIS_MODULE, - }, - .remove = __devexit_p(spi_tegra_remove), -#ifdef CONFIG_PM - .suspend = spi_tegra_suspend, - .resume = spi_tegra_resume, -#endif -}; - -static int __init spi_tegra_init(void) -{ - return platform_driver_probe(&spi_tegra_driver, spi_tegra_probe); -} -module_init(spi_tegra_init); - -static void __exit spi_tegra_exit(void) -{ - platform_driver_unregister(&spi_tegra_driver); -} -module_exit(spi_tegra_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index 744d3f6e4709..ef9c6a04ad8f 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c @@ -24,7 +24,6 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, - { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 96f6dda3ee69..335311a98fdc 100755 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -81,8 +81,6 @@ source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/frontier/Kconfig" -source "drivers/staging/android/Kconfig" - source "drivers/staging/dream/Kconfig" source "drivers/staging/pohmelfs/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 47c0b9489caf..e3f1e1b6095e 100755 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ -obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_DREAM) += dream/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_IDE_PHISON) += phison/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig deleted file mode 100644 index 247194992374..000000000000 --- a/drivers/staging/android/Kconfig +++ /dev/null @@ -1,95 +0,0 @@ -menu "Android" - -config ANDROID - bool "Android Drivers" - default N - ---help--- - Enable support for various drivers needed on the Android platform - -if ANDROID - -config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - default n - -config ANDROID_LOGGER - tristate "Android log driver" - default n - -config ANDROID_RAM_CONSOLE - bool "Android RAM buffer console" - default n - -config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - bool "Enable verbose console messages on Android RAM console" - default y - depends on ANDROID_RAM_CONSOLE - -menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION - bool "Android RAM Console Enable error correction" - default n - depends on ANDROID_RAM_CONSOLE - depends on !ANDROID_RAM_CONSOLE_EARLY_INIT - select REED_SOLOMON - select REED_SOLOMON_ENC8 - select REED_SOLOMON_DEC8 - -if ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE - int "Android RAM Console Data data size" - default 128 - help - Must be a power of 2. - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE - int "Android RAM Console ECC size" - default 16 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE - int "Android RAM Console Symbol size" - default 8 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL - hex "Android RAM Console Polynomial" - default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4) - default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5) - default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6) - default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7) - default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8) - -endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_EARLY_INIT - bool "Start Android RAM console early" - default n - depends on ANDROID_RAM_CONSOLE - -config ANDROID_RAM_CONSOLE_EARLY_ADDR - hex "Android RAM console virtual address" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_RAM_CONSOLE_EARLY_SIZE - hex "Android RAM console buffer size" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_TIMED_OUTPUT - bool "Timed output class driver" - default y - -config ANDROID_TIMED_GPIO - tristate "Android timed gpio driver" - depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT - default n - -config ANDROID_LOW_MEMORY_KILLER - bool "Android Low Memory Killer" - default N - ---help--- - Register processes to be killed when memory is low - -endif # if ANDROID - -endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile deleted file mode 100644 index 8e057e626d11..000000000000 --- a/drivers/staging/android/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o -obj-$(CONFIG_ANDROID_LOGGER) += logger.o -obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o -obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o -obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c deleted file mode 100644 index e13b4c483407..000000000000 --- a/drivers/staging/android/binder.c +++ /dev/null @@ -1,3600 +0,0 @@ -/* binder.c - * - * Android IPC Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "binder.h" - -static DEFINE_MUTEX(binder_lock); -static DEFINE_MUTEX(binder_deferred_lock); - -static HLIST_HEAD(binder_procs); -static HLIST_HEAD(binder_deferred_list); -static HLIST_HEAD(binder_dead_nodes); - -static struct dentry *binder_debugfs_dir_entry_root; -static struct dentry *binder_debugfs_dir_entry_proc; -static struct binder_node *binder_context_mgr_node; -static uid_t binder_context_mgr_uid = -1; -static int binder_last_id; -static struct workqueue_struct *binder_deferred_workqueue; - -#define BINDER_DEBUG_ENTRY(name) \ -static int binder_##name##_open(struct inode *inode, struct file *file) \ -{ \ - return single_open(file, binder_##name##_show, inode->i_private); \ -} \ -\ -static const struct file_operations binder_##name##_fops = { \ - .owner = THIS_MODULE, \ - .open = binder_##name##_open, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ -} - -static int binder_proc_show(struct seq_file *m, void *unused); -BINDER_DEBUG_ENTRY(proc); - -/* This is only defined in include/asm-arm/sizes.h */ -#ifndef SZ_1K -#define SZ_1K 0x400 -#endif - -#ifndef SZ_4M -#define SZ_4M 0x400000 -#endif - -#define FORBIDDEN_MMAP_FLAGS (VM_WRITE) - -#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) - -enum { - BINDER_DEBUG_USER_ERROR = 1U << 0, - BINDER_DEBUG_FAILED_TRANSACTION = 1U << 1, - BINDER_DEBUG_DEAD_TRANSACTION = 1U << 2, - BINDER_DEBUG_OPEN_CLOSE = 1U << 3, - BINDER_DEBUG_DEAD_BINDER = 1U << 4, - BINDER_DEBUG_DEATH_NOTIFICATION = 1U << 5, - BINDER_DEBUG_READ_WRITE = 1U << 6, - BINDER_DEBUG_USER_REFS = 1U << 7, - BINDER_DEBUG_THREADS = 1U << 8, - BINDER_DEBUG_TRANSACTION = 1U << 9, - BINDER_DEBUG_TRANSACTION_COMPLETE = 1U << 10, - BINDER_DEBUG_FREE_BUFFER = 1U << 11, - BINDER_DEBUG_INTERNAL_REFS = 1U << 12, - BINDER_DEBUG_BUFFER_ALLOC = 1U << 13, - BINDER_DEBUG_PRIORITY_CAP = 1U << 14, - BINDER_DEBUG_BUFFER_ALLOC_ASYNC = 1U << 15, -}; -static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | - BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; -module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); - -static int binder_debug_no_lock; -module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); - -static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); -static int binder_stop_on_user_error; - -static int binder_set_stop_on_user_error(const char *val, - struct kernel_param *kp) -{ - int ret; - ret = param_set_int(val, kp); - if (binder_stop_on_user_error < 2) - wake_up(&binder_user_error_wait); - return ret; -} -module_param_call(stop_on_user_error, binder_set_stop_on_user_error, - param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); - -#define binder_debug(mask, x...) \ - do { \ - if (binder_debug_mask & mask) \ - printk(KERN_INFO x); \ - } while (0) - -#define binder_user_error(x...) \ - do { \ - if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ - printk(KERN_INFO x); \ - if (binder_stop_on_user_error) \ - binder_stop_on_user_error = 2; \ - } while (0) - -enum binder_stat_types { - BINDER_STAT_PROC, - BINDER_STAT_THREAD, - BINDER_STAT_NODE, - BINDER_STAT_REF, - BINDER_STAT_DEATH, - BINDER_STAT_TRANSACTION, - BINDER_STAT_TRANSACTION_COMPLETE, - BINDER_STAT_COUNT -}; - -struct binder_stats { - int br[_IOC_NR(BR_FAILED_REPLY) + 1]; - int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; - int obj_created[BINDER_STAT_COUNT]; - int obj_deleted[BINDER_STAT_COUNT]; -}; - -static struct binder_stats binder_stats; - -static inline void binder_stats_deleted(enum binder_stat_types type) -{ - binder_stats.obj_deleted[type]++; -} - -static inline void binder_stats_created(enum binder_stat_types type) -{ - binder_stats.obj_created[type]++; -} - -struct binder_transaction_log_entry { - int debug_id; - int call_type; - int from_proc; - int from_thread; - int target_handle; - int to_proc; - int to_thread; - int to_node; - int data_size; - int offsets_size; -}; -struct binder_transaction_log { - int next; - int full; - struct binder_transaction_log_entry entry[32]; -}; -static struct binder_transaction_log binder_transaction_log; -static struct binder_transaction_log binder_transaction_log_failed; - -static struct binder_transaction_log_entry *binder_transaction_log_add( - struct binder_transaction_log *log) -{ - struct binder_transaction_log_entry *e; - e = &log->entry[log->next]; - memset(e, 0, sizeof(*e)); - log->next++; - if (log->next == ARRAY_SIZE(log->entry)) { - log->next = 0; - log->full = 1; - } - return e; -} - -struct binder_work { - struct list_head entry; - enum { - BINDER_WORK_TRANSACTION = 1, - BINDER_WORK_TRANSACTION_COMPLETE, - BINDER_WORK_NODE, - BINDER_WORK_DEAD_BINDER, - BINDER_WORK_DEAD_BINDER_AND_CLEAR, - BINDER_WORK_CLEAR_DEATH_NOTIFICATION, - } type; -}; - -struct binder_node { - int debug_id; - struct binder_work work; - union { - struct rb_node rb_node; - struct hlist_node dead_node; - }; - struct binder_proc *proc; - struct hlist_head refs; - int internal_strong_refs; - int local_weak_refs; - int local_strong_refs; - void __user *ptr; - void __user *cookie; - unsigned has_strong_ref:1; - unsigned pending_strong_ref:1; - unsigned has_weak_ref:1; - unsigned pending_weak_ref:1; - unsigned has_async_transaction:1; - unsigned accept_fds:1; - unsigned min_priority:8; - struct list_head async_todo; -}; - -struct binder_ref_death { - struct binder_work work; - void __user *cookie; -}; - -struct binder_ref { - /* Lookups needed: */ - /* node + proc => ref (transaction) */ - /* desc + proc => ref (transaction, inc/dec ref) */ - /* node => refs + procs (proc exit) */ - int debug_id; - struct rb_node rb_node_desc; - struct rb_node rb_node_node; - struct hlist_node node_entry; - struct binder_proc *proc; - struct binder_node *node; - uint32_t desc; - int strong; - int weak; - struct binder_ref_death *death; -}; - -struct binder_buffer { - struct list_head entry; /* free and allocated entries by addesss */ - struct rb_node rb_node; /* free entry by size or allocated entry */ - /* by address */ - unsigned free:1; - unsigned allow_user_free:1; - unsigned async_transaction:1; - unsigned debug_id:29; - - struct binder_transaction *transaction; - - struct binder_node *target_node; - size_t data_size; - size_t offsets_size; - uint8_t data[0]; -}; - -enum binder_deferred_state { - BINDER_DEFERRED_PUT_FILES = 0x01, - BINDER_DEFERRED_FLUSH = 0x02, - BINDER_DEFERRED_RELEASE = 0x04, -}; - -struct binder_proc { - struct hlist_node proc_node; - struct rb_root threads; - struct rb_root nodes; - struct rb_root refs_by_desc; - struct rb_root refs_by_node; - int pid; - struct vm_area_struct *vma; - struct task_struct *tsk; - struct files_struct *files; - struct hlist_node deferred_work_node; - int deferred_work; - void *buffer; - ptrdiff_t user_buffer_offset; - - struct list_head buffers; - struct rb_root free_buffers; - struct rb_root allocated_buffers; - size_t free_async_space; - - struct page **pages; - size_t buffer_size; - uint32_t buffer_free; - struct list_head todo; - wait_queue_head_t wait; - struct binder_stats stats; - struct list_head delivered_death; - int max_threads; - int requested_threads; - int requested_threads_started; - int ready_threads; - long default_priority; - struct dentry *debugfs_entry; -}; - -enum { - BINDER_LOOPER_STATE_REGISTERED = 0x01, - BINDER_LOOPER_STATE_ENTERED = 0x02, - BINDER_LOOPER_STATE_EXITED = 0x04, - BINDER_LOOPER_STATE_INVALID = 0x08, - BINDER_LOOPER_STATE_WAITING = 0x10, - BINDER_LOOPER_STATE_NEED_RETURN = 0x20 -}; - -struct binder_thread { - struct binder_proc *proc; - struct rb_node rb_node; - int pid; - int looper; - struct binder_transaction *transaction_stack; - struct list_head todo; - uint32_t return_error; /* Write failed, return error code in read buf */ - uint32_t return_error2; /* Write failed, return error code in read */ - /* buffer. Used when sending a reply to a dead process that */ - /* we are also waiting on */ - wait_queue_head_t wait; - struct binder_stats stats; -}; - -struct binder_transaction { - int debug_id; - struct binder_work work; - struct binder_thread *from; - struct binder_transaction *from_parent; - struct binder_proc *to_proc; - struct binder_thread *to_thread; - struct binder_transaction *to_parent; - unsigned need_reply:1; - /* unsigned is_dead:1; */ /* not used at the moment */ - - struct binder_buffer *buffer; - unsigned int code; - unsigned int flags; - long priority; - long saved_priority; - uid_t sender_euid; -}; - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); - -/* - * copied from get_unused_fd_flags - */ -int task_get_unused_fd_flags(struct binder_proc *proc, int flags) -{ - struct files_struct *files = proc->files; - int fd, error; - struct fdtable *fdt; - unsigned long rlim_cur; - unsigned long irqs; - - if (files == NULL) - return -ESRCH; - - error = -EMFILE; - spin_lock(&files->file_lock); - -repeat: - fdt = files_fdtable(files); - fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, - files->next_fd); - - /* - * N.B. For clone tasks sharing a files structure, this test - * will limit the total number of files that can be opened. - */ - rlim_cur = 0; - if (lock_task_sighand(proc->tsk, &irqs)) { - rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; - unlock_task_sighand(proc->tsk, &irqs); - } - if (fd >= rlim_cur) - goto out; - - /* Do we need to expand the fd array or fd set? */ - error = expand_files(files, fd); - if (error < 0) - goto out; - - if (error) { - /* - * If we needed to expand the fs array we - * might have blocked - try again. - */ - error = -EMFILE; - goto repeat; - } - - FD_SET(fd, fdt->open_fds); - if (flags & O_CLOEXEC) - FD_SET(fd, fdt->close_on_exec); - else - FD_CLR(fd, fdt->close_on_exec); - files->next_fd = fd + 1; -#if 1 - /* Sanity check */ - if (fdt->fd[fd] != NULL) { - printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); - fdt->fd[fd] = NULL; - } -#endif - error = fd; - -out: - spin_unlock(&files->file_lock); - return error; -} - -/* - * copied from fd_install - */ -static void task_fd_install( - struct binder_proc *proc, unsigned int fd, struct file *file) -{ - struct files_struct *files = proc->files; - struct fdtable *fdt; - - if (files == NULL) - return; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - BUG_ON(fdt->fd[fd] != NULL); - rcu_assign_pointer(fdt->fd[fd], file); - spin_unlock(&files->file_lock); -} - -/* - * copied from __put_unused_fd in open.c - */ -static void __put_unused_fd(struct files_struct *files, unsigned int fd) -{ - struct fdtable *fdt = files_fdtable(files); - __FD_CLR(fd, fdt->open_fds); - if (fd < files->next_fd) - files->next_fd = fd; -} - -/* - * copied from sys_close - */ -static long task_close_fd(struct binder_proc *proc, unsigned int fd) -{ - struct file *filp; - struct files_struct *files = proc->files; - struct fdtable *fdt; - int retval; - - if (files == NULL) - return -ESRCH; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - if (fd >= fdt->max_fds) - goto out_unlock; - filp = fdt->fd[fd]; - if (!filp) - goto out_unlock; - rcu_assign_pointer(fdt->fd[fd], NULL); - FD_CLR(fd, fdt->close_on_exec); - __put_unused_fd(files, fd); - spin_unlock(&files->file_lock); - retval = filp_close(filp, files); - - /* can't restart close syscall because file table entry was cleared */ - if (unlikely(retval == -ERESTARTSYS || - retval == -ERESTARTNOINTR || - retval == -ERESTARTNOHAND || - retval == -ERESTART_RESTARTBLOCK)) - retval = -EINTR; - - return retval; - -out_unlock: - spin_unlock(&files->file_lock); - return -EBADF; -} - -static void binder_set_nice(long nice) -{ - long min_nice; - if (can_nice(current, nice)) { - set_user_nice(current, nice); - return; - } - min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; - binder_debug(BINDER_DEBUG_PRIORITY_CAP, - "binder: %d: nice value %ld not allowed use " - "%ld instead\n", current->pid, nice, min_nice); - set_user_nice(current, min_nice); - if (min_nice < 20) - return; - binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid); -} - -static size_t binder_buffer_size(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - if (list_is_last(&buffer->entry, &proc->buffers)) - return proc->buffer + proc->buffer_size - (void *)buffer->data; - else - return (size_t)list_entry(buffer->entry.next, - struct binder_buffer, entry) - (size_t)buffer->data; -} - -static void binder_insert_free_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->free_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - size_t buffer_size; - size_t new_buffer_size; - - BUG_ON(!new_buffer->free); - - new_buffer_size = binder_buffer_size(proc, new_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: add free buffer, size %zd, " - "at %p\n", proc->pid, new_buffer_size, new_buffer); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - - buffer_size = binder_buffer_size(proc, buffer); - - if (new_buffer_size < buffer_size) - p = &parent->rb_left; - else - p = &parent->rb_right; - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->free_buffers); -} - -static void binder_insert_allocated_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->allocated_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - - BUG_ON(new_buffer->free); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (new_buffer < buffer) - p = &parent->rb_left; - else if (new_buffer > buffer) - p = &parent->rb_right; - else - BUG(); - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers); -} - -static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc, - void __user *user_ptr) -{ - struct rb_node *n = proc->allocated_buffers.rb_node; - struct binder_buffer *buffer; - struct binder_buffer *kern_ptr; - - kern_ptr = user_ptr - proc->user_buffer_offset - - offsetof(struct binder_buffer, data); - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (kern_ptr < buffer) - n = n->rb_left; - else if (kern_ptr > buffer) - n = n->rb_right; - else - return buffer; - } - return NULL; -} - -static int binder_update_page_range(struct binder_proc *proc, int allocate, - void *start, void *end, - struct vm_area_struct *vma) -{ - void *page_addr; - unsigned long user_page_addr; - struct vm_struct tmp_area; - struct page **page; - struct mm_struct *mm; - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: %s pages %p-%p\n", proc->pid, - allocate ? "allocate" : "free", start, end); - - if (end <= start) - return 0; - - if (vma) - mm = NULL; - else - mm = get_task_mm(proc->tsk); - - if (mm) { - down_write(&mm->mmap_sem); - vma = proc->vma; - } - - if (allocate == 0) - goto free_range; - - if (vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed to " - "map pages in userspace, no vma\n", proc->pid); - goto err_no_vma; - } - - for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) { - int ret; - struct page **page_array_ptr; - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - - BUG_ON(*page); - *page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (*page == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "for page at %p\n", proc->pid, page_addr); - goto err_alloc_page_failed; - } - tmp_area.addr = page_addr; - tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */; - page_array_ptr = page; - ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %p in kernel\n", - proc->pid, page_addr); - goto err_map_kernel_failed; - } - user_page_addr = - (uintptr_t)page_addr + proc->user_buffer_offset; - ret = vm_insert_page(vma, user_page_addr, page[0]); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %lx in userspace\n", - proc->pid, user_page_addr); - goto err_vm_insert_page_failed; - } - /* vm_insert_page does not seem to increment the refcount */ - } - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return 0; - -free_range: - for (page_addr = end - PAGE_SIZE; page_addr >= start; - page_addr -= PAGE_SIZE) { - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - if (vma) - zap_page_range(vma, (uintptr_t)page_addr + - proc->user_buffer_offset, PAGE_SIZE, NULL); -err_vm_insert_page_failed: - unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); -err_map_kernel_failed: - __free_page(*page); - *page = NULL; -err_alloc_page_failed: - ; - } -err_no_vma: - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return -ENOMEM; -} - -static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, - size_t data_size, - size_t offsets_size, int is_async) -{ - struct rb_node *n = proc->free_buffers.rb_node; - struct binder_buffer *buffer; - size_t buffer_size; - struct rb_node *best_fit = NULL; - void *has_page_addr; - void *end_page_addr; - size_t size; - - if (proc->vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n", - proc->pid); - return NULL; - } - - size = ALIGN(data_size, sizeof(void *)) + - ALIGN(offsets_size, sizeof(void *)); - - if (size < data_size || size < offsets_size) { - binder_user_error("binder: %d: got transaction with invalid " - "size %zd-%zd\n", proc->pid, data_size, offsets_size); - return NULL; - } - - if (is_async && - proc->free_async_space < size + sizeof(struct binder_buffer)) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd" - "failed, no async space left\n", proc->pid, size); - return NULL; - } - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - buffer_size = binder_buffer_size(proc, buffer); - - if (size < buffer_size) { - best_fit = n; - n = n->rb_left; - } else if (size > buffer_size) - n = n->rb_right; - else { - best_fit = n; - break; - } - } - if (best_fit == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, " - "no address space\n", proc->pid, size); - return NULL; - } - if (n == NULL) { - buffer = rb_entry(best_fit, struct binder_buffer, rb_node); - buffer_size = binder_buffer_size(proc, buffer); - } - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got buff" - "er %p size %zd\n", proc->pid, size, buffer, buffer_size); - - has_page_addr = - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); - if (n == NULL) { - if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) - buffer_size = size; /* no room for other buffers */ - else - buffer_size = size + sizeof(struct binder_buffer); - } - end_page_addr = - (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); - if (end_page_addr > has_page_addr) - end_page_addr = has_page_addr; - if (binder_update_page_range(proc, 1, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) - return NULL; - - rb_erase(best_fit, &proc->free_buffers); - buffer->free = 0; - binder_insert_allocated_buffer(proc, buffer); - if (buffer_size != size) { - struct binder_buffer *new_buffer = (void *)buffer->data + size; - list_add(&new_buffer->entry, &buffer->entry); - new_buffer->free = 1; - binder_insert_free_buffer(proc, new_buffer); - } - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got " - "%p\n", proc->pid, size, buffer); - buffer->data_size = data_size; - buffer->offsets_size = offsets_size; - buffer->async_transaction = is_async; - if (is_async) { - proc->free_async_space -= size + sizeof(struct binder_buffer); - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_alloc_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - return buffer; -} - -static void *buffer_start_page(struct binder_buffer *buffer) -{ - return (void *)((uintptr_t)buffer & PAGE_MASK); -} - -static void *buffer_end_page(struct binder_buffer *buffer) -{ - return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); -} - -static void binder_delete_free_buffer(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - struct binder_buffer *prev, *next = NULL; - int free_page_end = 1; - int free_page_start = 1; - - BUG_ON(proc->buffers.next == &buffer->entry); - prev = list_entry(buffer->entry.prev, struct binder_buffer, entry); - BUG_ON(!prev->free); - if (buffer_end_page(prev) == buffer_start_page(buffer)) { - free_page_start = 0; - if (buffer_end_page(prev) == buffer_end_page(buffer)) - free_page_end = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p " - "share page with %p\n", proc->pid, buffer, prev); - } - - if (!list_is_last(&buffer->entry, &proc->buffers)) { - next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (buffer_start_page(next) == buffer_end_page(buffer)) { - free_page_end = 0; - if (buffer_start_page(next) == - buffer_start_page(buffer)) - free_page_start = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer" - " %p share page with %p\n", proc->pid, - buffer, prev); - } - } - list_del(&buffer->entry); - if (free_page_start || free_page_end) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p do " - "not share page%s%s with with %p or %p\n", - proc->pid, buffer, free_page_start ? "" : " end", - free_page_end ? "" : " start", prev, next); - binder_update_page_range(proc, 0, free_page_start ? - buffer_start_page(buffer) : buffer_end_page(buffer), - (free_page_end ? buffer_end_page(buffer) : - buffer_start_page(buffer)) + PAGE_SIZE, NULL); - } -} - -static void binder_free_buf(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - size_t size, buffer_size; - - buffer_size = binder_buffer_size(proc, buffer); - - size = ALIGN(buffer->data_size, sizeof(void *)) + - ALIGN(buffer->offsets_size, sizeof(void *)); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_free_buf %p size %zd buffer" - "_size %zd\n", proc->pid, buffer, size, buffer_size); - - BUG_ON(buffer->free); - BUG_ON(size > buffer_size); - BUG_ON(buffer->transaction != NULL); - BUG_ON((void *)buffer < proc->buffer); - BUG_ON((void *)buffer > proc->buffer + proc->buffer_size); - - if (buffer->async_transaction) { - proc->free_async_space += size + sizeof(struct binder_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_free_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - binder_update_page_range(proc, 0, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), - NULL); - rb_erase(&buffer->rb_node, &proc->allocated_buffers); - buffer->free = 1; - if (!list_is_last(&buffer->entry, &proc->buffers)) { - struct binder_buffer *next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (next->free) { - rb_erase(&next->rb_node, &proc->free_buffers); - binder_delete_free_buffer(proc, next); - } - } - if (proc->buffers.next != &buffer->entry) { - struct binder_buffer *prev = list_entry(buffer->entry.prev, - struct binder_buffer, entry); - if (prev->free) { - binder_delete_free_buffer(proc, buffer); - rb_erase(&prev->rb_node, &proc->free_buffers); - buffer = prev; - } - } - binder_insert_free_buffer(proc, buffer); -} - -static struct binder_node *binder_get_node(struct binder_proc *proc, - void __user *ptr) -{ - struct rb_node *n = proc->nodes.rb_node; - struct binder_node *node; - - while (n) { - node = rb_entry(n, struct binder_node, rb_node); - - if (ptr < node->ptr) - n = n->rb_left; - else if (ptr > node->ptr) - n = n->rb_right; - else - return node; - } - return NULL; -} - -static struct binder_node *binder_new_node(struct binder_proc *proc, - void __user *ptr, - void __user *cookie) -{ - struct rb_node **p = &proc->nodes.rb_node; - struct rb_node *parent = NULL; - struct binder_node *node; - - while (*p) { - parent = *p; - node = rb_entry(parent, struct binder_node, rb_node); - - if (ptr < node->ptr) - p = &(*p)->rb_left; - else if (ptr > node->ptr) - p = &(*p)->rb_right; - else - return NULL; - } - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (node == NULL) - return NULL; - binder_stats_created(BINDER_STAT_NODE); - rb_link_node(&node->rb_node, parent, p); - rb_insert_color(&node->rb_node, &proc->nodes); - node->debug_id = ++binder_last_id; - node->proc = proc; - node->ptr = ptr; - node->cookie = cookie; - node->work.type = BINDER_WORK_NODE; - INIT_LIST_HEAD(&node->work.entry); - INIT_LIST_HEAD(&node->async_todo); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p created\n", - proc->pid, current->pid, node->debug_id, - node->ptr, node->cookie); - return node; -} - -static int binder_inc_node(struct binder_node *node, int strong, int internal, - struct list_head *target_list) -{ - if (strong) { - if (internal) { - if (target_list == NULL && - node->internal_strong_refs == 0 && - !(node == binder_context_mgr_node && - node->has_strong_ref)) { - printk(KERN_ERR "binder: invalid inc strong " - "node for %d\n", node->debug_id); - return -EINVAL; - } - node->internal_strong_refs++; - } else - node->local_strong_refs++; - if (!node->has_strong_ref && target_list) { - list_del_init(&node->work.entry); - list_add_tail(&node->work.entry, target_list); - } - } else { - if (!internal) - node->local_weak_refs++; - if (!node->has_weak_ref && list_empty(&node->work.entry)) { - if (target_list == NULL) { - printk(KERN_ERR "binder: invalid inc weak node " - "for %d\n", node->debug_id); - return -EINVAL; - } - list_add_tail(&node->work.entry, target_list); - } - } - return 0; -} - -static int binder_dec_node(struct binder_node *node, int strong, int internal) -{ - if (strong) { - if (internal) - node->internal_strong_refs--; - else - node->local_strong_refs--; - if (node->local_strong_refs || node->internal_strong_refs) - return 0; - } else { - if (!internal) - node->local_weak_refs--; - if (node->local_weak_refs || !hlist_empty(&node->refs)) - return 0; - } - if (node->proc && (node->has_strong_ref || node->has_weak_ref)) { - if (list_empty(&node->work.entry)) { - list_add_tail(&node->work.entry, &node->proc->todo); - wake_up_interruptible(&node->proc->wait); - } - } else { - if (hlist_empty(&node->refs) && !node->local_strong_refs && - !node->local_weak_refs) { - list_del_init(&node->work.entry); - if (node->proc) { - rb_erase(&node->rb_node, &node->proc->nodes); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: refless node %d deleted\n", - node->debug_id); - } else { - hlist_del(&node->dead_node); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: dead node %d deleted\n", - node->debug_id); - } - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } - } - - return 0; -} - - -static struct binder_ref *binder_get_ref(struct binder_proc *proc, - uint32_t desc) -{ - struct rb_node *n = proc->refs_by_desc.rb_node; - struct binder_ref *ref; - - while (n) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - - if (desc < ref->desc) - n = n->rb_left; - else if (desc > ref->desc) - n = n->rb_right; - else - return ref; - } - return NULL; -} - -static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, - struct binder_node *node) -{ - struct rb_node *n; - struct rb_node **p = &proc->refs_by_node.rb_node; - struct rb_node *parent = NULL; - struct binder_ref *ref, *new_ref; - - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_node); - - if (node < ref->node) - p = &(*p)->rb_left; - else if (node > ref->node) - p = &(*p)->rb_right; - else - return ref; - } - new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); - if (new_ref == NULL) - return NULL; - binder_stats_created(BINDER_STAT_REF); - new_ref->debug_id = ++binder_last_id; - new_ref->proc = proc; - new_ref->node = node; - rb_link_node(&new_ref->rb_node_node, parent, p); - rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); - - new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - if (ref->desc > new_ref->desc) - break; - new_ref->desc = ref->desc + 1; - } - - p = &proc->refs_by_desc.rb_node; - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_desc); - - if (new_ref->desc < ref->desc) - p = &(*p)->rb_left; - else if (new_ref->desc > ref->desc) - p = &(*p)->rb_right; - else - BUG(); - } - rb_link_node(&new_ref->rb_node_desc, parent, p); - rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); - if (node) { - hlist_add_head(&new_ref->node_entry, &node->refs); - - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "node %d\n", proc->pid, new_ref->debug_id, - new_ref->desc, node->debug_id); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "dead node\n", proc->pid, new_ref->debug_id, - new_ref->desc); - } - return new_ref; -} - -static void binder_delete_ref(struct binder_ref *ref) -{ - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d delete ref %d desc %d for " - "node %d\n", ref->proc->pid, ref->debug_id, - ref->desc, ref->node->debug_id); - - rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); - rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); - if (ref->strong) - binder_dec_node(ref->node, 1, 1); - hlist_del(&ref->node_entry); - binder_dec_node(ref->node, 0, 1); - if (ref->death) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d delete ref %d desc %d " - "has death notification\n", ref->proc->pid, - ref->debug_id, ref->desc); - list_del(&ref->death->work.entry); - kfree(ref->death); - binder_stats_deleted(BINDER_STAT_DEATH); - } - kfree(ref); - binder_stats_deleted(BINDER_STAT_REF); -} - -static int binder_inc_ref(struct binder_ref *ref, int strong, - struct list_head *target_list) -{ - int ret; - if (strong) { - if (ref->strong == 0) { - ret = binder_inc_node(ref->node, 1, 1, target_list); - if (ret) - return ret; - } - ref->strong++; - } else { - if (ref->weak == 0) { - ret = binder_inc_node(ref->node, 0, 1, target_list); - if (ret) - return ret; - } - ref->weak++; - } - return 0; -} - - -static int binder_dec_ref(struct binder_ref *ref, int strong) -{ - if (strong) { - if (ref->strong == 0) { - binder_user_error("binder: %d invalid dec strong, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->strong--; - if (ref->strong == 0) { - int ret; - ret = binder_dec_node(ref->node, strong, 1); - if (ret) - return ret; - } - } else { - if (ref->weak == 0) { - binder_user_error("binder: %d invalid dec weak, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->weak--; - } - if (ref->strong == 0 && ref->weak == 0) - binder_delete_ref(ref); - return 0; -} - -static void binder_pop_transaction(struct binder_thread *target_thread, - struct binder_transaction *t) -{ - if (target_thread) { - BUG_ON(target_thread->transaction_stack != t); - BUG_ON(target_thread->transaction_stack->from != target_thread); - target_thread->transaction_stack = - target_thread->transaction_stack->from_parent; - t->from = NULL; - } - t->need_reply = 0; - if (t->buffer) - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -} - -static void binder_send_failed_reply(struct binder_transaction *t, - uint32_t error_code) -{ - struct binder_thread *target_thread; - BUG_ON(t->flags & TF_ONE_WAY); - while (1) { - target_thread = t->from; - if (target_thread) { - if (target_thread->return_error != BR_OK && - target_thread->return_error2 == BR_OK) { - target_thread->return_error2 = - target_thread->return_error; - target_thread->return_error = BR_OK; - } - if (target_thread->return_error == BR_OK) { - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply for " - "transaction %d to %d:%d\n", - t->debug_id, target_thread->proc->pid, - target_thread->pid); - - binder_pop_transaction(target_thread, t); - target_thread->return_error = error_code; - wake_up_interruptible(&target_thread->wait); - } else { - printk(KERN_ERR "binder: reply failed, target " - "thread, %d:%d, has error code %d " - "already\n", target_thread->proc->pid, - target_thread->pid, - target_thread->return_error); - } - return; - } else { - struct binder_transaction *next = t->from_parent; - - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply " - "for transaction %d, target dead\n", - t->debug_id); - - binder_pop_transaction(target_thread, t); - if (next == NULL) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed," - " no target thread at root\n"); - return; - } - t = next; - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed, no target " - "thread -- retry %d\n", t->debug_id); - } - } -} - -static void binder_transaction_buffer_release(struct binder_proc *proc, - struct binder_buffer *buffer, - size_t *failed_at) -{ - size_t *offp, *off_end; - int debug_id = buffer->debug_id; - - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", - proc->pid, buffer->debug_id, - buffer->data_size, buffer->offsets_size, failed_at); - - if (buffer->target_node) - binder_dec_node(buffer->target_node, 1, 0); - - offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); - if (failed_at) - off_end = failed_at; - else - off_end = (void *)offp + buffer->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > buffer->data_size - sizeof(*fp) || - buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - printk(KERN_ERR "binder: transaction release %d bad" - "offset %zd, size %zd\n", debug_id, - *offp, buffer->data_size); - continue; - } - fp = (struct flat_binder_object *)(buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad node %p\n", debug_id, fp->binder); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p\n", - node->debug_id, node->ptr); - binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad handle %ld\n", debug_id, - fp->handle); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, ref->node->debug_id); - binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); - } break; - - case BINDER_TYPE_FD: - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld\n", fp->handle); - if (failed_at) - task_close_fd(proc, fp->handle); - break; - - default: - printk(KERN_ERR "binder: transaction release %d bad " - "object type %lx\n", debug_id, fp->type); - break; - } - } -} - -static void binder_transaction(struct binder_proc *proc, - struct binder_thread *thread, - struct binder_transaction_data *tr, int reply) -{ - struct binder_transaction *t; - struct binder_work *tcomplete; - size_t *offp, *off_end; - struct binder_proc *target_proc; - struct binder_thread *target_thread = NULL; - struct binder_node *target_node = NULL; - struct list_head *target_list; - wait_queue_head_t *target_wait; - struct binder_transaction *in_reply_to = NULL; - struct binder_transaction_log_entry *e; - uint32_t return_error; - - e = binder_transaction_log_add(&binder_transaction_log); - e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); - e->from_proc = proc->pid; - e->from_thread = thread->pid; - e->target_handle = tr->target.handle; - e->data_size = tr->data_size; - e->offsets_size = tr->offsets_size; - - if (reply) { - in_reply_to = thread->transaction_stack; - if (in_reply_to == NULL) { - binder_user_error("binder: %d:%d got reply transaction " - "with no transaction stack\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_empty_call_stack; - } - binder_set_nice(in_reply_to->saved_priority); - if (in_reply_to->to_thread != thread) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad transaction stack," - " transaction %d has target %d:%d\n", - proc->pid, thread->pid, in_reply_to->debug_id, - in_reply_to->to_proc ? - in_reply_to->to_proc->pid : 0, - in_reply_to->to_thread ? - in_reply_to->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - goto err_bad_call_stack; - } - thread->transaction_stack = in_reply_to->to_parent; - target_thread = in_reply_to->from; - if (target_thread == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (target_thread->transaction_stack != in_reply_to) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad target transaction stack %d, " - "expected %d\n", - proc->pid, thread->pid, - target_thread->transaction_stack ? - target_thread->transaction_stack->debug_id : 0, - in_reply_to->debug_id); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - target_thread = NULL; - goto err_dead_binder; - } - target_proc = target_thread->proc; - } else { - if (tr->target.handle) { - struct binder_ref *ref; - ref = binder_get_ref(proc, tr->target.handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction to invalid handle\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_invalid_target_handle; - } - target_node = ref->node; - } else { - target_node = binder_context_mgr_node; - if (target_node == NULL) { - return_error = BR_DEAD_REPLY; - goto err_no_context_mgr_node; - } - } - e->to_node = target_node->debug_id; - target_proc = target_node->proc; - if (target_proc == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { - struct binder_transaction *tmp; - tmp = thread->transaction_stack; - if (tmp->to_thread != thread) { - binder_user_error("binder: %d:%d got new " - "transaction with bad transaction stack" - ", transaction %d has target %d:%d\n", - proc->pid, thread->pid, tmp->debug_id, - tmp->to_proc ? tmp->to_proc->pid : 0, - tmp->to_thread ? - tmp->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - goto err_bad_call_stack; - } - while (tmp) { - if (tmp->from && tmp->from->proc == target_proc) - target_thread = tmp->from; - tmp = tmp->from_parent; - } - } - } - if (target_thread) { - e->to_thread = target_thread->pid; - target_list = &target_thread->todo; - target_wait = &target_thread->wait; - } else { - target_list = &target_proc->todo; - target_wait = &target_proc->wait; - } - e->to_proc = target_proc->pid; - - /* TODO: reuse incoming transaction for reply */ - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (t == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_t_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION); - - tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); - if (tcomplete == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_tcomplete_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); - - t->debug_id = ++binder_last_id; - e->debug_id = t->debug_id; - - if (reply) - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_REPLY %d -> %d:%d, " - "data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_thread->pid, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - else - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_TRANSACTION %d -> " - "%d - node %d, data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_node->debug_id, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - - if (!reply && !(tr->flags & TF_ONE_WAY)) - t->from = thread; - else - t->from = NULL; - t->sender_euid = proc->tsk->cred->euid; - t->to_proc = target_proc; - t->to_thread = target_thread; - t->code = tr->code; - t->flags = tr->flags; - t->priority = task_nice(current); - t->buffer = binder_alloc_buf(target_proc, tr->data_size, - tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); - if (t->buffer == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_alloc_buf_failed; - } - t->buffer->allow_user_free = 0; - t->buffer->debug_id = t->debug_id; - t->buffer->transaction = t; - t->buffer->target_node = target_node; - if (target_node) - binder_inc_node(target_node, 1, 0, NULL); - - offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); - - if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "data ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "offsets ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offsets size, %zd\n", - proc->pid, thread->pid, tr->offsets_size); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - off_end = (void *)offp + tr->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > t->buffer->data_size - sizeof(*fp) || - t->buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offset, %zd\n", - proc->pid, thread->pid, *offp); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - fp = (struct flat_binder_object *)(t->buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_ref *ref; - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - node = binder_new_node(proc, fp->binder, fp->cookie); - if (node == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_new_node_failed; - } - node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK; - node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); - } - if (fp->cookie != node->cookie) { - binder_user_error("binder: %d:%d sending u%p " - "node %d, cookie mismatch %p != %p\n", - proc->pid, thread->pid, - fp->binder, node->debug_id, - fp->cookie, node->cookie); - goto err_binder_get_ref_for_node_failed; - } - ref = binder_get_ref_for_node(target_proc, node); - if (ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - if (fp->type == BINDER_TYPE_BINDER) - fp->type = BINDER_TYPE_HANDLE; - else - fp->type = BINDER_TYPE_WEAK_HANDLE; - fp->handle = ref->desc; - binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, - &thread->todo); - - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p -> ref %d desc %d\n", - node->debug_id, node->ptr, ref->debug_id, - ref->desc); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction with invalid " - "handle, %ld\n", proc->pid, - thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_failed; - } - if (ref->node->proc == target_proc) { - if (fp->type == BINDER_TYPE_HANDLE) - fp->type = BINDER_TYPE_BINDER; - else - fp->type = BINDER_TYPE_WEAK_BINDER; - fp->binder = ref->node->ptr; - fp->cookie = ref->node->cookie; - binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> node %d u%p\n", - ref->debug_id, ref->desc, ref->node->debug_id, - ref->node->ptr); - } else { - struct binder_ref *new_ref; - new_ref = binder_get_ref_for_node(target_proc, ref->node); - if (new_ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - fp->handle = new_ref->desc; - binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, new_ref->debug_id, - new_ref->desc, ref->node->debug_id); - } - } break; - - case BINDER_TYPE_FD: { - int target_fd; - struct file *file; - - if (reply) { - if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { - binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - } else if (!target_node->accept_fds) { - binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - - file = fget(fp->handle); - if (file == NULL) { - binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fget_failed; - } - target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); - if (target_fd < 0) { - fput(file); - return_error = BR_FAILED_REPLY; - goto err_get_unused_fd_failed; - } - task_fd_install(target_proc, target_fd, file); - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld -> %d\n", fp->handle, target_fd); - /* TODO: fput? */ - fp->handle = target_fd; - } break; - - default: - binder_user_error("binder: %d:%d got transactio" - "n with invalid object type, %lx\n", - proc->pid, thread->pid, fp->type); - return_error = BR_FAILED_REPLY; - goto err_bad_object_type; - } - } - if (reply) { - BUG_ON(t->buffer->async_transaction != 0); - binder_pop_transaction(target_thread, in_reply_to); - } else if (!(t->flags & TF_ONE_WAY)) { - BUG_ON(t->buffer->async_transaction != 0); - t->need_reply = 1; - t->from_parent = thread->transaction_stack; - thread->transaction_stack = t; - } else { - BUG_ON(target_node == NULL); - BUG_ON(t->buffer->async_transaction != 1); - if (target_node->has_async_transaction) { - target_list = &target_node->async_todo; - target_wait = NULL; - } else - target_node->has_async_transaction = 1; - } - t->work.type = BINDER_WORK_TRANSACTION; - list_add_tail(&t->work.entry, target_list); - tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; - list_add_tail(&tcomplete->entry, &thread->todo); - if (target_wait) - wake_up_interruptible(target_wait); - return; - -err_get_unused_fd_failed: -err_fget_failed: -err_fd_not_allowed: -err_binder_get_ref_for_node_failed: -err_binder_get_ref_failed: -err_binder_new_node_failed: -err_bad_object_type: -err_bad_offset: -err_copy_data_failed: - binder_transaction_buffer_release(target_proc, t->buffer, offp); - t->buffer->transaction = NULL; - binder_free_buf(target_proc, t->buffer); -err_binder_alloc_buf_failed: - kfree(tcomplete); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -err_alloc_tcomplete_failed: - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -err_alloc_t_failed: -err_bad_call_stack: -err_empty_call_stack: -err_dead_binder: -err_invalid_target_handle: -err_no_context_mgr_node: - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d transaction failed %d, size %zd-%zd\n", - proc->pid, thread->pid, return_error, - tr->data_size, tr->offsets_size); - - { - struct binder_transaction_log_entry *fe; - fe = binder_transaction_log_add(&binder_transaction_log_failed); - *fe = *e; - } - - BUG_ON(thread->return_error != BR_OK); - if (in_reply_to) { - thread->return_error = BR_TRANSACTION_COMPLETE; - binder_send_failed_reply(in_reply_to, return_error); - } else - thread->return_error = return_error; -} - -int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, - void __user *buffer, int size, signed long *consumed) -{ - uint32_t cmd; - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - while (ptr < end && thread->return_error == BR_OK) { - if (get_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { - binder_stats.bc[_IOC_NR(cmd)]++; - proc->stats.bc[_IOC_NR(cmd)]++; - thread->stats.bc[_IOC_NR(cmd)]++; - } - switch (cmd) { - case BC_INCREFS: - case BC_ACQUIRE: - case BC_RELEASE: - case BC_DECREFS: { - uint32_t target; - struct binder_ref *ref; - const char *debug_string; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (target == 0 && binder_context_mgr_node && - (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { - ref = binder_get_ref_for_node(proc, - binder_context_mgr_node); - if (ref->desc != target) { - binder_user_error("binder: %d:" - "%d tried to acquire " - "reference to desc 0, " - "got %d instead\n", - proc->pid, thread->pid, - ref->desc); - } - } else - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d refcou" - "nt change on invalid ref %d\n", - proc->pid, thread->pid, target); - break; - } - switch (cmd) { - case BC_INCREFS: - debug_string = "IncRefs"; - binder_inc_ref(ref, 0, NULL); - break; - case BC_ACQUIRE: - debug_string = "Acquire"; - binder_inc_ref(ref, 1, NULL); - break; - case BC_RELEASE: - debug_string = "Release"; - binder_dec_ref(ref, 1); - break; - case BC_DECREFS: - default: - debug_string = "DecRefs"; - binder_dec_ref(ref, 0); - break; - } - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, debug_string, ref->debug_id, - ref->desc, ref->strong, ref->weak, ref->node->debug_id); - break; - } - case BC_INCREFS_DONE: - case BC_ACQUIRE_DONE: { - void __user *node_ptr; - void *cookie; - struct binder_node *node; - - if (get_user(node_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (get_user(cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - node = binder_get_node(proc, node_ptr); - if (node == NULL) { - binder_user_error("binder: %d:%d " - "%s u%p no match\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : - "BC_ACQUIRE_DONE", - node_ptr); - break; - } - if (cookie != node->cookie) { - binder_user_error("binder: %d:%d %s u%p node %d" - " cookie mismatch %p != %p\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node_ptr, node->debug_id, - cookie, node->cookie); - break; - } - if (cmd == BC_ACQUIRE_DONE) { - if (node->pending_strong_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_ACQUIRE_DONE node %d has " - "no pending acquire request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_strong_ref = 0; - } else { - if (node->pending_weak_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_INCREFS_DONE node %d has " - "no pending increfs request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_weak_ref = 0; - } - binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s node %d ls %d lw %d\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node->debug_id, node->local_strong_refs, node->local_weak_refs); - break; - } - case BC_ATTEMPT_ACQUIRE: - printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n"); - return -EINVAL; - case BC_ACQUIRE_RESULT: - printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n"); - return -EINVAL; - - case BC_FREE_BUFFER: { - void __user *data_ptr; - struct binder_buffer *buffer; - - if (get_user(data_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - buffer = binder_buffer_lookup(proc, data_ptr); - if (buffer == NULL) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p no match\n", - proc->pid, thread->pid, data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p matched " - "unreturned buffer\n", - proc->pid, thread->pid, data_ptr); - break; - } - binder_debug(BINDER_DEBUG_FREE_BUFFER, - "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", - proc->pid, thread->pid, data_ptr, buffer->debug_id, - buffer->transaction ? "active" : "finished"); - - if (buffer->transaction) { - buffer->transaction->buffer = NULL; - buffer->transaction = NULL; - } - if (buffer->async_transaction && buffer->target_node) { - BUG_ON(!buffer->target_node->has_async_transaction); - if (list_empty(&buffer->target_node->async_todo)) - buffer->target_node->has_async_transaction = 0; - else - list_move_tail(buffer->target_node->async_todo.next, &thread->todo); - } - binder_transaction_buffer_release(proc, buffer, NULL); - binder_free_buf(proc, buffer); - break; - } - - case BC_TRANSACTION: - case BC_REPLY: { - struct binder_transaction_data tr; - - if (copy_from_user(&tr, ptr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - binder_transaction(proc, thread, &tr, cmd == BC_REPLY); - break; - } - - case BC_REGISTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "after BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - } else if (proc->requested_threads == 0) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "without request\n", - proc->pid, thread->pid); - } else { - proc->requested_threads--; - proc->requested_threads_started++; - } - thread->looper |= BINDER_LOOPER_STATE_REGISTERED; - break; - case BC_ENTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_ENTER_LOOPER called after " - "BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - } - thread->looper |= BINDER_LOOPER_STATE_ENTERED; - break; - case BC_EXIT_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_EXIT_LOOPER\n", - proc->pid, thread->pid); - thread->looper |= BINDER_LOOPER_STATE_EXITED; - break; - - case BC_REQUEST_DEATH_NOTIFICATION: - case BC_CLEAR_DEATH_NOTIFICATION: { - uint32_t target; - void __user *cookie; - struct binder_ref *ref; - struct binder_ref_death *death; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d %s " - "invalid ref %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - target); - break; - } - - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - cookie, ref->debug_id, ref->desc, - ref->strong, ref->weak, ref->node->debug_id); - - if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { - if (ref->death) { - binder_user_error("binder: %d:%" - "d BC_REQUEST_DEATH_NOTI" - "FICATION death notific" - "ation already set\n", - proc->pid, thread->pid); - break; - } - death = kzalloc(sizeof(*death), GFP_KERNEL); - if (death == NULL) { - thread->return_error = BR_ERROR; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d " - "BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); - break; - } - binder_stats_created(BINDER_STAT_DEATH); - INIT_LIST_HEAD(&death->work.entry); - death->cookie = cookie; - ref->death = death; - if (ref->node->proc == NULL) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&ref->death->work.entry, &thread->todo); - } else { - list_add_tail(&ref->death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } else { - if (ref->death == NULL) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion not active\n", - proc->pid, thread->pid); - break; - } - death = ref->death; - if (death->cookie != cookie) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion cookie mismatch " - "%p != %p\n", - proc->pid, thread->pid, - death->cookie, cookie); - break; - } - ref->death = NULL; - if (list_empty(&death->work.entry)) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } else { - BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); - death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; - } - } - } break; - case BC_DEAD_BINDER_DONE: { - struct binder_work *w; - void __user *cookie; - struct binder_ref_death *death = NULL; - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - - ptr += sizeof(void *); - list_for_each_entry(w, &proc->delivered_death, entry) { - struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); - if (tmp_death->cookie == cookie) { - death = tmp_death; - break; - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", - proc->pid, thread->pid, cookie, death); - if (death == NULL) { - binder_user_error("binder: %d:%d BC_DEAD" - "_BINDER_DONE %p not found\n", - proc->pid, thread->pid, cookie); - break; - } - - list_del_init(&death->work.entry); - if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } break; - - default: - printk(KERN_ERR "binder: %d:%d unknown command %d\n", - proc->pid, thread->pid, cmd); - return -EINVAL; - } - *consumed = ptr - buffer; - } - return 0; -} - -void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, - uint32_t cmd) -{ - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { - binder_stats.br[_IOC_NR(cmd)]++; - proc->stats.br[_IOC_NR(cmd)]++; - thread->stats.br[_IOC_NR(cmd)]++; - } -} - -static int binder_has_proc_work(struct binder_proc *proc, - struct binder_thread *thread) -{ - return !list_empty(&proc->todo) || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_has_thread_work(struct binder_thread *thread) -{ - return !list_empty(&thread->todo) || thread->return_error != BR_OK || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_thread_read(struct binder_proc *proc, - struct binder_thread *thread, - void __user *buffer, int size, - signed long *consumed, int non_block) -{ - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - int ret = 0; - int wait_for_proc_work; - - if (*consumed == 0) { - if (put_user(BR_NOOP, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - } - -retry: - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo); - - if (thread->return_error != BR_OK && ptr < end) { - if (thread->return_error2 != BR_OK) { - if (put_user(thread->return_error2, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (ptr == end) - goto done; - thread->return_error2 = BR_OK; - } - if (put_user(thread->return_error, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - thread->return_error = BR_OK; - goto done; - } - - - thread->looper |= BINDER_LOOPER_STATE_WAITING; - if (wait_for_proc_work) - proc->ready_threads++; - mutex_unlock(&binder_lock); - if (wait_for_proc_work) { - if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED))) { - binder_user_error("binder: %d:%d ERROR: Thread waiting " - "for process work before calling BC_REGISTER_" - "LOOPER or BC_ENTER_LOOPER (state %x)\n", - proc->pid, thread->pid, thread->looper); - wait_event_interruptible(binder_user_error_wait, - binder_stop_on_user_error < 2); - } - binder_set_nice(proc->default_priority); - if (non_block) { - if (!binder_has_proc_work(proc, thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread)); - } else { - if (non_block) { - if (!binder_has_thread_work(thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); - } - mutex_lock(&binder_lock); - if (wait_for_proc_work) - proc->ready_threads--; - thread->looper &= ~BINDER_LOOPER_STATE_WAITING; - - if (ret) - return ret; - - while (1) { - uint32_t cmd; - struct binder_transaction_data tr; - struct binder_work *w; - struct binder_transaction *t = NULL; - - if (!list_empty(&thread->todo)) - w = list_first_entry(&thread->todo, struct binder_work, entry); - else if (!list_empty(&proc->todo) && wait_for_proc_work) - w = list_first_entry(&proc->todo, struct binder_work, entry); - else { - if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */ - goto retry; - break; - } - - if (end - ptr < sizeof(tr) + 4) - break; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - t = container_of(w, struct binder_transaction, work); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - cmd = BR_TRANSACTION_COMPLETE; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, - "binder: %d:%d BR_TRANSACTION_COMPLETE\n", - proc->pid, thread->pid); - - list_del(&w->entry); - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - case BINDER_WORK_NODE: { - struct binder_node *node = container_of(w, struct binder_node, work); - uint32_t cmd = BR_NOOP; - const char *cmd_name; - int strong = node->internal_strong_refs || node->local_strong_refs; - int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong; - if (weak && !node->has_weak_ref) { - cmd = BR_INCREFS; - cmd_name = "BR_INCREFS"; - node->has_weak_ref = 1; - node->pending_weak_ref = 1; - node->local_weak_refs++; - } else if (strong && !node->has_strong_ref) { - cmd = BR_ACQUIRE; - cmd_name = "BR_ACQUIRE"; - node->has_strong_ref = 1; - node->pending_strong_ref = 1; - node->local_strong_refs++; - } else if (!strong && node->has_strong_ref) { - cmd = BR_RELEASE; - cmd_name = "BR_RELEASE"; - node->has_strong_ref = 0; - } else if (!weak && node->has_weak_ref) { - cmd = BR_DECREFS; - cmd_name = "BR_DECREFS"; - node->has_weak_ref = 0; - } - if (cmd != BR_NOOP) { - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(node->ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (put_user(node->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s %d u%p c%p\n", - proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); - } else { - list_del_init(&w->entry); - if (!weak && !strong) { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p deleted\n", - proc->pid, thread->pid, node->debug_id, - node->ptr, node->cookie); - rb_erase(&node->rb_node, &proc->nodes); - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p state unchanged\n", - proc->pid, thread->pid, node->debug_id, node->ptr, - node->cookie); - } - } - } break; - case BINDER_WORK_DEAD_BINDER: - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { - struct binder_ref_death *death; - uint32_t cmd; - - death = container_of(w, struct binder_ref_death, work); - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) - cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; - else - cmd = BR_DEAD_BINDER; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(death->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p\n", - proc->pid, thread->pid, - cmd == BR_DEAD_BINDER ? - "BR_DEAD_BINDER" : - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - death->cookie); - - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { - list_del(&w->entry); - kfree(death); - binder_stats_deleted(BINDER_STAT_DEATH); - } else - list_move(&w->entry, &proc->delivered_death); - if (cmd == BR_DEAD_BINDER) - goto done; /* DEAD_BINDER notifications can cause transactions */ - } break; - } - - if (!t) - continue; - - BUG_ON(t->buffer == NULL); - if (t->buffer->target_node) { - struct binder_node *target_node = t->buffer->target_node; - tr.target.ptr = target_node->ptr; - tr.cookie = target_node->cookie; - t->saved_priority = task_nice(current); - if (t->priority < target_node->min_priority && - !(t->flags & TF_ONE_WAY)) - binder_set_nice(t->priority); - else if (!(t->flags & TF_ONE_WAY) || - t->saved_priority > target_node->min_priority) - binder_set_nice(target_node->min_priority); - cmd = BR_TRANSACTION; - } else { - tr.target.ptr = NULL; - tr.cookie = NULL; - cmd = BR_REPLY; - } - tr.code = t->code; - tr.flags = t->flags; - tr.sender_euid = t->sender_euid; - - if (t->from) { - struct task_struct *sender = t->from->proc->tsk; - tr.sender_pid = task_tgid_nr_ns(sender, - current->nsproxy->pid_ns); - } else { - tr.sender_pid = 0; - } - - tr.data_size = t->buffer->data_size; - tr.offsets_size = t->buffer->offsets_size; - tr.data.ptr.buffer = (void *)t->buffer->data + - proc->user_buffer_offset; - tr.data.ptr.offsets = tr.data.ptr.buffer + - ALIGN(t->buffer->data_size, - sizeof(void *)); - - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (copy_to_user(ptr, &tr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d %s %d %d:%d, cmd %d" - "size %zd-%zd ptr %p-%p\n", - proc->pid, thread->pid, - (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : - "BR_REPLY", - t->debug_id, t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, cmd, - t->buffer->data_size, t->buffer->offsets_size, - tr.data.ptr.buffer, tr.data.ptr.offsets); - - list_del(&t->work.entry); - t->buffer->allow_user_free = 1; - if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { - t->to_parent = thread->transaction_stack; - t->to_thread = thread; - thread->transaction_stack = t; - } else { - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); - } - break; - } - -done: - - *consumed = ptr - buffer; - if (proc->requested_threads + proc->ready_threads == 0 && - proc->requested_threads_started < proc->max_threads && - (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ - /*spawn a new thread if we leave this out */) { - proc->requested_threads++; - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BR_SPAWN_LOOPER\n", - proc->pid, thread->pid); - if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) - return -EFAULT; - } - return 0; -} - -static void binder_release_work(struct list_head *list) -{ - struct binder_work *w; - while (!list_empty(list)) { - w = list_first_entry(list, struct binder_work, entry); - list_del_init(&w->entry); - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - struct binder_transaction *t; - - t = container_of(w, struct binder_transaction, work); - if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) - binder_send_failed_reply(t, BR_DEAD_REPLY); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - default: - break; - } - } - -} - -static struct binder_thread *binder_get_thread(struct binder_proc *proc) -{ - struct binder_thread *thread = NULL; - struct rb_node *parent = NULL; - struct rb_node **p = &proc->threads.rb_node; - - while (*p) { - parent = *p; - thread = rb_entry(parent, struct binder_thread, rb_node); - - if (current->pid < thread->pid) - p = &(*p)->rb_left; - else if (current->pid > thread->pid) - p = &(*p)->rb_right; - else - break; - } - if (*p == NULL) { - thread = kzalloc(sizeof(*thread), GFP_KERNEL); - if (thread == NULL) - return NULL; - binder_stats_created(BINDER_STAT_THREAD); - thread->proc = proc; - thread->pid = current->pid; - init_waitqueue_head(&thread->wait); - INIT_LIST_HEAD(&thread->todo); - rb_link_node(&thread->rb_node, parent, p); - rb_insert_color(&thread->rb_node, &proc->threads); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - thread->return_error = BR_OK; - thread->return_error2 = BR_OK; - } - return thread; -} - -static int binder_free_thread(struct binder_proc *proc, - struct binder_thread *thread) -{ - struct binder_transaction *t; - struct binder_transaction *send_reply = NULL; - int active_transactions = 0; - - rb_erase(&thread->rb_node, &proc->threads); - t = thread->transaction_stack; - if (t && t->to_thread == thread) - send_reply = t; - while (t) { - active_transactions++; - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: release %d:%d transaction %d " - "%s, still active\n", proc->pid, thread->pid, - t->debug_id, - (t->to_thread == thread) ? "in" : "out"); - - if (t->to_thread == thread) { - t->to_proc = NULL; - t->to_thread = NULL; - if (t->buffer) { - t->buffer->transaction = NULL; - t->buffer = NULL; - } - t = t->to_parent; - } else if (t->from == thread) { - t->from = NULL; - t = t->from_parent; - } else - BUG(); - } - if (send_reply) - binder_send_failed_reply(send_reply, BR_DEAD_REPLY); - binder_release_work(&thread->todo); - kfree(thread); - binder_stats_deleted(BINDER_STAT_THREAD); - return active_transactions; -} - -static unsigned int binder_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread = NULL; - int wait_for_proc_work; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo) && thread->return_error == BR_OK; - mutex_unlock(&binder_lock); - - if (wait_for_proc_work) { - if (binder_has_proc_work(proc, thread)) - return POLLIN; - poll_wait(filp, &proc->wait, wait); - if (binder_has_proc_work(proc, thread)) - return POLLIN; - } else { - if (binder_has_thread_work(thread)) - return POLLIN; - poll_wait(filp, &thread->wait, wait); - if (binder_has_thread_work(thread)) - return POLLIN; - } - return 0; -} - -static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret; - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread; - unsigned int size = _IOC_SIZE(cmd); - void __user *ubuf = (void __user *)arg; - - /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ - - ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret) - return ret; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - if (thread == NULL) { - ret = -ENOMEM; - goto err; - } - - switch (cmd) { - case BINDER_WRITE_READ: { - struct binder_write_read bwr; - if (size != sizeof(struct binder_write_read)) { - ret = -EINVAL; - goto err; - } - if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", - proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, - bwr.read_size, bwr.read_buffer); - - if (bwr.write_size > 0) { - ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); - if (ret < 0) { - bwr.read_consumed = 0; - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - if (bwr.read_size > 0) { - ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); - if (!list_empty(&proc->todo)) - wake_up_interruptible(&proc->wait); - if (ret < 0) { - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", - proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, - bwr.read_consumed, bwr.read_size); - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - break; - } - case BINDER_SET_MAX_THREADS: - if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { - ret = -EINVAL; - goto err; - } - break; - case BINDER_SET_CONTEXT_MGR: - if (binder_context_mgr_node != NULL) { - printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); - ret = -EBUSY; - goto err; - } - if (binder_context_mgr_uid != -1) { - if (binder_context_mgr_uid != current->cred->euid) { - printk(KERN_ERR "binder: BINDER_SET_" - "CONTEXT_MGR bad uid %d != %d\n", - current->cred->euid, - binder_context_mgr_uid); - ret = -EPERM; - goto err; - } - } else - binder_context_mgr_uid = current->cred->euid; - binder_context_mgr_node = binder_new_node(proc, NULL, NULL); - if (binder_context_mgr_node == NULL) { - ret = -ENOMEM; - goto err; - } - binder_context_mgr_node->local_weak_refs++; - binder_context_mgr_node->local_strong_refs++; - binder_context_mgr_node->has_strong_ref = 1; - binder_context_mgr_node->has_weak_ref = 1; - break; - case BINDER_THREAD_EXIT: - binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", - proc->pid, thread->pid); - binder_free_thread(proc, thread); - thread = NULL; - break; - case BINDER_VERSION: - if (size != sizeof(struct binder_version)) { - ret = -EINVAL; - goto err; - } - if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) { - ret = -EINVAL; - goto err; - } - break; - default: - ret = -EINVAL; - goto err; - } - ret = 0; -err: - if (thread) - thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; - mutex_unlock(&binder_lock); - wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret && ret != -ERESTARTSYS) - printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); - return ret; -} - -static void binder_vma_open(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - dump_stack(); -} - -static void binder_vma_close(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - proc->vma = NULL; - binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); -} - -static struct vm_operations_struct binder_vm_ops = { - .open = binder_vma_open, - .close = binder_vma_close, -}; - -static int binder_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - struct vm_struct *area; - struct binder_proc *proc = filp->private_data; - const char *failure_string; - struct binder_buffer *buffer; - - if ((vma->vm_end - vma->vm_start) > SZ_4M) - vma->vm_end = vma->vm_start + SZ_4M; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - - if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { - ret = -EPERM; - failure_string = "bad vm_flags"; - goto err_bad_arg; - } - vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; - - if (proc->buffer) { - ret = -EBUSY; - failure_string = "already mapped"; - goto err_already_mapped; - } - - area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); - if (area == NULL) { - ret = -ENOMEM; - failure_string = "get_vm_area"; - goto err_get_vm_area_failed; - } - proc->buffer = area->addr; - proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; - -#ifdef CONFIG_CPU_CACHE_VIPT - if (cache_is_vipt_aliasing()) { - while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { - printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); - vma->vm_start += PAGE_SIZE; - } - } -#endif - proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL); - if (proc->pages == NULL) { - ret = -ENOMEM; - failure_string = "alloc page array"; - goto err_alloc_pages_failed; - } - proc->buffer_size = vma->vm_end - vma->vm_start; - - vma->vm_ops = &binder_vm_ops; - vma->vm_private_data = proc; - - if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { - ret = -ENOMEM; - failure_string = "alloc small buf"; - goto err_alloc_small_buf_failed; - } - buffer = proc->buffer; - INIT_LIST_HEAD(&proc->buffers); - list_add(&buffer->entry, &proc->buffers); - buffer->free = 1; - binder_insert_free_buffer(proc, buffer); - proc->free_async_space = proc->buffer_size / 2; - barrier(); - proc->files = get_files_struct(current); - proc->vma = vma; - - /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", - proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ - return 0; - -err_alloc_small_buf_failed: - kfree(proc->pages); - proc->pages = NULL; -err_alloc_pages_failed: - vfree(proc->buffer); - proc->buffer = NULL; -err_get_vm_area_failed: -err_already_mapped: -err_bad_arg: - printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", - proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); - return ret; -} - -static int binder_open(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", - current->group_leader->pid, current->pid); - - proc = kzalloc(sizeof(*proc), GFP_KERNEL); - if (proc == NULL) - return -ENOMEM; - get_task_struct(current); - proc->tsk = current; - INIT_LIST_HEAD(&proc->todo); - init_waitqueue_head(&proc->wait); - proc->default_priority = task_nice(current); - mutex_lock(&binder_lock); - binder_stats_created(BINDER_STAT_PROC); - hlist_add_head(&proc->proc_node, &binder_procs); - proc->pid = current->group_leader->pid; - INIT_LIST_HEAD(&proc->delivered_death); - filp->private_data = proc; - mutex_unlock(&binder_lock); - - if (binder_debugfs_dir_entry_proc) { - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); - proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, - binder_debugfs_dir_entry_proc, proc, &binder_proc_fops); - } - - return 0; -} - -static int binder_flush(struct file *filp, fl_owner_t id) -{ - struct binder_proc *proc = filp->private_data; - - binder_defer_work(proc, BINDER_DEFERRED_FLUSH); - - return 0; -} - -static void binder_deferred_flush(struct binder_proc *proc) -{ - struct rb_node *n; - int wake_count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - if (thread->looper & BINDER_LOOPER_STATE_WAITING) { - wake_up_interruptible(&thread->wait); - wake_count++; - } - } - wake_up_interruptible_all(&proc->wait); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_flush: %d woke %d threads\n", proc->pid, - wake_count); -} - -static int binder_release(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc = filp->private_data; - debugfs_remove(proc->debugfs_entry); - binder_defer_work(proc, BINDER_DEFERRED_RELEASE); - - return 0; -} - -static void binder_deferred_release(struct binder_proc *proc) -{ - struct hlist_node *pos; - struct binder_transaction *t; - struct rb_node *n; - int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; - - BUG_ON(proc->vma); - BUG_ON(proc->files); - - hlist_del(&proc->proc_node); - if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder_release: %d context_mgr_node gone\n", - proc->pid); - binder_context_mgr_node = NULL; - } - - threads = 0; - active_transactions = 0; - while ((n = rb_first(&proc->threads))) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - threads++; - active_transactions += binder_free_thread(proc, thread); - } - nodes = 0; - incoming_refs = 0; - while ((n = rb_first(&proc->nodes))) { - struct binder_node *node = rb_entry(n, struct binder_node, rb_node); - - nodes++; - rb_erase(&node->rb_node, &proc->nodes); - list_del_init(&node->work.entry); - if (hlist_empty(&node->refs)) { - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - struct binder_ref *ref; - int death = 0; - - node->proc = NULL; - node->local_strong_refs = 0; - node->local_weak_refs = 0; - hlist_add_head(&node->dead_node, &binder_dead_nodes); - - hlist_for_each_entry(ref, pos, &node->refs, node_entry) { - incoming_refs++; - if (ref->death) { - death++; - if (list_empty(&ref->death->work.entry)) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - list_add_tail(&ref->death->work.entry, &ref->proc->todo); - wake_up_interruptible(&ref->proc->wait); - } else - BUG(); - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: node %d now dead, " - "refs %d, death %d\n", node->debug_id, - incoming_refs, death); - } - } - outgoing_refs = 0; - while ((n = rb_first(&proc->refs_by_desc))) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - outgoing_refs++; - binder_delete_ref(ref); - } - binder_release_work(&proc->todo); - buffers = 0; - - while ((n = rb_first(&proc->allocated_buffers))) { - struct binder_buffer *buffer = rb_entry(n, struct binder_buffer, - rb_node); - t = buffer->transaction; - if (t) { - t->buffer = NULL; - buffer->transaction = NULL; - printk(KERN_ERR "binder: release proc %d, " - "transaction %d, not freed\n", - proc->pid, t->debug_id); - /*BUG();*/ - } - binder_free_buf(proc, buffer); - buffers++; - } - - binder_stats_deleted(BINDER_STAT_PROC); - - page_count = 0; - if (proc->pages) { - int i; - for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { - if (proc->pages[i]) { - void *page_addr = proc->buffer + i * PAGE_SIZE; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder_release: %d: " - "page %d at %p not freed\n", - proc->pid, i, - page_addr); - unmap_kernel_range((unsigned long)page_addr, - PAGE_SIZE); - __free_page(proc->pages[i]); - page_count++; - } - } - kfree(proc->pages); - vfree(proc->buffer); - } - - put_task_struct(proc->tsk); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_release: %d threads %d, nodes %d (ref %d), " - "refs %d, active transactions %d, buffers %d, " - "pages %d\n", - proc->pid, threads, nodes, incoming_refs, outgoing_refs, - active_transactions, buffers, page_count); - - kfree(proc); -} - -static void binder_deferred_func(struct work_struct *work) -{ - struct binder_proc *proc; - struct files_struct *files; - - int defer; - do { - mutex_lock(&binder_lock); - mutex_lock(&binder_deferred_lock); - if (!hlist_empty(&binder_deferred_list)) { - proc = hlist_entry(binder_deferred_list.first, - struct binder_proc, deferred_work_node); - hlist_del_init(&proc->deferred_work_node); - defer = proc->deferred_work; - proc->deferred_work = 0; - } else { - proc = NULL; - defer = 0; - } - mutex_unlock(&binder_deferred_lock); - - files = NULL; - if (defer & BINDER_DEFERRED_PUT_FILES) { - files = proc->files; - if (files) - proc->files = NULL; - } - - if (defer & BINDER_DEFERRED_FLUSH) - binder_deferred_flush(proc); - - if (defer & BINDER_DEFERRED_RELEASE) - binder_deferred_release(proc); /* frees proc */ - - mutex_unlock(&binder_lock); - if (files) - put_files_struct(files); - } while (proc); -} -static DECLARE_WORK(binder_deferred_work, binder_deferred_func); - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) -{ - mutex_lock(&binder_deferred_lock); - proc->deferred_work |= defer; - if (hlist_unhashed(&proc->deferred_work_node)) { - hlist_add_head(&proc->deferred_work_node, - &binder_deferred_list); - queue_work(binder_deferred_workqueue, &binder_deferred_work); - } - mutex_unlock(&binder_deferred_lock); -} - -static void print_binder_transaction(struct seq_file *m, const char *prefix, - struct binder_transaction *t) -{ - seq_printf(m, - "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d", - prefix, t->debug_id, t, - t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, - t->to_proc ? t->to_proc->pid : 0, - t->to_thread ? t->to_thread->pid : 0, - t->code, t->flags, t->priority, t->need_reply); - if (t->buffer == NULL) { - seq_puts(m, " buffer free\n"); - return; - } - if (t->buffer->target_node) - seq_printf(m, " node %d", - t->buffer->target_node->debug_id); - seq_printf(m, " size %zd:%zd data %p\n", - t->buffer->data_size, t->buffer->offsets_size, - t->buffer->data); -} - -static void print_binder_buffer(struct seq_file *m, const char *prefix, - struct binder_buffer *buffer) -{ - seq_printf(m, "%s %d: %p size %zd:%zd %s\n", - prefix, buffer->debug_id, buffer->data, - buffer->data_size, buffer->offsets_size, - buffer->transaction ? "active" : "delivered"); -} - -static void print_binder_work(struct seq_file *m, const char *prefix, - const char *transaction_prefix, - struct binder_work *w) -{ - struct binder_node *node; - struct binder_transaction *t; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: - t = container_of(w, struct binder_transaction, work); - print_binder_transaction(m, transaction_prefix, t); - break; - case BINDER_WORK_TRANSACTION_COMPLETE: - seq_printf(m, "%stransaction complete\n", prefix); - break; - case BINDER_WORK_NODE: - node = container_of(w, struct binder_node, work); - seq_printf(m, "%snode work %d: u%p c%p\n", - prefix, node->debug_id, node->ptr, node->cookie); - break; - case BINDER_WORK_DEAD_BINDER: - seq_printf(m, "%shas dead binder\n", prefix); - break; - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - seq_printf(m, "%shas cleared dead binder\n", prefix); - break; - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: - seq_printf(m, "%shas cleared death notification\n", prefix); - break; - default: - seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); - break; - } -} - -static void print_binder_thread(struct seq_file *m, - struct binder_thread *thread, - int print_always) -{ - struct binder_transaction *t; - struct binder_work *w; - size_t start_pos = m->count; - size_t header_pos; - - seq_printf(m, " thread %d: l %02x\n", thread->pid, thread->looper); - header_pos = m->count; - t = thread->transaction_stack; - while (t) { - if (t->from == thread) { - print_binder_transaction(m, - " outgoing transaction", t); - t = t->from_parent; - } else if (t->to_thread == thread) { - print_binder_transaction(m, - " incoming transaction", t); - t = t->to_parent; - } else { - print_binder_transaction(m, " bad transaction", t); - t = NULL; - } - } - list_for_each_entry(w, &thread->todo, entry) { - print_binder_work(m, " ", " pending transaction", w); - } - if (!print_always && m->count == header_pos) - m->count = start_pos; -} - -static void print_binder_node(struct seq_file *m, struct binder_node *node) -{ - struct binder_ref *ref; - struct hlist_node *pos; - struct binder_work *w; - int count; - - count = 0; - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - count++; - - seq_printf(m, " node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d", - node->debug_id, node->ptr, node->cookie, - node->has_strong_ref, node->has_weak_ref, - node->local_strong_refs, node->local_weak_refs, - node->internal_strong_refs, count); - if (count) { - seq_puts(m, " proc"); - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - seq_printf(m, " %d", ref->proc->pid); - } - seq_puts(m, "\n"); - list_for_each_entry(w, &node->async_todo, entry) - print_binder_work(m, " ", - " pending async transaction", w); -} - -static void print_binder_ref(struct seq_file *m, struct binder_ref *ref) -{ - seq_printf(m, " ref %d: desc %d %snode %d s %d w %d d %p\n", - ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ", - ref->node->debug_id, ref->strong, ref->weak, ref->death); -} - -static void print_binder_proc(struct seq_file *m, - struct binder_proc *proc, int print_all) -{ - struct binder_work *w; - struct rb_node *n; - size_t start_pos = m->count; - size_t header_pos; - - seq_printf(m, "proc %d\n", proc->pid); - header_pos = m->count; - - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - print_binder_thread(m, rb_entry(n, struct binder_thread, - rb_node), print_all); - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { - struct binder_node *node = rb_entry(n, struct binder_node, - rb_node); - if (print_all || node->has_async_transaction) - print_binder_node(m, node); - } - if (print_all) { - for (n = rb_first(&proc->refs_by_desc); - n != NULL; - n = rb_next(n)) - print_binder_ref(m, rb_entry(n, struct binder_ref, - rb_node_desc)); - } - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - print_binder_buffer(m, " buffer", - rb_entry(n, struct binder_buffer, rb_node)); - list_for_each_entry(w, &proc->todo, entry) - print_binder_work(m, " ", " pending transaction", w); - list_for_each_entry(w, &proc->delivered_death, entry) { - seq_puts(m, " has delivered dead binder\n"); - break; - } - if (!print_all && m->count == header_pos) - m->count = start_pos; -} - -static const char *binder_return_strings[] = { - "BR_ERROR", - "BR_OK", - "BR_TRANSACTION", - "BR_REPLY", - "BR_ACQUIRE_RESULT", - "BR_DEAD_REPLY", - "BR_TRANSACTION_COMPLETE", - "BR_INCREFS", - "BR_ACQUIRE", - "BR_RELEASE", - "BR_DECREFS", - "BR_ATTEMPT_ACQUIRE", - "BR_NOOP", - "BR_SPAWN_LOOPER", - "BR_FINISHED", - "BR_DEAD_BINDER", - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - "BR_FAILED_REPLY" -}; - -static const char *binder_command_strings[] = { - "BC_TRANSACTION", - "BC_REPLY", - "BC_ACQUIRE_RESULT", - "BC_FREE_BUFFER", - "BC_INCREFS", - "BC_ACQUIRE", - "BC_RELEASE", - "BC_DECREFS", - "BC_INCREFS_DONE", - "BC_ACQUIRE_DONE", - "BC_ATTEMPT_ACQUIRE", - "BC_REGISTER_LOOPER", - "BC_ENTER_LOOPER", - "BC_EXIT_LOOPER", - "BC_REQUEST_DEATH_NOTIFICATION", - "BC_CLEAR_DEATH_NOTIFICATION", - "BC_DEAD_BINDER_DONE" -}; - -static const char *binder_objstat_strings[] = { - "proc", - "thread", - "node", - "ref", - "death", - "transaction", - "transaction_complete" -}; - -static void print_binder_stats(struct seq_file *m, const char *prefix, - struct binder_stats *stats) -{ - int i; - - BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != - ARRAY_SIZE(binder_command_strings)); - for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { - if (stats->bc[i]) - seq_printf(m, "%s%s: %d\n", prefix, - binder_command_strings[i], stats->bc[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->br) != - ARRAY_SIZE(binder_return_strings)); - for (i = 0; i < ARRAY_SIZE(stats->br); i++) { - if (stats->br[i]) - seq_printf(m, "%s%s: %d\n", prefix, - binder_return_strings[i], stats->br[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(binder_objstat_strings)); - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(stats->obj_deleted)); - for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { - if (stats->obj_created[i] || stats->obj_deleted[i]) - seq_printf(m, "%s%s: active %d total %d\n", prefix, - binder_objstat_strings[i], - stats->obj_created[i] - stats->obj_deleted[i], - stats->obj_created[i]); - } -} - -static void print_binder_proc_stats(struct seq_file *m, - struct binder_proc *proc) -{ - struct binder_work *w; - struct rb_node *n; - int count, strong, weak; - - seq_printf(m, "proc %d\n", proc->pid); - count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " threads: %d\n", count); - seq_printf(m, " requested threads: %d+%d/%d\n" - " ready threads %d\n" - " free async space %zd\n", proc->requested_threads, - proc->requested_threads_started, proc->max_threads, - proc->ready_threads, proc->free_async_space); - count = 0; - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " nodes: %d\n", count); - count = 0; - strong = 0; - weak = 0; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - count++; - strong += ref->strong; - weak += ref->weak; - } - seq_printf(m, " refs: %d s %d w %d\n", count, strong, weak); - - count = 0; - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - count++; - seq_printf(m, " buffers: %d\n", count); - - count = 0; - list_for_each_entry(w, &proc->todo, entry) { - switch (w->type) { - case BINDER_WORK_TRANSACTION: - count++; - break; - default: - break; - } - } - seq_printf(m, " pending transactions: %d\n", count); - - print_binder_stats(m, " ", &proc->stats); -} - - -static int binder_state_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - struct binder_node *node; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder state:\n"); - - if (!hlist_empty(&binder_dead_nodes)) - seq_puts(m, "dead nodes:\n"); - hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) - print_binder_node(m, node); - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_stats_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder stats:\n"); - - print_binder_stats(m, "", &binder_stats); - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc_stats(m, proc); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_transactions_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - - seq_puts(m, "binder transactions:\n"); - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) - print_binder_proc(m, proc, 0); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static int binder_proc_show(struct seq_file *m, void *unused) -{ - struct binder_proc *proc = m->private; - int do_lock = !binder_debug_no_lock; - - if (do_lock) - mutex_lock(&binder_lock); - seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); - return 0; -} - -static void print_binder_transaction_log_entry(struct seq_file *m, - struct binder_transaction_log_entry *e) -{ - seq_printf(m, - "%d: %s from %d:%d to %d:%d node %d handle %d size %d:%d\n", - e->debug_id, (e->call_type == 2) ? "reply" : - ((e->call_type == 1) ? "async" : "call "), e->from_proc, - e->from_thread, e->to_proc, e->to_thread, e->to_node, - e->target_handle, e->data_size, e->offsets_size); -} - -static int binder_transaction_log_show(struct seq_file *m, void *unused) -{ - struct binder_transaction_log *log = m->private; - int i; - - if (log->full) { - for (i = log->next; i < ARRAY_SIZE(log->entry); i++) - print_binder_transaction_log_entry(m, &log->entry[i]); - } - for (i = 0; i < log->next; i++) - print_binder_transaction_log_entry(m, &log->entry[i]); - return 0; -} - -static const struct file_operations binder_fops = { - .owner = THIS_MODULE, - .poll = binder_poll, - .unlocked_ioctl = binder_ioctl, - .mmap = binder_mmap, - .open = binder_open, - .flush = binder_flush, - .release = binder_release, -}; - -static struct miscdevice binder_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "binder", - .fops = &binder_fops -}; - -BINDER_DEBUG_ENTRY(state); -BINDER_DEBUG_ENTRY(stats); -BINDER_DEBUG_ENTRY(transactions); -BINDER_DEBUG_ENTRY(transaction_log); - -static int __init binder_init(void) -{ - int ret; - - binder_deferred_workqueue = create_singlethread_workqueue("binder"); - if (!binder_deferred_workqueue) - return -ENOMEM; - - binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); - if (binder_debugfs_dir_entry_root) - binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", - binder_debugfs_dir_entry_root); - ret = misc_register(&binder_miscdev); - if (binder_debugfs_dir_entry_root) { - debugfs_create_file("state", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_state_fops); - debugfs_create_file("stats", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_stats_fops); - debugfs_create_file("transactions", - S_IRUGO, - binder_debugfs_dir_entry_root, - NULL, - &binder_transactions_fops); - debugfs_create_file("transaction_log", - S_IRUGO, - binder_debugfs_dir_entry_root, - &binder_transaction_log, - &binder_transaction_log_fops); - debugfs_create_file("failed_transaction_log", - S_IRUGO, - binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); - } - return ret; -} - -device_initcall(binder_init); - -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h deleted file mode 100644 index 863ae1ad5d55..000000000000 --- a/drivers/staging/android/binder.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_BINDER_H -#define _LINUX_BINDER_H - -#include - -#define B_PACK_CHARS(c1, c2, c3, c4) \ - ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -#define B_TYPE_LARGE 0x85 - -enum { - BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -}; - -enum { - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -}; - -/* - * This is the flattened representation of a Binder object for transfer - * between processes. The 'offsets' supplied as part of a binder transaction - * contains offsets into the data where these structures occur. The Binder - * driver takes care of re-writing the structure type and data as it moves - * between processes. - */ -struct flat_binder_object { - /* 8 bytes for large_flat_header. */ - unsigned long type; - unsigned long flags; - - /* 8 bytes of data. */ - union { - void *binder; /* local object */ - signed long handle; /* remote object */ - }; - - /* extra data associated with local object */ - void *cookie; -}; - -/* - * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses apropriately. - */ - -struct binder_write_read { - signed long write_size; /* bytes to write */ - signed long write_consumed; /* bytes consumed by driver */ - unsigned long write_buffer; - signed long read_size; /* bytes to read */ - signed long read_consumed; /* bytes consumed by driver */ - unsigned long read_buffer; -}; - -/* Use with BINDER_VERSION, driver fills in fields. */ -struct binder_version { - /* driver protocol version -- increment with incompatible change */ - signed long protocol_version; -}; - -/* This is the current protocol version. */ -#define BINDER_CURRENT_PROTOCOL_VERSION 7 - -#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) -#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int) -#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int) -#define BINDER_THREAD_EXIT _IOW('b', 8, int) -#define BINDER_VERSION _IOWR('b', 9, struct binder_version) - -/* - * NOTE: Two special error codes you should check for when calling - * in to the driver are: - * - * EINTR -- The operation has been interupted. This should be - * handled by retrying the ioctl() until a different error code - * is returned. - * - * ECONNREFUSED -- The driver is no longer accepting operations - * from your process. That is, the process is being destroyed. - * You should handle this by exiting from your process. Note - * that once this error code is returned, all further calls to - * the driver from any thread will return this same code. - */ - -enum transaction_flags { - TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ - TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ - TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ - TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -}; - -struct binder_transaction_data { - /* The first two are only used for bcTRANSACTION and brTRANSACTION, - * identifying the target and contents of the transaction. - */ - union { - size_t handle; /* target descriptor of command transaction */ - void *ptr; /* target descriptor of return transaction */ - } target; - void *cookie; /* target object cookie */ - unsigned int code; /* transaction command */ - - /* General information about the transaction. */ - unsigned int flags; - pid_t sender_pid; - uid_t sender_euid; - size_t data_size; /* number of bytes of data */ - size_t offsets_size; /* number of bytes of offsets */ - - /* If this transaction is inline, the data immediately - * follows here; otherwise, it ends with a pointer to - * the data buffer. - */ - union { - struct { - /* transaction data */ - const void *buffer; - /* offsets from buffer to flat_binder_object structs */ - const void *offsets; - } ptr; - uint8_t buf[8]; - } data; -}; - -struct binder_ptr_cookie { - void *ptr; - void *cookie; -}; - -struct binder_pri_desc { - int priority; - int desc; -}; - -struct binder_pri_ptr_cookie { - int priority; - void *ptr; - void *cookie; -}; - -enum BinderDriverReturnProtocol { - BR_ERROR = _IOR('r', 0, int), - /* - * int: error code - */ - - BR_OK = _IO('r', 1), - /* No parameters! */ - - BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), - BR_REPLY = _IOR('r', 3, struct binder_transaction_data), - /* - * binder_transaction_data: the received command. - */ - - BR_ACQUIRE_RESULT = _IOR('r', 4, int), - /* - * not currently supported - * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. - * Else the remote object has acquired a primary reference. - */ - - BR_DEAD_REPLY = _IO('r', 5), - /* - * The target of the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. - */ - - BR_TRANSACTION_COMPLETE = _IO('r', 6), - /* - * No parameters... always refers to the last transaction requested - * (including replies). Note that this will be sent even for - * asynchronous transactions. - */ - - BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), - BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), - BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), - BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), - /* - * not currently supported - * int: priority - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_NOOP = _IO('r', 12), - /* - * No parameters. Do nothing and examine the next command. It exists - * primarily so that we can replace it with a BR_SPAWN_LOOPER command. - */ - - BR_SPAWN_LOOPER = _IO('r', 13), - /* - * No parameters. The driver has determined that a process has no - * threads waiting to service incomming transactions. When a process - * receives this command, it must spawn a new service thread and - * register it via bcENTER_LOOPER. - */ - - BR_FINISHED = _IO('r', 14), - /* - * not currently supported - * stop threadpool thread - */ - - BR_DEAD_BINDER = _IOR('r', 15, void *), - /* - * void *: cookie - */ - BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), - /* - * void *: cookie - */ - - BR_FAILED_REPLY = _IO('r', 17), - /* - * The the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. - */ -}; - -enum BinderDriverCommandProtocol { - BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), - BC_REPLY = _IOW('c', 1, struct binder_transaction_data), - /* - * binder_transaction_data: the sent command. - */ - - BC_ACQUIRE_RESULT = _IOW('c', 2, int), - /* - * not currently supported - * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. - * Else you have acquired a primary reference on the object. - */ - - BC_FREE_BUFFER = _IOW('c', 3, int), - /* - * void *: ptr to transaction data received on a read - */ - - BC_INCREFS = _IOW('c', 4, int), - BC_ACQUIRE = _IOW('c', 5, int), - BC_RELEASE = _IOW('c', 6, int), - BC_DECREFS = _IOW('c', 7, int), - /* - * int: descriptor - */ - - BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), - BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), - /* - * not currently supported - * int: priority - * int: descriptor - */ - - BC_REGISTER_LOOPER = _IO('c', 11), - /* - * No parameters. - * Register a spawned looper thread with the device. - */ - - BC_ENTER_LOOPER = _IO('c', 12), - BC_EXIT_LOOPER = _IO('c', 13), - /* - * No parameters. - * These two commands are sent as an application-level thread - * enters and exits the binder loop, respectively. They are - * used so the binder can have an accurate count of the number - * of looping threads it has available. - */ - - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), - /* - * void *: cookie - */ -}; - -#endif /* _LINUX_BINDER_H */ - diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c deleted file mode 100644 index 531bdbeede89..000000000000 --- a/drivers/staging/android/logger.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * drivers/misc/logger.c - * - * A Logging Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * Robert Love - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include "logger.h" - -#include - -/* - * struct logger_log - represents a specific log, such as 'main' or 'radio' - * - * This structure lives from module insertion until module removal, so it does - * not need additional reference counting. The structure is protected by the - * mutex 'mutex'. - */ -struct logger_log { - unsigned char *buffer;/* the ring buffer itself */ - struct miscdevice misc; /* misc device representing the log */ - wait_queue_head_t wq; /* wait queue for readers */ - struct list_head readers; /* this log's readers */ - struct mutex mutex; /* mutex protecting buffer */ - size_t w_off; /* current write head offset */ - size_t head; /* new readers start here */ - size_t size; /* size of the log */ -}; - -/* - * struct logger_reader - a logging device open for reading - * - * This object lives from open to release, so we don't need additional - * reference counting. The structure is protected by log->mutex. - */ -struct logger_reader { - struct logger_log *log; /* associated log */ - struct list_head list; /* entry in logger_log's list */ - size_t r_off; /* current read head offset */ -}; - -/* logger_offset - returns index 'n' into the log via (optimized) modulus */ -#define logger_offset(n) ((n) & (log->size - 1)) - -/* - * file_get_log - Given a file structure, return the associated log - * - * This isn't aesthetic. We have several goals: - * - * 1) Need to quickly obtain the associated log during an I/O operation - * 2) Readers need to maintain state (logger_reader) - * 3) Writers need to be very fast (open() should be a near no-op) - * - * In the reader case, we can trivially go file->logger_reader->logger_log. - * For a writer, we don't want to maintain a logger_reader, so we just go - * file->logger_log. Thus what file->private_data points at depends on whether - * or not the file was opened for reading. This function hides that dirtiness. - */ -static inline struct logger_log *file_get_log(struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - return reader->log; - } else - return file->private_data; -} - -/* - * get_entry_len - Grabs the length of the payload of the next entry starting - * from 'off'. - * - * Caller needs to hold log->mutex. - */ -static __u32 get_entry_len(struct logger_log *log, size_t off) -{ - __u16 val; - - switch (log->size - off) { - case 1: - memcpy(&val, log->buffer + off, 1); - memcpy(((char *) &val) + 1, log->buffer, 1); - break; - default: - memcpy(&val, log->buffer + off, 2); - } - - return sizeof(struct logger_entry) + val; -} - -/* - * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the - * user-space buffer 'buf'. Returns 'count' on success. - * - * Caller must hold log->mutex. - */ -static ssize_t do_read_log_to_user(struct logger_log *log, - struct logger_reader *reader, - char __user *buf, - size_t count) -{ - size_t len; - - /* - * We read from the log in two disjoint operations. First, we read from - * the current read head offset up to 'count' bytes or to the end of - * the log, whichever comes first. - */ - len = min(count, log->size - reader->r_off); - if (copy_to_user(buf, log->buffer + reader->r_off, len)) - return -EFAULT; - - /* - * Second, we read any remaining bytes, starting back at the head of - * the log. - */ - if (count != len) - if (copy_to_user(buf + len, log->buffer, count - len)) - return -EFAULT; - - reader->r_off = logger_offset(reader->r_off + count); - - return count; -} - -/* - * logger_read - our log's read() method - * - * Behavior: - * - * - O_NONBLOCK works - * - If there are no log entries to read, blocks until log is written to - * - Atomically reads exactly one log entry - * - * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read - * buffer is insufficient to hold next entry. - */ -static ssize_t logger_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct logger_reader *reader = file->private_data; - struct logger_log *log = reader->log; - ssize_t ret; - DEFINE_WAIT(wait); - -start: - while (1) { - prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE); - - mutex_lock(&log->mutex); - ret = (log->w_off == reader->r_off); - mutex_unlock(&log->mutex); - if (!ret) - break; - - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -EINTR; - break; - } - - schedule(); - } - - finish_wait(&log->wq, &wait); - if (ret) - return ret; - - mutex_lock(&log->mutex); - - /* is there still something to read or did we race? */ - if (unlikely(log->w_off == reader->r_off)) { - mutex_unlock(&log->mutex); - goto start; - } - - /* get the size of the next entry */ - ret = get_entry_len(log, reader->r_off); - if (count < ret) { - ret = -EINVAL; - goto out; - } - - /* get exactly one entry from the log */ - ret = do_read_log_to_user(log, reader, buf, ret); - -out: - mutex_unlock(&log->mutex); - - return ret; -} - -/* - * get_next_entry - return the offset of the first valid entry at least 'len' - * bytes after 'off'. - * - * Caller must hold log->mutex. - */ -static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) -{ - size_t count = 0; - - do { - size_t nr = get_entry_len(log, off); - off = logger_offset(off + nr); - count += nr; - } while (count < len); - - return off; -} - -/* - * clock_interval - is a < c < b in mod-space? Put another way, does the line - * from a to b cross c? - */ -static inline int clock_interval(size_t a, size_t b, size_t c) -{ - if (b < a) { - if (a < c || b >= c) - return 1; - } else { - if (a < c && b >= c) - return 1; - } - - return 0; -} - -/* - * fix_up_readers - walk the list of all readers and "fix up" any who were - * lapped by the writer; also do the same for the default "start head". - * We do this by "pulling forward" the readers and start head to the first - * entry after the new write head. - * - * The caller needs to hold log->mutex. - */ -static void fix_up_readers(struct logger_log *log, size_t len) -{ - size_t old = log->w_off; - size_t new = logger_offset(old + len); - struct logger_reader *reader; - - if (clock_interval(old, new, log->head)) - log->head = get_next_entry(log, log->head, len); - - list_for_each_entry(reader, &log->readers, list) - if (clock_interval(old, new, reader->r_off)) - reader->r_off = get_next_entry(log, reader->r_off, len); -} - -/* - * do_write_log - writes 'len' bytes from 'buf' to 'log' - * - * The caller needs to hold log->mutex. - */ -static void do_write_log(struct logger_log *log, const void *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - memcpy(log->buffer + log->w_off, buf, len); - - if (count != len) - memcpy(log->buffer, buf + len, count - len); - - log->w_off = logger_offset(log->w_off + count); - -} - -/* - * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to - * the log 'log' - * - * The caller needs to hold log->mutex. - * - * Returns 'count' on success, negative error code on failure. - */ -static ssize_t do_write_log_from_user(struct logger_log *log, - const void __user *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - if (len && copy_from_user(log->buffer + log->w_off, buf, len)) - return -EFAULT; - - if (count != len) - if (copy_from_user(log->buffer, buf + len, count - len)) - return -EFAULT; - - log->w_off = logger_offset(log->w_off + count); - - return count; -} - -/* - * logger_aio_write - our write method, implementing support for write(), - * writev(), and aio_write(). Writes are our fast path, and we try to optimize - * them above all else. - */ -ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t ppos) -{ - struct logger_log *log = file_get_log(iocb->ki_filp); - size_t orig = log->w_off; - struct logger_entry header; - struct timespec now; - ssize_t ret = 0; - - now = current_kernel_time(); - - header.pid = current->tgid; - header.tid = current->pid; - header.sec = now.tv_sec; - header.nsec = now.tv_nsec; - header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); - - /* null writes succeed, return zero */ - if (unlikely(!header.len)) - return 0; - - mutex_lock(&log->mutex); - - /* - * Fix up any readers, pulling them forward to the first readable - * entry after (what will be) the new write offset. We do this now - * because if we partially fail, we can end up with clobbered log - * entries that encroach on readable buffer. - */ - fix_up_readers(log, sizeof(struct logger_entry) + header.len); - - do_write_log(log, &header, sizeof(struct logger_entry)); - - while (nr_segs-- > 0) { - size_t len; - ssize_t nr; - - /* figure out how much of this vector we can keep */ - len = min_t(size_t, iov->iov_len, header.len - ret); - - /* write out this segment's payload */ - nr = do_write_log_from_user(log, iov->iov_base, len); - if (unlikely(nr < 0)) { - log->w_off = orig; - mutex_unlock(&log->mutex); - return nr; - } - - iov++; - ret += nr; - } - - mutex_unlock(&log->mutex); - - /* wake up any blocked readers */ - wake_up_interruptible(&log->wq); - - return ret; -} - -static struct logger_log *get_log_from_minor(int); - -/* - * logger_open - the log's open() file operation - * - * Note how near a no-op this is in the write-only case. Keep it that way! - */ -static int logger_open(struct inode *inode, struct file *file) -{ - struct logger_log *log; - int ret; - - ret = nonseekable_open(inode, file); - if (ret) - return ret; - - log = get_log_from_minor(MINOR(inode->i_rdev)); - if (!log) - return -ENODEV; - - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader; - - reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL); - if (!reader) - return -ENOMEM; - - reader->log = log; - INIT_LIST_HEAD(&reader->list); - - mutex_lock(&log->mutex); - reader->r_off = log->head; - list_add_tail(&reader->list, &log->readers); - mutex_unlock(&log->mutex); - - file->private_data = reader; - } else - file->private_data = log; - - return 0; -} - -/* - * logger_release - the log's release file operation - * - * Note this is a total no-op in the write-only case. Keep it that way! - */ -static int logger_release(struct inode *ignored, struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - list_del(&reader->list); - kfree(reader); - } - - return 0; -} - -/* - * logger_poll - the log's poll file operation, for poll/select/epoll - * - * Note we always return POLLOUT, because you can always write() to the log. - * Note also that, strictly speaking, a return value of POLLIN does not - * guarantee that the log is readable without blocking, as there is a small - * chance that the writer can lap the reader in the interim between poll() - * returning and the read() request. - */ -static unsigned int logger_poll(struct file *file, poll_table *wait) -{ - struct logger_reader *reader; - struct logger_log *log; - unsigned int ret = POLLOUT | POLLWRNORM; - - if (!(file->f_mode & FMODE_READ)) - return ret; - - reader = file->private_data; - log = reader->log; - - poll_wait(file, &log->wq, wait); - - mutex_lock(&log->mutex); - if (log->w_off != reader->r_off) - ret |= POLLIN | POLLRDNORM; - mutex_unlock(&log->mutex); - - return ret; -} - -static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct logger_log *log = file_get_log(file); - struct logger_reader *reader; - long ret = -ENOTTY; - - mutex_lock(&log->mutex); - - switch (cmd) { - case LOGGER_GET_LOG_BUF_SIZE: - ret = log->size; - break; - case LOGGER_GET_LOG_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - if (log->w_off >= reader->r_off) - ret = log->w_off - reader->r_off; - else - ret = (log->size - reader->r_off) + log->w_off; - break; - case LOGGER_GET_NEXT_ENTRY_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - if (log->w_off != reader->r_off) - ret = get_entry_len(log, reader->r_off); - else - ret = 0; - break; - case LOGGER_FLUSH_LOG: - if (!(file->f_mode & FMODE_WRITE)) { - ret = -EBADF; - break; - } - list_for_each_entry(reader, &log->readers, list) - reader->r_off = log->w_off; - log->head = log->w_off; - ret = 0; - break; - } - - mutex_unlock(&log->mutex); - - return ret; -} - -static const struct file_operations logger_fops = { - .owner = THIS_MODULE, - .read = logger_read, - .aio_write = logger_aio_write, - .poll = logger_poll, - .unlocked_ioctl = logger_ioctl, - .compat_ioctl = logger_ioctl, - .open = logger_open, - .release = logger_release, -}; - -/* - * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which - * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than - * LONG_MAX minus LOGGER_ENTRY_MAX_LEN. - */ -#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -static unsigned char _buf_ ## VAR[SIZE]; \ -static struct logger_log VAR = { \ - .buffer = _buf_ ## VAR, \ - .misc = { \ - .minor = MISC_DYNAMIC_MINOR, \ - .name = NAME, \ - .fops = &logger_fops, \ - .parent = NULL, \ - }, \ - .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ - .readers = LIST_HEAD_INIT(VAR .readers), \ - .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ - .w_off = 0, \ - .head = 0, \ - .size = SIZE, \ -}; - -DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024) -DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024) -DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024) - -static struct logger_log *get_log_from_minor(int minor) -{ - if (log_main.misc.minor == minor) - return &log_main; - if (log_events.misc.minor == minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; - if (log_system.misc.minor == minor) - return &log_system; - return NULL; -} - -static int __init init_log(struct logger_log *log) -{ - int ret; - - ret = misc_register(&log->misc); - if (unlikely(ret)) { - printk(KERN_ERR "logger: failed to register misc " - "device for log '%s'!\n", log->misc.name); - return ret; - } - - printk(KERN_INFO "logger: created %luK log '%s'\n", - (unsigned long) log->size >> 10, log->misc.name); - - return 0; -} - -static int __init logger_init(void) -{ - int ret; - - ret = init_log(&log_main); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_events); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_radio); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_system); - if (unlikely(ret)) - goto out; - -out: - return ret; -} -device_initcall(logger_init); diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h deleted file mode 100644 index 2cb06e9d8f98..000000000000 --- a/drivers/staging/android/logger.h +++ /dev/null @@ -1,49 +0,0 @@ -/* include/linux/logger.h - * - * Copyright (C) 2007-2008 Google, Inc. - * Author: Robert Love - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_LOGGER_H -#define _LINUX_LOGGER_H - -#include -#include - -struct logger_entry { - __u16 len; /* length of the payload */ - __u16 __pad; /* no matter what, we get 2 bytes of padding */ - __s32 pid; /* generating process's pid */ - __s32 tid; /* generating process's tid */ - __s32 sec; /* seconds since Epoch */ - __s32 nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ -}; - -#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ -#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ -#define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */ -#define LOGGER_LOG_MAIN "log_main" /* everything else */ - -#define LOGGER_ENTRY_MAX_LEN (4*1024) -#define LOGGER_ENTRY_MAX_PAYLOAD \ - (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) - -#define __LOGGERIO 0xAE - -#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ -#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ -#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ -#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ - -#endif /* _LINUX_LOGGER_H */ diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c deleted file mode 100644 index 897bc3ab9667..000000000000 --- a/drivers/staging/android/lowmemorykiller.c +++ /dev/null @@ -1,213 +0,0 @@ -/* drivers/misc/lowmemorykiller.c - * - * The lowmemorykiller driver lets user-space specify a set of memory thresholds - * where processes with a range of oom_adj values will get killed. Specify the - * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the - * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both - * files take a comma separated list of numbers in ascending order. - * - * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and - * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes - * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages - * and kill processes with a oom_adj value of 0 or higher when the free memory - * drops below 1024 pages. - * - * The driver considers memory used for caches to be free, but if a large - * percentage of the cached memory is locked this can be very inaccurate - * and processes may not get killed until the normal oom killer is triggered. - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -static uint32_t lowmem_debug_level = 2; -static int lowmem_adj[6] = { - 0, - 1, - 6, - 12, -}; -static int lowmem_adj_size = 4; -static size_t lowmem_minfree[6] = { - 3 * 512, /* 6MB */ - 2 * 1024, /* 8MB */ - 4 * 1024, /* 16MB */ - 16 * 1024, /* 64MB */ -}; -static int lowmem_minfree_size = 4; - -static struct task_struct *lowmem_deathpending; -static unsigned long lowmem_deathpending_timeout; - -#define lowmem_print(level, x...) \ - do { \ - if (lowmem_debug_level >= (level)) \ - printk(x); \ - } while (0) - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data); - -static struct notifier_block task_nb = { - .notifier_call = task_notify_func, -}; - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data) -{ - struct task_struct *task = data; - - if (task == lowmem_deathpending) - lowmem_deathpending = NULL; - - return NOTIFY_OK; -} - -static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) -{ - struct task_struct *p; - struct task_struct *selected = NULL; - int rem = 0; - int tasksize; - int i; - int min_adj = OOM_ADJUST_MAX + 1; - int selected_tasksize = 0; - int selected_oom_adj; - int array_size = ARRAY_SIZE(lowmem_adj); - int other_free = global_page_state(NR_FREE_PAGES); - int other_file = global_page_state(NR_FILE_PAGES) - - global_page_state(NR_SHMEM); - - /* - * If we already have a death outstanding, then - * bail out right away; indicating to vmscan - * that we have nothing further to offer on - * this pass. - * - */ - if (lowmem_deathpending && - time_before_eq(jiffies, lowmem_deathpending_timeout)) - return 0; - - if (lowmem_adj_size < array_size) - array_size = lowmem_adj_size; - if (lowmem_minfree_size < array_size) - array_size = lowmem_minfree_size; - for (i = 0; i < array_size; i++) { - if (other_free < lowmem_minfree[i] && - other_file < lowmem_minfree[i]) { - min_adj = lowmem_adj[i]; - break; - } - } - if (nr_to_scan > 0) - lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n", - nr_to_scan, gfp_mask, other_free, other_file, - min_adj); - rem = global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); - if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { - lowmem_print(5, "lowmem_shrink %d, %x, return %d\n", - nr_to_scan, gfp_mask, rem); - return rem; - } - selected_oom_adj = min_adj; - - read_lock(&tasklist_lock); - for_each_process(p) { - struct mm_struct *mm; - struct signal_struct *sig; - int oom_adj; - - task_lock(p); - mm = p->mm; - sig = p->signal; - if (!mm || !sig) { - task_unlock(p); - continue; - } - oom_adj = sig->oom_adj; - if (oom_adj < min_adj) { - task_unlock(p); - continue; - } - tasksize = get_mm_rss(mm); - task_unlock(p); - if (tasksize <= 0) - continue; - if (selected) { - if (oom_adj < selected_oom_adj) - continue; - if (oom_adj == selected_oom_adj && - tasksize <= selected_tasksize) - continue; - } - selected = p; - selected_tasksize = tasksize; - selected_oom_adj = oom_adj; - lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", - p->pid, p->comm, oom_adj, tasksize); - } - if (selected) { - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); - lowmem_deathpending = selected; - lowmem_deathpending_timeout = jiffies + HZ; - force_sig(SIGKILL, selected); - rem -= selected_tasksize; - } - lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", - nr_to_scan, gfp_mask, rem); - read_unlock(&tasklist_lock); - return rem; -} - -static struct shrinker lowmem_shrinker = { - .shrink = lowmem_shrink, - .seeks = DEFAULT_SEEKS * 16 -}; - -static int __init lowmem_init(void) -{ - task_free_register(&task_nb); - register_shrinker(&lowmem_shrinker); - return 0; -} - -static void __exit lowmem_exit(void) -{ - unregister_shrinker(&lowmem_shrinker); - task_free_unregister(&task_nb); -} - -module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, - S_IRUGO | S_IWUSR); -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, - S_IRUGO | S_IWUSR); -module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); - -module_init(lowmem_init); -module_exit(lowmem_exit); - -MODULE_LICENSE("GPL"); - diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c deleted file mode 100644 index 53f736b0ec83..000000000000 --- a/drivers/staging/android/ram_console.c +++ /dev/null @@ -1,418 +0,0 @@ -/* drivers/android/ram_console.c - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -#include -#endif - -struct ram_console_buffer { - uint32_t sig; - uint32_t start; - uint32_t size; - uint8_t data[0]; -}; - -#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */ - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static char __initdata - ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE]; -#endif -static char *ram_console_old_log; -static size_t ram_console_old_log_size; - -static struct ram_console_buffer *ram_console_buffer; -static size_t ram_console_buffer_size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static char *ram_console_par_buffer; -static struct rs_control *ram_console_rs_decoder; -static int ram_console_corrected_bytes; -static int ram_console_bad_blocks; -#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE -#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE -#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE -#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL -#endif - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - /* Initialize the parity buffer */ - memset(par, 0, sizeof(par)); - encode_rs8(ram_console_rs_decoder, data, len, par, 0); - for (i = 0; i < ECC_SIZE; i++) - ecc[i] = par[i]; -} - -static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - for (i = 0; i < ECC_SIZE; i++) - par[i] = ecc[i]; - return decode_rs8(ram_console_rs_decoder, data, par, len, - NULL, 0, NULL, 0, NULL); -} -#endif - -static void ram_console_update(const char *s, unsigned int count) -{ - struct ram_console_buffer *buffer = ram_console_buffer; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *buffer_end = buffer->data + ram_console_buffer_size; - uint8_t *block; - uint8_t *par; - int size = ECC_BLOCK_SIZE; -#endif - memcpy(buffer->data + buffer->start, s, count); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1)); - par = ram_console_par_buffer + - (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE; - do { - if (block + ECC_BLOCK_SIZE > buffer_end) - size = buffer_end - block; - ram_console_encode_rs8(block, size, par); - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } while (block < buffer->data + buffer->start + count); -#endif -} - -static void ram_console_update_header(void) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - struct ram_console_buffer *buffer = ram_console_buffer; - uint8_t *par; - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par); -#endif -} - -static void -ram_console_write(struct console *console, const char *s, unsigned int count) -{ - int rem; - struct ram_console_buffer *buffer = ram_console_buffer; - - if (count > ram_console_buffer_size) { - s += count - ram_console_buffer_size; - count = ram_console_buffer_size; - } - rem = ram_console_buffer_size - buffer->start; - if (rem < count) { - ram_console_update(s, rem); - s += rem; - count -= rem; - buffer->start = 0; - buffer->size = ram_console_buffer_size; - } - ram_console_update(s, count); - - buffer->start += count; - if (buffer->size < ram_console_buffer_size) - buffer->size += count; - ram_console_update_header(); -} - -static struct console ram_console = { - .name = "ram", - .write = ram_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED, - .index = -1, -}; - -void ram_console_enable_console(int enabled) -{ - if (enabled) - ram_console.flags |= CON_ENABLED; - else - ram_console.flags &= ~CON_ENABLED; -} - -static void __init -ram_console_save_old(struct ram_console_buffer *buffer, char *dest) -{ - size_t old_log_size = buffer->size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *block; - uint8_t *par; - char strbuf[80]; - int strbuf_len; - - block = buffer->data; - par = ram_console_par_buffer; - while (block < buffer->data + buffer->size) { - int numerr; - int size = ECC_BLOCK_SIZE; - if (block + size > buffer->data + ram_console_buffer_size) - size = buffer->data + ram_console_buffer_size - block; - numerr = ram_console_decode_rs8(block, size, par); - if (numerr > 0) { -#if 0 - printk(KERN_INFO "ram_console: error in block %p, %d\n", - block, numerr); -#endif - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { -#if 0 - printk(KERN_INFO "ram_console: uncorrectable error in " - "block %p\n", block); -#endif - ram_console_bad_blocks++; - } - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } - if (ram_console_corrected_bytes || ram_console_bad_blocks) - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\n%d Corrected bytes, %d unrecoverable blocks\n", - ram_console_corrected_bytes, ram_console_bad_blocks); - else - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\nNo errors detected\n"); - if (strbuf_len >= sizeof(strbuf)) - strbuf_len = sizeof(strbuf) - 1; - old_log_size += strbuf_len; -#endif - - if (dest == NULL) { - dest = kmalloc(old_log_size, GFP_KERNEL); - if (dest == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer\n"); - return; - } - } - - ram_console_old_log = dest; - ram_console_old_log_size = old_log_size; - memcpy(ram_console_old_log, - &buffer->data[buffer->start], buffer->size - buffer->start); - memcpy(ram_console_old_log + buffer->size - buffer->start, - &buffer->data[0], buffer->start); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - memcpy(ram_console_old_log + old_log_size - strbuf_len, - strbuf, strbuf_len); -#endif -} - -static int __init ram_console_init(struct ram_console_buffer *buffer, - size_t buffer_size, char *old_buf) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - int numerr; - uint8_t *par; -#endif - ram_console_buffer = buffer; - ram_console_buffer_size = - buffer_size - sizeof(struct ram_console_buffer); - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "datasize %zu\n", buffer, buffer_size, - ram_console_buffer_size); - return 0; - } - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, - ECC_BLOCK_SIZE) + 1) * ECC_SIZE; - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "non-ecc datasize %zu\n", - buffer, buffer_size, ram_console_buffer_size); - return 0; - } - - ram_console_par_buffer = buffer->data + ram_console_buffer_size; - - - /* first consecutive root is 0 - * primitive element to generate roots = 1 - */ - ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE); - if (ram_console_rs_decoder == NULL) { - printk(KERN_INFO "ram_console: init_rs failed\n"); - return 0; - } - - ram_console_corrected_bytes = 0; - ram_console_bad_blocks = 0; - - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - - numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par); - if (numerr > 0) { - printk(KERN_INFO "ram_console: error in header, %d\n", numerr); - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { - printk(KERN_INFO - "ram_console: uncorrectable error in header\n"); - ram_console_bad_blocks++; - } -#endif - - if (buffer->sig == RAM_CONSOLE_SIG) { - if (buffer->size > ram_console_buffer_size - || buffer->start > buffer->size) - printk(KERN_INFO "ram_console: found existing invalid " - "buffer, size %d, start %d\n", - buffer->size, buffer->start); - else { - printk(KERN_INFO "ram_console: found existing buffer, " - "size %d, start %d\n", - buffer->size, buffer->start); - ram_console_save_old(buffer, old_buf); - } - } else { - printk(KERN_INFO "ram_console: no valid data in buffer " - "(sig = 0x%08x)\n", buffer->sig); - } - - buffer->sig = RAM_CONSOLE_SIG; - buffer->start = 0; - buffer->size = 0; - - register_console(&ram_console); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - console_verbose(); -#endif - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static int __init ram_console_early_init(void) -{ - return ram_console_init((struct ram_console_buffer *) - CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR, - CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE, - ram_console_old_log_init_buffer); -} -#else -static int ram_console_driver_probe(struct platform_device *pdev) -{ - struct resource *res = pdev->resource; - size_t start; - size_t buffer_size; - void *buffer; - - if (res == NULL || pdev->num_resources != 1 || - !(res->flags & IORESOURCE_MEM)) { - printk(KERN_ERR "ram_console: invalid resource, %p %d flags " - "%lx\n", res, pdev->num_resources, res ? res->flags : 0); - return -ENXIO; - } - buffer_size = res->end - res->start + 1; - start = res->start; - printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n", - start, buffer_size); - buffer = ioremap(res->start, buffer_size); - if (buffer == NULL) { - printk(KERN_ERR "ram_console: failed to map memory\n"); - return -ENOMEM; - } - - return ram_console_init(buffer, buffer_size, NULL/* allocate */); -} - -static struct platform_driver ram_console_driver = { - .probe = ram_console_driver_probe, - .driver = { - .name = "ram_console", - }, -}; - -static int __init ram_console_module_init(void) -{ - int err; - err = platform_driver_register(&ram_console_driver); - return err; -} -#endif - -static ssize_t ram_console_read_old(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - loff_t pos = *offset; - ssize_t count; - - if (pos >= ram_console_old_log_size) - return 0; - - count = min(len, (size_t)(ram_console_old_log_size - pos)); - if (copy_to_user(buf, ram_console_old_log + pos, count)) - return -EFAULT; - - *offset += count; - return count; -} - -static const struct file_operations ram_console_file_ops = { - .owner = THIS_MODULE, - .read = ram_console_read_old, -}; - -static int __init ram_console_late_init(void) -{ - struct proc_dir_entry *entry; - - if (ram_console_old_log == NULL) - return 0; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT - ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL); - if (ram_console_old_log == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer for old log\n"); - ram_console_old_log_size = 0; - return 0; - } - memcpy(ram_console_old_log, - ram_console_old_log_init_buffer, ram_console_old_log_size); -#endif - entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); - if (!entry) { - printk(KERN_ERR "ram_console: failed to create proc entry\n"); - kfree(ram_console_old_log); - ram_console_old_log = NULL; - return 0; - } - - entry->proc_fops = &ram_console_file_ops; - entry->size = ram_console_old_log_size; - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -console_initcall(ram_console_early_init); -#else -postcore_initcall(ram_console_module_init); -#endif -late_initcall(ram_console_late_init); - diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c deleted file mode 100755 index a64481c3e86d..000000000000 --- a/drivers/staging/android/timed_gpio.c +++ /dev/null @@ -1,176 +0,0 @@ -/* drivers/misc/timed_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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 -#include -#include -#include -#include -#include - -#include "timed_output.h" -#include "timed_gpio.h" - - -struct timed_gpio_data { - struct timed_output_dev dev; - struct hrtimer timer; - spinlock_t lock; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -{ - struct timed_gpio_data *data = - container_of(timer, struct timed_gpio_data, timer); - - gpio_direction_output(data->gpio, data->active_low ? 1 : 0); - return HRTIMER_NORESTART; -} - -static int gpio_get_time(struct timed_output_dev *dev) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - - if (hrtimer_active(&data->timer)) { - ktime_t r = hrtimer_get_remaining(&data->timer); - struct timeval t = ktime_to_timeval(r); - return t.tv_sec * 1000 + t.tv_usec / 1000; - } else - return 0; -} - -static void gpio_enable(struct timed_output_dev *dev, int value) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - unsigned long flags; - - spin_lock_irqsave(&data->lock, flags); - - /* cancel previous timer and set GPIO according to value */ - hrtimer_cancel(&data->timer); - gpio_direction_output(data->gpio, data->active_low ? !value : !!value); - - if (value > 0) { - if (value > data->max_timeout) - value = data->max_timeout; - - hrtimer_start(&data->timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); - } - - spin_unlock_irqrestore(&data->lock, flags); -} - -static int timed_gpio_probe(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio *cur_gpio; - struct timed_gpio_data *gpio_data, *gpio_dat; - int i, j, ret = 0; - - if (!pdata) - return -EBUSY; - - gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, - GFP_KERNEL); - if (!gpio_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_gpios; i++) { - cur_gpio = &pdata->gpios[i]; - gpio_dat = &gpio_data[i]; - - hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - gpio_dat->timer.function = gpio_timer_func; - spin_lock_init(&gpio_dat->lock); - - gpio_dat->dev.name = cur_gpio->name; - gpio_dat->dev.get_time = gpio_get_time; - gpio_dat->dev.enable = gpio_enable; - ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret >= 0) { - ret = timed_output_dev_register(&gpio_dat->dev); - if (ret < 0) - gpio_free(cur_gpio->gpio); - } - if (ret < 0) { - for (j = 0; j < i; j++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - kfree(gpio_data); - return ret; - } - - gpio_dat->gpio = cur_gpio->gpio; - gpio_dat->max_timeout = cur_gpio->max_timeout; - gpio_dat->active_low = cur_gpio->active_low; - gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); - } - - platform_set_drvdata(pdev, gpio_data); - - return 0; -} - -static int timed_gpio_remove(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < pdata->num_gpios; i++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - - kfree(gpio_data); - - return 0; -} - -static struct platform_driver timed_gpio_driver = { - .probe = timed_gpio_probe, - .remove = timed_gpio_remove, - .driver = { - .name = TIMED_GPIO_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init timed_gpio_init(void) -{ - return platform_driver_register(&timed_gpio_driver); -} - -static void __exit timed_gpio_exit(void) -{ - platform_driver_unregister(&timed_gpio_driver); -} - -module_init(timed_gpio_init); -module_exit(timed_gpio_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed gpio driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h deleted file mode 100644 index a0e15f8be3f7..000000000000 --- a/drivers/staging/android/timed_gpio.h +++ /dev/null @@ -1,33 +0,0 @@ -/* include/linux/timed_gpio.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_GPIO_H -#define _LINUX_TIMED_GPIO_H - -#define TIMED_GPIO_NAME "timed-gpio" - -struct timed_gpio { - const char *name; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -struct timed_gpio_platform_data { - int num_gpios; - struct timed_gpio *gpios; -}; - -#endif diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c deleted file mode 100644 index f373422308e0..000000000000 --- a/drivers/staging/android/timed_output.c +++ /dev/null @@ -1,123 +0,0 @@ -/* drivers/misc/timed_output.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Mike Lockwood - * - * 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 -#include -#include -#include -#include - -#include "timed_output.h" - -static struct class *timed_output_class; -static atomic_t device_count; - -static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int remaining = tdev->get_time(tdev); - - return sprintf(buf, "%d\n", remaining); -} - -static ssize_t enable_store( - struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int value; - - if (sscanf(buf, "%d", &value) != 1) - return -EINVAL; - - tdev->enable(tdev, value); - - return size; -} - -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); - -static int create_timed_output_class(void) -{ - if (!timed_output_class) { - timed_output_class = class_create(THIS_MODULE, "timed_output"); - if (IS_ERR(timed_output_class)) - return PTR_ERR(timed_output_class); - atomic_set(&device_count, 0); - } - - return 0; -} - -int timed_output_dev_register(struct timed_output_dev *tdev) -{ - int ret; - - if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time) - return -EINVAL; - - ret = create_timed_output_class(); - if (ret < 0) - return ret; - - tdev->index = atomic_inc_return(&device_count); - tdev->dev = device_create(timed_output_class, NULL, - MKDEV(0, tdev->index), NULL, tdev->name); - if (IS_ERR(tdev->dev)) - return PTR_ERR(tdev->dev); - - ret = device_create_file(tdev->dev, &dev_attr_enable); - if (ret < 0) - goto err_create_file; - - dev_set_drvdata(tdev->dev, tdev); - tdev->state = 0; - return 0; - -err_create_file: - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - printk(KERN_ERR "timed_output: Failed to register driver %s\n", - tdev->name); - - return ret; -} -EXPORT_SYMBOL_GPL(timed_output_dev_register); - -void timed_output_dev_unregister(struct timed_output_dev *tdev) -{ - device_remove_file(tdev->dev, &dev_attr_enable); - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - dev_set_drvdata(tdev->dev, NULL); -} -EXPORT_SYMBOL_GPL(timed_output_dev_unregister); - -static int __init timed_output_init(void) -{ - return create_timed_output_class(); -} - -static void __exit timed_output_exit(void) -{ - class_destroy(timed_output_class); -} - -module_init(timed_output_init); -module_exit(timed_output_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed output class driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h deleted file mode 100644 index ec907ab2ff54..000000000000 --- a/drivers/staging/android/timed_output.h +++ /dev/null @@ -1,37 +0,0 @@ -/* include/linux/timed_output.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_OUTPUT_H -#define _LINUX_TIMED_OUTPUT_H - -struct timed_output_dev { - const char *name; - - /* enable the output and set the timer */ - void (*enable)(struct timed_output_dev *sdev, int timeout); - - /* returns the current number of milliseconds remaining on the timer */ - int (*get_time)(struct timed_output_dev *sdev); - - /* private data */ - struct device *dev; - int index; - int state; -}; - -extern int timed_output_dev_register(struct timed_output_dev *dev); -extern void timed_output_dev_unregister(struct timed_output_dev *dev); - -#endif diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 62445551eecf..5b279fb30f3f 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_IWUSR | S_IRUGO, +static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, get_enabled, set_enabled); -static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture); +static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture); -static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, class_get_enabled, class_set_enabled); -static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture); +static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture); static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 876be5a2913d..2ea97de435ce 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -246,10 +246,6 @@ void interface_rx(struct sk_buff *skb, int hdr_size) skb_pull_rcsum(skb, hdr_size); /* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/ - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) { - kfree_skb(skb); - return; - } skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index 0d318c739528..1d5e8796d383 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c @@ -92,7 +92,7 @@ int cx25821_get_format_size(void) return ARRAY_SIZE(formats); } -struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) +struct cx25821_fmt *format_by_fourcc(unsigned int fourcc) { unsigned int i; @@ -848,7 +848,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 = cx25821_format_by_fourcc(pix_format); + fh->fmt = format_by_fourcc(pix_format); v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); @@ -1009,7 +1009,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, if (0 != err) return err; - fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); fh->vidq.field = f->fmt.pix.field; /* check if width and height is valid based on set standard */ @@ -1117,7 +1117,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 = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + fmt = format_by_fourcc(f->fmt.pix.pixelformat); if (NULL == fmt) return -EINVAL; diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h index a2415d33235b..cc6034b1a95d 100644 --- a/drivers/staging/cx25821/cx25821-video.h +++ b/drivers/staging/cx25821/cx25821-video.h @@ -87,7 +87,7 @@ extern unsigned int vid_limit; #define FORMAT_FLAGS_PACKED 0x01 extern struct cx25821_fmt formats[]; -extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); +extern struct cx25821_fmt *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, diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index f21a0e8d8d9b..eed74f0fe0b6 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_IWUSR | S_IRUGO, show_##value, set_##value); + static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); show_int(enable); show_int(offline); diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index ab2d5fa0349f..bb7d76539cd7 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -506,7 +506,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); #define IIO_DEV_ATTR_CAPTURE(_store) \ - IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0) + IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0) static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c index e414571938a3..0b598526de62 100644 --- a/drivers/staging/line6/control.c +++ b/drivers/staging/line6/control.c @@ -268,210 +268,210 @@ VARIAX_PARAM_R(float, mix2); VARIAX_PARAM_R(float, mix1); VARIAX_PARAM_R(int, pickup_wiring); -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, +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, pod_set_wah_position); -static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain); -static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position); -static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold); -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, +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, pod_set_amp_model_setup); -static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model, +static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model); -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, +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, pod_set_highmid); -static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol, +static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol); -static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix, +static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix); -static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup, +static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup); -static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency); -static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence, +static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence); -static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass); -static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable); -static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold, +static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold); -static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time, +static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time); -static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable, +static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable); -static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable, +static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable); -static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time, +static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time); -static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable, +static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable); -static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1, +static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1); -static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1, +static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1); -static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | 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_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass); -static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2, +static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2); -static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix); -static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3, +static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3); -static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable, +static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable); -static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type, +static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type); -static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay, +static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay); -static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone, +static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone); -static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); -static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post, +static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post); -static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency); -static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass); -static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable, +static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable); -static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); -static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); -static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); -static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post, +static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post); -static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post, +static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post); -static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model, +static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model); -static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay, +static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay); -static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable, +static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable); -static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value); -static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2, +static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2); -static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3, +static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3); -static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4, +static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4); -static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5, +static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5); -static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix, +static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix); -static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post, +static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post); -static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model); -static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency); -static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass); -static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | 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_IWUSR | S_IRUGO, +static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision); -static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable, +static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable); -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, +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, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign); -static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency); -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, +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, pod_set_mic_selection); -static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model, +static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model); -static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model, +static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model); -static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel, +static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel); -static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency); -static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency); -static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value); -static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2, +static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2); -static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3, +static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3); -static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4, +static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4); -static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5, +static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5); -static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6, +static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6); -static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select); -static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4, +static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4); -static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5, +static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5); -static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post, +static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post); -static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model, +static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model); -static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model); -static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb, +static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb); -static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb, +static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb); -static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model, +static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model); -static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume, +static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume); -static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off, +static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off); -static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select); -static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage, +static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage); -static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain, +static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain); -static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); -static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain, +static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain); -static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); -static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain, +static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain); -static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | 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_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); -static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain, +static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain); -static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO, +static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | 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 9b42e34763f1..32b6ca75cadb 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -362,8 +362,8 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev, return count; } -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_IWUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); +static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); +static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); /* MIDI device destructor */ static int snd_line6_midi_free(struct snd_device *device) diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 63318d717cd7..28f514611abc 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -952,33 +952,33 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1); #undef GET_SYSTEM_PARAM /* POD special files: */ -static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel, pod_set_channel); +static DEVICE_ATTR(channel, S_IWUGO | 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_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_IWUSR, line6_nop_read, pod_set_finish); +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, pod_set_dump_buf); +static DEVICE_ATTR(finish, S_IWUGO, 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_IWUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); -static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level); +static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); +static DEVICE_ATTR(monitor_level, S_IWUGO | 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_IWUSR, line6_nop_read, pod_set_retrieve_amp_setup); -static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read, pod_set_retrieve_channel); -static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_effects_setup); -static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing, pod_set_routing); +static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup); +static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel); +static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup); +static DEVICE_ATTR(routing, S_IWUGO | 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_IWUSR, line6_nop_read, pod_set_store_amp_setup); -static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read, pod_set_store_channel); -static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read, pod_set_store_effects_setup); -static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); -static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute); +static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup); +static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel); +static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup); +static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); +static DEVICE_ATTR(tuner_mute, S_IWUGO | 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); #if CREATE_RAW_FILE -static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); #endif /* diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index db421781d550..e6770ea17936 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -124,9 +124,9 @@ static ssize_t toneport_set_led_green(struct device *dev, return count; } -static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red); -static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_green, S_IWUGO | 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 b2fc09b05939..58ddbe6393ff 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -389,17 +389,17 @@ static ssize_t variax_set_raw2(struct device *dev, #endif /* Variax workbench special files: */ -static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model, variax_set_model); -static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume, variax_set_volume); -static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone); +static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model); +static DEVICE_ATTR(volume, S_IWUGO | 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(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_IWUSR | S_IRUGO, variax_get_active, variax_set_active); +static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active); #if CREATE_RAW_FILE -static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); -static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2); +static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2); #endif diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index 677152044f45..42783d7367e3 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -62,7 +62,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, NULL }; - ret = ata_pci_bmdma_init_one(pdev, ppi, &phison_sht, NULL, 0); + ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL, 0); dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret); diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index cd15daae5412..ebf9074a9083 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -65,7 +65,6 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x14B2, 0x3C07)}, /* AL */ {USB_DEVICE(0x050D, 0x8053)}, /* Belkin */ {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x935A)}, /* Belkin F6D4050 v1 */ {USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */ {USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */ {USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */ @@ -182,7 +181,6 @@ 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 e7e8745c9478..a0ece1fd64a5 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -268,12 +268,8 @@ HwHSSIThreeWire( } udelay(10); } - 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; - } + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) + panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp); // RTL8187S HSSI Read/Write Function u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); @@ -313,23 +309,13 @@ HwHSSIThreeWire( int idx; int ByteCnt = nDataBufBitCnt / 8; //printk("%d\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 % 8) != 0) + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n", + nDataBufBitCnt); - if (nDataBufBitCnt > 64) { - printk(KERN_ERR "rtl8187se: HwThreeWire():" - " nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); - dump_stack(); - nDataBufBitCnt = 64; - } + if (nDataBufBitCnt > 64) + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n", + nDataBufBitCnt); for(idx = 0; idx < ByteCnt; idx++) { diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index ac2bf11e1119..eb44b60e1eb5 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_IWUSR | S_IRUGO, +static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO, get_silent_state, set_silent_state); diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 456cd5c95765..c7e061e5e04d 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1143,7 +1143,7 @@ static struct device_attribute fb_device_attrs[] = { __ATTR_RO(metrics_bytes_sent), __ATTR_RO(metrics_cpu_kcycles_used), __ATTR_RO(metrics_misc), - __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store), + __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store), __ATTR_RW(use_defio), }; diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c index af3832b03e4b..a2566f1075d5 100644 --- a/drivers/staging/usbip/usbip_event.c +++ b/drivers/staging/usbip/usbip_event.c @@ -38,13 +38,21 @@ static int event_handler(struct usbip_device *ud) ud->eh_ops.shutdown(ud); ud->event &= ~USBIP_EH_SHUTDOWN; + + break; } + /* Stop the error handler. */ + if (ud->event & USBIP_EH_BYE) + return -1; + /* Reset the device. */ if (ud->event & USBIP_EH_RESET) { ud->eh_ops.reset(ud); ud->event &= ~USBIP_EH_RESET; + + break; } /* Mark the device as unusable. */ @@ -52,11 +60,13 @@ static int event_handler(struct usbip_device *ud) ud->eh_ops.unusable(ud); ud->event &= ~USBIP_EH_UNUSABLE; + + break; } - /* Stop the error handler. */ - if (ud->event & USBIP_EH_BYE) - return -1; + /* NOTREACHED */ + printk(KERN_ERR "%s: unknown event\n", __func__); + return -1; } return 0; diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 832608d3e579..0574d848b900 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -164,8 +164,6 @@ void rh_port_disconnect(int rhport) * spin_unlock(&vdev->ud.lock); */ spin_unlock_irqrestore(&the_controller->lock, flags); - - usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } diff --git a/drivers/switch/Kconfig b/drivers/switch/Kconfig deleted file mode 100644 index 52385914b9ae..000000000000 --- a/drivers/switch/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -menuconfig SWITCH - tristate "Switch class support" - help - Say Y here to enable switch class support. This allows - monitoring switches by userspace via sysfs and uevent. - -if SWITCH - -config SWITCH_GPIO - tristate "GPIO Swith support" - depends on GENERIC_GPIO - help - Say Y here to enable GPIO based switch support. - -endif # SWITCH diff --git a/drivers/switch/Makefile b/drivers/switch/Makefile deleted file mode 100644 index f7606ed4a719..000000000000 --- a/drivers/switch/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# Switch Class Driver -obj-$(CONFIG_SWITCH) += switch_class.o -obj-$(CONFIG_SWITCH_GPIO) += switch_gpio.o - diff --git a/drivers/switch/switch_class.c b/drivers/switch/switch_class.c deleted file mode 100644 index e05fc2591147..000000000000 --- a/drivers/switch/switch_class.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * drivers/switch/switch_class.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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 -#include -#include -#include -#include -#include -#include - -struct class *switch_class; -static atomic_t device_count; - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *sdev = (struct switch_dev *) - dev_get_drvdata(dev); - - if (sdev->print_state) { - int ret = sdev->print_state(sdev, buf); - if (ret >= 0) - return ret; - } - return sprintf(buf, "%d\n", sdev->state); -} - -static ssize_t name_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct switch_dev *sdev = (struct switch_dev *) - dev_get_drvdata(dev); - - if (sdev->print_name) { - int ret = sdev->print_name(sdev, buf); - if (ret >= 0) - return ret; - } - return sprintf(buf, "%s\n", sdev->name); -} - -static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL); -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL); - -void switch_set_state(struct switch_dev *sdev, int state) -{ - char name_buf[120]; - char state_buf[120]; - char *prop_buf; - char *envp[3]; - int env_offset = 0; - int length; - - if (sdev->state != state) { - sdev->state = state; - - prop_buf = (char *)get_zeroed_page(GFP_KERNEL); - if (prop_buf) { - length = name_show(sdev->dev, NULL, prop_buf); - if (length > 0) { - if (prop_buf[length - 1] == '\n') - prop_buf[length - 1] = 0; - snprintf(name_buf, sizeof(name_buf), - "SWITCH_NAME=%s", prop_buf); - envp[env_offset++] = name_buf; - } - length = state_show(sdev->dev, NULL, prop_buf); - if (length > 0) { - if (prop_buf[length - 1] == '\n') - prop_buf[length - 1] = 0; - snprintf(state_buf, sizeof(state_buf), - "SWITCH_STATE=%s", prop_buf); - envp[env_offset++] = state_buf; - } - envp[env_offset] = NULL; - kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp); - free_page((unsigned long)prop_buf); - } else { - printk(KERN_ERR "out of memory in switch_set_state\n"); - kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE); - } - } -} -EXPORT_SYMBOL_GPL(switch_set_state); - -static int create_switch_class(void) -{ - if (!switch_class) { - switch_class = class_create(THIS_MODULE, "switch"); - if (IS_ERR(switch_class)) - return PTR_ERR(switch_class); - atomic_set(&device_count, 0); - } - - return 0; -} - -int switch_dev_register(struct switch_dev *sdev) -{ - int ret; - - if (!switch_class) { - ret = create_switch_class(); - if (ret < 0) - return ret; - } - - sdev->index = atomic_inc_return(&device_count); - sdev->dev = device_create(switch_class, NULL, - MKDEV(0, sdev->index), NULL, sdev->name); - if (IS_ERR(sdev->dev)) - return PTR_ERR(sdev->dev); - - ret = device_create_file(sdev->dev, &dev_attr_state); - if (ret < 0) - goto err_create_file_1; - ret = device_create_file(sdev->dev, &dev_attr_name); - if (ret < 0) - goto err_create_file_2; - - dev_set_drvdata(sdev->dev, sdev); - sdev->state = 0; - return 0; - -err_create_file_2: - device_remove_file(sdev->dev, &dev_attr_state); -err_create_file_1: - device_destroy(switch_class, MKDEV(0, sdev->index)); - printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name); - - return ret; -} -EXPORT_SYMBOL_GPL(switch_dev_register); - -void switch_dev_unregister(struct switch_dev *sdev) -{ - device_remove_file(sdev->dev, &dev_attr_name); - device_remove_file(sdev->dev, &dev_attr_state); - device_destroy(switch_class, MKDEV(0, sdev->index)); - dev_set_drvdata(sdev->dev, NULL); -} -EXPORT_SYMBOL_GPL(switch_dev_unregister); - -static int __init switch_class_init(void) -{ - return create_switch_class(); -} - -static void __exit switch_class_exit(void) -{ - class_destroy(switch_class); -} - -module_init(switch_class_init); -module_exit(switch_class_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("Switch class driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/switch/switch_gpio.c b/drivers/switch/switch_gpio.c deleted file mode 100644 index 7e9faa211e48..000000000000 --- a/drivers/switch/switch_gpio.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * drivers/switch/switch_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -struct gpio_switch_data { - struct switch_dev sdev; - unsigned gpio; - const char *name_on; - const char *name_off; - const char *state_on; - const char *state_off; - int irq; - struct work_struct work; -}; - -static void gpio_switch_work(struct work_struct *work) -{ - int state; - struct gpio_switch_data *data = - container_of(work, struct gpio_switch_data, work); - - state = gpio_get_value(data->gpio); - switch_set_state(&data->sdev, state); -} - -static irqreturn_t gpio_irq_handler(int irq, void *dev_id) -{ - struct gpio_switch_data *switch_data = - (struct gpio_switch_data *)dev_id; - - schedule_work(&switch_data->work); - return IRQ_HANDLED; -} - -static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf) -{ - struct gpio_switch_data *switch_data = - container_of(sdev, struct gpio_switch_data, sdev); - const char *state; - if (switch_get_state(sdev)) - state = switch_data->state_on; - else - state = switch_data->state_off; - - if (state) - return sprintf(buf, "%s\n", state); - return -1; -} - -static int gpio_switch_probe(struct platform_device *pdev) -{ - struct gpio_switch_platform_data *pdata = pdev->dev.platform_data; - struct gpio_switch_data *switch_data; - int ret = 0; - - if (!pdata) - return -EBUSY; - - switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL); - if (!switch_data) - return -ENOMEM; - - switch_data->sdev.name = pdata->name; - switch_data->gpio = pdata->gpio; - switch_data->name_on = pdata->name_on; - switch_data->name_off = pdata->name_off; - switch_data->state_on = pdata->state_on; - switch_data->state_off = pdata->state_off; - switch_data->sdev.print_state = switch_gpio_print_state; - - ret = switch_dev_register(&switch_data->sdev); - if (ret < 0) - goto err_switch_dev_register; - - ret = gpio_request(switch_data->gpio, pdev->name); - if (ret < 0) - goto err_request_gpio; - - ret = gpio_direction_input(switch_data->gpio); - if (ret < 0) - goto err_set_gpio_input; - - INIT_WORK(&switch_data->work, gpio_switch_work); - - switch_data->irq = gpio_to_irq(switch_data->gpio); - if (switch_data->irq < 0) { - ret = switch_data->irq; - goto err_detect_irq_num_failed; - } - - ret = request_irq(switch_data->irq, gpio_irq_handler, - IRQF_TRIGGER_LOW, pdev->name, switch_data); - if (ret < 0) - goto err_request_irq; - - /* Perform initial detection */ - gpio_switch_work(&switch_data->work); - - return 0; - -err_request_irq: -err_detect_irq_num_failed: -err_set_gpio_input: - gpio_free(switch_data->gpio); -err_request_gpio: - switch_dev_unregister(&switch_data->sdev); -err_switch_dev_register: - kfree(switch_data); - - return ret; -} - -static int __devexit gpio_switch_remove(struct platform_device *pdev) -{ - struct gpio_switch_data *switch_data = platform_get_drvdata(pdev); - - cancel_work_sync(&switch_data->work); - gpio_free(switch_data->gpio); - switch_dev_unregister(&switch_data->sdev); - kfree(switch_data); - - return 0; -} - -static struct platform_driver gpio_switch_driver = { - .probe = gpio_switch_probe, - .remove = __devexit_p(gpio_switch_remove), - .driver = { - .name = "switch-gpio", - .owner = THIS_MODULE, - }, -}; - -static int __init gpio_switch_init(void) -{ - return platform_driver_register(&gpio_switch_driver); -} - -static void __exit gpio_switch_exit(void) -{ - platform_driver_unregister(&gpio_switch_driver); -} - -module_init(gpio_switch_init); -module_exit(gpio_switch_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("GPIO Switch driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 44447f54942f..ea071a5b6eee 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2301,7 +2301,7 @@ out: return ret; } -static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot); +static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, char *buf) @@ -2364,7 +2364,8 @@ out: return ret; } -static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL); +static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, + read_human_status, NULL); static ssize_t read_delin(struct device *dev, struct device_attribute *attr, char *buf) @@ -2396,7 +2397,7 @@ out: return ret; } -static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL); +static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); #define UEA_ATTR(name, reset) \ \ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 045bb4b823e1..f1aaff6202a5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -965,11 +965,10 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; return 0; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ffa3e22083c2..d7a4401ef019 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1324,20 +1324,6 @@ int usb_resume(struct device *dev, pm_message_t msg) * Unbind the interfaces that will need rebinding later. */ } else { - /* If a device aborts suspend, usb_resume may be called on a - * device whose parent has been auto-suspended. Recursively - * resume its parents and change their runtime pm state. - */ - if (udev->parent && msg.event == PM_EVENT_RESUME - && udev->parent->state == USB_STATE_SUSPENDED) { - status = usb_resume(&udev->parent->dev, msg); - if (status) { - dev_err(dev, "%s: failed to resume parent\n", - __func__); - return status; - } - } - status = usb_resume_both(udev, msg); if (status == 0) { pm_runtime_disable(dev); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 0ec8c12b4afb..e81faa5cc7d6 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1264,14 +1264,6 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle, } static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) -{ - if (hcd->driver->unmap_urb_for_dma) - hcd->driver->unmap_urb_for_dma(hcd, urb); - else - usb_hcd_unmap_urb_for_dma(hcd, urb); -} - -void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { enum dma_data_direction dir; @@ -1315,19 +1307,9 @@ void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) URB_DMA_MAP_SG | URB_DMA_MAP_PAGE | URB_DMA_MAP_SINGLE | URB_MAP_LOCAL); } -EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_for_dma); static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) -{ - if (hcd->driver->map_urb_for_dma) - return hcd->driver->map_urb_for_dma(hcd, urb, mem_flags); - else - return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); -} - -int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - gfp_t mem_flags) { enum dma_data_direction dir; int ret = 0; @@ -1418,11 +1400,10 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, } if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL))) - usb_hcd_unmap_urb_for_dma(hcd, urb); + unmap_urb_for_dma(hcd, urb); } return ret; } -EXPORT_SYMBOL_GPL(usb_hcd_map_urb_for_dma); /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8323699c2950..ed7ec9887a0e 100755 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2863,16 +2863,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, else i = udev->descriptor.bMaxPacketSize0; if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { - if (udev->speed == USB_SPEED_LOW || + if (udev->speed != USB_SPEED_FULL || !(i == 8 || i == 16 || i == 32 || i == 64)) { - dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); + dev_err(&udev->dev, "ep0 maxpacket = %d\n", i); retval = -EMSGSIZE; goto fail; } - if (udev->speed == USB_SPEED_FULL) - dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); - else - dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); + dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); usb_ep0_reinit(udev); } diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d6e3e410477e..9f0ce7de0e36 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1140,6 +1140,13 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; + dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, + skip_ep0 ? "non-ep0" : "all"); + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); + } + /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) */ @@ -1169,13 +1176,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) if (dev->state == USB_STATE_CONFIGURED) usb_set_device_state(dev, USB_STATE_ADDRESS); } - - dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, - skip_ep0 ? "non-ep0" : "all"); - for (i = skip_ep0; i < 16; ++i) { - usb_disable_endpoint(dev, i, true); - usb_disable_endpoint(dev, i + USB_DIR_IN, true); - } } /** diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a096d6f0932b..cd27f9bde2c8 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -156,7 +156,7 @@ config USB_ATMEL_USBA config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" - depends on FSL_SOC || ARCH_MXC || ARCH_TEGRA + depends on FSL_SOC || ARCH_MXC select USB_GADGET_DUALSPEED help Some of Freescale PowerPC processors have a High Speed @@ -837,61 +837,6 @@ config USB_G_PRINTER For more information, see Documentation/usb/gadget_printer.txt which includes sample code for accessing the device file. -config USB_ANDROID - boolean "Android Gadget" - depends on SWITCH - help - The Android gadget driver supports multiple USB functions. - The functions can be configured via a board file and may be - enabled and disabled dynamically. - -config USB_ANDROID_ACM - boolean "Android gadget ACM serial function" - depends on USB_ANDROID - help - Provides ACM serial function for android gadget driver. - -config USB_ANDROID_ADB - boolean "Android gadget adb function" - depends on USB_ANDROID - help - Provides adb function for android gadget driver. - -config USB_ANDROID_MASS_STORAGE - boolean "Android gadget mass storage function" - depends on USB_ANDROID && SWITCH - help - Provides USB mass storage function for android gadget driver. - -config USB_ANDROID_MTP - boolean "Android MTP function" - depends on USB_ANDROID - help - Provides Media Transfer Protocol (MTP) support for android gadget driver. - -config USB_ANDROID_RNDIS - boolean "Android gadget RNDIS ethernet function" - depends on USB_ANDROID - help - Provides RNDIS ethernet function for android gadget driver. - -config USB_ANDROID_RNDIS_WCEIS - boolean "Use Windows Internet Sharing Class/SubClass/Protocol" - depends on USB_ANDROID_RNDIS - help - Causes the driver to look like a Windows-compatible Internet - Sharing device, so Windows auto-detects it. - - If you enable this option, the device is no longer CDC ethernet - compatible. - - -config USB_ANDROID_ACCESSORY - boolean "Android USB accessory function" - depends on USB_ANDROID - help - Provides Android USB Accessory support for android gadget driver. - config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" depends on NET diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 010239b381da..27283df37d09 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -22,9 +22,6 @@ fsl_usb2_udc-objs := fsl_udc_core.o ifeq ($(CONFIG_ARCH_MXC),y) fsl_usb2_udc-objs += fsl_mxc_udc.o endif -ifeq ($(CONFIG_ARCH_TEGRA),y) -fsl_usb2_udc-objs += fsl_tegra_udc.o -endif obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o @@ -67,10 +64,4 @@ obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o -obj-$(CONFIG_USB_ANDROID) += android.o -obj-$(CONFIG_USB_ANDROID_ACM) += f_acm.o u_serial.o -obj-$(CONFIG_USB_ANDROID_ADB) += f_adb.o -obj-$(CONFIG_USB_ANDROID_MASS_STORAGE) += f_mass_storage.o -obj-$(CONFIG_USB_ANDROID_MTP) += f_mtp.o -obj-$(CONFIG_USB_ANDROID_RNDIS) += f_rndis.o u_ether.o -obj-$(CONFIG_USB_ANDROID_ACCESSORY) += f_accessory.o + diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c deleted file mode 100644 index a107dd25fc8f..000000000000 --- a/drivers/usb/gadget/android.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Gadget Driver for Android - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" -#include "composite.c" - -MODULE_AUTHOR("Mike Lockwood"); -MODULE_DESCRIPTION("Android Composite USB Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -static const char longname[] = "Gadget Android"; - -/* Default vendor and product IDs, overridden by platform data */ -#define VENDOR_ID 0x18D1 -#define PRODUCT_ID 0x0001 - -struct android_dev { - struct usb_composite_dev *cdev; - struct usb_configuration *config; - int num_products; - struct android_usb_product *products; - int num_functions; - char **functions; - - int vendor_id; - int product_id; - int version; -}; - -static struct android_dev *_android_dev; - -/* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_SERIAL_IDX 2 - -/* String Table */ -static struct usb_string strings_dev[] = { - /* These dummy values should be overridden by platform data */ - [STRING_MANUFACTURER_IDX].s = "Android", - [STRING_PRODUCT_IDX].s = "Android", - [STRING_SERIAL_IDX].s = "0123456789ABCDEF", - { } /* end of list */ -}; - -static struct usb_gadget_strings stringtab_dev = { - .language = 0x0409, /* en-us */ - .strings = strings_dev, -}; - -static struct usb_gadget_strings *dev_strings[] = { - &stringtab_dev, - NULL, -}; - -static struct usb_device_descriptor device_desc = { - .bLength = sizeof(device_desc), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .idVendor = __constant_cpu_to_le16(VENDOR_ID), - .idProduct = __constant_cpu_to_le16(PRODUCT_ID), - .bcdDevice = __constant_cpu_to_le16(0xffff), - .bNumConfigurations = 1, -}; - -static struct list_head _functions = LIST_HEAD_INIT(_functions); -static bool _are_functions_bound; - -static struct android_usb_function *get_function(const char *name) -{ - struct android_usb_function *f; - list_for_each_entry(f, &_functions, list) { - if (!strcmp(name, f->name)) - return f; - } - return 0; -} - -static bool are_functions_registered(struct android_dev *dev) -{ - char **functions = dev->functions; - int i; - - /* Look only for functions required by the board config */ - for (i = 0; i < dev->num_functions; i++) { - char *name = *functions++; - bool is_match = false; - /* Could reuse get_function() here, but a reverse search - * should yield less comparisons overall */ - struct android_usb_function *f; - list_for_each_entry_reverse(f, &_functions, list) { - if (!strcmp(name, f->name)) { - is_match = true; - break; - } - } - if (is_match) - continue; - else - return false; - } - - return true; -} - -static bool should_bind_functions(struct android_dev *dev) -{ - /* Don't waste time if the main driver hasn't bound */ - if (!dev->config) - return false; - - /* Don't waste time if we've already bound the functions */ - if (_are_functions_bound) - return false; - - /* This call is the most costly, so call it last */ - if (!are_functions_registered(dev)) - return false; - - return true; -} - -static void bind_functions(struct android_dev *dev) -{ - struct android_usb_function *f; - char **functions = dev->functions; - int i; - - for (i = 0; i < dev->num_functions; i++) { - char *name = *functions++; - f = get_function(name); - if (f) - f->bind_config(dev->config); - else - printk(KERN_ERR "function %s not found in bind_functions\n", name); - } - - _are_functions_bound = true; -} - -static int android_bind_config(struct usb_configuration *c) -{ - struct android_dev *dev = _android_dev; - - printk(KERN_DEBUG "android_bind_config\n"); - dev->config = c; - - if (should_bind_functions(dev)) - bind_functions(dev); - - return 0; -} - -static int android_setup_config(struct usb_configuration *c, - const struct usb_ctrlrequest *ctrl); - -static struct usb_configuration android_config_driver = { - .label = "android", - .bind = android_bind_config, - .setup = android_setup_config, - .bConfigurationValue = 1, - .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 0xFA, /* 500ma */ -}; - -static int android_setup_config(struct usb_configuration *c, - const struct usb_ctrlrequest *ctrl) -{ - int i; - int ret = -EOPNOTSUPP; - - for (i = 0; i < android_config_driver.next_interface_id; i++) { - if (android_config_driver.interface[i]->setup) { - ret = android_config_driver.interface[i]->setup( - android_config_driver.interface[i], ctrl); - if (ret >= 0) - return ret; - } - } - return ret; -} - -static int product_has_function(struct android_usb_product *p, - struct usb_function *f) -{ - char **functions = p->functions; - int count = p->num_functions; - const char *name = f->name; - int i; - - for (i = 0; i < count; i++) { - /* For functions with multiple instances, usb_function.name - * will have an index appended to the core name (ex: acm0), - * while android_usb_product.functions[i] will only have the - * core name (ex: acm). So, only compare up to the length of - * android_usb_product.functions[i]. - */ - if (!strncmp(name, functions[i], strlen(functions[i]))) - return 1; - } - return 0; -} - -static int product_matches_functions(struct android_usb_product *p) -{ - struct usb_function *f; - list_for_each_entry(f, &android_config_driver.functions, list) { - if (product_has_function(p, f) == !!f->disabled) - return 0; - } - return 1; -} - -static int get_vendor_id(struct android_dev *dev) -{ - struct android_usb_product *p = dev->products; - int count = dev->num_products; - int i; - - if (p) { - for (i = 0; i < count; i++, p++) { - if (p->vendor_id && product_matches_functions(p)) - return p->vendor_id; - } - } - /* use default vendor ID */ - return dev->vendor_id; -} - -static int get_product_id(struct android_dev *dev) -{ - struct android_usb_product *p = dev->products; - int count = dev->num_products; - int i; - - if (p) { - for (i = 0; i < count; i++, p++) { - if (product_matches_functions(p)) - return p->product_id; - } - } - /* use default product ID */ - return dev->product_id; -} - -static int android_bind(struct usb_composite_dev *cdev) -{ - struct android_dev *dev = _android_dev; - struct usb_gadget *gadget = cdev->gadget; - int gcnum, id, ret; - - printk(KERN_INFO "android_bind\n"); - - /* Allocate string descriptor numbers ... note that string - * contents can be overridden by the composite_dev glue. - */ - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_MANUFACTURER_IDX].id = id; - device_desc.iManufacturer = id; - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_PRODUCT_IDX].id = id; - device_desc.iProduct = id; - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_SERIAL_IDX].id = id; - device_desc.iSerialNumber = id; - - /* register our configuration */ - ret = usb_add_config(cdev, &android_config_driver); - if (ret) { - printk(KERN_ERR "usb_add_config failed\n"); - return ret; - } - - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - else { - /* gadget zero is so simple (for now, no altsettings) that - * it SHOULD NOT have problems with bulk-capable hardware. - * so just warn about unrcognized controllers -- don't panic. - * - * things like configuration and altsetting numbering - * can need hardware-specific attention though. - */ - pr_warning("%s: controller '%s' not recognized\n", - longname, gadget->name); - device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); - } - - usb_gadget_set_selfpowered(gadget); - dev->cdev = cdev; - device_desc.idVendor = __constant_cpu_to_le16(get_vendor_id(dev)); - device_desc.idProduct = __constant_cpu_to_le16(get_product_id(dev)); - cdev->desc.idVendor = device_desc.idVendor; - cdev->desc.idProduct = device_desc.idProduct; - - return 0; -} - -static struct usb_composite_driver android_usb_driver = { - .name = "android_usb", - .dev = &device_desc, - .strings = dev_strings, - .bind = android_bind, - .enable_function = android_enable_function, -}; - -void android_register_function(struct android_usb_function *f) -{ - struct android_dev *dev = _android_dev; - - printk(KERN_INFO "android_register_function %s\n", f->name); - list_add_tail(&f->list, &_functions); - - if (dev && should_bind_functions(dev)) - bind_functions(dev); -} - -void update_dev_desc(struct android_dev *dev) -{ - struct usb_function *f; - struct usb_function *last_enabled_f = NULL; - int num_enabled = 0; - int has_iad = 0; - - dev->cdev->desc.bDeviceClass = USB_CLASS_PER_INTERFACE; - dev->cdev->desc.bDeviceSubClass = 0x00; - dev->cdev->desc.bDeviceProtocol = 0x00; - - list_for_each_entry(f, &android_config_driver.functions, list) { - if (!f->disabled) { - num_enabled++; - last_enabled_f = f; - if (f->descriptors[0]->bDescriptorType == - USB_DT_INTERFACE_ASSOCIATION) - has_iad = 1; - } - if (num_enabled > 1 && has_iad) { - dev->cdev->desc.bDeviceClass = USB_CLASS_MISC; - dev->cdev->desc.bDeviceSubClass = 0x02; - dev->cdev->desc.bDeviceProtocol = 0x01; - break; - } - } - - if (num_enabled == 1) { -#ifdef CONFIG_USB_ANDROID_RNDIS - if (!strcmp(last_enabled_f->name, "rndis")) { -#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS - dev->cdev->desc.bDeviceClass = - USB_CLASS_WIRELESS_CONTROLLER; -#else - dev->cdev->desc.bDeviceClass = USB_CLASS_COMM; -#endif - } -#endif - } -} - -void android_enable_function(struct usb_function *f, int enable) -{ - struct android_dev *dev = _android_dev; - int disable = !enable; - - if (!!f->disabled != disable) { - usb_function_set_enabled(f, !disable); - -#ifdef CONFIG_USB_ANDROID_RNDIS - if (!strcmp(f->name, "rndis")) { - struct usb_function *func; - /* Windows does not support other interfaces when RNDIS is enabled, - * so we disable UMS and MTP when RNDIS is on. - */ - list_for_each_entry(func, &android_config_driver.functions, list) { - if (!strcmp(func->name, "usb_mass_storage") - || !strcmp(func->name, "mtp")) { - usb_function_set_enabled(func, !enable); - } - } - } -#endif -#ifdef CONFIG_USB_ANDROID_ACCESSORY - if (!strcmp(f->name, "accessory") && enable) { - struct usb_function *func; - - /* disable everything else (and keep adb for now) */ - list_for_each_entry(func, &android_config_driver.functions, list) { - if (strcmp(func->name, "accessory") - && strcmp(func->name, "adb")) { - usb_function_set_enabled(func, 0); - } - } - } -#endif - - update_dev_desc(dev); - - device_desc.idVendor = __constant_cpu_to_le16(get_vendor_id(dev)); - device_desc.idProduct = __constant_cpu_to_le16(get_product_id(dev)); - if (dev->cdev) { - dev->cdev->desc.idVendor = device_desc.idVendor; - dev->cdev->desc.idProduct = device_desc.idProduct; - } - usb_composite_force_reset(dev->cdev); - } -} - -static int android_probe(struct platform_device *pdev) -{ - struct android_usb_platform_data *pdata = pdev->dev.platform_data; - struct android_dev *dev = _android_dev; - - printk(KERN_INFO "android_probe pdata: %p\n", pdata); - - if (pdata) { - dev->products = pdata->products; - dev->num_products = pdata->num_products; - dev->functions = pdata->functions; - dev->num_functions = pdata->num_functions; - if (pdata->vendor_id) { - dev->vendor_id = pdata->vendor_id; - device_desc.idVendor = - __constant_cpu_to_le16(pdata->vendor_id); - } - if (pdata->product_id) { - dev->product_id = pdata->product_id; - device_desc.idProduct = - __constant_cpu_to_le16(pdata->product_id); - } - if (pdata->version) - dev->version = pdata->version; - - if (pdata->product_name) - strings_dev[STRING_PRODUCT_IDX].s = pdata->product_name; - if (pdata->manufacturer_name) - strings_dev[STRING_MANUFACTURER_IDX].s = - pdata->manufacturer_name; - if (pdata->serial_number) - strings_dev[STRING_SERIAL_IDX].s = pdata->serial_number; - } - - return usb_composite_register(&android_usb_driver); -} - -static struct platform_driver android_platform_driver = { - .driver = { .name = "android_usb", }, - .probe = android_probe, -}; - -static int __init init(void) -{ - struct android_dev *dev; - - printk(KERN_INFO "android init\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - /* set default values, which should be overridden by platform data */ - dev->product_id = PRODUCT_ID; - _android_dev = dev; - - return platform_driver_register(&android_platform_driver); -} -module_init(init); - -static void __exit cleanup(void) -{ - usb_composite_unregister(&android_usb_driver); - platform_driver_unregister(&android_platform_driver); - kfree(_android_dev); - _android_dev = NULL; -} -module_exit(cleanup); diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 2d19d88846ef..d623c7bda1f6 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -2014,9 +2014,6 @@ static int __init usba_udc_probe(struct platform_device *pdev) } else { disable_irq(gpio_to_irq(udc->vbus_pin)); } - } else { - /* gpio_request fail so use -EINVAL for gpio_is_valid */ - udc->vbus_pin = -EINVAL; } } diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d91cdcab8f65..86a58e4d8b85 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -71,56 +71,6 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); /*-------------------------------------------------------------------------*/ -static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct usb_function *f = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", !f->disabled); -} - -static ssize_t enable_store( - struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct usb_function *f = dev_get_drvdata(dev); - struct usb_composite_driver *driver = f->config->cdev->driver; - int value; - - sscanf(buf, "%d", &value); - if (driver->enable_function) - driver->enable_function(f, value); - else - usb_function_set_enabled(f, value); - - return size; -} - -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); - -void usb_function_set_enabled(struct usb_function *f, int enabled) -{ - f->disabled = !enabled; - kobject_uevent(&f->dev->kobj, KOBJ_CHANGE); -} - - -void usb_composite_force_reset(struct usb_composite_dev *cdev) -{ - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - /* force reenumeration */ - if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) { - spin_unlock_irqrestore(&cdev->lock, flags); - - usb_gadget_disconnect(cdev->gadget); - msleep(10); - usb_gadget_connect(cdev->gadget); - } else { - spin_unlock_irqrestore(&cdev->lock, flags); - } -} - /** * usb_add_function() - add a function to a configuration * @config: the configuration @@ -138,30 +88,15 @@ void usb_composite_force_reset(struct usb_composite_dev *cdev) int usb_add_function(struct usb_configuration *config, struct usb_function *function) { - struct usb_composite_dev *cdev = config->cdev; int value = -EINVAL; - int index; - DBG(cdev, "adding '%s'/%p to config '%s'/%p\n", + DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", function->name, function, config->label, config); if (!function->set_alt || !function->disable) goto done; - index = atomic_inc_return(&cdev->driver->function_count); - function->dev = device_create(cdev->driver->class, NULL, - MKDEV(0, index), NULL, function->name); - if (IS_ERR(function->dev)) - return PTR_ERR(function->dev); - - value = device_create_file(function->dev, &dev_attr_enable); - if (value < 0) { - device_destroy(cdev->driver->class, MKDEV(0, index)); - return value; - } - dev_set_drvdata(function->dev, function); - function->config = config; list_add_tail(&function->list, &config->functions); @@ -187,7 +122,7 @@ int usb_add_function(struct usb_configuration *config, done: if (value) - DBG(cdev, "adding '%s'/%p --> %d\n", + DBG(config->cdev, "adding '%s'/%p --> %d\n", function->name, function, value); return value; } @@ -297,20 +232,17 @@ static int config_buf(struct usb_configuration *config, enum usb_device_speed speed, void *buf, u8 type) { struct usb_config_descriptor *c = buf; - struct usb_interface_descriptor *intf; - struct usb_interface_assoc_descriptor *iad = NULL; void *next = buf + USB_DT_CONFIG_SIZE; int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE; struct usb_function *f; int status; - int interfaceCount = 0; - u8 *dest; /* write the config descriptor */ c = buf; c->bLength = USB_DT_CONFIG_SIZE; c->bDescriptorType = type; - /* wTotalLength and bNumInterfaces are written later */ + /* wTotalLength is written later */ + c->bNumInterfaces = config->next_interface_id; c->bConfigurationValue = config->bConfigurationValue; c->iConfiguration = config->iConfiguration; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; @@ -329,54 +261,23 @@ static int config_buf(struct usb_configuration *config, /* add each function's descriptors */ list_for_each_entry(f, &config->functions, list) { struct usb_descriptor_header **descriptors; - struct usb_descriptor_header *descriptor; if (speed == USB_SPEED_HIGH) descriptors = f->hs_descriptors; else descriptors = f->descriptors; - if (f->disabled || !descriptors || descriptors[0] == NULL) + if (!descriptors) continue; status = usb_descriptor_fillbuf(next, len, (const struct usb_descriptor_header **) descriptors); if (status < 0) return status; - - /* set interface numbers dynamically */ - dest = next; - while ((descriptor = *descriptors++) != NULL) { - intf = (struct usb_interface_descriptor *)dest; - if (intf->bDescriptorType == USB_DT_INTERFACE) { - /* don't increment bInterfaceNumber for alternate settings */ - if (intf->bAlternateSetting == 0) - intf->bInterfaceNumber = interfaceCount++; - else - intf->bInterfaceNumber = interfaceCount - 1; - if (iad) { - iad->bFirstInterface = - intf->bInterfaceNumber; - iad = NULL; - } - } else if (intf->bDescriptorType == - USB_DT_INTERFACE_ASSOCIATION) { - /* This will be first if it exists. Save - * a pointer to it so we can properly set - * bFirstInterface when we process the first - * interface. - */ - iad = (struct usb_interface_assoc_descriptor *) - dest; - } - dest += intf->bLength; - } - len -= status; next += status; } len = next - buf; c->wTotalLength = cpu_to_le16(len); - c->bNumInterfaces = interfaceCount; return len; } @@ -523,8 +424,6 @@ static int set_config(struct usb_composite_dev *cdev, if (!f) break; - if (f->disabled) - continue; /* * Record which endpoints are used by the function. This is used @@ -564,8 +463,6 @@ static int set_config(struct usb_composite_dev *cdev, power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; done: usb_gadget_vbus_draw(gadget, power); - - schedule_work(&cdev->switch_work); return result; } @@ -883,14 +780,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) u16 w_length = le16_to_cpu(ctrl->wLength); struct usb_function *f = NULL; u8 endp; - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - if (!cdev->connected) { - cdev->connected = 1; - schedule_work(&cdev->switch_work); - } - spin_unlock_irqrestore(&cdev->lock, flags); /* partial re-init of the response message; the function or the * gadget might need to intercept e.g. a control-OUT completion @@ -934,21 +823,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_DT_STRING: value = get_string(cdev, req->buf, w_index, w_value & 0xff); - - /* Allow functions to handle USB_DT_STRING. - * This is required for MTP. - */ - if (value < 0) { - struct usb_configuration *cfg; - list_for_each_entry(cfg, &cdev->configs, list) { - if (cfg && cfg->setup) { - value = cfg->setup(cfg, ctrl); - if (value >= 0) - break; - } - } - } - if (value >= 0) value = min(w_length, (u16) value); break; @@ -974,11 +848,11 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; - if (cdev->config) { + if (cdev->config) *(u8 *)req->buf = cdev->config->bConfigurationValue; - value = min(w_length, (u16) 1); - } else + else *(u8 *)req->buf = 0; + value = min(w_length, (u16) 1); break; /* function drivers must handle get/set altsetting; if there's @@ -1028,8 +902,7 @@ unknown: */ switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: - if (cdev->config) - f = cdev->config->interface[intf]; + f = cdev->config->interface[intf]; break; case USB_RECIP_ENDPOINT: @@ -1053,25 +926,6 @@ unknown: value = c->setup(c, ctrl); } - /* If the vendor request is not processed (value < 0), - * call all device registered configure setup callbacks - * to process it. - * This is used to handle the following cases: - * - vendor request is for the device and arrives before - * setconfiguration. - * - Some devices are required to handle vendor request before - * setconfiguration such as MTP, USBNET. - */ - - if (value < 0) { - struct usb_configuration *cfg; - - list_for_each_entry(cfg, &cdev->configs, list) { - if (cfg && cfg->setup) - value = cfg->setup(cfg, ctrl); - } - } - goto done; } @@ -1103,12 +957,8 @@ static void composite_disconnect(struct usb_gadget *gadget) spin_lock_irqsave(&cdev->lock, flags); if (cdev->config) reset_config(cdev); - if (composite->disconnect) composite->disconnect(cdev); - - cdev->connected = 0; - schedule_work(&cdev->switch_work); spin_unlock_irqrestore(&cdev->lock, flags); } @@ -1170,9 +1020,6 @@ composite_unbind(struct usb_gadget *gadget) kfree(cdev->req->buf); usb_ep_free_request(gadget->ep0, cdev->req); } - - switch_dev_unregister(&cdev->sw_connected); - switch_dev_unregister(&cdev->sw_config); kfree(cdev); set_gadget_data(gadget, NULL); device_remove_file(&gadget->dev, &dev_attr_suspended); @@ -1201,30 +1048,6 @@ string_override(struct usb_gadget_strings **tab, u8 id, const char *s) } } -static void -composite_switch_work(struct work_struct *data) -{ - struct usb_composite_dev *cdev = - container_of(data, struct usb_composite_dev, switch_work); - struct usb_configuration *config = cdev->config; - int connected; - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->connected != cdev->sw_connected.state) { - connected = cdev->connected; - spin_unlock_irqrestore(&cdev->lock, flags); - switch_set_state(&cdev->sw_connected, connected); - } else { - spin_unlock_irqrestore(&cdev->lock, flags); - } - - if (config) - switch_set_state(&cdev->sw_config, config->bConfigurationValue); - else - switch_set_state(&cdev->sw_config, 0); -} - static int composite_bind(struct usb_gadget *gadget) { struct usb_composite_dev *cdev; @@ -1260,6 +1083,14 @@ 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 @@ -1268,27 +1099,9 @@ static int composite_bind(struct usb_gadget *gadget) if (status < 0) goto fail; - cdev->sw_connected.name = "usb_connected"; - status = switch_dev_register(&cdev->sw_connected); - if (status < 0) - goto fail; - cdev->sw_config.name = "usb_configuration"; - status = switch_dev_register(&cdev->sw_config); - if (status < 0) - goto fail; - INIT_WORK(&cdev->switch_work, composite_switch_work); - 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); - /* strings can't be assigned before bind() allocates the * releavnt identifiers */ @@ -1360,23 +1173,6 @@ composite_resume(struct usb_gadget *gadget) cdev->suspended = 0; } -static int -composite_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct usb_function *f = dev_get_drvdata(dev); - - if (!f) { - /* this happens when the device is first created */ - return 0; - } - - if (add_uevent_var(env, "FUNCTION=%s", f->name)) - return -ENOMEM; - if (add_uevent_var(env, "ENABLED=%d", !f->disabled)) - return -ENOMEM; - return 0; -} - /*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { @@ -1422,11 +1218,6 @@ int usb_composite_register(struct usb_composite_driver *driver) composite_driver.driver.name = driver->name; composite = driver; - driver->class = class_create(THIS_MODULE, "usb_composite"); - if (IS_ERR(driver->class)) - return PTR_ERR(driver->class); - driver->class->dev_uevent = composite_uevent; - return usb_gadget_register_driver(&composite_driver); } diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c deleted file mode 100644 index ad3c1738336f..000000000000 --- a/drivers/usb/gadget/f_accessory.c +++ /dev/null @@ -1,808 +0,0 @@ -/* - * Gadget Function Driver for Android USB accessories - * - * Copyright (C) 2011 Google, Inc. - * Author: Mike Lockwood - * - * 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. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#define BULK_BUFFER_SIZE 16384 -#define ACC_STRING_SIZE 256 - -#define PROTOCOL_VERSION 1 - -/* String IDs */ -#define INTERFACE_STRING_INDEX 0 - -/* number of tx and rx requests to allocate */ -#define TX_REQ_MAX 4 -#define RX_REQ_MAX 2 - -struct acc_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - - /* set to 1 when we connect */ - int online:1; - /* Set to 1 when we disconnect. - * Not cleared until our file is closed. - */ - int disconnected:1; - - /* strings sent by the host */ - char manufacturer[ACC_STRING_SIZE]; - char model[ACC_STRING_SIZE]; - char description[ACC_STRING_SIZE]; - char version[ACC_STRING_SIZE]; - char uri[ACC_STRING_SIZE]; - char serial[ACC_STRING_SIZE]; - - /* for acc_complete_set_string */ - int string_index; - - /* synchronize access to our device file */ - atomic_t open_excl; - - struct list_head tx_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - struct usb_request *rx_req[RX_REQ_MAX]; - int rx_done; - struct delayed_work work; -}; - -static struct usb_interface_descriptor acc_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, - .bInterfaceProtocol = 0, -}; - -static struct usb_endpoint_descriptor acc_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor acc_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor acc_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *fs_acc_descs[] = { - (struct usb_descriptor_header *) &acc_interface_desc, - (struct usb_descriptor_header *) &acc_fullspeed_in_desc, - (struct usb_descriptor_header *) &acc_fullspeed_out_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_acc_descs[] = { - (struct usb_descriptor_header *) &acc_interface_desc, - (struct usb_descriptor_header *) &acc_highspeed_in_desc, - (struct usb_descriptor_header *) &acc_highspeed_out_desc, - NULL, -}; - -static struct usb_string acc_string_defs[] = { - [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", - { }, /* end of list */ -}; - -static struct usb_gadget_strings acc_string_table = { - .language = 0x0409, /* en-US */ - .strings = acc_string_defs, -}; - -static struct usb_gadget_strings *acc_strings[] = { - &acc_string_table, - NULL, -}; - -/* temporary variable used between acc_open() and acc_gadget_bind() */ -static struct acc_dev *_acc_dev; - -static inline struct acc_dev *func_to_dev(struct usb_function *f) -{ - return container_of(f, struct acc_dev, function); -} - -static struct usb_request *acc_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void acc_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -/* add a request to the tail of a list */ -static void req_put(struct acc_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -static struct usb_request *req_get(struct acc_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void acc_set_disconnected(struct acc_dev *dev) -{ - dev->online = 0; - dev->disconnected = 1; -} - -static void acc_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = _acc_dev; - - if (req->status != 0) - acc_set_disconnected(dev); - - req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void acc_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = _acc_dev; - - dev->rx_done = 1; - if (req->status != 0) - acc_set_disconnected(dev); - - wake_up(&dev->read_wq); -} - -static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) -{ - struct acc_dev *dev = ep->driver_data; - struct usb_composite_dev *cdev = dev->cdev; - char *string_dest = NULL; - int length = req->actual; - - if (req->status != 0) { - DBG(cdev, "acc_complete_set_string, err %d\n", req->status); - return; - } - - switch (dev->string_index) { - case ACCESSORY_STRING_MANUFACTURER: - string_dest = dev->manufacturer; - break; - case ACCESSORY_STRING_MODEL: - string_dest = dev->model; - break; - case ACCESSORY_STRING_DESCRIPTION: - string_dest = dev->description; - break; - case ACCESSORY_STRING_VERSION: - string_dest = dev->version; - break; - case ACCESSORY_STRING_URI: - string_dest = dev->uri; - break; - case ACCESSORY_STRING_SERIAL: - string_dest = dev->serial; - break; - } - if (string_dest) { - unsigned long flags; - - if (length >= ACC_STRING_SIZE) - length = ACC_STRING_SIZE - 1; - - spin_lock_irqsave(&dev->lock, flags); - memcpy(string_dest, cdev->req->buf, length); - /* ensure zero termination */ - string_dest[length] = 0; - spin_unlock_irqrestore(&dev->lock, flags); - } else { - DBG(cdev, "unknown accessory string index %d\n", - dev->string_index); - } -} - -static int __init create_bulk_endpoints(struct acc_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - /* now allocate requests for our endpoints */ - for (i = 0; i < TX_REQ_MAX; i++) { - req = acc_request_new(dev->ep_in, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = acc_complete_in; - req_put(dev, &dev->tx_idle, req); - } - for (i = 0; i < RX_REQ_MAX; i++) { - req = acc_request_new(dev->ep_out, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = acc_complete_out; - dev->rx_req[i] = req; - } - - return 0; - -fail: - printk(KERN_ERR "acc_bind() could not allocate requests\n"); - while ((req = req_get(dev, &dev->tx_idle))) - acc_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - acc_request_free(dev->rx_req[i], dev->ep_out); - return -1; -} - -static ssize_t acc_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct acc_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - int r = count, xfer; - int ret = 0; - - DBG(cdev, "acc_read(%d)\n", count); - - if (dev->disconnected) - return -ENODEV; - - if (count > BULK_BUFFER_SIZE) - count = BULK_BUFFER_SIZE; - - /* we will block until we're online */ - DBG(cdev, "acc_read: waiting for online\n"); - ret = wait_event_interruptible(dev->read_wq, dev->online); - if (ret < 0) { - r = ret; - goto done; - } - -requeue_req: - /* queue a request */ - req = dev->rx_req[0]; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - goto done; - } else { - DBG(cdev, "rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - r = ret; - usb_ep_dequeue(dev->ep_out, req); - goto done; - } - if (dev->online) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - DBG(cdev, "rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - r = xfer; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - } else - r = -EIO; - -done: - DBG(cdev, "acc_read returning %d\n", r); - return r; -} - -static ssize_t acc_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct acc_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - int r = count, xfer; - int ret; - - DBG(cdev, "acc_write(%d)\n", count); - - if (!dev->online || dev->disconnected) - return -ENODEV; - - while (count > 0) { - if (!dev->online) { - DBG(cdev, "acc_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); - if (!req) { - r = ret; - break; - } - - if (count > BULK_BUFFER_SIZE) - xfer = BULK_BUFFER_SIZE; - else - xfer = count; - if (copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - DBG(cdev, "acc_write: xfer error %d\n", ret); - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - req_put(dev, &dev->tx_idle, req); - - DBG(cdev, "acc_write returning %d\n", r); - return r; -} - -static long acc_ioctl(struct file *fp, unsigned code, unsigned long value) -{ - struct acc_dev *dev = fp->private_data; - char *src = NULL; - int ret; - - if (dev->function.disabled) - return -ENODEV; - - switch (code) { - case ACCESSORY_GET_STRING_MANUFACTURER: - src = dev->manufacturer; - break; - case ACCESSORY_GET_STRING_MODEL: - src = dev->model; - break; - case ACCESSORY_GET_STRING_DESCRIPTION: - src = dev->description; - break; - case ACCESSORY_GET_STRING_VERSION: - src = dev->version; - break; - case ACCESSORY_GET_STRING_URI: - src = dev->uri; - break; - case ACCESSORY_GET_STRING_SERIAL: - src = dev->serial; - break; - } - if (!src) - return -EINVAL; - - ret = strlen(src) + 1; - if (copy_to_user((void __user *)value, src, ret)) - ret = -EFAULT; - return ret; -} - -static int acc_open(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "acc_open\n"); - if (atomic_xchg(&_acc_dev->open_excl, 1)) - return -EBUSY; - - _acc_dev->disconnected = 0; - fp->private_data = _acc_dev; - return 0; -} - -static int acc_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "acc_release\n"); - - WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0)); - _acc_dev->disconnected = 0; - return 0; -} - -/* file operations for /dev/acc_usb */ -static const struct file_operations acc_fops = { - .owner = THIS_MODULE, - .read = acc_read, - .write = acc_write, - .unlocked_ioctl = acc_ioctl, - .open = acc_open, - .release = acc_release, -}; - -static struct miscdevice acc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "usb_accessory", - .fops = &acc_fops, -}; - -static int -acc_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct acc_dev *dev = func_to_dev(f); - int id; - int ret; - - dev->cdev = cdev; - DBG(cdev, "acc_function_bind dev: %p\n", dev); - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - acc_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, - &acc_fullspeed_out_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - acc_highspeed_in_desc.bEndpointAddress = - acc_fullspeed_in_desc.bEndpointAddress; - acc_highspeed_out_desc.bEndpointAddress = - acc_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -acc_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_request *req; - int i; - - spin_lock_irq(&dev->lock); - while ((req = req_get(dev, &dev->tx_idle))) - acc_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - acc_request_free(dev->rx_req[i], dev->ep_out); - dev->online = 0; - spin_unlock_irq(&dev->lock); - - misc_deregister(&acc_device); - kfree(_acc_dev); - _acc_dev = NULL; -} - -static void acc_work(struct work_struct *data) -{ - struct delayed_work *delayed = to_delayed_work(data); - struct acc_dev *dev = - container_of(delayed, struct acc_dev, work); - android_enable_function(&dev->function, 1); -} - -static int acc_function_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - int value = -EOPNOTSUPP; - u8 b_requestType = ctrl->bRequestType; - u8 b_request = ctrl->bRequest; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - -/* - printk(KERN_INFO "acc_function_setup " - "%02x.%02x v%04x i%04x l%u\n", - b_requestType, b_request, - w_value, w_index, w_length); -*/ - - if (dev->function.disabled) { - if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { - if (b_request == ACCESSORY_START) { - schedule_delayed_work( - &dev->work, msecs_to_jiffies(10)); - value = 0; - } else if (b_request == ACCESSORY_SEND_STRING) { - dev->string_index = w_index; - cdev->gadget->ep0->driver_data = dev; - cdev->req->complete = acc_complete_set_string; - value = w_length; - } - } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { - if (b_request == ACCESSORY_GET_PROTOCOL) { - *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; - value = sizeof(u16); - - /* clear any strings left over from a previous session */ - memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); - memset(dev->model, 0, sizeof(dev->model)); - memset(dev->description, 0, sizeof(dev->description)); - memset(dev->version, 0, sizeof(dev->version)); - memset(dev->uri, 0, sizeof(dev->uri)); - memset(dev->serial, 0, sizeof(dev->serial)); - } - } - } - - if (value >= 0) { - cdev->req->zero = 0; - cdev->req->length = value; - value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); - if (value < 0) - ERROR(cdev, "%s setup response queue error\n", - __func__); - } - - if (value == -EOPNOTSUPP) - VDBG(cdev, - "unknown class-specific control req " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - return value; -} - -static int acc_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &acc_highspeed_in_desc, - &acc_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &acc_highspeed_out_desc, - &acc_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - if (!dev->function.disabled) - dev->online = 1; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void acc_function_disable(struct usb_function *f) -{ - struct acc_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "acc_function_disable\n"); - acc_set_disconnected(dev); - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int acc_bind_config(struct usb_configuration *c) -{ - struct acc_dev *dev; - int ret; - - printk(KERN_INFO "acc_bind_config\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - /* allocate a string ID for our interface */ - if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { - ret = usb_string_id(c->cdev); - if (ret < 0) - return ret; - acc_string_defs[INTERFACE_STRING_INDEX].id = ret; - acc_interface_desc.iInterface = ret; - } - - spin_lock_init(&dev->lock); - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - atomic_set(&dev->open_excl, 0); - INIT_LIST_HEAD(&dev->tx_idle); - INIT_DELAYED_WORK(&dev->work, acc_work); - - dev->cdev = c->cdev; - dev->function.name = "accessory"; - dev->function.strings = acc_strings, - dev->function.descriptors = fs_acc_descs; - dev->function.hs_descriptors = hs_acc_descs; - dev->function.bind = acc_function_bind; - dev->function.unbind = acc_function_unbind; - dev->function.setup = acc_function_setup; - dev->function.set_alt = acc_function_set_alt; - dev->function.disable = acc_function_disable; - dev->function.disabled = 1; - - /* _acc_dev must be set before calling usb_gadget_register_driver */ - _acc_dev = dev; - - ret = misc_register(&acc_device); - if (ret) - goto err1; - - ret = usb_add_function(c, &dev->function); - if (ret) - goto err2; - - return 0; - -err2: - misc_deregister(&acc_device); -err1: - kfree(dev); - printk(KERN_ERR "USB accessory gadget driver failed to initialize\n"); - return ret; -} - -static struct android_usb_function acc_function = { - .name = "accessory", - .bind_config = acc_bind_config, -}; - -static int __init init(void) -{ - printk(KERN_INFO "f_accessory init\n"); - android_register_function(&acc_function); - return 0; -} -module_init(init); diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index cf2e7fc7659f..d47a123f15ab 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "u_serial.h" #include "gadget_chips.h" @@ -112,7 +111,7 @@ acm_iad_descriptor = { .bInterfaceCount = 2, // control + data .bFunctionClass = USB_CLASS_COMM, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, - .bFunctionProtocol = USB_CDC_ACM_PROTO_AT_V25TER, + .bFunctionProtocol = USB_CDC_PROTO_NONE, /* .iFunction = DYNAMIC */ }; @@ -406,10 +405,10 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_disable(acm->notify); } else { VDBG(cdev, "init acm ctrl interface %d\n", intf); + acm->notify_desc = ep_choose(cdev->gadget, + acm->hs.notify, + acm->fs.notify); } - acm->notify_desc = ep_choose(cdev->gadget, - acm->hs.notify, - acm->fs.notify); usb_ep_enable(acm->notify, acm->notify_desc); acm->notify->driver_data = acm; @@ -419,11 +418,11 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gserial_disconnect(&acm->port); } else { DBG(cdev, "activate acm ttyGS%d\n", acm->port_num); + acm->port.in_desc = ep_choose(cdev->gadget, + acm->hs.in, acm->fs.in); + acm->port.out_desc = ep_choose(cdev->gadget, + acm->hs.out, acm->fs.out); } - acm->port.in_desc = ep_choose(cdev->gadget, - acm->hs.in, acm->fs.in); - acm->port.out_desc = ep_choose(cdev->gadget, - acm->hs.out, acm->fs.out); gserial_connect(&acm->port, acm->port_num); } else @@ -698,7 +697,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) usb_free_descriptors(f->hs_descriptors); usb_free_descriptors(f->descriptors); gs_free_req(acm->notify, acm->notify_req); - kfree(acm->port.func.name); kfree(acm); } @@ -770,11 +768,7 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) acm->port.disconnect = acm_disconnect; acm->port.send_break = acm_send_break; - acm->port.func.name = kasprintf(GFP_KERNEL, "acm%u", port_num); - if (!acm->port.func.name) { - kfree(acm); - return -ENOMEM; - } + acm->port.func.name = "acm"; acm->port.func.strings = acm_strings; /* descriptors are per-instance copies */ acm->port.func.bind = acm_bind; @@ -788,55 +782,3 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) kfree(acm); return status; } - -#ifdef CONFIG_USB_ANDROID_ACM -#include - -static struct acm_platform_data *acm_pdata; - -static int acm_probe(struct platform_device *pdev) -{ - acm_pdata = pdev->dev.platform_data; - return 0; -} - -static struct platform_driver acm_platform_driver = { - .driver = { .name = "acm", }, - .probe = acm_probe, -}; - -int acm_function_bind_config(struct usb_configuration *c) -{ - int i; - u8 num_inst = acm_pdata ? acm_pdata->num_inst : 1; - int ret = gserial_setup(c->cdev->gadget, num_inst); - - if (ret) - return ret; - - for (i = 0; i < num_inst; i++) { - ret = acm_bind_config(c, i); - if (ret) { - pr_err("Could not bind acm%u config\n", i); - break; - } - } - - return ret; -} - -static struct android_usb_function acm_function = { - .name = "acm", - .bind_config = acm_function_bind_config, -}; - -static int __init init(void) -{ - printk(KERN_INFO "f_acm init\n"); - platform_driver_register(&acm_platform_driver); - android_register_function(&acm_function); - return 0; -} -module_init(init); - -#endif /* CONFIG_USB_ANDROID_ACM */ diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c deleted file mode 100644 index a0b0774b9556..000000000000 --- a/drivers/usb/gadget/f_adb.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Gadget Driver for Android ADB - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * 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. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define BULK_BUFFER_SIZE 4096 - -/* number of tx requests to allocate */ -#define TX_REQ_MAX 4 - -static const char shortname[] = "android_adb"; - -struct adb_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - - int online; - int error; - - atomic_t read_excl; - atomic_t write_excl; - atomic_t open_excl; - - struct list_head tx_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - struct usb_request *rx_req; - int rx_done; -}; - -static struct usb_interface_descriptor adb_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = 0xFF, - .bInterfaceSubClass = 0x42, - .bInterfaceProtocol = 1, -}; - -static struct usb_endpoint_descriptor adb_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor adb_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor adb_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor adb_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *fs_adb_descs[] = { - (struct usb_descriptor_header *) &adb_interface_desc, - (struct usb_descriptor_header *) &adb_fullspeed_in_desc, - (struct usb_descriptor_header *) &adb_fullspeed_out_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_adb_descs[] = { - (struct usb_descriptor_header *) &adb_interface_desc, - (struct usb_descriptor_header *) &adb_highspeed_in_desc, - (struct usb_descriptor_header *) &adb_highspeed_out_desc, - NULL, -}; - - -/* temporary variable used between adb_open() and adb_gadget_bind() */ -static struct adb_dev *_adb_dev; - -static atomic_t adb_enable_excl; - -static inline struct adb_dev *func_to_dev(struct usb_function *f) -{ - return container_of(f, struct adb_dev, function); -} - - -static struct usb_request *adb_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void adb_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -static inline int _lock(atomic_t *excl) -{ - if (atomic_inc_return(excl) == 1) { - return 0; - } else { - atomic_dec(excl); - return -1; - } -} - -static inline void _unlock(atomic_t *excl) -{ - atomic_dec(excl); -} - -/* add a request to the tail of a list */ -void req_put(struct adb_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -struct usb_request *req_get(struct adb_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void adb_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct adb_dev *dev = _adb_dev; - - if (req->status != 0) - dev->error = 1; - - req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void adb_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct adb_dev *dev = _adb_dev; - - dev->rx_done = 1; - if (req->status != 0) - dev->error = 1; - - wake_up(&dev->read_wq); -} - -static int __init create_bulk_endpoints(struct adb_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for adb ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - /* now allocate requests for our endpoints */ - req = adb_request_new(dev->ep_out, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = adb_complete_out; - dev->rx_req = req; - - for (i = 0; i < TX_REQ_MAX; i++) { - req = adb_request_new(dev->ep_in, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = adb_complete_in; - req_put(dev, &dev->tx_idle, req); - } - - return 0; - -fail: - printk(KERN_ERR "adb_bind() could not allocate requests\n"); - return -1; -} - -static ssize_t adb_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct adb_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - int r = count, xfer; - int ret; - - DBG(cdev, "adb_read(%d)\n", count); - - if (count > BULK_BUFFER_SIZE) - return -EINVAL; - - if (_lock(&dev->read_excl)) - return -EBUSY; - - /* we will block until we're online */ - while (!(dev->online || dev->error)) { - DBG(cdev, "adb_read: waiting for online state\n"); - ret = wait_event_interruptible(dev->read_wq, - (dev->online || dev->error)); - if (ret < 0) { - _unlock(&dev->read_excl); - return ret; - } - } - if (dev->error) { - r = -EIO; - goto done; - } - -requeue_req: - /* queue a request */ - req = dev->rx_req; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC); - if (ret < 0) { - DBG(cdev, "adb_read: failed to queue req %p (%d)\n", req, ret); - r = -EIO; - dev->error = 1; - goto done; - } else { - DBG(cdev, "rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - dev->error = 1; - r = ret; - goto done; - } - if (!dev->error) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - DBG(cdev, "rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - } else - r = -EIO; - -done: - _unlock(&dev->read_excl); - DBG(cdev, "adb_read returning %d\n", r); - return r; -} - -static ssize_t adb_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct adb_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - int r = count, xfer; - int ret; - - DBG(cdev, "adb_write(%d)\n", count); - - if (_lock(&dev->write_excl)) - return -EBUSY; - - while (count > 0) { - if (dev->error) { - DBG(cdev, "adb_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = req_get(dev, &dev->tx_idle)) || dev->error)); - - if (ret < 0) { - r = ret; - break; - } - - if (req != 0) { - if (count > BULK_BUFFER_SIZE) - xfer = BULK_BUFFER_SIZE; - else - xfer = count; - if (copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC); - if (ret < 0) { - DBG(cdev, "adb_write: xfer error %d\n", ret); - dev->error = 1; - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - } - - if (req) - req_put(dev, &dev->tx_idle, req); - - _unlock(&dev->write_excl); - DBG(cdev, "adb_write returning %d\n", r); - return r; -} - -static int adb_open(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "adb_open\n"); - if (_lock(&_adb_dev->open_excl)) - return -EBUSY; - - fp->private_data = _adb_dev; - - /* clear the error latch */ - _adb_dev->error = 0; - - return 0; -} - -static int adb_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "adb_release\n"); - _unlock(&_adb_dev->open_excl); - return 0; -} - -/* file operations for ADB device /dev/android_adb */ -static struct file_operations adb_fops = { - .owner = THIS_MODULE, - .read = adb_read, - .write = adb_write, - .open = adb_open, - .release = adb_release, -}; - -static struct miscdevice adb_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = shortname, - .fops = &adb_fops, -}; - -static int adb_enable_open(struct inode *ip, struct file *fp) -{ - if (atomic_inc_return(&adb_enable_excl) != 1) { - atomic_dec(&adb_enable_excl); - return -EBUSY; - } - - printk(KERN_INFO "enabling adb\n"); - android_enable_function(&_adb_dev->function, 1); - - return 0; -} - -static int adb_enable_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "disabling adb\n"); - android_enable_function(&_adb_dev->function, 0); - atomic_dec(&adb_enable_excl); - return 0; -} - -static const struct file_operations adb_enable_fops = { - .owner = THIS_MODULE, - .open = adb_enable_open, - .release = adb_enable_release, -}; - -static struct miscdevice adb_enable_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "android_adb_enable", - .fops = &adb_enable_fops, -}; - -static int -adb_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct adb_dev *dev = func_to_dev(f); - int id; - int ret; - - dev->cdev = cdev; - DBG(cdev, "adb_function_bind dev: %p\n", dev); - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - adb_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = create_bulk_endpoints(dev, &adb_fullspeed_in_desc, - &adb_fullspeed_out_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - adb_highspeed_in_desc.bEndpointAddress = - adb_fullspeed_in_desc.bEndpointAddress; - adb_highspeed_out_desc.bEndpointAddress = - adb_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -adb_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct adb_dev *dev = func_to_dev(f); - struct usb_request *req; - - spin_lock_irq(&dev->lock); - - adb_request_free(dev->rx_req, dev->ep_out); - while ((req = req_get(dev, &dev->tx_idle))) - adb_request_free(req, dev->ep_in); - - dev->online = 0; - dev->error = 1; - spin_unlock_irq(&dev->lock); - - misc_deregister(&adb_device); - misc_deregister(&adb_enable_device); - kfree(_adb_dev); - _adb_dev = NULL; -} - -static int adb_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct adb_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &adb_highspeed_in_desc, - &adb_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &adb_highspeed_out_desc, - &adb_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - dev->online = 1; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void adb_function_disable(struct usb_function *f) -{ - struct adb_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "adb_function_disable\n"); - dev->online = 0; - dev->error = 1; - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int adb_bind_config(struct usb_configuration *c) -{ - struct adb_dev *dev; - int ret; - - printk(KERN_INFO "adb_bind_config\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - spin_lock_init(&dev->lock); - - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - - atomic_set(&dev->open_excl, 0); - atomic_set(&dev->read_excl, 0); - atomic_set(&dev->write_excl, 0); - - INIT_LIST_HEAD(&dev->tx_idle); - - dev->cdev = c->cdev; - dev->function.name = "adb"; - dev->function.descriptors = fs_adb_descs; - dev->function.hs_descriptors = hs_adb_descs; - dev->function.bind = adb_function_bind; - dev->function.unbind = adb_function_unbind; - dev->function.set_alt = adb_function_set_alt; - dev->function.disable = adb_function_disable; - - /* start disabled */ - dev->function.disabled = 1; - - /* _adb_dev must be set before calling usb_gadget_register_driver */ - _adb_dev = dev; - - ret = misc_register(&adb_device); - if (ret) - goto err1; - ret = misc_register(&adb_enable_device); - if (ret) - goto err2; - - ret = usb_add_function(c, &dev->function); - if (ret) - goto err3; - - return 0; - -err3: - misc_deregister(&adb_enable_device); -err2: - misc_deregister(&adb_device); -err1: - kfree(dev); - printk(KERN_ERR "adb gadget driver failed to initialize\n"); - return ret; -} - -static struct android_usb_function adb_function = { - .name = "adb", - .bind_config = adb_bind_config, -}; - -static int __init init(void) -{ - printk(KERN_INFO "f_adb init\n"); - android_register_function(&adb_function); - return 0; -} -module_init(init); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 9e37e0863143..32cce029f65c 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -295,12 +295,7 @@ #include "gadget_chips.h" -#ifdef CONFIG_USB_ANDROID_MASS_STORAGE -#include -#include -#define FUNCTION_NAME "usb_mass_storage" -#endif /*------------------------------------------------------------------------*/ @@ -429,10 +424,6 @@ struct fsg_config { u16 release; char can_stall; - -#ifdef CONFIG_USB_ANDROID_MASS_STORAGE - struct platform_device *pdev; -#endif }; @@ -2755,13 +2746,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, curlun->ro = lcfg->cdrom || lcfg->ro; curlun->removable = lcfg->removable; curlun->dev.release = fsg_lun_release; - -#ifdef CONFIG_USB_ANDROID_MASS_STORAGE - /* use "usb_mass_storage" platform device as parent */ - curlun->dev.parent = &cfg->pdev->dev; -#else curlun->dev.parent = &gadget->dev; -#endif /* curlun->dev.driver = &fsg_driver.driver; XXX */ dev_set_drvdata(&curlun->dev, &common->filesem); dev_set_name(&curlun->dev, @@ -3044,11 +3029,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, if (unlikely(!fsg)) return -ENOMEM; -#ifdef CONFIG_USB_ANDROID_MASS_STORAGE - fsg->function.name = FUNCTION_NAME; -#else fsg->function.name = FSG_DRIVER_DESC; -#endif fsg->function.strings = fsg_strings_array; fsg->function.bind = fsg_bind; fsg->function.unbind = fsg_unbind; @@ -3172,63 +3153,3 @@ fsg_common_from_params(struct fsg_common *common, return fsg_common_init(common, cdev, &cfg); } -#ifdef CONFIG_USB_ANDROID_MASS_STORAGE - -static struct fsg_config fsg_cfg; - -static int fsg_probe(struct platform_device *pdev) -{ - struct usb_mass_storage_platform_data *pdata = pdev->dev.platform_data; - int i, nluns; - - printk(KERN_INFO "fsg_probe pdev: %p, pdata: %p\n", pdev, pdata); - if (!pdata) - return -1; - - nluns = pdata->nluns; - if (nluns > FSG_MAX_LUNS) - nluns = FSG_MAX_LUNS; - fsg_cfg.nluns = nluns; - for (i = 0; i < nluns; i++) - fsg_cfg.luns[i].removable = 1; - - fsg_cfg.vendor_name = pdata->vendor; - fsg_cfg.product_name = pdata->product; - fsg_cfg.release = pdata->release; - fsg_cfg.can_stall = 0; - fsg_cfg.pdev = pdev; - - return 0; -} - -static struct platform_driver fsg_platform_driver = { - .driver = { .name = FUNCTION_NAME, }, - .probe = fsg_probe, -}; - -int mass_storage_bind_config(struct usb_configuration *c) -{ - struct fsg_common *common = fsg_common_init(NULL, c->cdev, &fsg_cfg); - if (IS_ERR(common)) - return -1; - return fsg_add(c->cdev, c, common); -} - -static struct android_usb_function mass_storage_function = { - .name = FUNCTION_NAME, - .bind_config = mass_storage_bind_config, -}; - -static int __init init(void) -{ - int rc; - printk(KERN_INFO "f_mass_storage init\n"); - rc = platform_driver_register(&fsg_platform_driver); - if (rc != 0) - return rc; - android_register_function(&mass_storage_function); - return 0; -}module_init(init); - -#endif /* CONFIG_USB_ANDROID_MASS_STORAGE */ - diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c deleted file mode 100644 index 0c3d3e3bfbd5..000000000000 --- a/drivers/usb/gadget/f_mtp.c +++ /dev/null @@ -1,1269 +0,0 @@ -/* - * Gadget Function Driver for MTP - * - * Copyright (C) 2010 Google, Inc. - * Author: Mike Lockwood - * - * 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. - * - */ - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define BULK_BUFFER_SIZE 16384 -#define INTR_BUFFER_SIZE 28 - -/* String IDs */ -#define INTERFACE_STRING_INDEX 0 - -/* values for mtp_dev.state */ -#define STATE_OFFLINE 0 /* initial state, disconnected */ -#define STATE_READY 1 /* ready for userspace calls */ -#define STATE_BUSY 2 /* processing userspace calls */ -#define STATE_CANCELED 3 /* transaction canceled by host */ -#define STATE_ERROR 4 /* error from completion routine */ - -/* number of tx and rx requests to allocate */ -#define TX_REQ_MAX 4 -#define RX_REQ_MAX 2 -#define INTR_REQ_MAX 5 - -/* ID for Microsoft MTP OS String */ -#define MTP_OS_STRING_ID 0xEE - -/* MTP class reqeusts */ -#define MTP_REQ_CANCEL 0x64 -#define MTP_REQ_GET_EXT_EVENT_DATA 0x65 -#define MTP_REQ_RESET 0x66 -#define MTP_REQ_GET_DEVICE_STATUS 0x67 - -/* constants for device status */ -#define MTP_RESPONSE_OK 0x2001 -#define MTP_RESPONSE_DEVICE_BUSY 0x2019 - -static const char shortname[] = "mtp_usb"; - -struct mtp_dev { - struct usb_function function; - struct usb_composite_dev *cdev; - spinlock_t lock; - - /* appear as MTP or PTP when enumerating */ - int interface_mode; - - struct usb_ep *ep_in; - struct usb_ep *ep_out; - struct usb_ep *ep_intr; - - int state; - - /* synchronize access to our device file */ - atomic_t open_excl; - /* to enforce only one ioctl at a time */ - atomic_t ioctl_excl; - - struct list_head tx_idle; - struct list_head intr_idle; - - wait_queue_head_t read_wq; - wait_queue_head_t write_wq; - wait_queue_head_t intr_wq; - struct usb_request *rx_req[RX_REQ_MAX]; - int rx_done; - - /* for processing MTP_SEND_FILE and MTP_RECEIVE_FILE - * ioctls on a work queue - */ - struct workqueue_struct *wq; - struct work_struct send_file_work; - struct work_struct receive_file_work; - struct file *xfer_file; - loff_t xfer_file_offset; - int64_t xfer_file_length; - int xfer_result; -}; - -static struct usb_interface_descriptor mtp_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 3, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, - .bInterfaceProtocol = 0, -}; - -static struct usb_interface_descriptor ptp_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 3, - .bInterfaceClass = USB_CLASS_STILL_IMAGE, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, -}; - -static struct usb_endpoint_descriptor mtp_highspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor mtp_highspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor mtp_fullspeed_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor mtp_fullspeed_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor mtp_intr_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = __constant_cpu_to_le16(INTR_BUFFER_SIZE), - .bInterval = 6, -}; - -static struct usb_descriptor_header *fs_mtp_descs[] = { - (struct usb_descriptor_header *) &mtp_interface_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_mtp_descs[] = { - (struct usb_descriptor_header *) &mtp_interface_desc, - (struct usb_descriptor_header *) &mtp_highspeed_in_desc, - (struct usb_descriptor_header *) &mtp_highspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *fs_ptp_descs[] = { - (struct usb_descriptor_header *) &ptp_interface_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, - (struct usb_descriptor_header *) &mtp_fullspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_descriptor_header *hs_ptp_descs[] = { - (struct usb_descriptor_header *) &ptp_interface_desc, - (struct usb_descriptor_header *) &mtp_highspeed_in_desc, - (struct usb_descriptor_header *) &mtp_highspeed_out_desc, - (struct usb_descriptor_header *) &mtp_intr_desc, - NULL, -}; - -static struct usb_string mtp_string_defs[] = { - /* Naming interface "MTP" so libmtp will recognize us */ - [INTERFACE_STRING_INDEX].s = "MTP", - { }, /* end of list */ -}; - -static struct usb_gadget_strings mtp_string_table = { - .language = 0x0409, /* en-US */ - .strings = mtp_string_defs, -}; - -static struct usb_gadget_strings *mtp_strings[] = { - &mtp_string_table, - NULL, -}; - -/* Microsoft MTP OS String */ -static u8 mtp_os_string[] = { - 18, /* sizeof(mtp_os_string) */ - USB_DT_STRING, - /* Signature field: "MSFT100" */ - 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, - /* vendor code */ - 1, - /* padding */ - 0 -}; - -/* Microsoft Extended Configuration Descriptor Header Section */ -struct mtp_ext_config_desc_header { - __le32 dwLength; - __u16 bcdVersion; - __le16 wIndex; - __u8 bCount; - __u8 reserved[7]; -}; - -/* Microsoft Extended Configuration Descriptor Function Section */ -struct mtp_ext_config_desc_function { - __u8 bFirstInterfaceNumber; - __u8 bInterfaceCount; - __u8 compatibleID[8]; - __u8 subCompatibleID[8]; - __u8 reserved[6]; -}; - -/* MTP Extended Configuration Descriptor */ -struct { - struct mtp_ext_config_desc_header header; - struct mtp_ext_config_desc_function function; -} mtp_ext_config_desc = { - .header = { - .dwLength = __constant_cpu_to_le32(sizeof(mtp_ext_config_desc)), - .bcdVersion = __constant_cpu_to_le16(0x0100), - .wIndex = __constant_cpu_to_le16(4), - .bCount = __constant_cpu_to_le16(1), - }, - .function = { - .bFirstInterfaceNumber = 0, - .bInterfaceCount = 1, - .compatibleID = { 'M', 'T', 'P' }, - }, -}; - -struct mtp_device_status { - __le16 wLength; - __le16 wCode; -}; - -/* temporary variable used between mtp_open() and mtp_gadget_bind() */ -static struct mtp_dev *_mtp_dev; - -static inline struct mtp_dev *func_to_dev(struct usb_function *f) -{ - return container_of(f, struct mtp_dev, function); -} - -static struct usb_request *mtp_request_new(struct usb_ep *ep, int buffer_size) -{ - struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!req) - return NULL; - - /* now allocate buffers for the requests */ - req->buf = kmalloc(buffer_size, GFP_KERNEL); - if (!req->buf) { - usb_ep_free_request(ep, req); - return NULL; - } - - return req; -} - -static void mtp_request_free(struct usb_request *req, struct usb_ep *ep) -{ - if (req) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -static inline int _lock(atomic_t *excl) -{ - if (atomic_inc_return(excl) == 1) { - return 0; - } else { - atomic_dec(excl); - return -1; - } -} - -static inline void _unlock(atomic_t *excl) -{ - atomic_dec(excl); -} - -/* add a request to the tail of a list */ -static void req_put(struct mtp_dev *dev, struct list_head *head, - struct usb_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - list_add_tail(&req->list, head); - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* remove a request from the head of a list */ -static struct usb_request *req_get(struct mtp_dev *dev, struct list_head *head) -{ - unsigned long flags; - struct usb_request *req; - - spin_lock_irqsave(&dev->lock, flags); - if (list_empty(head)) { - req = 0; - } else { - req = list_first_entry(head, struct usb_request, list); - list_del(&req->list); - } - spin_unlock_irqrestore(&dev->lock, flags); - return req; -} - -static void mtp_complete_in(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - if (req->status != 0) - dev->state = STATE_ERROR; - - req_put(dev, &dev->tx_idle, req); - - wake_up(&dev->write_wq); -} - -static void mtp_complete_out(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - dev->rx_done = 1; - if (req->status != 0) - dev->state = STATE_ERROR; - - wake_up(&dev->read_wq); -} - -static void mtp_complete_intr(struct usb_ep *ep, struct usb_request *req) -{ - struct mtp_dev *dev = _mtp_dev; - - if (req->status != 0) - dev->state = STATE_ERROR; - - req_put(dev, &dev->intr_idle, req); - - wake_up(&dev->intr_wq); -} - -static int __init create_bulk_endpoints(struct mtp_dev *dev, - struct usb_endpoint_descriptor *in_desc, - struct usb_endpoint_descriptor *out_desc, - struct usb_endpoint_descriptor *intr_desc) -{ - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - struct usb_ep *ep; - int i; - - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); - - ep = usb_ep_autoconfig(cdev->gadget, in_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_in = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, out_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_out got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_out = ep; - - ep = usb_ep_autoconfig(cdev->gadget, intr_desc); - if (!ep) { - DBG(cdev, "usb_ep_autoconfig for ep_intr failed\n"); - return -ENODEV; - } - DBG(cdev, "usb_ep_autoconfig for mtp ep_intr got %s\n", ep->name); - ep->driver_data = dev; /* claim the endpoint */ - dev->ep_intr = ep; - - /* now allocate requests for our endpoints */ - for (i = 0; i < TX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_in, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_in; - req_put(dev, &dev->tx_idle, req); - } - for (i = 0; i < RX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_out, BULK_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_out; - dev->rx_req[i] = req; - } - for (i = 0; i < INTR_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_intr, INTR_BUFFER_SIZE); - if (!req) - goto fail; - req->complete = mtp_complete_intr; - req_put(dev, &dev->intr_idle, req); - } - - return 0; - -fail: - printk(KERN_ERR "mtp_bind() could not allocate requests\n"); - return -1; -} - -static ssize_t mtp_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct mtp_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req; - int r = count, xfer; - int ret = 0; - - DBG(cdev, "mtp_read(%d)\n", count); - - if (count > BULK_BUFFER_SIZE) - return -EINVAL; - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_OFFLINE) { - spin_unlock_irq(&dev->lock); - return -ENODEV; - } - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - return -ECANCELED; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - -requeue_req: - /* queue a request */ - req = dev->rx_req[0]; - req->length = count; - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - goto done; - } else { - DBG(cdev, "rx %p queue\n", req); - } - - /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); - if (ret < 0) { - r = ret; - usb_ep_dequeue(dev->ep_out, req); - goto done; - } - if (dev->state == STATE_BUSY) { - /* If we got a 0-len packet, throw it back and try again. */ - if (req->actual == 0) - goto requeue_req; - - DBG(cdev, "rx %p %d\n", req, req->actual); - xfer = (req->actual < count) ? req->actual : count; - r = xfer; - if (copy_to_user(buf, req->buf, xfer)) - r = -EFAULT; - } else - r = -EIO; - -done: - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - r = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - - DBG(cdev, "mtp_read returning %d\n", r); - return r; -} - -static ssize_t mtp_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct mtp_dev *dev = fp->private_data; - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - int r = count, xfer; - int sendZLP = 0; - int ret; - - DBG(cdev, "mtp_write(%d)\n", count); - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - return -ECANCELED; - } - if (dev->state == STATE_OFFLINE) { - spin_unlock_irq(&dev->lock); - return -ENODEV; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - - /* we need to send a zero length packet to signal the end of transfer - * if the transfer size is aligned to a packet boundary. - */ - if ((count & (dev->ep_in->maxpacket - 1)) == 0) { - sendZLP = 1; - } - - while (count > 0 || sendZLP) { - /* so we exit after sending ZLP */ - if (count == 0) - sendZLP = 0; - - if (dev->state != STATE_BUSY) { - DBG(cdev, "mtp_write dev->error\n"); - r = -EIO; - break; - } - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = req_get(dev, &dev->tx_idle)) - || dev->state != STATE_BUSY)); - if (!req) { - r = ret; - break; - } - - if (count > BULK_BUFFER_SIZE) - xfer = BULK_BUFFER_SIZE; - else - xfer = count; - if (xfer && copy_from_user(req->buf, buf, xfer)) { - r = -EFAULT; - break; - } - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - DBG(cdev, "mtp_write: xfer error %d\n", ret); - r = -EIO; - break; - } - - buf += xfer; - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - req_put(dev, &dev->tx_idle, req); - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - r = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - - DBG(cdev, "mtp_write returning %d\n", r); - return r; -} - -/* read from a local file and write to USB */ -static void send_file_work(struct work_struct *data) { - struct mtp_dev *dev = container_of(data, struct mtp_dev, send_file_work); - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *req = 0; - struct file *filp; - loff_t offset; - int64_t count; - int xfer, ret; - int r = 0; - int sendZLP = 0; - - /* read our parameters */ - smp_rmb(); - filp = dev->xfer_file; - offset = dev->xfer_file_offset; - count = dev->xfer_file_length; - - DBG(cdev, "send_file_work(%lld %lld)\n", offset, count); - - /* we need to send a zero length packet to signal the end of transfer - * if the transfer size is aligned to a packet boundary. - */ - if ((dev->xfer_file_length & (dev->ep_in->maxpacket - 1)) == 0) { - sendZLP = 1; - } - - while (count > 0 || sendZLP) { - /* so we exit after sending ZLP */ - if (count == 0) - sendZLP = 0; - - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - (req = req_get(dev, &dev->tx_idle)) - || dev->state != STATE_BUSY); - if (dev->state == STATE_CANCELED) { - r = -ECANCELED; - break; - } - if (!req) { - r = ret; - break; - } - - if (count > BULK_BUFFER_SIZE) - xfer = BULK_BUFFER_SIZE; - else - xfer = count; - ret = vfs_read(filp, req->buf, xfer, &offset); - if (ret < 0) { - r = ret; - break; - } - xfer = ret; - - req->length = xfer; - ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); - if (ret < 0) { - DBG(cdev, "send_file_work: xfer error %d\n", ret); - dev->state = STATE_ERROR; - r = -EIO; - break; - } - - count -= xfer; - - /* zero this so we don't try to free it on error exit */ - req = 0; - } - - if (req) - req_put(dev, &dev->tx_idle, req); - - DBG(cdev, "send_file_work returning %d\n", r); - /* write the result */ - dev->xfer_result = r; - smp_wmb(); -} - -/* read from USB and write to a local file */ -static void receive_file_work(struct work_struct *data) -{ - struct mtp_dev *dev = container_of(data, struct mtp_dev, receive_file_work); - struct usb_composite_dev *cdev = dev->cdev; - struct usb_request *read_req = NULL, *write_req = NULL; - struct file *filp; - loff_t offset; - int64_t count; - int ret, cur_buf = 0; - int r = 0; - - /* read our parameters */ - smp_rmb(); - filp = dev->xfer_file; - offset = dev->xfer_file_offset; - count = dev->xfer_file_length; - - DBG(cdev, "receive_file_work(%lld)\n", count); - - while (count > 0 || write_req) { - if (count > 0) { - /* queue a request */ - read_req = dev->rx_req[cur_buf]; - cur_buf = (cur_buf + 1) % RX_REQ_MAX; - - read_req->length = (count > BULK_BUFFER_SIZE - ? BULK_BUFFER_SIZE : count); - dev->rx_done = 0; - ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL); - if (ret < 0) { - r = -EIO; - dev->state = STATE_ERROR; - break; - } - } - - if (write_req) { - DBG(cdev, "rx %p %d\n", write_req, write_req->actual); - ret = vfs_write(filp, write_req->buf, write_req->actual, - &offset); - DBG(cdev, "vfs_write %d\n", ret); - if (ret != write_req->actual) { - r = -EIO; - dev->state = STATE_ERROR; - break; - } - write_req = NULL; - } - - if (read_req) { - /* wait for our last read to complete */ - ret = wait_event_interruptible(dev->read_wq, - dev->rx_done || dev->state != STATE_BUSY); - if (dev->state == STATE_CANCELED) { - r = -ECANCELED; - if (!dev->rx_done) - usb_ep_dequeue(dev->ep_out, read_req); - break; - } - /* if xfer_file_length is 0xFFFFFFFF, then we read until - * we get a zero length packet - */ - if (count != 0xFFFFFFFF) - count -= read_req->actual; - if (read_req->actual < read_req->length) { - /* short packet is used to signal EOF for sizes > 4 gig */ - DBG(cdev, "got short packet\n"); - count = 0; - } - - write_req = read_req; - read_req = NULL; - } - } - - DBG(cdev, "receive_file_work returning %d\n", r); - /* write the result */ - dev->xfer_result = r; - smp_wmb(); -} - -static int mtp_send_event(struct mtp_dev *dev, struct mtp_event *event) -{ - struct usb_request *req= NULL; - int ret; - int length = event->length; - - DBG(dev->cdev, "mtp_send_event(%d)\n", event->length); - - if (length < 0 || length > INTR_BUFFER_SIZE) - return -EINVAL; - if (dev->state == STATE_OFFLINE) - return -ENODEV; - - ret = wait_event_interruptible_timeout(dev->intr_wq, - (req = req_get(dev, &dev->intr_idle)), msecs_to_jiffies(1000)); - if (!req) - return -ETIME; - - if (copy_from_user(req->buf, (void __user *)event->data, length)) { - req_put(dev, &dev->intr_idle, req); - return -EFAULT; - } - req->length = length; - ret = usb_ep_queue(dev->ep_intr, req, GFP_KERNEL); - if (ret) - req_put(dev, &dev->intr_idle, req); - - return ret; -} - -static long mtp_ioctl(struct file *fp, unsigned code, unsigned long value) -{ - struct mtp_dev *dev = fp->private_data; - struct file *filp = NULL; - int ret = -EINVAL; - - if (_lock(&dev->ioctl_excl)) - return -EBUSY; - - switch (code) { - case MTP_SEND_FILE: - case MTP_RECEIVE_FILE: - { - struct mtp_file_range mfr; - struct work_struct *work; - - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) { - /* report cancelation to userspace */ - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); - ret = -ECANCELED; - goto out; - } - if (dev->state == STATE_OFFLINE) { - spin_unlock_irq(&dev->lock); - ret = -ENODEV; - goto out; - } - dev->state = STATE_BUSY; - spin_unlock_irq(&dev->lock); - - if (copy_from_user(&mfr, (void __user *)value, sizeof(mfr))) { - ret = -EFAULT; - goto fail; - } - /* hold a reference to the file while we are working with it */ - filp = fget(mfr.fd); - if (!filp) { - ret = -EBADF; - goto fail; - } - - /* write the parameters */ - dev->xfer_file = filp; - dev->xfer_file_offset = mfr.offset; - dev->xfer_file_length = mfr.length; - smp_wmb(); - - if (code == MTP_SEND_FILE) - work = &dev->send_file_work; - else - work = &dev->receive_file_work; - - /* We do the file transfer on a work queue so it will run - * in kernel context, which is necessary for vfs_read and - * vfs_write to use our buffers in the kernel address space. - */ - queue_work(dev->wq, work); - /* wait for operation to complete */ - flush_workqueue(dev->wq); - fput(filp); - - /* read the result */ - smp_rmb(); - ret = dev->xfer_result; - break; - } - case MTP_SET_INTERFACE_MODE: - if (value == MTP_INTERFACE_MODE_MTP || - value == MTP_INTERFACE_MODE_PTP) { - dev->interface_mode = value; - if (value == MTP_INTERFACE_MODE_PTP) { - dev->function.descriptors = fs_ptp_descs; - dev->function.hs_descriptors = hs_ptp_descs; - } else { - dev->function.descriptors = fs_mtp_descs; - dev->function.hs_descriptors = hs_mtp_descs; - } - ret = 0; - } - break; - case MTP_SEND_EVENT: - { - struct mtp_event event; - /* return here so we don't change dev->state below, - * which would interfere with bulk transfer state. - */ - if (copy_from_user(&event, (void __user *)value, sizeof(event))) - ret = -EFAULT; - else - ret = mtp_send_event(dev, &event); - goto out; - } - } - -fail: - spin_lock_irq(&dev->lock); - if (dev->state == STATE_CANCELED) - ret = -ECANCELED; - else if (dev->state != STATE_OFFLINE) - dev->state = STATE_READY; - spin_unlock_irq(&dev->lock); -out: - _unlock(&dev->ioctl_excl); - DBG(dev->cdev, "ioctl returning %d\n", ret); - return ret; -} - -static int mtp_open(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "mtp_open\n"); - if (_lock(&_mtp_dev->open_excl)) - return -EBUSY; - - /* clear any error condition */ - if (_mtp_dev->state != STATE_OFFLINE) - _mtp_dev->state = STATE_READY; - - fp->private_data = _mtp_dev; - return 0; -} - -static int mtp_release(struct inode *ip, struct file *fp) -{ - printk(KERN_INFO "mtp_release\n"); - - _unlock(&_mtp_dev->open_excl); - return 0; -} - -/* file operations for /dev/mtp_usb */ -static const struct file_operations mtp_fops = { - .owner = THIS_MODULE, - .read = mtp_read, - .write = mtp_write, - .unlocked_ioctl = mtp_ioctl, - .open = mtp_open, - .release = mtp_release, -}; - -static struct miscdevice mtp_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = shortname, - .fops = &mtp_fops, -}; - -static int -mtp_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct mtp_dev *dev = func_to_dev(f); - int id; - int ret; - - dev->cdev = cdev; - DBG(cdev, "mtp_function_bind dev: %p\n", dev); - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - mtp_interface_desc.bInterfaceNumber = id; - - /* allocate endpoints */ - ret = create_bulk_endpoints(dev, &mtp_fullspeed_in_desc, - &mtp_fullspeed_out_desc, &mtp_intr_desc); - if (ret) - return ret; - - /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - mtp_highspeed_in_desc.bEndpointAddress = - mtp_fullspeed_in_desc.bEndpointAddress; - mtp_highspeed_out_desc.bEndpointAddress = - mtp_fullspeed_out_desc.bEndpointAddress; - } - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - f->name, dev->ep_in->name, dev->ep_out->name); - return 0; -} - -static void -mtp_function_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct mtp_dev *dev = func_to_dev(f); - struct usb_request *req; - int i; - - spin_lock_irq(&dev->lock); - while ((req = req_get(dev, &dev->tx_idle))) - mtp_request_free(req, dev->ep_in); - for (i = 0; i < RX_REQ_MAX; i++) - mtp_request_free(dev->rx_req[i], dev->ep_out); - while ((req = req_get(dev, &dev->intr_idle))) - mtp_request_free(req, dev->ep_intr); - dev->state = STATE_OFFLINE; - spin_unlock_irq(&dev->lock); - - misc_deregister(&mtp_device); - kfree(_mtp_dev); - _mtp_dev = NULL; -} - -static int mtp_function_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct mtp_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - unsigned long flags; - - /* do nothing if we are disabled */ - if (dev->function.disabled) - return value; - - VDBG(cdev, "mtp_function_setup " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - - /* Handle MTP OS string */ - if (dev->interface_mode == MTP_INTERFACE_MODE_MTP - && ctrl->bRequestType == - (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) - && ctrl->bRequest == USB_REQ_GET_DESCRIPTOR - && (w_value >> 8) == USB_DT_STRING - && (w_value & 0xFF) == MTP_OS_STRING_ID) { - value = (w_length < sizeof(mtp_os_string) - ? w_length : sizeof(mtp_os_string)); - memcpy(cdev->req->buf, mtp_os_string, value); - /* return here since composite.c will send for us */ - return value; - } - if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { - /* Handle MTP OS descriptor */ - DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n", - ctrl->bRequest, w_index, w_value, w_length); - - if (dev->interface_mode == MTP_INTERFACE_MODE_MTP - && ctrl->bRequest == 1 - && (ctrl->bRequestType & USB_DIR_IN) - && (w_index == 4 || w_index == 5)) { - value = (w_length < sizeof(mtp_ext_config_desc) ? - w_length : sizeof(mtp_ext_config_desc)); - memcpy(cdev->req->buf, &mtp_ext_config_desc, value); - } - } - if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { - DBG(cdev, "class request: %d index: %d value: %d length: %d\n", - ctrl->bRequest, w_index, w_value, w_length); - - if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0 - && w_value == 0) { - DBG(cdev, "MTP_REQ_CANCEL\n"); - - spin_lock_irqsave(&dev->lock, flags); - if (dev->state == STATE_BUSY) { - dev->state = STATE_CANCELED; - wake_up(&dev->read_wq); - wake_up(&dev->write_wq); - } - spin_unlock_irqrestore(&dev->lock, flags); - - /* We need to queue a request to read the remaining - * bytes, but we don't actually need to look at - * the contents. - */ - value = w_length; - } else if (ctrl->bRequest == MTP_REQ_GET_DEVICE_STATUS - && w_index == 0 && w_value == 0) { - struct mtp_device_status *status = cdev->req->buf; - status->wLength = - __constant_cpu_to_le16(sizeof(*status)); - - DBG(cdev, "MTP_REQ_GET_DEVICE_STATUS\n"); - spin_lock_irqsave(&dev->lock, flags); - /* device status is "busy" until we report - * the cancelation to userspace - */ - if (dev->state == STATE_CANCELED) - status->wCode = - __cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY); - else - status->wCode = - __cpu_to_le16(MTP_RESPONSE_OK); - spin_unlock_irqrestore(&dev->lock, flags); - value = sizeof(*status); - } - } - - /* respond with data transfer or status phase? */ - if (value >= 0) { - int rc; - cdev->req->zero = value < w_length; - cdev->req->length = value; - rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); - if (rc < 0) - ERROR(cdev, "%s setup response queue error\n", __func__); - } - - if (value == -EOPNOTSUPP) - VDBG(cdev, - "unknown class-specific control req " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - return value; -} - -static int mtp_function_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct mtp_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = f->config->cdev; - int ret; - - DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt); - ret = usb_ep_enable(dev->ep_in, - ep_choose(cdev->gadget, - &mtp_highspeed_in_desc, - &mtp_fullspeed_in_desc)); - if (ret) - return ret; - ret = usb_ep_enable(dev->ep_out, - ep_choose(cdev->gadget, - &mtp_highspeed_out_desc, - &mtp_fullspeed_out_desc)); - if (ret) { - usb_ep_disable(dev->ep_in); - return ret; - } - ret = usb_ep_enable(dev->ep_intr, &mtp_intr_desc); - if (ret) { - usb_ep_disable(dev->ep_out); - usb_ep_disable(dev->ep_in); - return ret; - } - dev->state = STATE_READY; - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - return 0; -} - -static void mtp_function_disable(struct usb_function *f) -{ - struct mtp_dev *dev = func_to_dev(f); - struct usb_composite_dev *cdev = dev->cdev; - - DBG(cdev, "mtp_function_disable\n"); - dev->state = STATE_OFFLINE; - usb_ep_disable(dev->ep_in); - usb_ep_disable(dev->ep_out); - usb_ep_disable(dev->ep_intr); - - /* readers may be blocked waiting for us to go online */ - wake_up(&dev->read_wq); - - VDBG(cdev, "%s disabled\n", dev->function.name); -} - -static int mtp_bind_config(struct usb_configuration *c) -{ - struct mtp_dev *dev; - int ret = 0; - - printk(KERN_INFO "mtp_bind_config\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - /* allocate a string ID for our interface */ - if (mtp_string_defs[INTERFACE_STRING_INDEX].id == 0) { - ret = usb_string_id(c->cdev); - if (ret < 0) - return ret; - mtp_string_defs[INTERFACE_STRING_INDEX].id = ret; - mtp_interface_desc.iInterface = ret; - } - - spin_lock_init(&dev->lock); - init_waitqueue_head(&dev->read_wq); - init_waitqueue_head(&dev->write_wq); - init_waitqueue_head(&dev->intr_wq); - atomic_set(&dev->open_excl, 0); - atomic_set(&dev->ioctl_excl, 0); - INIT_LIST_HEAD(&dev->tx_idle); - INIT_LIST_HEAD(&dev->intr_idle); - - dev->wq = create_singlethread_workqueue("f_mtp"); - if (!dev->wq) - goto err1; - INIT_WORK(&dev->send_file_work, send_file_work); - INIT_WORK(&dev->receive_file_work, receive_file_work); - - dev->cdev = c->cdev; - dev->function.name = "mtp"; - dev->function.strings = mtp_strings, - dev->function.descriptors = fs_mtp_descs; - dev->function.hs_descriptors = hs_mtp_descs; - dev->function.bind = mtp_function_bind; - dev->function.unbind = mtp_function_unbind; - dev->function.setup = mtp_function_setup; - dev->function.set_alt = mtp_function_set_alt; - dev->function.disable = mtp_function_disable; - - /* MTP mode by default */ - dev->interface_mode = MTP_INTERFACE_MODE_MTP; - - /* _mtp_dev must be set before calling usb_gadget_register_driver */ - _mtp_dev = dev; - - ret = misc_register(&mtp_device); - if (ret) - goto err1; - - ret = usb_add_function(c, &dev->function); - if (ret) - goto err2; - - return 0; - -err2: - misc_deregister(&mtp_device); -err1: - if (dev->wq) - destroy_workqueue(dev->wq); - kfree(dev); - printk(KERN_ERR "mtp gadget driver failed to initialize\n"); - return ret; -} - -static struct android_usb_function mtp_function = { - .name = "mtp", - .bind_config = mtp_bind_config, -}; - -static int __init init(void) -{ - printk(KERN_INFO "f_mtp init\n"); - android_register_function(&mtp_function); - return 0; -} -module_init(init); diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index af60922d6713..882484a40398 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -26,9 +26,8 @@ #include #include -#include +#include #include -#include #include @@ -130,16 +129,9 @@ static struct usb_interface_descriptor rndis_control_intf = { /* .bInterfaceNumber = DYNAMIC */ /* status endpoint is optional; this could be patched later */ .bNumEndpoints = 1, -#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS - /* "Wireless" RNDIS; auto-detected by Windows */ - .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x03, -#else .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR, -#endif /* .iInterface = DYNAMIC */ }; @@ -198,16 +190,9 @@ rndis_iad_descriptor = { .bFirstInterface = 0, /* XXX, hardcoded */ .bInterfaceCount = 2, // control + data -#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS - /* "Wireless" RNDIS; auto-detected by Windows */ - .bFunctionClass = USB_CLASS_WIRELESS_CONTROLLER, - .bFunctionSubClass = 0x01, - .bFunctionProtocol = 0x03, -#else .bFunctionClass = USB_CLASS_COMM, .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bFunctionProtocol = USB_CDC_ACM_PROTO_VENDOR, -#endif + .bFunctionProtocol = USB_CDC_PROTO_NONE, /* .iFunction = DYNAMIC */ }; @@ -319,10 +304,6 @@ static struct usb_gadget_strings *rndis_strings[] = { NULL, }; -#ifdef CONFIG_USB_ANDROID_RNDIS -static struct usb_ether_platform_data *rndis_pdata; -#endif - /*-------------------------------------------------------------------------*/ static struct sk_buff *rndis_add_header(struct gether *port, @@ -506,10 +487,10 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_disable(rndis->notify); } else { VDBG(cdev, "init rndis ctrl %d\n", intf); + rndis->notify_desc = ep_choose(cdev->gadget, + rndis->hs.notify, + rndis->fs.notify); } - rndis->notify_desc = ep_choose(cdev->gadget, - rndis->hs.notify, - rndis->fs.notify); usb_ep_enable(rndis->notify, rndis->notify_desc); rndis->notify->driver_data = rndis; @@ -523,11 +504,11 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (!rndis->port.in) { DBG(cdev, "init rndis\n"); + rndis->port.in = ep_choose(cdev->gadget, + rndis->hs.in, rndis->fs.in); + rndis->port.out = ep_choose(cdev->gadget, + rndis->hs.out, rndis->fs.out); } - rndis->port.in = ep_choose(cdev->gadget, - rndis->hs.in, rndis->fs.in); - rndis->port.out = ep_choose(cdev->gadget, - rndis->hs.out, rndis->fs.out); /* Avoid ZLPs; they can be troublesome. */ rndis->port.is_zlp_ok = false; @@ -726,12 +707,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); rndis_set_host_mac(rndis->config, rndis->ethaddr); -#ifdef CONFIG_USB_ANDROID_RNDIS - if (rndis_pdata) { - if (rndis_set_param_vendor(rndis->config, rndis_pdata->vendorID, - rndis_pdata->vendorDescr)) - goto fail; - } +#if 0 +// FIXME + if (rndis_set_param_vendor(rndis->config, vendorID, + manufacturer)) + goto fail0; #endif /* NOTE: all that is done without knowing or caring about @@ -870,11 +850,6 @@ rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) rndis->port.func.setup = rndis_setup; rndis->port.func.disable = rndis_disable; -#ifdef CONFIG_USB_ANDROID_RNDIS - /* start disabled */ - rndis->port.func.disabled = 1; -#endif - status = usb_add_function(c, &rndis->port.func); if (status) { kfree(rndis); @@ -883,54 +858,3 @@ fail: } return status; } - -#ifdef CONFIG_USB_ANDROID_RNDIS -#include "rndis.c" - -static int rndis_probe(struct platform_device *pdev) -{ - rndis_pdata = pdev->dev.platform_data; - return 0; -} - -static struct platform_driver rndis_platform_driver = { - .driver = { .name = "rndis", }, - .probe = rndis_probe, -}; - -int rndis_function_bind_config(struct usb_configuration *c) -{ - int ret; - - if (!rndis_pdata) { - printk(KERN_ERR "rndis_pdata null in rndis_function_bind_config\n"); - return -1; - } - - printk(KERN_INFO - "rndis_function_bind_config MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", - rndis_pdata->ethaddr[0], rndis_pdata->ethaddr[1], - rndis_pdata->ethaddr[2], rndis_pdata->ethaddr[3], - rndis_pdata->ethaddr[4], rndis_pdata->ethaddr[5]); - - ret = gether_setup(c->cdev->gadget, rndis_pdata->ethaddr); - if (ret == 0) - ret = rndis_bind_config(c, rndis_pdata->ethaddr); - return ret; -} - -static struct android_usb_function rndis_function = { - .name = "rndis", - .bind_config = rndis_function_bind_config, -}; - -static int __init init(void) -{ - printk(KERN_INFO "f_rndis init\n"); - platform_driver_register(&rndis_platform_driver); - android_register_function(&rndis_function); - return 0; -} -module_init(init); - -#endif /* CONFIG_USB_ANDROID_RNDIS */ diff --git a/drivers/usb/gadget/fsl_tegra_udc.c b/drivers/usb/gadget/fsl_tegra_udc.c deleted file mode 100644 index 24867cd60909..000000000000 --- a/drivers/usb/gadget/fsl_tegra_udc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Description: - * Helper functions to support the tegra USB controller - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the 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 -#include -#include -#include -#include - -static struct tegra_usb_phy *phy; -static struct clk *udc_clk; -static struct clk *emc_clk; -static void *udc_base; - -int fsl_udc_clk_init(struct platform_device *pdev) -{ - struct resource *res; - int err; - int instance; - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - - udc_clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(udc_clk)) { - dev_err(&pdev->dev, "Can't get udc clock\n"); - return PTR_ERR(udc_clk); - } - - clk_enable(udc_clk); - - emc_clk = clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc_clk)) { - dev_err(&pdev->dev, "Can't get emc clock\n"); - err = PTR_ERR(emc_clk); - goto err_emc; - } - - clk_enable(emc_clk); - clk_set_rate(emc_clk, 300000000); - - /* we have to remap the registers ourselves as fsl_udc does not - * export them for us. - */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -ENXIO; - goto err0; - } - udc_base = ioremap(res->start, resource_size(res)); - if (!udc_base) { - err = -ENOMEM; - goto err0; - } - - instance = pdev->id; - if (instance == -1) - instance = 0; - - phy = tegra_usb_phy_open(instance, udc_base, pdata->phy_config, - TEGRA_USB_PHY_MODE_DEVICE); - if (IS_ERR(phy)) { - dev_err(&pdev->dev, "Can't open phy\n"); - err = PTR_ERR(phy); - goto err1; - } - - tegra_usb_phy_power_on(phy); - - return 0; -err1: - iounmap(udc_base); -err0: - clk_disable(emc_clk); - clk_put(emc_clk); -err_emc: - clk_disable(udc_clk); - clk_put(udc_clk); - return err; -} - -void fsl_udc_clk_finalize(struct platform_device *pdev) -{ -} - -void fsl_udc_clk_release(void) -{ - tegra_usb_phy_close(phy); - - iounmap(udc_base); - - clk_disable(udc_clk); - clk_put(udc_clk); - - clk_disable(emc_clk); - clk_put(emc_clk); -} - -void fsl_udc_clk_suspend(void) -{ - tegra_usb_phy_power_off(phy); - clk_disable(udc_clk); - clk_disable(emc_clk); -} - -void fsl_udc_clk_resume(void) -{ - clk_enable(emc_clk); - clk_enable(udc_clk); - tegra_usb_phy_power_on(phy); -} diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 2fab37a2a094..08a9a62a39e3 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -48,22 +48,13 @@ #include "fsl_usb2_udc.h" -#ifdef CONFIG_ARCH_TEGRA -#define DRIVER_DESC "NVidia Tegra High-Speed USB SOC Device Controller driver" -#else #define DRIVER_DESC "Freescale High-Speed USB SOC Device Controller driver" -#endif #define DRIVER_AUTHOR "Li Yang/Jiang Bo" #define DRIVER_VERSION "Apr 20, 2007" #define DMA_ADDR_INVALID (~(dma_addr_t)0) -#define STATUS_BUFFER_SIZE 8 -#ifdef CONFIG_ARCH_TEGRA -static const char driver_name[] = "fsl-tegra-udc"; -#else static const char driver_name[] = "fsl-usb2-udc"; -#endif static const char driver_desc[] = DRIVER_DESC; static struct usb_dr_device *dr_regs; @@ -84,7 +75,6 @@ fsl_ep0_desc = { }; static void fsl_ep_fifo_flush(struct usb_ep *_ep); -static int reset_queues(struct fsl_udc *udc); #ifdef CONFIG_PPC32 #define fsl_readl(addr) in_le32(addr) @@ -94,25 +84,6 @@ static int reset_queues(struct fsl_udc *udc); #define fsl_writel(val32, addr) writel(val32, addr) #endif -/* - * High speed test mode packet(53 bytes). - * See USB 2.0 spec, section 7.1.20. - */ -static const u8 fsl_udc_test_packet[53] = { - /* JKJKJKJK x9 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* JJKKJJKK x8 */ - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - /* JJJJKKKK x8 */ - 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, - /* JJJJJJJKKKKKKK x8 */ - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* JJJJJJJK x8 */ - 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, - /* JKKKKKKK x10, JK */ - 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e -}; - /******************************************************************** * Internal Used Function ********************************************************************/ @@ -204,43 +175,14 @@ static void nuke(struct fsl_ep *ep, int status) Internal Hardware related function ------------------------------------------------------------------*/ -#define FSL_UDC_RESET_TIMEOUT 1000 -static int dr_controller_reset(struct fsl_udc *udc) -{ - unsigned int tmp; - unsigned long timeout; - - /* Stop and reset the usb controller */ - tmp = fsl_readl(&dr_regs->usbcmd); - tmp &= ~USB_CMD_RUN_STOP; - fsl_writel(tmp, &dr_regs->usbcmd); - - tmp = fsl_readl(&dr_regs->usbcmd); - tmp |= USB_CMD_CTRL_RESET; - fsl_writel(tmp, &dr_regs->usbcmd); - - /* Wait for reset to complete */ - timeout = jiffies + FSL_UDC_RESET_TIMEOUT; - while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) { - if (time_after(jiffies, timeout)) { - ERR("udc reset timeout!\n"); - return -ETIMEDOUT; - } - cpu_relax(); - } - return 0; -} - static int dr_controller_setup(struct fsl_udc *udc) { unsigned int tmp, portctrl; -#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_ARCH_TEGRA) +#ifndef CONFIG_ARCH_MXC unsigned int ctrl; #endif -#ifdef CONFIG_ARCH_TEGRA unsigned long timeout; -#endif - int status; +#define FSL_UDC_RESET_TIMEOUT 1000 /* Config PHY interface */ portctrl = fsl_readl(&dr_regs->portsc1); @@ -263,29 +205,31 @@ static int dr_controller_setup(struct fsl_udc *udc) } fsl_writel(portctrl, &dr_regs->portsc1); - status = dr_controller_reset(udc); - if (status) - return status; + /* Stop and reset the usb controller */ + tmp = fsl_readl(&dr_regs->usbcmd); + tmp &= ~USB_CMD_RUN_STOP; + fsl_writel(tmp, &dr_regs->usbcmd); - /* Set the controller as device mode */ - tmp = fsl_readl(&dr_regs->usbmode); - tmp |= USB_MODE_CTRL_MODE_DEVICE; - /* Disable Setup Lockout */ - tmp |= USB_MODE_SETUP_LOCK_OFF; - fsl_writel(tmp, &dr_regs->usbmode); + tmp = fsl_readl(&dr_regs->usbcmd); + tmp |= USB_CMD_CTRL_RESET; + fsl_writel(tmp, &dr_regs->usbcmd); -#ifdef CONFIG_ARCH_TEGRA - /* Wait for controller to switch to device mode */ + /* Wait for reset to complete */ timeout = jiffies + FSL_UDC_RESET_TIMEOUT; - while ((fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_DEVICE) != - USB_MODE_CTRL_MODE_DEVICE) { + while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) { if (time_after(jiffies, timeout)) { - ERR("udc device mode setup timeout!\n"); + ERR("udc reset timeout!\n"); return -ETIMEDOUT; } cpu_relax(); } -#endif + + /* Set the controller as device mode */ + tmp = fsl_readl(&dr_regs->usbmode); + tmp |= USB_MODE_CTRL_MODE_DEVICE; + /* Disable Setup Lockout */ + tmp |= USB_MODE_SETUP_LOCK_OFF; + fsl_writel(tmp, &dr_regs->usbmode); /* Clear the setup status */ fsl_writel(0, &dr_regs->usbsts); @@ -299,7 +243,7 @@ static int dr_controller_setup(struct fsl_udc *udc) fsl_readl(&dr_regs->endpointlistaddr)); /* Config control enable i/o output, cpu endian register */ -#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_ARCH_TEGRA) +#ifndef CONFIG_ARCH_MXC ctrl = __raw_readl(&usb_sys_regs->control); ctrl |= USB_CTRL_IOENB; __raw_writel(ctrl, &usb_sys_regs->control); @@ -323,12 +267,6 @@ static int dr_controller_setup(struct fsl_udc *udc) static void dr_controller_run(struct fsl_udc *udc) { u32 temp; -#ifdef CONFIG_ARCH_TEGRA - unsigned long timeout; -#define FSL_UDC_RUN_TIMEOUT 1000 -#endif - /* Clear stopped bit */ - udc->stopped = 0; /* Enable DR irq reg */ temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN @@ -337,6 +275,9 @@ static void dr_controller_run(struct fsl_udc *udc) fsl_writel(temp, &dr_regs->usbintr); + /* Clear stopped bit */ + udc->stopped = 0; + /* Set the controller as device mode */ temp = fsl_readl(&dr_regs->usbmode); temp |= USB_MODE_CTRL_MODE_DEVICE; @@ -347,19 +288,6 @@ static void dr_controller_run(struct fsl_udc *udc) temp |= USB_CMD_RUN_STOP; fsl_writel(temp, &dr_regs->usbcmd); -#ifdef CONFIG_ARCH_TEGRA - /* Wait for controller to start */ - timeout = jiffies + FSL_UDC_RUN_TIMEOUT; - while ((fsl_readl(&dr_regs->usbcmd) & USB_CMD_RUN_STOP) != - USB_CMD_RUN_STOP) { - if (time_after(jiffies, timeout)) { - ERR("udc start timeout!\n"); - return; - } - cpu_relax(); - } -#endif - return; } @@ -688,9 +616,6 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) ? (1 << (ep_index(ep) + 16)) : (1 << (ep_index(ep))); - /* Flush all the dTD structs out to memory */ - wmb(); - /* check if the pipe is empty */ if (!(list_empty(&ep->queue))) { /* Add td to the end */ @@ -698,7 +623,6 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); lastreq->tail->next_td_ptr = cpu_to_le32(req->head->td_dma & DTD_ADDR_MASK); - wmb(); /* Read prime bit, if 1 goto done */ if (fsl_readl(&dr_regs->endpointprime) & bitmask) goto out; @@ -749,7 +673,7 @@ out: * @is_last: return flag if it is the last dTD of the request * return: pointer to the built dTD */ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, - dma_addr_t *dma, int *is_last, gfp_t gfp_flags) + dma_addr_t *dma, int *is_last) { u32 swap_temp; struct ep_td_struct *dtd; @@ -758,7 +682,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, *length = min(req->req.length - req->req.actual, (unsigned)EP_MAX_LENGTH_TRANSFER); - dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); + dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); if (dtd == NULL) return dtd; @@ -808,7 +732,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, } /* Generate dtd chain for a request */ -static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) +static int fsl_req_to_dtd(struct fsl_req *req) { unsigned count; int is_last; @@ -817,7 +741,7 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) dma_addr_t dma; do { - dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); + dtd = fsl_build_dtd(req, &count, &dma, &is_last); if (dtd == NULL) return -ENOMEM; @@ -846,11 +770,9 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) { struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); struct fsl_req *req = container_of(_req, struct fsl_req, req); - struct fsl_udc *udc = ep->udc; + struct fsl_udc *udc; unsigned long flags; - enum dma_data_direction dir; int is_iso = 0; - int status; /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf @@ -858,27 +780,17 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) VDBG("%s, bad params", __func__); return -EINVAL; } - - spin_lock_irqsave(&udc->lock, flags); - - if (unlikely(!ep->desc)) { + if (unlikely(!_ep || !ep->desc)) { VDBG("%s, bad ep", __func__); - spin_unlock_irqrestore(&udc->lock, flags); return -EINVAL; } - if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { - if (req->req.length > ep->ep.maxpacket) { - spin_unlock_irqrestore(&udc->lock, flags); + if (req->req.length > ep->ep.maxpacket) return -EMSGSIZE; - } is_iso = 1; } - dir = ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - - spin_unlock_irqrestore(&udc->lock, flags); - + udc = ep->udc; if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; @@ -886,12 +798,18 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* map virtual address to hardware */ if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single(udc->gadget.dev.parent, - req->req.buf, req->req.length, dir); + req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, + req->req.buf, + req->req.length, ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); req->mapped = 1; } else { - dma_sync_single_for_device(udc->gadget.dev.parent, - req->req.dma, req->req.length, dir); + dma_sync_single_for_device(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); req->mapped = 0; } @@ -899,23 +817,16 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->req.actual = 0; req->dtd_count = 0; - - /* build dtds and push them to device queue */ - status = fsl_req_to_dtd(req, gfp_flags); - if (status) - goto err_unmap; - spin_lock_irqsave(&udc->lock, flags); - /* re-check if the ep has not been disabled */ - if (unlikely(!ep->desc)) { + /* build dtds and push them to device queue */ + if (!fsl_req_to_dtd(req)) { + fsl_queue_td(ep, req); + } else { spin_unlock_irqrestore(&udc->lock, flags); - status = -EINVAL; - goto err_unmap; + return -ENOMEM; } - fsl_queue_td(ep, req); - /* Update ep0 state */ if ((ep_index(ep) == 0)) udc->ep0_state = DATA_STATE_XMIT; @@ -926,15 +837,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) spin_unlock_irqrestore(&udc->lock, flags); return 0; - -err_unmap: - if (req->mapped) { - dma_unmap_single(udc->gadget.dev.parent, - req->req.dma, req->req.length, dir); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } - return status; } /* dequeues (cancels, unlinks) an I/O request from an endpoint */ @@ -1171,38 +1073,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) udc = container_of(gadget, struct fsl_udc, gadget); spin_lock_irqsave(&udc->lock, flags); - VDBG("VBUS %s", is_active ? "on" : "off"); - - if (udc->transceiver) { - if (udc->vbus_active && !is_active) { - /* reset all internal Queues and inform client driver */ - reset_queues(udc); - /* stop the controller and turn off the clocks */ - dr_controller_stop(udc); - dr_controller_reset(udc); - spin_unlock_irqrestore(&udc->lock, flags); - fsl_udc_clk_suspend(); - udc->vbus_active = 0; - udc->usb_state = USB_STATE_DEFAULT; - } else if (!udc->vbus_active && is_active) { - spin_unlock_irqrestore(&udc->lock, flags); - fsl_udc_clk_resume(); - /* setup the controller in the device mode */ - dr_controller_setup(udc); - /* setup EP0 for setup packet */ - ep0_setup(udc); - /* initialize the USB and EP states */ - udc->usb_state = USB_STATE_ATTACHED; - udc->ep0_state = WAIT_FOR_SETUP; - udc->ep0_dir = 0; - udc->vbus_active = 1; - /* start the controller */ - dr_controller_run(udc); - } - return 0; - } - udc->vbus_active = (is_active != 0); if (can_pullup(udc)) fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), @@ -1295,7 +1166,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) req->req.complete = NULL; req->dtd_count = 0; - if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) + if (fsl_req_to_dtd(req) == 0) fsl_queue_td(ep, req); else return -ENOMEM; @@ -1373,7 +1244,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, req->dtd_count = 0; /* prime the data phase */ - if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) + if ((fsl_req_to_dtd(req) == 0)) fsl_queue_td(ep, req); else /* no mem */ goto stall; @@ -1385,107 +1256,6 @@ stall: ep0stall(udc); } -static void udc_test_mode(struct fsl_udc *udc, u32 test_mode) -{ - struct fsl_req *req; - struct fsl_ep *ep; - u32 portsc, bitmask; - unsigned long timeout; - - /* Ack the ep0 IN */ - if (ep0_prime_status(udc, EP_DIR_IN)) - ep0stall(udc); - - /* get the ep0 */ - ep = &udc->eps[0]; - bitmask = ep_is_in(ep) - ? (1 << (ep_index(ep) + 16)) - : (1 << (ep_index(ep))); - - timeout = jiffies + HZ; - /* Wait until ep0 IN endpoint txfr is complete */ - while (!(fsl_readl(&dr_regs->endptcomplete) & bitmask)) { - if (time_after(jiffies, timeout)) { - pr_err("Timeout for Ep0 IN Ack\n"); - break; - } - cpu_relax(); - } - - switch (test_mode << PORTSCX_PTC_BIT_POS) { - case PORTSCX_PTC_JSTATE: - VDBG("TEST_J\n"); - break; - case PORTSCX_PTC_KSTATE: - VDBG("TEST_K\n"); - break; - case PORTSCX_PTC_SEQNAK: - VDBG("TEST_SE0_NAK\n"); - break; - case PORTSCX_PTC_PACKET: - VDBG("TEST_PACKET\n"); - - /* get the ep and configure for IN direction */ - ep = &udc->eps[0]; - udc->ep0_dir = USB_DIR_IN; - - /* Initialize ep0 status request structure */ - req = container_of(fsl_alloc_request(NULL, GFP_ATOMIC), - struct fsl_req, req); - /* allocate a small amount of memory to get valid address */ - req->req.buf = kmalloc(sizeof(fsl_udc_test_packet), GFP_ATOMIC); - req->req.dma = virt_to_phys(req->req.buf); - - /* Fill in the reqest structure */ - memcpy(req->req.buf, fsl_udc_test_packet, sizeof(fsl_udc_test_packet)); - req->ep = ep; - req->req.length = sizeof(fsl_udc_test_packet); - req->req.status = -EINPROGRESS; - req->req.actual = 0; - req->req.complete = NULL; - req->dtd_count = 0; - req->mapped = 0; - - dma_sync_single_for_device(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_is_in(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - - /* prime the data phase */ - if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) - fsl_queue_td(ep, req); - else /* no mem */ - goto stall; - - list_add_tail(&req->queue, &ep->queue); - udc->ep0_state = DATA_STATE_XMIT; - break; - case PORTSCX_PTC_FORCE_EN: - VDBG("TEST_FORCE_EN\n"); - break; - default: - ERR("udc unknown test mode[%d]!\n", test_mode); - goto stall; - } - - /* read the portsc register */ - portsc = fsl_readl(&dr_regs->portsc1); - /* set the test mode selector */ - portsc |= test_mode << PORTSCX_PTC_BIT_POS; - fsl_writel(portsc, &dr_regs->portsc1); - - /* - * The device must have its power cycled to exit test mode. - * See USB 2.0 spec, section 9.4.9 for test modes operation in "Set Feature" - * See USB 2.0 spec, section 7.1.20 for test modes. - */ - pr_info("udc entering the test mode, power cycle to exit test mode\n"); - return; -stall: - ep0stall(udc); -} - static void setup_received_irq(struct fsl_udc *udc, struct usb_ctrlrequest *setup) { @@ -1519,17 +1289,7 @@ static void setup_received_irq(struct fsl_udc *udc, { int rc = -EOPNOTSUPP; - if (setup->bRequestType == USB_RECIP_DEVICE && - wValue == USB_DEVICE_TEST_MODE) { - /* - * If the feature selector is TEST_MODE, then the most - * significant byte of wIndex is used to specify the specific - * test mode and the lower byte of wIndex must be zero. - */ - udc_test_mode(udc, wIndex >> 8); - return; - - } else if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) + if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { int pipe = get_pipe_by_windex(wIndex); struct fsl_ep *ep; @@ -1756,12 +1516,7 @@ static void dtd_complete_irq(struct fsl_udc *udc) if (!bit_pos) return; -#ifdef CONFIG_ARCH_TEGRA - /* XXX what's going on here */ - for (i = 0; i < udc->max_ep; i++) { -#else for (i = 0; i < udc->max_ep * 2; i++) { -#endif ep_num = i >> 1; direction = i % 2; @@ -1909,15 +1664,6 @@ static void reset_irq(struct fsl_udc *udc) /* Write 1s to the flush register */ fsl_writel(0xffffffff, &dr_regs->endptflush); -#if defined(CONFIG_ARCH_TEGRA) - /* When the bus reset is seen on Tegra, the PORTSCX_PORT_RESET bit - * is not set */ - VDBG("Bus reset"); - /* Reset all the queues, include XD, dTD, EP queue - * head and TR Queue */ - reset_queues(udc); - udc->usb_state = USB_STATE_DEFAULT; -#else if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { VDBG("Bus reset"); /* Reset all the queues, include XD, dTD, EP queue @@ -1939,7 +1685,6 @@ static void reset_irq(struct fsl_udc *udc) dr_controller_run(udc); udc->usb_state = USB_STATE_ATTACHED; } -#endif } /* @@ -1952,14 +1697,10 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) irqreturn_t status = IRQ_NONE; unsigned long flags; - spin_lock_irqsave(&udc->lock, flags); - /* Disable ISR for OTG host mode */ - if (udc->stopped) { - spin_unlock_irqrestore(&udc->lock, flags); + if (udc->stopped) return IRQ_NONE; - } - + spin_lock_irqsave(&udc->lock, flags); irq_src = fsl_readl(&dr_regs->usbsts) & fsl_readl(&dr_regs->usbintr); /* Clear notification bits */ fsl_writel(irq_src, &dr_regs->usbsts); @@ -2060,13 +1801,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) } /* Enable DR IRQ reg and Set usbcmd reg Run bit */ - if (!udc_controller->transceiver) { - dr_controller_run(udc_controller); - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; - } - + dr_controller_run(udc_controller); + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = 0; printk(KERN_INFO "%s: bind to driver %s\n", udc_controller->gadget.name, driver->driver.name); @@ -2090,6 +1828,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!driver || driver != udc_controller->driver || !driver->unbind) return -EINVAL; + if (udc_controller->transceiver) + otg_set_peripheral(udc_controller->transceiver, NULL); + /* stop DR, disable intr */ dr_controller_stop(udc_controller); @@ -2128,11 +1869,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); #include -#ifdef CONFIG_ARCH_TEGRA -static const char proc_filename[] = "driver/fsl_tegra_udc"; -#else static const char proc_filename[] = "driver/fsl_usb2_udc"; -#endif static int fsl_proc_read(char *page, char **start, off_t off, int count, int *eof, void *_dev) @@ -2314,7 +2051,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, size -= t; next += t; -#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_ARCH_TEGRA) +#ifndef CONFIG_ARCH_MXC tmp_reg = usb_sys_regs->snoop1; t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); size -= t; @@ -2402,10 +2139,8 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, static void fsl_udc_release(struct device *dev) { complete(udc_controller->done); -#ifndef CONFIG_ARCH_TEGRA dma_free_coherent(dev->parent, udc_controller->ep_qh_size, udc_controller->ep_qh, udc_controller->ep_qh_dma); -#endif kfree(udc_controller); } @@ -2431,13 +2166,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc, return -1; } -#ifdef CONFIG_ARCH_TEGRA - /* Tegra uses hardware queue heads */ - size = udc->max_ep * sizeof(struct ep_queue_head); - udc->ep_qh = (struct ep_queue_head *)((u8 *)dr_regs + QH_OFFSET); - udc->ep_qh_dma = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start + - QH_OFFSET; -#else /* initialized QHs, take care of alignment */ size = udc->max_ep * sizeof(struct ep_queue_head); if (size < QH_ALIGNMENT) @@ -2453,7 +2181,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc, kfree(udc->eps); return -1; } -#endif udc->ep_qh_size = size; @@ -2462,17 +2189,8 @@ static int __init struct_udc_setup(struct fsl_udc *udc, udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), struct fsl_req, req); /* allocate a small amount of memory to get valid address */ - udc->status_req->req.buf = dma_alloc_coherent(&pdev->dev, - STATUS_BUFFER_SIZE, &udc->status_req->req.dma, - GFP_KERNEL); - if (!udc->status_req->req.buf) { - ERR("alloc status_req buffer failed\n"); -#ifndef CONFIG_ARCH_TEGRA - dma_free_coherent(&pdev->dev, size, udc->ep_qh, udc->ep_qh_dma); -#endif - kfree(udc->eps); - return -ENOMEM; - } + udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); + udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); udc->resume_state = USB_STATE_NOTATTACHED; udc->usb_state = USB_STATE_POWERED; @@ -2527,9 +2245,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) int ret = -ENODEV; unsigned int i; u32 dccparams; -#if defined(CONFIG_ARCH_TEGRA) - struct resource *res_sys = NULL; -#endif if (strcmp(pdev->name, driver_name)) { VDBG("Wrong device"); @@ -2564,21 +2279,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) goto err_release_mem_region; } -#if defined(CONFIG_ARCH_TEGRA) - /* If the PHY registers are NOT provided as a seperate aperture, then - * we should be using the registers inside the controller aperture. */ - res_sys = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (res_sys) { - usb_sys_regs = ioremap(res_sys->start, resource_size(res_sys)); - if (!usb_sys_regs) - goto err_release_mem_region; - } else { - usb_sys_regs = (struct usb_sys_interface *) - ((u32)dr_regs + USB_DR_SYS_OFFSET); - } -#endif - -#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_ARCH_TEGRA) +#ifndef CONFIG_ARCH_MXC usb_sys_regs = (struct usb_sys_interface *) ((u32)dr_regs + USB_DR_SYS_OFFSET); #endif @@ -2673,25 +2374,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) goto err_unregister; } create_proc_file(); - -#ifdef CONFIG_USB_OTG_UTILS - udc_controller->transceiver = otg_get_transceiver(); - if (udc_controller->transceiver) { - dr_controller_stop(udc_controller); - dr_controller_reset(udc_controller); - fsl_udc_clk_suspend(); - udc_controller->vbus_active = 0; - udc_controller->usb_state = USB_STATE_DEFAULT; - otg_set_peripheral(udc_controller->transceiver, &udc_controller->gadget); - } -#else -#ifdef CONFIG_ARCH_TEGRA - /* Power down the phy if cable is not connected */ - if (!(fsl_readl(&usb_sys_regs->vbus_wakeup) & USB_SYS_VBUS_STATUS)) - fsl_udc_clk_suspend(); -#endif -#endif - return 0; err_unregister: @@ -2723,18 +2405,13 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) return -ENODEV; udc_controller->done = &done; - if (udc_controller->transceiver) - otg_set_peripheral(udc_controller->transceiver, NULL); - fsl_udc_clk_release(); /* DR has been stopped in usb_gadget_unregister_driver() */ remove_proc_file(); /* Free allocated memory */ - dma_free_coherent(&pdev->dev, STATUS_BUFFER_SIZE, - udc_controller->status_req->req.buf, - udc_controller->status_req->req.dma); + kfree(udc_controller->status_req->req.buf); kfree(udc_controller->status_req); kfree(udc_controller->eps); @@ -2756,10 +2433,6 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) -----------------------------------------------------------------*/ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) { - if (udc_controller->transceiver && - udc_controller->transceiver->state != OTG_STATE_B_PERIPHERAL) - return 0; - dr_controller_stop(udc_controller); return 0; } @@ -2770,10 +2443,6 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) *-----------------------------------------------------------------*/ static int fsl_udc_resume(struct platform_device *pdev) { - if (udc_controller->transceiver && - udc_controller->transceiver->state != OTG_STATE_B_PERIPHERAL) - return 0; - /* Enable DR irq reg and set controller Run */ if (udc_controller->stopped) { dr_controller_setup(udc_controller); diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 8d5bd2fe7475..20aeceed48c7 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -84,15 +84,6 @@ struct usb_dr_host { }; /* non-EHCI USB system interface registers (Big Endian) */ -#ifdef CONFIG_ARCH_TEGRA -struct usb_sys_interface { - u32 suspend_ctrl; - u32 vbus_sensors; - u32 vbus_wakeup; - u32 vbus_alt_status; - u32 legacy_ctrl; -}; -#else struct usb_sys_interface { u32 snoop1; u32 snoop2; @@ -102,7 +93,6 @@ struct usb_sys_interface { u8 res[236]; u32 control; /* General Purpose Control Register */ }; -#endif /* ep0 transfer state */ #define WAIT_FOR_SETUP 0 @@ -430,19 +420,10 @@ struct ep_td_struct { /* Alignment requirements; must be a power of two */ #define DTD_ALIGNMENT 0x20 #define QH_ALIGNMENT 2048 -#define QH_OFFSET 0x1000 /* Controller dma boundary */ #define UDC_DMA_BOUNDARY 0x1000 -#define USB_SYS_VBUS_ASESSION_INT_EN 0x10000 -#define USB_SYS_VBUS_ASESSION_CHANGED 0x20000 -#define USB_SYS_VBUS_ASESSION 0x40000 -#define USB_SYS_VBUS_WAKEUP_ENABLE 0x40000000 -#define USB_SYS_VBUS_WAKEUP_INT_ENABLE 0x100 -#define USB_SYS_VBUS_WAKEUP_INT_STATUS 0x200 -#define USB_SYS_VBUS_STATUS 0x400 - /*-------------------------------------------------------------------------*/ /* ### driver private data @@ -583,12 +564,10 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) struct platform_device; -#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_ARCH_TEGRA) +#ifdef CONFIG_ARCH_MXC int fsl_udc_clk_init(struct platform_device *pdev); void fsl_udc_clk_finalize(struct platform_device *pdev); void fsl_udc_clk_release(void); -void fsl_udc_clk_suspend(void); -void fsl_udc_clk_resume(void); #else static inline int fsl_udc_clk_init(struct platform_device *pdev) { @@ -600,12 +579,6 @@ static inline void fsl_udc_clk_finalize(struct platform_device *pdev) static inline void fsl_udc_clk_release(void) { } -static inline void fsl_udc_clk_suspend(void) -{ -} -static inline void fsl_udc_clk_resume(void) -{ -} #endif #endif diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 3c2f0a43c9c6..a9474f8d5325 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -53,8 +53,8 @@ MODULE_AUTHOR("Michal Nazarewicz"); MODULE_LICENSE("GPL"); -static unsigned short gfs_vendor_id = 0x1d6b; /* Linux Foundation */ -static unsigned short gfs_product_id = 0x0105; /* FunctionFS Gadget */ +static unsigned short gfs_vendor_id = 0x0525; /* XXX NetChip */ +static unsigned short gfs_product_id = 0xa4ac; /* XXX */ static struct usb_device_descriptor gfs_dev_desc = { .bLength = sizeof gfs_dev_desc, diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 36d67a32abef..795d76232167 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -74,8 +74,8 @@ MODULE_LICENSE("GPL"); /***************************** Device Descriptor ****************************/ -#define MULTI_VENDOR_NUM 0x1d6b /* Linux Foundation */ -#define MULTI_PRODUCT_NUM 0x0104 /* Multifunction Composite Gadget */ +#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */ +#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */ enum { diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 116347b0bf13..972d5ddd1e18 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -159,25 +159,6 @@ static const u32 oid_supported_list [] = #endif /* RNDIS_PM */ }; -/* HACK: copied from net/core/dev.c to replace dev_get_stats since - * dev_get_stats cannot be called from atomic context */ -static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, - const struct net_device_stats *netdev_stats) -{ -#if BITS_PER_LONG == 64 - BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats)); - memcpy(stats64, netdev_stats, sizeof(*stats64)); -#else - size_t i, n = sizeof(*stats64) / sizeof(u64); - const unsigned long *src = (const unsigned long *)netdev_stats; - u64 *dst = (u64 *)stats64; - - BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) != - sizeof(*stats64) / sizeof(u64)); - for (i = 0; i < n; i++) - dst[i] = src[i]; -#endif -} /* NDIS Functions */ static int @@ -191,7 +172,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, rndis_query_cmplt_type *resp; struct net_device *net; struct rtnl_link_stats64 temp; - struct rtnl_link_stats64 *stats = &temp; + const struct rtnl_link_stats64 *stats; if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *) r->buf; @@ -214,7 +195,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, resp->InformationBufferOffset = cpu_to_le32 (16); net = rndis_per_dev_params[configNr].dev; - netdev_stats_to_stats64(stats, &net->stats); + stats = dev_get_stats(net, &temp); switch (OID) { diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 2771166ac69a..484acfb1a7c5 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -805,16 +805,10 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, struct rw_semaphore *filesem = dev_get_drvdata(dev); int rc = 0; - -#ifndef CONFIG_USB_ANDROID_MASS_STORAGE - /* disabled in android because we need to allow closing the backing file - * if the media was removed - */ if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { LDBG(curlun, "eject attempt prevented\n"); return -EBUSY; /* "Door is locked" */ } -#endif /* Remove a trailing newline */ if (count > 0 && buf[count-1] == '\n') diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index efdc8817f77d..6bb876d65252 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -936,6 +936,7 @@ void gether_disconnect(struct gether *link) struct eth_dev *dev = link->ioport; struct usb_request *req; + WARN_ON(!dev); if (!dev) return; diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index 99e4aa3b1374..3c8c0c9f9d72 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h @@ -105,7 +105,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); int eem_bind_config(struct usb_configuration *c); -#if defined(USB_ETH_RNDIS) || defined(CONFIG_USB_ANDROID_RNDIS) +#ifdef USB_ETH_RNDIS int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index fdc934523c0f..01e5354a4c20 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -118,7 +118,7 @@ struct gs_port { }; /* increase N_PORTS if you need more */ -#define N_PORTS 8 +#define N_PORTS 4 static struct portmaster { struct mutex lock; /* protect open/close */ struct gs_port *port; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 28deb1ac09b0..2d926cec0725 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -126,14 +126,6 @@ config USB_EHCI_MXC ---help--- Variation of ARC USB block used in some Freescale chips. -config USB_EHCI_TEGRA - boolean "NVIDIA Tegra HCD support" - depends on USB_EHCI_HCD && ARCH_TEGRA - select USB_EHCI_ROOT_HUB_TT - help - This driver enables support for the internal USB Host Controller - found in NVIDIA Tegra SoCs. The Tegra controller is EHCI compliant. - config USB_EHCI_HCD_PPC_OF bool "EHCI support for PPC USB controller on OF platform bus" depends on USB_EHCI_HCD && PPC_OF diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index b349021c052b..76b7fd2d838a 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -1063,7 +1063,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci) &debug_registers_fops)) goto file_error; - if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus, + if (!debugfs_create_file("lpm", S_IRUGO|S_IWUGO, ehci->debug_dir, bus, &debug_lpm_fops)) goto file_error; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 36ec66bb995e..34a928d3b7d2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1048,11 +1048,10 @@ rescan: tmp && tmp != qh; tmp = tmp->qh_next.qh) continue; - /* periodic qh self-unlinks on empty, and a COMPLETING qh - * may already be unlinked. - */ - if (tmp) - unlink_async(ehci, qh); + /* periodic qh self-unlinks on empty */ + if (!tmp) + goto nogood; + unlink_async (ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: @@ -1069,6 +1068,7 @@ idle_timeout: } /* else FALL THROUGH */ default: +nogood: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. */ @@ -1197,11 +1197,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_atmel_driver #endif -#ifdef CONFIG_USB_EHCI_TEGRA -#include "ehci-tegra.c" -#define PLATFORM_DRIVER tegra_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-hub.c b/drivers/usb/host/ehci-hub.c index e33e78cbde00..796ea0c8900f 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -900,7 +900,6 @@ static int ehci_hub_control ( /* whoever resets must GetPortStatus to complete it!! */ if ((temp & PORT_RESET) - && !ehci->port_reset_no_wait && time_after_eq(jiffies, ehci->reset_done[wIndex])) { status |= USB_PORT_STAT_C_RESET << 16; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 8d24d1c5e6a2..a1e8d273103f 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -148,18 +148,6 @@ 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/ehci-q.c b/drivers/usb/host/ehci-q.c index 95bd514c0d06..233c288e3f93 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -838,7 +838,6 @@ qh_make ( is_input, 0, hb_mult(maxp) * max_packet(maxp))); qh->start = NO_FRAME; - qh->stamp = ehci->periodic_stamp; if (urb->dev->speed == USB_SPEED_HIGH) { qh->c_usecs = 0; @@ -1009,7 +1008,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) qh_get(qh); qh->xacterrs = 0; qh->qh_state = QH_STATE_LINKED; - wmb(); /* qtd completions reported later by interrupt */ } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index fa442c5ec16b..a92526d6e5ae 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -2261,7 +2261,6 @@ scan_periodic (struct ehci_hcd *ehci) } clock &= mod - 1; clock_frame = clock >> 3; - ++ehci->periodic_stamp; for (;;) { union ehci_shadow q, *q_p; @@ -2290,14 +2289,10 @@ restart: temp.qh = qh_get (q.qh); type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); q = q.qh->qh_next; - if (temp.qh->stamp != ehci->periodic_stamp) { - modified = qh_completions(ehci, temp.qh); - if (!modified) - temp.qh->stamp = ehci->periodic_stamp; - if (unlikely(list_empty(&temp.qh->qtd_list) || - temp.qh->needs_rescan)) - intr_deschedule(ehci, temp.qh); - } + modified = qh_completions (ehci, temp.qh); + if (unlikely(list_empty(&temp.qh->qtd_list) || + temp.qh->needs_rescan)) + intr_deschedule (ehci, temp.qh); qh_put (temp.qh); break; case Q_TYPE_FSTN: @@ -2432,7 +2427,6 @@ restart: free_cached_lists(ehci); ehci->clock_frame = clock_frame; } - ++ehci->periodic_stamp; } else { now_uframe++; now_uframe &= mod - 1; diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c deleted file mode 100644 index 9738b994f391..000000000000 --- a/drivers/usb/host/ehci-tegra.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs - * - * Copyright (C) 2010 Google, Inc. - * Copyright (C) 2009 NVIDIA 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. - * - */ - -#include -#include -#include -#include -#include -#include - -#define TEGRA_USB_DMA_ALIGN 32 - -#define STS_SRI (1<<7) /* SOF Recieved */ - -struct tegra_ehci_hcd { - struct ehci_hcd *ehci; - struct tegra_usb_phy *phy; - struct clk *clk; - struct clk *emc_clk; - struct otg_transceiver *transceiver; - int host_resumed; - int bus_suspended; - int port_resuming; - int power_down_on_bus_suspend; - enum tegra_usb_phy_port_speed port_speed; -}; - -static void tegra_ehci_power_up(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - clk_enable(tegra->emc_clk); - clk_enable(tegra->clk); - tegra_usb_phy_power_on(tegra->phy); - tegra->host_resumed = 1; -} - -static void tegra_ehci_power_down(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - tegra->host_resumed = 0; - tegra_usb_phy_power_off(tegra->phy); - clk_disable(tegra->clk); - clk_disable(tegra->emc_clk); -} - -static int tegra_ehci_hub_control( - struct usb_hcd *hcd, - u16 typeReq, - u16 wValue, - u16 wIndex, - char *buf, - u16 wLength -) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - u32 __iomem *status_reg; - u32 temp; - u32 usbsts_reg; - unsigned long flags; - int retval = 0; - - status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; - - spin_lock_irqsave(&ehci->lock, flags); - - /* - * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits - * that are write on clear, by writing back the register read value, so - * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits - */ - if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) { - temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; - ehci_writel(ehci, temp & ~PORT_PE, status_reg); - goto done; - } - - else if (typeReq == GetPortStatus) { - temp = ehci_readl(ehci, status_reg); - if (tegra->port_resuming && !(temp & PORT_SUSPEND) && - time_after_eq(jiffies, ehci->reset_done[wIndex-1])) { - /* Resume completed, re-enable disconnect detection */ - tegra->port_resuming = 0; - clear_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); - ehci->reset_done[wIndex-1] = 0; - tegra_usb_phy_postresume(tegra->phy); - } - } - - else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { - temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { - retval = -EPIPE; - goto done; - } - - temp &= ~PORT_WKCONN_E; - temp |= PORT_WKDISC_E | PORT_WKOC_E; - ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); - - /* - * If a transaction is in progress, there may be a delay in - * suspending the port. Poll until the port is suspended. - */ - if (handshake(ehci, status_reg, PORT_SUSPEND, - PORT_SUSPEND, 5000)) - pr_err("%s: timeout waiting for SUSPEND\n", __func__); - - set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); - goto done; - } - - /* - * Tegra host controller will time the resume operation to clear the bit - * when the port control state switches to HS or FS Idle. This behavior - * is different from EHCI where the host controller driver is required - * to set this bit to a zero after the resume duration is timed in the - * driver. - */ - else if (typeReq == ClearPortFeature && - wValue == USB_PORT_FEAT_SUSPEND) { - temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_RESET) || !(temp & PORT_PE)) { - retval = -EPIPE; - goto done; - } - - if (!(temp & PORT_SUSPEND)) - goto done; - - tegra->port_resuming = 1; - - /* Disable disconnect detection during port resume */ - tegra_usb_phy_preresume(tegra->phy); - - ehci_dbg(ehci, "%s:USBSTS = 0x%x", __func__, - ehci_readl(ehci, &ehci->regs->status)); - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - ehci_writel(ehci, usbsts_reg, &ehci->regs->status); - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - udelay(20); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, STS_SRI, 2000)) - pr_err("%s: timeout set for STS_SRI\n", __func__); - - usbsts_reg = ehci_readl(ehci, &ehci->regs->status); - ehci_writel(ehci, usbsts_reg, &ehci->regs->status); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, 0, 2000)) - pr_err("%s: timeout clear STS_SRI\n", __func__); - - if (handshake(ehci, &ehci->regs->status, STS_SRI, STS_SRI, 2000)) - pr_err("%s: timeout set STS_SRI\n", __func__); - - udelay(20); - temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - /* start resume signaling */ - ehci_writel(ehci, temp | PORT_RESUME, status_reg); - - ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); - /* whoever resumes must GetPortStatus to complete it!! */ - goto done; - } - - spin_unlock_irqrestore(&ehci->lock, flags); - - /* Handle the hub control events here */ - return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); -done: - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; -} - -static void tegra_ehci_restart(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci_reset(ehci); - - /* setup the frame list and Async q heads */ - ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); - ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); - /* setup the command register and set the controller in RUN mode */ - ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); - ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, &ehci->regs->command); - - down_write(&ehci_cf_port_reset_rwsem); - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - /* flush posted writes */ - ehci_readl(ehci, &ehci->regs->command); - up_write(&ehci_cf_port_reset_rwsem); -} - -static int tegra_usb_suspend(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - struct ehci_regs __iomem *hw = tegra->ehci->regs; - unsigned long flags; - - spin_lock_irqsave(&tegra->ehci->lock, flags); - - tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; - ehci_halt(tegra->ehci); - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - spin_unlock_irqrestore(&tegra->ehci->lock, flags); - - tegra_ehci_power_down(hcd); - return 0; -} - -static int tegra_usb_resume(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long val; - - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - tegra_ehci_power_up(hcd); - - if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { - /* Wait for the phy to detect new devices - * before we restart the controller */ - msleep(10); - goto restart; - } - - /* Force the phy to keep data lines in suspend state */ - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - - /* Enable host mode */ - tdi_reset(ehci); - - /* Enable Port Power */ - val = readl(&hw->port_status[0]); - val |= PORT_POWER; - writel(val, &hw->port_status[0]); - udelay(10); - - /* Check if the phy resume from LP0. When the phy resume from LP0 - * USB register will be reset. */ - if (!readl(&hw->async_next)) { - /* Program the field PTC based on the saved speed mode */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) - val |= PORT_TEST_FORCE; - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) - val |= PORT_TEST(6); - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= PORT_TEST(7); - writel(val, &hw->port_status[0]); - udelay(10); - - /* Disable test mode by setting PTC field to NORMAL_OP */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - writel(val, &hw->port_status[0]); - udelay(10); - } - - /* Poll until CCS is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, - PORT_CONNECT, 2000)) { - pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); - goto restart; - } - - /* Poll until PE is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_PE, - PORT_PE, 2000)) { - pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); - goto restart; - } - - /* Clear the PCI status, to avoid an interrupt taken upon resume */ - val = readl(&hw->status); - val |= STS_PCD; - writel(val, &hw->status); - - /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ - val = readl(&hw->port_status[0]); - if ((val & PORT_POWER) && (val & PORT_PE)) { - val |= PORT_SUSPEND; - writel(val, &hw->port_status[0]); - - /* Wait until port suspend completes */ - if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, - PORT_SUSPEND, 1000)) { - pr_err("%s: timeout waiting for PORT_SUSPEND\n", - __func__); - goto restart; - } - } - - tegra_ehci_phy_restore_end(tegra->phy); - return 0; - -restart: - if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) - tegra_ehci_phy_restore_end(tegra->phy); - - tegra_ehci_restart(hcd); - return 0; -} - -static void tegra_ehci_shutdown(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - /* ehci_shutdown touches the USB controller registers, make sure - * controller has clocks to it */ - if (!tegra->host_resumed) - tegra_ehci_power_up(hcd); - - ehci_shutdown(hcd); -} - -static int tegra_ehci_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - /* EHCI registers start at offset 0x100 */ - ehci->caps = hcd->regs + 0x100; - ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(readl(&ehci->caps->hc_capbase)); - - dbg_hcs_params(ehci, "reset"); - dbg_hcc_params(ehci, "reset"); - - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = readl(&ehci->caps->hcs_params); - - /* switch to host mode */ - hcd->has_tt = 1; - ehci_reset(ehci); - - retval = ehci_halt(ehci); - if (retval) - return retval; - - /* data structure init */ - retval = ehci_init(hcd); - if (retval) - return retval; - - ehci->sbrn = 0x20; - - ehci_port_power(ehci, 1); - return retval; -} - -#ifdef CONFIG_PM -static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - int error_status = 0; - - error_status = ehci_bus_suspend(hcd); - if (!error_status && tegra->power_down_on_bus_suspend) { - tegra_usb_suspend(hcd); - tegra->bus_suspended = 1; - } - - return error_status; -} - -static int tegra_ehci_bus_resume(struct usb_hcd *hcd) -{ - struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - - if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { - tegra_usb_resume(hcd); - tegra->bus_suspended = 0; - } - - return ehci_bus_resume(hcd); -} -#endif - -struct temp_buffer { - void *kmalloc_ptr; - void *old_xfer_buffer; - u8 data[0]; -}; - -static void free_temp_buffer(struct urb *urb) -{ - enum dma_data_direction dir; - struct temp_buffer *temp; - - if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) - return; - - dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - - temp = container_of(urb->transfer_buffer, struct temp_buffer, - data); - - if (dir == DMA_FROM_DEVICE) - memcpy(temp->old_xfer_buffer, temp->data, - urb->transfer_buffer_length); - urb->transfer_buffer = temp->old_xfer_buffer; - kfree(temp->kmalloc_ptr); - - urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; -} - -static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags) -{ - enum dma_data_direction dir; - struct temp_buffer *temp, *kmalloc_ptr; - size_t kmalloc_size; - - if (urb->num_sgs || urb->sg || - urb->transfer_buffer_length == 0 || - !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) - return 0; - - dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - - /* Allocate a buffer with enough padding for alignment */ - kmalloc_size = urb->transfer_buffer_length + - sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1; - - kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); - if (!kmalloc_ptr) - return -ENOMEM; - - /* Position our struct temp_buffer such that data is aligned */ - temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; - - temp->kmalloc_ptr = kmalloc_ptr; - temp->old_xfer_buffer = urb->transfer_buffer; - if (dir == DMA_TO_DEVICE) - memcpy(temp->data, urb->transfer_buffer, - urb->transfer_buffer_length); - urb->transfer_buffer = temp->data; - - urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; - - return 0; -} - -static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - gfp_t mem_flags) -{ - int ret; - - ret = alloc_temp_buffer(urb, mem_flags); - if (ret) - return ret; - - ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); - if (ret) - free_temp_buffer(urb); - - return ret; -} - -static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) -{ - usb_hcd_unmap_urb_for_dma(hcd, urb); - free_temp_buffer(urb); -} - -static const struct hc_driver tegra_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "Tegra EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - - .flags = HCD_USB2 | HCD_MEMORY, - - .reset = tegra_ehci_setup, - .irq = ehci_irq, - - .start = ehci_run, - .stop = ehci_stop, - .shutdown = tegra_ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .map_urb_for_dma = tegra_ehci_map_urb_for_dma, - .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma, - .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 = tegra_ehci_hub_control, - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -#ifdef CONFIG_PM - .bus_suspend = tegra_ehci_bus_suspend, - .bus_resume = tegra_ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, -}; - -static int tegra_ehci_probe(struct platform_device *pdev) -{ - struct resource *res; - struct usb_hcd *hcd; - struct tegra_ehci_hcd *tegra; - struct tegra_ehci_platform_data *pdata; - int err = 0; - int irq; - int instance = pdev->id; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "Platform data missing\n"); - return -EINVAL; - } - - tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); - if (!tegra) - return -ENOMEM; - - hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) { - dev_err(&pdev->dev, "Unable to create HCD\n"); - err = -ENOMEM; - goto fail_hcd; - } - - platform_set_drvdata(pdev, tegra); - - tegra->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(tegra->clk)) { - dev_err(&pdev->dev, "Can't get ehci clock\n"); - err = PTR_ERR(tegra->clk); - goto fail_clk; - } - - err = clk_enable(tegra->clk); - if (err) - goto fail_clken; - - tegra->emc_clk = clk_get(&pdev->dev, "emc"); - if (IS_ERR(tegra->emc_clk)) { - dev_err(&pdev->dev, "Can't get emc clock\n"); - err = PTR_ERR(tegra->emc_clk); - goto fail_emc_clk; - } - - clk_enable(tegra->emc_clk); - clk_set_rate(tegra->emc_clk, 300000000); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto fail_io; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = ioremap(res->start, resource_size(res)); - if (!hcd->regs) { - dev_err(&pdev->dev, "Failed to remap I/O memory\n"); - err = -ENOMEM; - goto fail_io; - } - - tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, - TEGRA_USB_PHY_MODE_HOST); - if (IS_ERR(tegra->phy)) { - dev_err(&pdev->dev, "Failed to open USB phy\n"); - err = -ENXIO; - goto fail_phy; - } - - err = tegra_usb_phy_power_on(tegra->phy); - if (err) { - dev_err(&pdev->dev, "Failed to power on the phy\n"); - goto fail; - } - - tegra->host_resumed = 1; - tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend; - tegra->ehci = hcd_to_ehci(hcd); - - irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(&pdev->dev, "Failed to get IRQ\n"); - err = -ENODEV; - goto fail; - } - set_irq_flags(irq, IRQF_VALID); - -#ifdef CONFIG_USB_OTG_UTILS - if (pdata->operating_mode == TEGRA_USB_OTG) { - tegra->transceiver = otg_get_transceiver(); - if (tegra->transceiver) - otg_set_host(tegra->transceiver, &hcd->self); - } -#endif - - err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); - if (err) { - dev_err(&pdev->dev, "Failed to add USB HCD\n"); - goto fail; - } - - return err; - -fail: -#ifdef CONFIG_USB_OTG_UTILS - if (tegra->transceiver) { - otg_set_host(tegra->transceiver, NULL); - otg_put_transceiver(tegra->transceiver); - } -#endif - tegra_usb_phy_close(tegra->phy); -fail_phy: - iounmap(hcd->regs); -fail_io: - clk_disable(tegra->emc_clk); - clk_put(tegra->emc_clk); -fail_emc_clk: - clk_disable(tegra->clk); -fail_clken: - clk_put(tegra->clk); -fail_clk: - usb_put_hcd(hcd); -fail_hcd: - kfree(tegra); - return err; -} - -#ifdef CONFIG_PM -static int tegra_ehci_resume(struct platform_device *pdev) -{ - struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - - if (tegra->bus_suspended) - return 0; - - return tegra_usb_resume(hcd); -} - -static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - - if (tegra->bus_suspended) - return 0; - - if (time_before(jiffies, tegra->ehci->next_statechange)) - msleep(10); - - return tegra_usb_suspend(hcd); -} -#endif - -static int tegra_ehci_remove(struct platform_device *pdev) -{ - struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - - if (tegra == NULL || hcd == NULL) - return -EINVAL; - -#ifdef CONFIG_USB_OTG_UTILS - if (tegra->transceiver) { - otg_set_host(tegra->transceiver, NULL); - otg_put_transceiver(tegra->transceiver); - } -#endif - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - tegra_usb_phy_close(tegra->phy); - iounmap(hcd->regs); - - clk_disable(tegra->clk); - clk_put(tegra->clk); - - clk_disable(tegra->emc_clk); - clk_put(tegra->emc_clk); - - kfree(tegra); - return 0; -} - -static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) -{ - struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - - if (hcd->driver->shutdown) - hcd->driver->shutdown(hcd); -} - -static struct platform_driver tegra_ehci_driver = { - .probe = tegra_ehci_probe, - .remove = tegra_ehci_remove, -#ifdef CONFIG_PM - .suspend = tegra_ehci_suspend, - .resume = tegra_ehci_resume, -#endif - .shutdown = tegra_ehci_hcd_shutdown, - .driver = { - .name = "tegra-ehci", - } -}; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6f62e68e0e6f..bde823f704e9 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -117,7 +117,6 @@ struct ehci_hcd { /* one per controller */ struct timer_list watchdog; unsigned long actions; unsigned stamp; - unsigned periodic_stamp; unsigned random_frame; unsigned long next_statechange; ktime_t last_periodic_enable; @@ -132,7 +131,6 @@ struct ehci_hcd { /* one per controller */ unsigned need_io_watchdog:1; unsigned broken_periodic:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ - unsigned port_reset_no_wait:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 931d588c3fb5..10e1872f3ab9 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -273,4 +273,4 @@ static struct platform_driver ohci_hcd_jz4740_driver = { }, }; -MODULE_ALIAS("platform:jz4740-ohci"); +MODULE_ALIAS("platfrom:jz4740-ohci"); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 25563e9a90bc..95d0f5adfdcf 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -227,7 +227,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, int odd = len & 0x0001; len = len / 2; - iowrite16_rep(fifoaddr, buf, len); + ioread16_rep(fifoaddr, buf, len); if (unlikely(odd)) { buf = &buf[len]; iowrite8((unsigned char)*buf, fifoaddr); diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 480936a870ce..a1a7a9795536 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -132,13 +132,6 @@ static u32 xhci_port_state_to_neutral(u32 state) 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 6627a956fa8e..4e51343ddffc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1043,7 +1043,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, if (udev->speed == USB_SPEED_SUPER) return ep->ss_ep_comp.wBytesPerInterval; - max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); + max_packet = ep->desc.wMaxPacketSize & 0x3ff; max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; /* A 0 in max burst means 1 transfer per ESIT */ return max_packet * (max_burst + 1); @@ -1133,7 +1133,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Fall through */ case USB_SPEED_FULL: case USB_SPEED_LOW: - max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); + max_packet = ep->desc.wMaxPacketSize & 0x3ff; ep_ctx->ep_info2 |= MAX_PACKET(max_packet); break; default: @@ -1441,13 +1441,6 @@ 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; } @@ -1631,166 +1624,6 @@ 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) { @@ -1971,8 +1804,6 @@ 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-ring.c b/drivers/usb/host/xhci-ring.c index e7547d8b3d67..48e60d166ff0 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2028,6 +2028,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) if (!(status & STS_EINT)) { spin_unlock(&xhci->lock); + xhci_warn(xhci, "Spurious interrupt.\n"); return IRQ_NONE; } xhci_dbg(xhci, "op reg status = %08x\n", status); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f3d5222cfc0b..d5c550ea3e68 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1284,15 +1284,6 @@ 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; @@ -2002,15 +1993,6 @@ int xhci_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 404ecbce5128..34a60d9f056a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -447,24 +447,6 @@ struct xhci_doorbell_array { #define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16) -/** - * 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. @@ -632,11 +614,6 @@ struct xhci_ep_ctx { #define MAX_PACKET_MASK (0xffff << 16) #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) -/* Get max packet size from ep desc. Bit 10..0 specify the max packet size. - * USB2.0 spec 9.6.6. - */ -#define GET_MAX_PACKET(p) ((p) & 0x7ff) - /* tx_info bitmasks */ #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) @@ -1222,15 +1199,6 @@ struct xhci_hcd { #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) #define XHCI_NEC_HOST (1 << 2) - - /* 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/Kconfig b/drivers/usb/misc/Kconfig index cfe991d5c40e..55660eaf947c 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -231,10 +231,3 @@ config USB_ISIGHTFW driver beforehand. Tools for doing so are available at http://bersace03.free.fr -config USB_OOBWAKE - boolean "USB Out-of-Band Wakeup" - depends on USB - help - This driver provides a simple mechanism to support USB wakeups - from gpios. This is needed in cases where the usb host or - device doesn't properly support remote wakeups. diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 2e9f7b6dde28..717703e81425 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -22,7 +22,6 @@ obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o obj-$(CONFIG_USB_USS720) += uss720.o obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o -obj-$(CONFIG_USB_OOBWAKE) += oob_wake.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 9251773ecef4..2f43c57743c9 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -196,9 +196,11 @@ static ssize_t get_port1_handler(struct device *dev, return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1); } -static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler); +static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO, + get_port0_handler, set_port0_handler); -static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler); +static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO, + get_port1_handler, set_port1_handler); static int cypress_probe(struct usb_interface *interface, diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 0db05b252e3b..bc88c79875a1 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -553,7 +553,6 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, /* needed for power consumption */ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc; - memset(&info, 0, sizeof(info)); /* directly from the descriptor */ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); info.product = dev->product_id; diff --git a/drivers/usb/misc/oob_wake.c b/drivers/usb/misc/oob_wake.c deleted file mode 100644 index 67cc96ff9a2a..000000000000 --- a/drivers/usb/misc/oob_wake.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2011 Motorola, 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif /* CONFIG_HAS_WAKELOCK */ - -#define GPIO_MAX_NAME 30 - -/* list of registered interfaces (intf_entry) */ -static LIST_HEAD(intf_list); -static DEFINE_MUTEX(intf_list_lock); - -struct intf_entry { - struct usb_interface *data; - struct list_head node; -}; - -struct oob_wake_info { - unsigned int gpio; - char name[GPIO_MAX_NAME]; - __le16 vendor; - __le16 product; -#ifdef CONFIG_HAS_WAKELOCK - struct wake_lock wake_lock; -#endif /* CONFIG_HAS_WAKELOCK */ -}; - -/* adds a single usb interface to the list to be woken up by the - * out of band interrupt. Only "unique wake events" are added. - * Meaning interfaces that coming from the same device and bus - * will be considered equivalent and only the first will be added. - */ -int oob_wake_register(struct usb_interface *intf) -{ - bool unique_wake_event = 1; - struct list_head *ptr; - struct usb_device *udev; - struct usb_device *new_udev; - struct intf_entry *entry; - struct intf_entry *new_entry = kzalloc(sizeof(struct intf_entry), - GFP_KERNEL); - - if (!new_entry) { - return -ENOMEM; - } - new_entry->data = intf; - new_udev = interface_to_usbdev(intf); - - mutex_lock(&intf_list_lock); - list_for_each(ptr, &intf_list) { - entry = list_entry(ptr, struct intf_entry, node); - udev = interface_to_usbdev(entry->data); - if ((udev->devnum == new_udev->devnum) && - (udev->bus->busnum == new_udev->bus->busnum)) { - unique_wake_event = 0; - break; - } - } - - if (unique_wake_event) - list_add(&new_entry->node, &intf_list); - mutex_unlock(&intf_list_lock); - - if (!unique_wake_event) - kfree(new_entry); - - return 0; -} -EXPORT_SYMBOL(oob_wake_register); - -/* removes the given interface from the list to be woken up by - the out of band interrupt */ -void oob_wake_unregister(struct usb_interface *intf) -{ - struct list_head *ptr; - struct list_head *next; - struct intf_entry *entry; - - mutex_lock(&intf_list_lock); - list_for_each_safe(ptr, next, &intf_list) { - entry = list_entry(ptr, struct intf_entry, node); - if (intf == entry->data) { - list_del(&entry->node); - kfree(entry); - break; - } - } - mutex_unlock(&intf_list_lock); -} -EXPORT_SYMBOL(oob_wake_unregister); - -/* wake up the usb bus if needed */ -static void wake_interface(struct usb_interface *intf) -{ - pr_debug("%s: called\n", __func__); - - device_lock(&intf->dev); - - if (intf->dev.power.status >= DPM_OFF || - intf->dev.power.status == DPM_RESUMING) { - device_unlock(&intf->dev); - return; - } - - if (usb_autopm_get_interface(intf) == 0) - usb_autopm_put_interface_async(intf); - - device_unlock(&intf->dev); -} - -/* Wake the interface for the associated device (vendor/product) */ -static irqreturn_t oob_wake_fn(int irq, void *data) -{ - struct list_head *ptr; - struct intf_entry *entry; - struct usb_device *udev; - struct oob_wake_info *info = (struct oob_wake_info *) data; - pr_debug("%s: irq (%d) fired\n", __func__, gpio_to_irq(info->gpio)); - - mutex_lock(&intf_list_lock); - list_for_each(ptr, &intf_list) { - entry = list_entry(ptr, struct intf_entry, node); - udev = interface_to_usbdev(entry->data); - pr_debug("%s: %04x:%04x\n", __func__, udev->descriptor.idVendor, - udev->descriptor.idProduct); - if ((udev->descriptor.idVendor == info->vendor) && - (udev->descriptor.idProduct == info->product)) - wake_interface(entry->data); - } - mutex_unlock(&intf_list_lock); - -#ifdef CONFIG_HAS_WAKELOCK - pr_debug("%s: release wakelock %s\n", __func__, info->wake_lock.name); - wake_unlock(&info->wake_lock); -#endif /* CONFIG_HAS_WAKELOCK */ - - return IRQ_HANDLED; -} - -static irqreturn_t oob_wake_isr(int irq, void *data) -{ - struct oob_wake_info *info = (struct oob_wake_info *) data; - -#ifdef CONFIG_HAS_WAKELOCK - pr_debug("%s: take wakelock %s\n", __func__, info->wake_lock.name); - wake_lock(&info->wake_lock); -#endif /* CONFIG_HAS_WAKELOCK */ - - return IRQ_WAKE_THREAD; -} - -static int __devinit oob_wake_probe(struct platform_device *pdev) -{ - struct oob_wake_platform_data *pdata = pdev->dev.platform_data; - struct oob_wake_info *info; - int irq; - int err = 0; - - pr_info("%s: %s\n", __func__, dev_name(&pdev->dev)); - info = kzalloc(sizeof(struct oob_wake_info), GFP_KERNEL); - if (!info) { - return -ENOMEM; - } - - info->gpio = pdata->gpio; - info->vendor = pdata->vendor; - info->product = pdata->product; - - platform_set_drvdata(pdev, info); - -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, - dev_name(&pdev->dev)); -#endif /* CONFIG_HAS_WAKELOCK */ - - snprintf(info->name, GPIO_MAX_NAME, "%s-%s", - dev_name(&pdev->dev), "host-wake"); - err = gpio_request(info->gpio, info->name); - if (err) { - pr_err("%s: error requesting host wake gpio\n", __func__); - return err; - } - gpio_direction_input(info->gpio); - - irq = gpio_to_irq(info->gpio); - err = request_threaded_irq(irq, oob_wake_isr, oob_wake_fn, - IRQ_TYPE_EDGE_FALLING, info->name, info); - if (err) { - pr_err("%s: error requesting host wake irq\n", __func__); - gpio_free(info->gpio); - return err; - } - - err = enable_irq_wake(irq); - if (err) { - pr_err("%s: request host_wake irq (%d) %s failed\n", - __func__, irq, info->name); - free_irq(irq, info); - gpio_free(info->gpio); - return err; - } - gpio_export(info->gpio, false); - - return 0; -} - -static void __devexit oob_wake_shutdown(struct platform_device *pdev) -{ - struct list_head *ptr; - struct list_head *next; - struct intf_entry *entry; - struct oob_wake_info *info = platform_get_drvdata(pdev); - - pr_info("%s: %s\n", __func__, dev_name(&pdev->dev)); - if (info) { - disable_irq_wake(gpio_to_irq(info->gpio)); - free_irq(gpio_to_irq(info->gpio), info); - gpio_free(info->gpio); -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_destroy(&info->wake_lock); -#endif /* CONFIG_HAS_WAKELOCK */ - - mutex_lock(&intf_list_lock); - list_for_each_safe(ptr, next, &intf_list) { - entry = list_entry(ptr, struct intf_entry, node); - list_del(&entry->node); - kfree(entry); - } - mutex_unlock(&intf_list_lock); - kfree(info); - - platform_set_drvdata(pdev, NULL); - } -} - -static struct platform_driver oob_wake_driver = { - .probe = oob_wake_probe, - .shutdown = __devexit_p(oob_wake_shutdown), - .driver = { - .name = "oob-wake", - .owner = THIS_MODULE, - }, -}; - -static int __init oob_wake_init(void) -{ - pr_info("%s: initializing %s\n", __func__, oob_wake_driver.driver.name); - - return platform_driver_register(&oob_wake_driver); -} - -static void __exit oob_wake_exit(void) -{ - pr_info("%s: exiting %s\n", __func__, oob_wake_driver.driver.name); - return platform_driver_unregister(&oob_wake_driver); -} - -module_init(oob_wake_init); -module_exit(oob_wake_exit); - -MODULE_AUTHOR("Jim Wylder "); -MODULE_DESCRIPTION("USB Out-of-Bounds Wake"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index dd573abd2d1e..70d00e99a4b4 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3008,7 +3008,6 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #else x.sisusb_conactive = 0; #endif - memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); if (copy_to_user((void __user *)arg, &x, sizeof(x))) retval = -EFAULT; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index f63776a48e2a..d77aba46ae85 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed); +static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed); static int tv_probe(struct usb_interface *interface, const struct usb_device_id *id) diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index c96f51de1696..63da2c3c838f 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c @@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co change_color(led); \ return count; \ } \ -static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value); +static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); show_set(blue); show_set(red); show_set(green); diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 417b8f207e8b..de8ef945b536 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev, \ \ return count; \ } \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name); +static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name); static ssize_t show_attr_text(struct device *dev, struct device_attribute *attr, char *buf) @@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev, return count; } -static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text); +static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text); static ssize_t show_attr_decimals(struct device *dev, struct device_attribute *attr, char *buf) @@ -272,7 +272,8 @@ static ssize_t set_attr_decimals(struct device *dev, return count; } -static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals); +static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO, + show_attr_decimals, set_attr_decimals); static ssize_t show_attr_textmode(struct device *dev, struct device_attribute *attr, char *buf) @@ -318,7 +319,8 @@ static ssize_t set_attr_textmode(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode); +static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO, + show_attr_textmode, set_attr_textmode); MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 4ff21587ab03..796e2f68f749 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, 2010 + * Copyright (C) 1999, 2005 * Thomas Sailer (t.sailer@alumni.ethz.ch) * * This program is free software; you can redistribute it and/or modify @@ -776,8 +776,6 @@ 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/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 611a9d274363..b611420a8050 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -342,10 +342,8 @@ int __init musb_platform_init(struct musb *musb, void *board_data) usb_nop_xceiv_register(); musb->xceiv = otg_get_transceiver(); - if (!musb->xceiv) { - gpio_free(musb->config->gpio_vrsel); + if (!musb->xceiv) return -ENODEV; - } if (ANOMALY_05000346) { bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); @@ -396,9 +394,8 @@ int __init musb_platform_init(struct musb *musb, void *board_data) int musb_platform_exit(struct musb *musb) { + gpio_free(musb->config->gpio_vrsel); - otg_put_transceiver(musb->xceiv); - usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 6e67629f50cc..57624361c1de 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -446,7 +446,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data) fail: clk_disable(musb->clock); - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); return -ENODEV; } @@ -497,7 +496,6 @@ int musb_platform_exit(struct musb *musb) clk_disable(musb->clock); - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0707b296cce4..540c766c4f86 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1921,6 +1921,10 @@ static void musb_free(struct musb *musb) dma_controller_destroy(c); } +#ifdef CONFIG_USB_MUSB_OTG + put_device(musb->xceiv->dev); +#endif + #ifdef CONFIG_USB_MUSB_HDRC_HCD usb_put_hcd(musb_to_hcd(musb)); #else @@ -2243,6 +2247,7 @@ static int __exit musb_remove(struct platform_device *pdev) #endif musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_platform_exit(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_free(musb); iounmap(ctrl_base); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index ed618bde1eec..2111a241dd03 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -320,6 +320,5 @@ int musb_platform_exit(struct musb *musb) musb_platform_suspend(musb); - otg_put_transceiver(musb->xceiv); return 0; } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index bde40efc7046..3c48e77a0aa2 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1152,8 +1152,6 @@ done: if (ret < 0) { if (sync) iounmap(sync); - - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); } return ret; @@ -1168,8 +1166,6 @@ int musb_platform_exit(struct musb *musb) musb->board_set_power(0); iounmap(musb->sync_va); - - otg_put_transceiver(musb->xceiv); usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index f05e1469ca61..3b1289572d72 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -49,13 +49,6 @@ config USB_ULPI Enable this to support ULPI connected USB OTG transceivers which are likely found on embedded boards. -config USB_ULPI_VIEWPORT - bool - depends on USB_ULPI - help - Provides read/write operations to the ULPI phy register set for - controllers with a viewport register (e.g. Chipidea/ARC controllers). - config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 @@ -74,23 +67,4 @@ config NOP_USB_XCEIV built-in with usb ip or which are autonomous and doesn't require any phy programming such as ISP1x04 etc. - -config USB_TEGRA_OTG - boolean "Tegra OTG Driver" - depends on USB && ARCH_TEGRA - select USB_OTG_UTILS - help - Enable this driver on boards which use the internal VBUS and ID - sensing of the Tegra USB PHY. - -config USB_CPCAP_OTG - boolean "Motorola CPCAP OTG Driver" - depends on USB && ARCH_TEGRA && MFD_CPCAP - select USB_OTG_UTILS - help - Enable this driver on boards that use the CPCAP sensors for - ID and VBUS sensing. The driver receives notifications from - cpcap-whisper and emulates the same behavior as when the VBUS - and ID pins are connected to the app processor. - endif # USB || OTG diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index cfaed1b9e08e..aeb49a8ec412 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -6,14 +6,11 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o # transceiver drivers -obj-$(CONFIG_USB_CPCAP_OTG) += cpcap-otg.o obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o -obj-$(CONFIG_USB_TEGRA_OTG) += tegra-otg.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o -obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG diff --git a/drivers/usb/otg/cpcap-otg.c b/drivers/usb/otg/cpcap-otg.c deleted file mode 100644 index e1f8b196f360..000000000000 --- a/drivers/usb/otg/cpcap-otg.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEGRA_USB_PHY_WAKEUP_REG_OFFSET 0x408 -#define TEGRA_VBUS_WAKEUP_SW_VALUE (1 << 12) -#define TEGRA_VBUS_WAKEUP_SW_ENABLE (1 << 11) -#define TEGRA_ID_SW_VALUE (1 << 4) -#define TEGRA_ID_SW_ENABLE (1 << 3) - -struct cpcap_otg_data { - struct otg_transceiver otg; - struct notifier_block nb; - void __iomem *regs; - struct clk *clk; - struct platform_device *host; - struct platform_device *pdev; - struct wake_lock wake_lock; -}; - -static const char *cpcap_state_name(enum usb_otg_state state) -{ - if (state == OTG_STATE_A_HOST) - return "HOST"; - if (state == OTG_STATE_B_PERIPHERAL) - return "PERIPHERAL"; - if (state == OTG_STATE_A_SUSPEND) - return "SUSPEND"; - return "INVALID"; -} - -void cpcap_start_host(struct cpcap_otg_data *cpcap) -{ - int retval; - struct platform_device *pdev; - struct platform_device *host = cpcap->host; - void *platform_data; - - pdev = platform_device_alloc(host->name, host->id); - if (!pdev) - return; - - if (host->resource) { - retval = platform_device_add_resources(pdev, host->resource, - host->num_resources); - if (retval) - goto error; - } - - pdev->dev.dma_mask = host->dev.dma_mask; - pdev->dev.coherent_dma_mask = host->dev.coherent_dma_mask; - - platform_data = kmalloc(sizeof(struct tegra_ehci_platform_data), GFP_KERNEL); - if (!platform_data) - goto error; - - memcpy(platform_data, host->dev.platform_data, - sizeof(struct tegra_ehci_platform_data)); - pdev->dev.platform_data = platform_data; - - retval = platform_device_add(pdev); - if (retval) - goto error_add; - - cpcap->pdev = pdev; - return; - -error_add: - kfree(platform_data); -error: - pr_err("%s: failed to add the host contoller device\n", __func__); - platform_device_put(pdev); -} - -void cpcap_stop_host(struct cpcap_otg_data *cpcap) -{ - if (cpcap->pdev) { - platform_device_unregister(cpcap->pdev); - cpcap->pdev = NULL; - } -} - -static int cpcap_otg_notify(struct notifier_block *nb, unsigned long event, - void *ignore) -{ - struct cpcap_otg_data *cpcap; - struct otg_transceiver *otg; - enum usb_otg_state from; - enum usb_otg_state to; - unsigned long val; - struct usb_hcd *hcd; - - cpcap = container_of(nb, struct cpcap_otg_data, nb); - otg = &cpcap->otg; - - from = otg->state; - if (event == USB_EVENT_VBUS) - to = OTG_STATE_B_PERIPHERAL; - else if (event == USB_EVENT_ID) - to = OTG_STATE_A_HOST; - else - to = OTG_STATE_A_SUSPEND; - - if (from == to) - return 0; - otg->state = to; - - if (to == OTG_STATE_B_PERIPHERAL) - wake_lock(&cpcap->wake_lock); - - dev_info(cpcap->otg.dev, "%s --> %s", cpcap_state_name(from), - cpcap_state_name(to)); - - clk_enable(cpcap->clk); - - if ((to == OTG_STATE_A_HOST) && (from == OTG_STATE_A_SUSPEND) - && cpcap->host) { - hcd = (struct usb_hcd *)otg->host; - - val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - val &= ~TEGRA_ID_SW_VALUE; - writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - - cpcap_start_host(cpcap); - - } else if ((to == OTG_STATE_A_SUSPEND) && (from == OTG_STATE_A_HOST) - && cpcap->host) { - val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - val |= TEGRA_ID_SW_VALUE; - writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - - cpcap_stop_host(cpcap); - - } else if ((to == OTG_STATE_B_PERIPHERAL) - && (from == OTG_STATE_A_SUSPEND) - && otg->gadget) { - val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - val |= TEGRA_VBUS_WAKEUP_SW_VALUE; - writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - - usb_gadget_vbus_connect(otg->gadget); - - } else if ((to == OTG_STATE_A_SUSPEND) - && (from == OTG_STATE_B_PERIPHERAL) - && otg->gadget) { - val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - val &= ~TEGRA_VBUS_WAKEUP_SW_VALUE; - writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - - usb_gadget_vbus_disconnect(otg->gadget); - } - - clk_disable(cpcap->clk); - - if (to == OTG_STATE_A_SUSPEND) - wake_unlock(&cpcap->wake_lock); - - return 0; -} - -static int cpcap_otg_set_peripheral(struct otg_transceiver *otg, - struct usb_gadget *gadget) -{ - otg->gadget = gadget; - return 0; -} - -static int cpcap_otg_set_host(struct otg_transceiver *otg, - struct usb_bus *host) -{ - otg->host = host; - return 0; -} - -static int cpcap_otg_set_power(struct otg_transceiver *otg, unsigned mA) -{ - return 0; -} - -static int cpcap_otg_set_suspend(struct otg_transceiver *otg, int suspend) -{ - return 0; -} - -static int cpcap_otg_probe(struct platform_device *pdev) -{ - struct cpcap_otg_data *cpcap; - struct resource *res; - unsigned long val; - int err; - - cpcap = kzalloc(sizeof(struct cpcap_otg_data), GFP_KERNEL); - if (!cpcap) - return -ENOMEM; - - cpcap->otg.dev = &pdev->dev; - cpcap->otg.label = "cpcap-otg"; - cpcap->otg.state = OTG_STATE_UNDEFINED; - cpcap->otg.set_host = cpcap_otg_set_host; - cpcap->otg.set_peripheral = cpcap_otg_set_peripheral; - cpcap->otg.set_suspend = cpcap_otg_set_suspend; - cpcap->otg.set_power = cpcap_otg_set_power; - cpcap->host = pdev->dev.platform_data; - wake_lock_init(&cpcap->wake_lock, WAKE_LOCK_SUSPEND, "cpcap_otg"); - - platform_set_drvdata(pdev, cpcap); - - cpcap->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(cpcap->clk)) { - dev_err(&pdev->dev, "Can't get otg clock\n"); - err = PTR_ERR(cpcap->clk); - goto err_clk; - } - - err = clk_enable(cpcap->clk); - if (err) - goto err_clken; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto err_io; - } - cpcap->regs = ioremap(res->start, resource_size(res)); - if (!cpcap->regs) { - err = -ENOMEM; - goto err_io; - } - - val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - val |= TEGRA_VBUS_WAKEUP_SW_ENABLE | TEGRA_ID_SW_ENABLE; - val |= TEGRA_ID_SW_VALUE; - val &= ~(TEGRA_VBUS_WAKEUP_SW_VALUE); - writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); - - clk_disable(cpcap->clk); - cpcap->otg.state = OTG_STATE_A_SUSPEND; - - BLOCKING_INIT_NOTIFIER_HEAD(&cpcap->otg.notifier); - cpcap->nb.notifier_call = cpcap_otg_notify; - otg_register_notifier(&cpcap->otg, &cpcap->nb); - - err = otg_set_transceiver(&cpcap->otg); - if (err) { - dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); - goto err_otg; - } - - return 0; - -err_otg: - iounmap(cpcap->regs); -err_io: - clk_disable(cpcap->clk); -err_clken: - clk_put(cpcap->clk); -err_clk: - wake_lock_destroy(&cpcap->wake_lock); - platform_set_drvdata(pdev, NULL); - kfree(cpcap); - return err; -} - -static int __exit cpcap_otg_remove(struct platform_device *pdev) -{ - struct cpcap_otg_data *cpcap = platform_get_drvdata(pdev); - - otg_set_transceiver(NULL); - iounmap(cpcap->regs); - clk_disable(cpcap->clk); - clk_put(cpcap->clk); - wake_lock_destroy(&cpcap->wake_lock); - platform_set_drvdata(pdev, NULL); - kfree(cpcap); - - return 0; -} - -static struct platform_driver cpcap_otg_driver = { - .driver = { - .name = "cpcap-otg", - }, - .remove = __exit_p(cpcap_otg_remove), - .probe = cpcap_otg_probe, -}; - -static int __init cpcap_otg_init(void) -{ - return platform_driver_register(&cpcap_otg_driver); -} -module_init(cpcap_otg_init); - -static void __exit cpcap_otg_exit(void) -{ - platform_driver_unregister(&cpcap_otg_driver); -} -module_exit(cpcap_otg_exit); diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c deleted file mode 100644 index 83d3369f1b27..000000000000 --- a/drivers/usb/otg/tegra-otg.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * drivers/usb/otg/tegra-otg.c - * - * OTG transceiver driver for Tegra UTMI phy - * - * Copyright (C) 2010 NVIDIA Corp. - * Copyright (C) 2010 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USB_PHY_WAKEUP 0x408 -#define USB_ID_INT_EN (1 << 0) -#define USB_ID_INT_STATUS (1 << 1) -#define USB_ID_STATUS (1 << 2) -#define USB_ID_PIN_WAKEUP_EN (1 << 6) -#define USB_VBUS_WAKEUP_EN (1 << 30) -#define USB_VBUS_INT_EN (1 << 8) -#define USB_VBUS_INT_STATUS (1 << 9) -#define USB_VBUS_STATUS (1 << 10) -#define USB_INTS (USB_VBUS_INT_STATUS | USB_ID_INT_STATUS) - -struct tegra_otg_data { - struct otg_transceiver otg; - unsigned long int_status; - spinlock_t lock; - void __iomem *regs; - struct clk *clk; - int irq; - struct platform_device *host; - struct platform_device *pdev; -}; - -static inline unsigned long otg_readl(struct tegra_otg_data *tegra, - unsigned int offset) -{ - return readl(tegra->regs + offset); -} - -static inline void otg_writel(struct tegra_otg_data *tegra, unsigned long val, - unsigned int offset) -{ - writel(val, tegra->regs + offset); -} - -static const char *tegra_state_name(enum usb_otg_state state) -{ - if (state == OTG_STATE_A_HOST) - return "HOST"; - if (state == OTG_STATE_B_PERIPHERAL) - return "PERIPHERAL"; - if (state == OTG_STATE_A_SUSPEND) - return "SUSPEND"; - return "INVALID"; -} - -void tegra_start_host(struct tegra_otg_data *tegra) -{ - int retval; - struct platform_device *pdev; - struct platform_device *host = tegra->host; - void *platform_data; - - pdev = platform_device_alloc(host->name, host->id); - if (!pdev) - return; - - if (host->resource) { - retval = platform_device_add_resources(pdev, host->resource, - host->num_resources); - if (retval) - goto error; - } - - pdev->dev.dma_mask = host->dev.dma_mask; - pdev->dev.coherent_dma_mask = host->dev.coherent_dma_mask; - - platform_data = kmalloc(sizeof(struct tegra_ehci_platform_data), GFP_KERNEL); - if (!platform_data) - goto error; - - memcpy(platform_data, host->dev.platform_data, - sizeof(struct tegra_ehci_platform_data)); - pdev->dev.platform_data = platform_data; - - retval = platform_device_add(pdev); - if (retval) - goto error_add; - - tegra->pdev = pdev; - return; - -error_add: - kfree(platform_data); -error: - pr_err("%s: failed to add the host contoller device\n", __func__); - platform_device_put(pdev); -} - -void tegra_stop_host(struct tegra_otg_data *tegra) -{ - if (tegra->pdev) { - platform_device_unregister(tegra->pdev); - tegra->pdev = NULL; - } -} - -static irqreturn_t tegra_otg_irq_thread(int irq, void *data) -{ - struct tegra_otg_data *tegra = data; - struct otg_transceiver *otg = &tegra->otg; - enum usb_otg_state from = otg->state; - enum usb_otg_state to = OTG_STATE_UNDEFINED; - unsigned long flags; - unsigned long status; - - clk_enable(tegra->clk); - - status = otg_readl(tegra, USB_PHY_WAKEUP); - - spin_lock_irqsave(&tegra->lock, flags); - - if (tegra->int_status & USB_ID_INT_STATUS) { - if (status & USB_ID_STATUS) - to = OTG_STATE_A_SUSPEND; - else - to = OTG_STATE_A_HOST; - } else if (tegra->int_status & USB_VBUS_INT_STATUS) { - if (status & USB_VBUS_STATUS) - to = OTG_STATE_B_PERIPHERAL; - else - to = OTG_STATE_A_SUSPEND; - } - - tegra->int_status = 0; - - spin_unlock_irqrestore(&tegra->lock, flags); - - otg->state = to; - - dev_info(tegra->otg.dev, "%s --> %s", tegra_state_name(from), - tegra_state_name(to)); - - if (to == OTG_STATE_A_SUSPEND) { - if (from == OTG_STATE_A_HOST && tegra->host) - tegra_stop_host(tegra); - else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) - usb_gadget_vbus_disconnect(otg->gadget); - } else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) { - if (from == OTG_STATE_A_SUSPEND) - usb_gadget_vbus_connect(otg->gadget); - } else if (to == OTG_STATE_A_HOST && tegra->host) { - if (from == OTG_STATE_A_SUSPEND) - tegra_start_host(tegra); - } - - clk_disable(tegra->clk); - - return IRQ_HANDLED; - -} - -static irqreturn_t tegra_otg_irq(int irq, void *data) -{ - struct tegra_otg_data *tegra = data; - unsigned long val; - - clk_enable(tegra->clk); - - spin_lock(&tegra->lock); - val = otg_readl(tegra, USB_PHY_WAKEUP); - otg_writel(tegra, val, USB_PHY_WAKEUP); - - /* and the interrupt enables into the interrupt status bits */ - val = (val & (val << 1)) & USB_INTS; - - tegra->int_status |= val; - - spin_unlock(&tegra->lock); - - clk_disable(tegra->clk); - - return (val) ? IRQ_WAKE_THREAD : IRQ_NONE; -} - -static int tegra_otg_set_peripheral(struct otg_transceiver *otg, - struct usb_gadget *gadget) -{ - struct tegra_otg_data *tegra; - unsigned long val; - - tegra = container_of(otg, struct tegra_otg_data, otg); - otg->gadget = gadget; - - clk_enable(tegra->clk); - val = otg_readl(tegra, USB_PHY_WAKEUP); - val &= ~(USB_VBUS_INT_STATUS | USB_ID_INT_STATUS); - - if (gadget) - val |= (USB_VBUS_INT_EN | USB_VBUS_WAKEUP_EN); - else - val &= ~(USB_VBUS_INT_EN | USB_VBUS_WAKEUP_EN); - - otg_writel(tegra, val, USB_PHY_WAKEUP); - clk_disable(tegra->clk); - - return 0; -} - -static int tegra_otg_set_host(struct otg_transceiver *otg, - struct usb_bus *host) -{ - struct tegra_otg_data *tegra; - unsigned long val; - - tegra = container_of(otg, struct tegra_otg_data, otg); - otg->host = host; - - clk_enable(tegra->clk); - val = otg_readl(tegra, USB_PHY_WAKEUP); - val &= ~(USB_VBUS_INT_STATUS | USB_ID_INT_STATUS); - - if (host) - val |= USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN; - else - val &= ~(USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN); - otg_writel(tegra, val, USB_PHY_WAKEUP); - clk_disable(tegra->clk); - - return 0; -} - -static int tegra_otg_set_power(struct otg_transceiver *otg, unsigned mA) -{ - return 0; -} - -static int tegra_otg_set_suspend(struct otg_transceiver *otg, int suspend) -{ - return 0; -} - -static int tegra_otg_probe(struct platform_device *pdev) -{ - struct tegra_otg_data *tegra; - struct resource *res; - unsigned long val; - int err; - - tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL); - if (!tegra) - return -ENOMEM; - - tegra->otg.dev = &pdev->dev; - tegra->otg.label = "tegra-otg"; - tegra->otg.state = OTG_STATE_UNDEFINED; - tegra->otg.set_host = tegra_otg_set_host; - tegra->otg.set_peripheral = tegra_otg_set_peripheral; - tegra->otg.set_suspend = tegra_otg_set_suspend; - tegra->otg.set_power = tegra_otg_set_power; - tegra->host = pdev->dev.platform_data; - spin_lock_init(&tegra->lock); - - platform_set_drvdata(pdev, tegra); - - tegra->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(tegra->clk)) { - dev_err(&pdev->dev, "Can't get otg clock\n"); - err = PTR_ERR(tegra->clk); - goto err_clk; - } - - err = clk_enable(tegra->clk); - if (err) - goto err_clken; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto err_io; - } - tegra->regs = ioremap(res->start, resource_size(res)); - if (!tegra->regs) { - err = -ENOMEM; - goto err_io; - } - - val = otg_readl(tegra, USB_PHY_WAKEUP); - - val &= ~(USB_VBUS_INT_STATUS | USB_VBUS_INT_EN | - USB_ID_INT_STATUS | USB_ID_INT_EN | - USB_VBUS_WAKEUP_EN | USB_ID_PIN_WAKEUP_EN); - - otg_writel(tegra, val, USB_PHY_WAKEUP); - - tegra->otg.state = OTG_STATE_A_SUSPEND; - - err = otg_set_transceiver(&tegra->otg); - if (err) { - dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); - goto err_otg; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get IRQ\n"); - err = -ENXIO; - goto err_irq; - } - tegra->irq = res->start; - err = request_threaded_irq(tegra->irq, tegra_otg_irq, - tegra_otg_irq_thread, - IRQF_SHARED, "tegra-otg", tegra); - if (err) { - dev_err(&pdev->dev, "Failed to register IRQ\n"); - goto err_irq; - } - - dev_info(&pdev->dev, "otg transceiver registered\n"); - return 0; - -err_irq: - otg_set_transceiver(NULL); -err_otg: - iounmap(tegra->regs); -err_io: - clk_disable(tegra->clk); -err_clken: - clk_put(tegra->clk); -err_clk: - platform_set_drvdata(pdev, NULL); - kfree(tegra); - return err; -} - -static int __exit tegra_otg_remove(struct platform_device *pdev) -{ - struct tegra_otg_data *tegra = platform_get_drvdata(pdev); - - free_irq(tegra->irq, tegra); - otg_set_transceiver(NULL); - iounmap(tegra->regs); - clk_disable(tegra->clk); - clk_put(tegra->clk); - platform_set_drvdata(pdev, NULL); - kfree(tegra); - - return 0; -} - -static struct platform_driver tegra_otg_driver = { - .driver = { - .name = "tegra-otg", - }, - .remove = __exit_p(tegra_otg_remove), - .probe = tegra_otg_probe, -}; - -static int __init tegra_otg_init(void) -{ - return platform_driver_register(&tegra_otg_driver); -} -subsys_initcall(tegra_otg_init); - -static void __exit tegra_otg_exit(void) -{ - platform_driver_unregister(&tegra_otg_driver); -} -module_exit(tegra_otg_exit); diff --git a/drivers/usb/otg/ulpi_viewport.c b/drivers/usb/otg/ulpi_viewport.c deleted file mode 100644 index e9a37f90994f..000000000000 --- a/drivers/usb/otg/ulpi_viewport.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011 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 -#include -#include -#include -#include - -#define ULPI_VIEW_WAKEUP (1 << 31) -#define ULPI_VIEW_RUN (1 << 30) -#define ULPI_VIEW_WRITE (1 << 29) -#define ULPI_VIEW_READ (0 << 29) -#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) -#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) -#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) - -static int ulpi_viewport_wait(void __iomem *view, u32 mask) -{ - unsigned long usec = 2000; - - while (usec--) { - if (!(readl(view) & mask)) - return 0; - - udelay(1); - }; - - return -ETIMEDOUT; -} - -static int ulpi_viewport_read(struct otg_transceiver *otg, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); - if (ret) - return ret; - - return ULPI_VIEW_DATA_READ(readl(view)); -} - -static int ulpi_viewport_write(struct otg_transceiver *otg, u32 val, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | - ULPI_VIEW_ADDR(reg), view); - - return ulpi_viewport_wait(view, ULPI_VIEW_RUN); -} - -struct otg_io_access_ops ulpi_viewport_access_ops = { - .read = ulpi_viewport_read, - .write = ulpi_viewport_write, -}; diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 1bdab84a7ea1..916b2b6d765f 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -458,20 +458,6 @@ config USB_SERIAL_MOTOROLA To compile this driver as a module, choose M here: the module will be called moto_modem. If unsure, choose N. -config USB_SERIAL_MDM6600 - tristate "USB MDM6600 modem" - help - Say Y here if you want to use a Qualcomm MDM6600 modem over USB. - -config USB_SERIAL_MOTO_FLASH_MODEM - tristate "USB Motorola modem flash driver" - ---help--- - Say Y here if you want to enable the AP/BP USB IPC link - driver for MDM6600 modem. - - To compile this driver as a module, choose M here: the - module will be called moto_flashmdm. If unsure, choose N. - config USB_SERIAL_NAVMAN tristate "USB Navman GPS device" help diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 3da56db47c76..40ebe17b6ea8 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -39,8 +39,6 @@ obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o -obj-$(CONFIG_USB_SERIAL_MDM6600) += mdm6600.o -obj-$(CONFIG_USB_SERIAL_MOTO_FLASH_MODEM) += moto_flashmdm.o obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 8d7731dbf478..4f1744c5871f 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -54,7 +54,6 @@ static int cp210x_carrier_raised(struct usb_serial_port *p); static int debug; static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ @@ -133,7 +132,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ - { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 62ff90097830..97cc87d654ce 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -177,7 +177,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, @@ -201,7 +200,6 @@ 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) }, @@ -676,6 +674,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, @@ -697,7 +696,6 @@ 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) }, @@ -717,37 +715,8 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, - - /* Papouch devices based on FTDI chip */ - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_2_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_2_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_2_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485S_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485C_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_LEC_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB232_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_IRAMP_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK5_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO8x8_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x2_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO10x1_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO30x3_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO60x3_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x16_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO3x32_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK6_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_UPSUSB_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_MU_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SIMUKEY_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMUX_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMSR_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, @@ -782,7 +751,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, - { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) }, { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, @@ -793,12 +761,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) }, - { 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 */ { } /* Terminating entry */ }; @@ -2066,6 +2028,8 @@ static void ftdi_set_termios(struct tty_struct *tty, "urb failed to set to rts/cts flow control\n"); } + /* raise DTR/RTS */ + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* * Xon/Xoff code @@ -2113,6 +2077,8 @@ static void ftdi_set_termios(struct tty_struct *tty, } } + /* lower DTR/RTS */ + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } return; } diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 77ace17fd143..15a4583775ad 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -61,7 +61,6 @@ #define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB -#define FTDI_OPENDCC_GBM_PID 0xBFDC /* * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) @@ -114,9 +113,6 @@ /* 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). */ @@ -724,7 +720,6 @@ */ #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. @@ -1027,34 +1022,9 @@ */ #define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_SB485_PID 0x0100 /* Papouch SB485 USB-485/422 Converter */ -#define PAPOUCH_AP485_PID 0x0101 /* AP485 USB-RS485 Converter */ -#define PAPOUCH_SB422_PID 0x0102 /* Papouch SB422 USB-RS422 Converter */ -#define PAPOUCH_SB485_2_PID 0x0103 /* Papouch SB485 USB-485/422 Converter */ -#define PAPOUCH_AP485_2_PID 0x0104 /* AP485 USB-RS485 Converter */ -#define PAPOUCH_SB422_2_PID 0x0105 /* Papouch SB422 USB-RS422 Converter */ -#define PAPOUCH_SB485S_PID 0x0106 /* Papouch SB485S USB-485/422 Converter */ -#define PAPOUCH_SB485C_PID 0x0107 /* Papouch SB485C USB-485/422 Converter */ -#define PAPOUCH_LEC_PID 0x0300 /* LEC USB Converter */ -#define PAPOUCH_SB232_PID 0x0301 /* Papouch SB232 USB-RS232 Converter */ #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -#define PAPOUCH_IRAMP_PID 0x0500 /* Papouch IRAmp Duplex */ -#define PAPOUCH_DRAK5_PID 0x0700 /* Papouch DRAK5 */ -#define PAPOUCH_QUIDO8x8_PID 0x0800 /* Papouch Quido 8/8 Module */ -#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Papouch Quido 4/4 Module */ -#define PAPOUCH_QUIDO2x2_PID 0x0a00 /* Papouch Quido 2/2 Module */ -#define PAPOUCH_QUIDO10x1_PID 0x0b00 /* Papouch Quido 10/1 Module */ -#define PAPOUCH_QUIDO30x3_PID 0x0c00 /* Papouch Quido 30/3 Module */ -#define PAPOUCH_QUIDO60x3_PID 0x0d00 /* Papouch Quido 60(100)/3 Module */ -#define PAPOUCH_QUIDO2x16_PID 0x0e00 /* Papouch Quido 2/16 Module */ -#define PAPOUCH_QUIDO3x32_PID 0x0f00 /* Papouch Quido 3/32 Module */ -#define PAPOUCH_DRAK6_PID 0x1000 /* Papouch DRAK6 */ -#define PAPOUCH_UPSUSB_PID 0x8000 /* Papouch UPS-USB adapter */ -#define PAPOUCH_MU_PID 0x8001 /* MU controller */ -#define PAPOUCH_SIMUKEY_PID 0x8002 /* Papouch SimuKey */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ #define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */ -#define PAPOUCH_GMUX_PID 0x8004 /* Papouch GOLIATH MUX */ -#define PAPOUCH_GMSR_PID 0x8005 /* Papouch GOLIATH MSR */ /* * Marvell SheevaPlug @@ -1080,11 +1050,6 @@ #define MJSG_XM_RADIO_PID 0x937A #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/) */ @@ -1098,21 +1063,3 @@ * Submitted by John G. Rogers */ #define SEGWAY_RMP200_PID 0xe729 - - -/* - * Accesio USB Data Acquisition products (http://www.accesio.com/) - */ -#define ACCESIO_COM4SM_PID 0xD578 - -/* www.sciencescope.co.uk educational dataloggers */ -#define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18 -#define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C -#define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D - -/* - * Milkymist One JTAG/Serial - */ -#define QIHARDWARE_VID 0x20B7 -#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 - diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2849f8c32015..7aa01b95b1d4 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -549,12 +549,9 @@ static void mct_u232_close(struct usb_serial_port *port) { dbg("%s port %d", __func__, port->number); - if (port->serial->dev) { - /* shutdown our urbs */ - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); + usb_serial_generic_close(port); + if (port->serial->dev) usb_kill_urb(port->interrupt_in_urb); - } } /* mct_u232_close */ diff --git a/drivers/usb/serial/mdm6600.c b/drivers/usb/serial/mdm6600.c deleted file mode 100644 index e4f9c6e48cbb..000000000000 --- a/drivers/usb/serial/mdm6600.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * Author: Nick Pelly - * Based on Motorola's mdm6600_modem driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - -/* - * TODO check if we need to implement throttling - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static bool debug = false; -static bool debug_data = false; - -#define BP_MODEM_STATUS 0x20a1 -#define BP_RSP_AVAIL 0x01a1 -#define BP_SPEED_CHANGE 0x2aa1 - -#define BP_STATUS_CAR 0x01 -#define BP_STATUS_DSR 0x02 -#define BP_STATUS_BREAK 0x04 -#define BP_STATUS_RNG 0x08 - -#define READ_POOL_SZ 8 -#define WRITE_POOL_SZ 32 - -#define MODEM_INTERFACE_NUM 4 - -#define MODEM_WAKELOCK_TIME msecs_to_jiffies(2000) -#define MODEM_AUTOSUSPEND_DELAY msecs_to_jiffies(1000) - -static const struct usb_device_id mdm6600_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2a70, 0xff, 0xff, 0xff) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, mdm6600_id_table); - -struct mdm6600_urb_write_pool { - struct usb_anchor free_list; - struct usb_anchor in_flight; - struct usb_anchor delayed; - int buffer_sz; /* allocated urb buffer size */ - int pending; /* number of in flight or delayed writes */ - spinlock_t pending_lock; -}; - -struct mdm6600_urb_read_pool { - struct usb_anchor free_list; - struct usb_anchor in_flight; /* urb's owned by USB core */ - struct usb_anchor pending; /* urb's waiting for driver bottom half */ - struct work_struct work; /* bottom half */ - int buffer_sz; /* allocated urb buffer size */ -}; - -struct mdm6600_port { - struct usb_serial *serial; - struct usb_serial_port *port; - - struct mdm6600_urb_write_pool write; - struct mdm6600_urb_read_pool read; - - struct wake_lock readlock; - char readlock_name[16]; - struct wake_lock writelock; - char writelock_name[16]; - - spinlock_t susp_lock; - int susp_count; - int opened; - int number; - u16 tiocm_status; - struct work_struct wake_work; -}; - -static int mdm6600_wake_irq; -static bool mdm6600_wake_irq_enabled; -static DEFINE_SPINLOCK(mdm6600_wake_irq_lock); - -/* - * Count the number of attached ports. Don't use port->number as it may - * changed if other ttyUSB have been registered before. - */ -static int mdm6600_attached_ports; - -static void mdm6600_read_bulk_work(struct work_struct *work); -static void mdm6600_read_bulk_cb(struct urb *urb); -static void mdm6600_write_bulk_cb(struct urb *urb); -static void mdm6600_release(struct usb_serial *serial); - -static void mdm6600_wake_work(struct work_struct *work) -{ - struct mdm6600_port *modem = container_of(work, struct mdm6600_port, - wake_work); - struct usb_interface *intf = modem->serial->interface; - - dbg("%s: port %d", __func__, modem->number); - - device_lock(&intf->dev); - - if (intf->dev.power.status >= DPM_OFF || - intf->dev.power.status == DPM_RESUMING) { - device_unlock(&intf->dev); - return; - } - - /* let usbcore auto-resume the modem */ - if (usb_autopm_get_interface(intf) == 0) - /* set usage count back to 0 */ - usb_autopm_put_interface_async(intf); - - device_unlock(&intf->dev); -} - -static irqreturn_t mdm6600_irq_handler(int irq, void *ptr) -{ - struct mdm6600_port *modem = ptr; - - spin_lock(&mdm6600_wake_irq_lock); - if (mdm6600_wake_irq_enabled) { - disable_irq_nosync(irq); - mdm6600_wake_irq_enabled = false; - } - spin_unlock(&mdm6600_wake_irq_lock); - - wake_lock_timeout(&modem->readlock, MODEM_WAKELOCK_TIME); - queue_work(system_nrt_wq, &modem->wake_work); - - return IRQ_HANDLED; -} - -/* called after probe for each of 5 usb_serial interfaces */ -static int mdm6600_attach(struct usb_serial *serial) -{ - int i; - int status; - struct mdm6600_port *modem; - struct usb_host_interface *host_iface = - serial->interface->cur_altsetting; - struct usb_endpoint_descriptor *epwrite = NULL; - struct usb_endpoint_descriptor *epread = NULL; - - modem = kzalloc(sizeof(*modem), GFP_KERNEL); - if (!modem) - return -ENOMEM; - usb_set_serial_data(serial, modem); - - modem->serial = serial; - modem->port = modem->serial->port[0]; /* always 1 port per usb_serial */ - modem->tiocm_status = 0; - modem->number = mdm6600_attached_ports++; - - /* find endpoints */ - for (i = 0; i < host_iface->desc.bNumEndpoints; i++) { - struct usb_endpoint_descriptor *ep = - &host_iface->endpoint[i].desc; - if (usb_endpoint_is_bulk_out(ep)) - epwrite = ep; - if (usb_endpoint_is_bulk_in(ep)) - epread = ep; - } - if (!epwrite) { - pr_err("%s No bulk out endpoint\n", __func__); - status = -EIO; - goto err_out; - } - if (!epread) { - pr_err("%s No bulk in endpoint\n", __func__); - status = -EIO; - goto err_out; - } - - /* setup write pool */ - init_usb_anchor(&modem->write.free_list); - init_usb_anchor(&modem->write.in_flight); - init_usb_anchor(&modem->write.delayed); - modem->write.buffer_sz = le16_to_cpu(epwrite->wMaxPacketSize) * 4; - for (i = 0; i < WRITE_POOL_SZ; i++) { - struct urb *u = usb_alloc_urb(0, GFP_KERNEL); - if (!u) { - status = -ENOMEM; - goto err_out; - } - - u->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - u->transfer_buffer = usb_alloc_coherent(serial->dev, - modem->write.buffer_sz, GFP_KERNEL, &u->transfer_dma); - if (!u->transfer_buffer) { - status = -ENOMEM; - usb_free_urb(u); - goto err_out; - } - usb_fill_bulk_urb(u, serial->dev, - usb_sndbulkpipe(serial->dev, epwrite->bEndpointAddress), - u->transfer_buffer, modem->write.buffer_sz, - mdm6600_write_bulk_cb, modem); - usb_anchor_urb(u, &modem->write.free_list); - } - - /* read pool */ - INIT_WORK(&modem->read.work, mdm6600_read_bulk_work); - init_usb_anchor(&modem->read.free_list); - init_usb_anchor(&modem->read.in_flight); - init_usb_anchor(&modem->read.pending); - modem->read.buffer_sz = le16_to_cpu(epread->wMaxPacketSize) * 4; - for (i = 0; i < READ_POOL_SZ; i++) { - struct urb *u = usb_alloc_urb(0, GFP_KERNEL); - if (!u) { - status = -ENOMEM; - goto err_out; - } - u->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - u->transfer_buffer = usb_alloc_coherent(serial->dev, - modem->read.buffer_sz, GFP_KERNEL, &u->transfer_dma); - if (!u->transfer_buffer) { - status = -ENOMEM; - usb_free_urb(u); - goto err_out; - } - usb_fill_bulk_urb(u, serial->dev, - usb_rcvbulkpipe(serial->dev, epread->bEndpointAddress), - u->transfer_buffer, modem->read.buffer_sz, - mdm6600_read_bulk_cb, modem); - usb_anchor_urb(u, &modem->read.free_list); - } - - spin_lock_init(&modem->susp_lock); - spin_lock_init(&modem->write.pending_lock); - - snprintf(modem->readlock_name, sizeof(modem->readlock_name), - "mdm6600_read.%d", modem->number); - wake_lock_init(&modem->readlock, WAKE_LOCK_SUSPEND, modem->readlock_name); - - snprintf(modem->writelock_name, sizeof(modem->writelock_name), - "mdm6600_write.%d", modem->number); - wake_lock_init(&modem->writelock, WAKE_LOCK_SUSPEND, modem->writelock_name); - - usb_get_intf(serial->interface); - usb_enable_autosuspend(serial->dev); - usb_mark_last_busy(serial->dev); - - /* the modem triggers wakeup requests only if remote wakeup is enabled */ - device_init_wakeup(&serial->dev->dev, 1); - serial->interface->needs_remote_wakeup = 1; - serial->dev->autosuspend_delay = MODEM_AUTOSUSPEND_DELAY; - serial->dev->parent->autosuspend_delay = 0; - - if (modem->number == MODEM_INTERFACE_NUM) { - INIT_WORK(&modem->wake_work, mdm6600_wake_work); - status = request_irq(mdm6600_wake_irq, mdm6600_irq_handler, - IRQ_TYPE_EDGE_FALLING, "usb_wake_host", modem); - if (status) { - pr_err("request_irq failed; err=%d", status); - status = -ENXIO; - goto err_out; - } - enable_irq_wake(mdm6600_wake_irq); - disable_irq(mdm6600_wake_irq); - } - - return 0; - -err_out: - mdm6600_release(serial); - mdm6600_attached_ports--; - return status; -} - -static void mdm6600_kill_urbs(struct mdm6600_port *modem) -{ - struct urb *u; - - dbg("%s: port %d", __func__, modem->number); - - /* cancel pending writes */ - usb_kill_anchored_urbs(&modem->write.in_flight); - - /* stop reading from mdm6600 */ - usb_kill_anchored_urbs(&modem->read.in_flight); - - usb_kill_urb(modem->port->interrupt_in_urb); - - if (!usb_wait_anchor_empty_timeout(&modem->read.pending, 1000)) { - WARN_ON_ONCE(1); - while ((u = usb_get_from_anchor(&modem->read.pending))) { - usb_anchor_urb(u, &modem->read.free_list); - usb_put_urb(u); - } - } - - /* cancel read bottom half */ - cancel_work_sync(&modem->read.work); -} - -static void mdm6600_disconnect(struct usb_serial *serial) -{ - struct mdm6600_port *modem = usb_get_serial_data(serial); - - dbg("%s: port %d", __func__, modem->number); - - modem->opened = 0; - smp_wmb(); - - if (modem->number == MODEM_INTERFACE_NUM) { - disable_irq_wake(mdm6600_wake_irq); - free_irq(mdm6600_wake_irq, modem); - mdm6600_wake_irq_enabled = false; - cancel_work_sync(&modem->wake_work); - } - - mdm6600_kill_urbs(modem); - - modem->tiocm_status = 0; - - wake_lock_destroy(&modem->readlock); - wake_lock_destroy(&modem->writelock); - - mdm6600_attached_ports--; -} - -static void mdm6600_release_urb(struct urb *u, int sz) -{ - if (u->transfer_buffer) { - usb_free_coherent(u->dev, sz, u->transfer_buffer, - u->transfer_dma); - u->transfer_buffer = NULL; - } - usb_free_urb(u); -} - -static void mdm6600_release(struct usb_serial *serial) -{ - struct mdm6600_port *modem = usb_get_serial_data(serial); - struct urb *u; - - dbg("%s: port %d", __func__, modem->number); - - while ((u = usb_get_from_anchor(&modem->write.free_list))) { - mdm6600_release_urb(u, modem->write.buffer_sz); - usb_put_urb(u); - } - - while ((u = usb_get_from_anchor(&modem->read.free_list))) { - mdm6600_release_urb(u, modem->read.buffer_sz); - usb_put_urb(u); - } - - usb_set_serial_data(serial, NULL); - usb_put_intf(serial->interface); - kfree(modem); -} - -static int mdm6600_submit_urbs(struct mdm6600_port *modem) -{ - struct urb *u; - int rc; - - dbg("%s: port %d", __func__, modem->number); - - if (modem->number == MODEM_INTERFACE_NUM) { - rc = usb_submit_urb(modem->port->interrupt_in_urb, GFP_KERNEL); - if (rc) { - pr_err("%s: failed to submit interrupt urb, error %d\n", - __func__, rc); - return rc; - } - } - while ((u = usb_get_from_anchor(&modem->read.free_list))) { - usb_anchor_urb(u, &modem->read.in_flight); - rc = usb_submit_urb(u, GFP_KERNEL); - if (rc) { - usb_unanchor_urb(u); - usb_anchor_urb(u, &modem->read.free_list); - usb_put_urb(u); - usb_kill_anchored_urbs(&modem->read.in_flight); - usb_kill_urb(modem->port->interrupt_in_urb); - pr_err("%s: failed to submit bulk read urb, error %d\n", - __func__, rc); - return rc; - } - usb_put_urb(u); - } - - return 0; -} - -/* called when tty is opened */ -static int mdm6600_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - int status; - - dbg("%s: port %d", __func__, modem->number); - - WARN_ON_ONCE(modem->port != port); - - if (tty) - tty->low_latency = 1; - - modem->tiocm_status = 0; - - modem->opened = 1; - smp_wmb(); - - status = mdm6600_submit_urbs(modem); - - usb_autopm_put_interface(modem->serial->interface); - return status; -} - -static void mdm6600_close(struct usb_serial_port *port) -{ - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - - dbg("%s: port %d", __func__, modem->number); - - usb_autopm_get_interface(modem->serial->interface); - - modem->opened = 0; - smp_wmb(); - - mdm6600_kill_urbs(modem); - - modem->tiocm_status = 0; -} - -static void mdm6600_write_bulk_cb(struct urb *u) -{ - unsigned long flags; - struct mdm6600_port *modem = u->context; - - dbg("%s: urb %p status %d", __func__, u, u->status); - - if (!u->status) - usb_serial_port_softint(modem->port); - else - pr_warn("%s non-zero status %d\n", __func__, u->status); - - usb_anchor_urb(u, &modem->write.free_list); - - spin_lock_irqsave(&modem->write.pending_lock, flags); - if (--modem->write.pending == 0) { - usb_autopm_put_interface_async(modem->serial->interface); - wake_unlock(&modem->writelock); - } - spin_unlock_irqrestore(&modem->write.pending_lock, flags); -} - -static int mdm6600_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - int rc; - struct urb *u; - struct usb_serial *serial = port->serial; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - unsigned long flags; - - dbg("%s: port %d count %d pool %p", __func__, modem->number, count, - &modem->write); - - if (!count || !serial->num_bulk_out) - return 0; - - u = usb_get_from_anchor(&modem->write.free_list); - if (!u) { - pr_info("%s: port %d all buffers busy!\n", __func__, modem->number); - return 0; - } - - count = min(count, modem->write.buffer_sz); - memcpy(u->transfer_buffer, buf, count); - u->transfer_buffer_length = count; - usb_serial_debug_data(debug_data, &port->dev, __func__, - u->transfer_buffer_length, u->transfer_buffer); - - spin_lock_irqsave(&modem->write.pending_lock, flags); - if (modem->write.pending++ == 0) { - wake_lock(&modem->writelock); - usb_autopm_get_interface_async(modem->serial->interface); - } - spin_unlock_irqrestore(&modem->write.pending_lock, flags); - - spin_lock_irqsave(&mdm6600_wake_irq_lock, flags); - if (mdm6600_wake_irq_enabled) { - disable_irq_nosync(mdm6600_wake_irq); - mdm6600_wake_irq_enabled = false; - } - spin_unlock_irqrestore(&mdm6600_wake_irq_lock, flags); - - spin_lock_irqsave(&modem->susp_lock, flags); - if (modem->susp_count) { - usb_anchor_urb(u, &modem->write.delayed); - spin_unlock_irqrestore(&modem->susp_lock, flags); - usb_put_urb(u); - return count; - } - spin_unlock_irqrestore(&modem->susp_lock, flags); - - usb_anchor_urb(u, &modem->write.in_flight); - rc = usb_submit_urb(u, GFP_KERNEL); - if (rc < 0) { - pr_err("%s: submit bulk urb failed %d\n", __func__, rc); - - usb_unanchor_urb(u); - usb_anchor_urb(u, &modem->write.free_list); - usb_put_urb(u); - - spin_lock_irqsave(&modem->write.pending_lock, flags); - if (--modem->write.pending == 0) { - usb_autopm_put_interface_async(serial->interface); - wake_unlock(&modem->writelock); - } - spin_unlock_irqrestore(&modem->write.pending_lock, flags); - return rc; - } - usb_put_urb(u); - return count; -} - -static int mdm6600_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - unsigned long flags; - int room = 0; - - if (!modem) - return 0; - - dbg("%s - port %d", __func__, modem->number); - - spin_lock_irqsave(&modem->write.pending_lock, flags); - if (modem->write.pending != WRITE_POOL_SZ) - room = modem->write.buffer_sz; - spin_unlock_irqrestore(&modem->write.pending_lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - -static int mdm6600_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - unsigned long flags; - int chars; - - dbg("%s - port %d", __func__, modem->number); - - spin_lock_irqsave(&modem->write.pending_lock, flags); - chars = modem->write.pending * modem->write.buffer_sz; - spin_unlock_irqrestore(&modem->write.pending_lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - -static int mdm6600_tiocmget(struct tty_struct *tty, struct file *file) -{ - struct usb_serial_port *port = tty->driver_data; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - - dbg("%s: port %d modem_status %x\n", __func__, modem->number, - modem->tiocm_status); - - return modem->tiocm_status; -} - -static int mdm6600_dtr_control(struct usb_serial_port *port, int ctrl) -{ - struct usb_device *dev = port->serial->dev; - struct usb_interface *iface = port->serial->interface; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - u8 request = 0x22; - u8 request_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT; - int timeout = HZ * 5; - int rc; - - dbg("%s - port %d", __func__, modem->number); - - rc = usb_autopm_get_interface(iface); - if (rc < 0) { - pr_err("%s %s autopm failed %d", dev_driver_string(&iface->dev), - dev_name(&iface->dev), rc); - return rc; - } - - rc = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, - request_type, ctrl, modem->number, NULL, 0, timeout); - usb_autopm_put_interface(iface); - - return rc; -} - -static int mdm6600_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - - dbg("%s: port %d set %x clear %x\n", __func__, modem->number, set, - clear); - - if (modem->number != MODEM_INTERFACE_NUM) - return 0; - if (clear & TIOCM_DTR) - return mdm6600_dtr_control(port, 0); - if (set & TIOCM_DTR) - return mdm6600_dtr_control(port, 1); - return 0; -} - -static void mdm6600_apply_bp_status(u8 bp_status, u16 *tiocm_status) -{ - if (bp_status & BP_STATUS_CAR) - *tiocm_status |= TIOCM_CAR; - else - *tiocm_status &= ~TIOCM_CAR; - if (bp_status & BP_STATUS_DSR) - *tiocm_status |= TIOCM_DSR; - else - *tiocm_status &= ~TIOCM_DSR; - if (bp_status & BP_STATUS_RNG) - *tiocm_status |= TIOCM_RNG; - else - *tiocm_status &= ~TIOCM_RNG; -} - -static void mdm6600_read_int_callback(struct urb *u) -{ - int rc; - u16 request; - u8 *data = u->transfer_buffer; - struct usb_serial_port *port = u->context; - struct mdm6600_port *modem = usb_get_serial_data(port->serial); - - dbg("%s: urb %p", __func__, u); - - switch (u->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -EPROTO: - dbg("%s: urb terminated, status %d", __func__, u->status); - return; - default: - pr_warn("%s non-zero status %d\n", __func__, u->status); - goto exit; - } - - usb_mark_last_busy(port->serial->dev); - usb_serial_debug_data(debug_data, &port->dev, __func__, - u->actual_length, data); - - if (u->actual_length < 2) { - dbg("%s: interrupt transfer too small %d", - __func__, u->actual_length); - goto exit; - } - request = *((u16 *)data); - - switch (request) { - case BP_MODEM_STATUS: - if (u->actual_length < 9) { - pr_err("%s: modem status urb too small %d\n", - __func__, u->actual_length); - break; - } - if (modem->number != MODEM_INTERFACE_NUM) - break; - mdm6600_apply_bp_status(data[8], &modem->tiocm_status); - dbg("%s: modem_status now %x", __func__, modem->tiocm_status); - break; - case BP_RSP_AVAIL: - dbg("%s: BP_RSP_AVAIL", __func__); - break; - case BP_SPEED_CHANGE: - dbg("%s: BP_SPEED_CHANGE", __func__); - break; - default: - dbg("%s: undefined BP request type %d", __func__, request); - break; - } - -exit: - rc = usb_submit_urb(u, GFP_ATOMIC); - if (rc) - pr_err("%s: Error %d re-submitting interrupt urb\n", - __func__, rc); -} - -static size_t mdm6600_pass_to_tty(struct tty_struct *tty, void *buf, size_t sz) -{ - unsigned char *b = buf; - size_t c; - size_t s; - - s = tty_buffer_request_room(tty, sz); - while (s > 0) { - c = tty_insert_flip_string(tty, b, s); - if (c != s) - dbg("%s passed only %u of %u bytes\n", - __func__, c, s); - if (c == 0) - break; - tty_flip_buffer_push(tty); - s -= c; - b += c; - } - - return sz - s; -} - -static void mdm6600_read_bulk_work(struct work_struct *work) -{ - int rc; - size_t c; - struct urb *u; - struct tty_struct *tty; - unsigned long flags; - struct mdm6600_port *modem = container_of(work, struct mdm6600_port, - read.work); - - dbg("%s", __func__); - - while ((u = usb_get_from_anchor(&modem->read.pending))) { - dbg("%s: processing urb %p len %u", __func__, u, - u->actual_length); - usb_serial_debug_data(debug_data, &modem->port->dev, __func__, - u->actual_length, u->transfer_buffer); - tty = tty_port_tty_get(&modem->port->port); - if (!tty) { - pr_warn("%s: could not find tty\n", __func__); - goto next; - } - - BUG_ON(u->actual_length > modem->read.buffer_sz); - - c = mdm6600_pass_to_tty(tty, u->transfer_buffer, - u->actual_length); - if (c != u->actual_length) - pr_warn("%s: port %d: dropped %u of %u bytes\n", - __func__, modem->number, u->actual_length - c, - u->actual_length); - tty_kref_put(tty); - -next: - spin_lock_irqsave(&modem->susp_lock, flags); - if (modem->susp_count || !modem->opened) { - spin_unlock_irqrestore(&modem->susp_lock, flags); - usb_anchor_urb(u, &modem->read.free_list); - usb_put_urb(u); - continue; - } - spin_unlock_irqrestore(&modem->susp_lock, flags); - - usb_anchor_urb(u, &modem->read.in_flight); - rc = usb_submit_urb(u, GFP_KERNEL); - if (rc) { - pr_err("%s: Error %d re-submitting read urb %p\n", - __func__, rc, u); - usb_unanchor_urb(u); - usb_anchor_urb(u, &modem->read.free_list); - } - usb_put_urb(u); - } -} - -static void mdm6600_read_bulk_cb(struct urb *u) -{ - int rc; - struct mdm6600_port *modem = u->context; - - dbg("%s: urb %p", __func__, u); - - switch (u->status) { - case 0: - break; /* success */ - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -EPROTO: - dbg("%s: urb terminated, status %d", __func__, u->status); - usb_anchor_urb(u, &modem->read.free_list); - return; - default: - pr_warn("%s non-zero status %d\n", __func__, u->status); - /* straight back into use */ - usb_anchor_urb(u, &modem->read.in_flight); - rc = usb_submit_urb(u, GFP_ATOMIC); - if (rc) { - usb_unanchor_urb(u); - usb_anchor_urb(u, &modem->read.free_list); - pr_err("%s: Error %d re-submitting read urb\n", - __func__, rc); - } - return; - } - - wake_lock_timeout(&modem->readlock, MODEM_WAKELOCK_TIME); - usb_mark_last_busy(modem->serial->dev); - - usb_anchor_urb(u, &modem->read.pending); - - queue_work(system_nrt_wq, &modem->read.work); -} - -static int mdm6600_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - struct mdm6600_port *modem = usb_get_serial_data(serial); - - dbg("%s: event=%d", __func__, message.event); - - if (modem->number == MODEM_INTERFACE_NUM) { - spin_lock_irq(&mdm6600_wake_irq_lock); - if (!mdm6600_wake_irq_enabled) { - enable_irq(mdm6600_wake_irq); - mdm6600_wake_irq_enabled = true; - } - spin_unlock_irq(&mdm6600_wake_irq_lock); - } - - spin_lock_irq(&modem->susp_lock); - - if (!modem->susp_count++ && modem->opened) { - spin_unlock_irq(&modem->susp_lock); - - dbg("%s: kill urbs", __func__); - mdm6600_kill_urbs(modem); - return 0; - } - - spin_unlock_irq(&modem->susp_lock); - return 0; -} - -static int mdm6600_resume(struct usb_interface *intf) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - struct mdm6600_port *modem = usb_get_serial_data(serial); - struct urb *u; - int rc; - - dbg("%s", __func__); - - spin_lock_irq(&modem->susp_lock); - - if (!--modem->susp_count && modem->opened) { - dbg("%s: submit urbs", __func__); - spin_unlock_irq(&modem->susp_lock); - - mdm6600_submit_urbs(modem); - - while ((u = usb_get_from_anchor(&modem->write.delayed))) { - usb_anchor_urb(u, &modem->write.in_flight); - rc = usb_submit_urb(u, GFP_KERNEL); - if (rc < 0) { - usb_unanchor_urb(u); - usb_anchor_urb(u, &modem->read.free_list); - usb_put_urb(u); - pr_err("%s: submit bulk urb failed %d\n", - __func__, rc); - goto err; - } - usb_put_urb(u); - } - - return 0; - } - - spin_unlock_irq(&modem->susp_lock); - return 0; - -err: - while ((u = usb_get_from_anchor(&modem->write.delayed))) { - usb_anchor_urb(u, &modem->write.free_list); - usb_put_urb(u); - } - return rc; -} - -static int mdm6600_reset_resume(struct usb_interface *intf) -{ - dbg("%s", __func__); - - return mdm6600_resume(intf); -} - -static int mdm6600_probe(struct usb_serial *serial, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(serial->interface); - - /* we only support 1 modem */ - if (mdm6600_attached_ports >= dev->config->desc.bNumInterfaces) { - pr_err("%s: only one modem supported", __func__); - return -EBUSY; - } - - return 0; -} - -static struct usb_driver mdm6600_usb_driver = { - .name = "mdm6600", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = mdm6600_id_table, - .no_dynamic_id = 1, - .supports_autosuspend = 1, - .suspend = mdm6600_suspend, - .resume = mdm6600_resume, - .reset_resume = mdm6600_reset_resume, -}; - -static struct usb_serial_driver mdm6600_usb_serial_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "mdm6600", - }, - .num_ports = 1, - .description = "MDM 6600 modem usb-serial driver", - .id_table = mdm6600_id_table, - .usb_driver = &mdm6600_usb_driver, - .probe = mdm6600_probe, - .attach = mdm6600_attach, - .disconnect = mdm6600_disconnect, - .release = mdm6600_release, - .open = mdm6600_open, - .close = mdm6600_close, - .write = mdm6600_write, - .write_room = mdm6600_write_room, - .chars_in_buffer = mdm6600_chars_in_buffer, - .tiocmset = mdm6600_tiocmset, - .tiocmget = mdm6600_tiocmget, - .read_int_callback = mdm6600_read_int_callback, -}; - - -static int mdm6600_modem_probe(struct platform_device *pdev) -{ - int retval; - - mdm6600_wake_irq = platform_get_irq(pdev, 0); - if (!mdm6600_wake_irq) { - dev_err(&pdev->dev, "Failed to get IRQ\n"); - return -ENODEV; - } - - retval = usb_serial_register(&mdm6600_usb_serial_driver); - if (retval) - return retval; - retval = usb_register(&mdm6600_usb_driver); - if (retval) - usb_serial_deregister(&mdm6600_usb_serial_driver); - - return retval; -} - -static int __exit mdm6600_modem_remove(struct platform_device *pdev) -{ - usb_deregister(&mdm6600_usb_driver); - usb_serial_deregister(&mdm6600_usb_serial_driver); - return 0; -} - -static struct platform_driver mdm6600_modem_driver = { - .driver = { - .name = "mdm6600_modem", - }, - .remove = __exit_p(mdm6600_modem_remove), - .probe = mdm6600_modem_probe, -}; - -static int __init mdm6600_init(void) -{ - return platform_driver_register(&mdm6600_modem_driver); -} - -static void __exit mdm6600_exit(void) -{ - platform_driver_unregister(&mdm6600_modem_driver); -} - -module_init(mdm6600_init); -module_exit(mdm6600_exit); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); -module_param(debug_data, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug_data, "Debug enabled or not"); diff --git a/drivers/usb/serial/moto_flashmdm.c b/drivers/usb/serial/moto_flashmdm.c deleted file mode 100644 index 49170f573471..000000000000 --- a/drivers/usb/serial/moto_flashmdm.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Motorola Modem flash mode driver - * - * Copyright (C) 2008 Greg Kroah-Hartman - * Copyright (C) 2009 Motorola, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_ARCH_OMAP34XX) -#include "../host/ehci-omap.h" -#endif - -static struct usb_device_id id_table[] = { - {USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2db4, 0x0a, 0, 0xfc)}, - {USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x4281, 0x0a, 0, 0xfc)}, - {USB_DEVICE(0x22b8, 0x4260)}, /* wrigley in flash mode */ - {USB_DEVICE(0x22b8, 0x426d)}, /* wrigley in flash bl3080 */ - {}, -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -#define MOTO_FLASHMDM_BULKOUT_SIZE 8192 - -#if defined(CONFIG_ARCH_OMAP34XX) -/* disable the uhh_sysconfig auto idle bit, - * so that, host iclk will not be disabled and BP - * can re-enumerated on AP - */ -static void omap_flashmdm_disable_uhh_smart_idle(void) -{ - u32 sysconfig; - - sysconfig = omap_readl(OMAP_UHH_SYSCONFIG); - sysconfig &= ~(1 << OMAP_UHH_SYSCONFIG_AUTOIDLE_SHIFT); - omap_writel(sysconfig, OMAP_UHH_SYSCONFIG); -} -#endif - -static int moto_flashmdm_attach(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - int i; - - if (port->bulk_out_size >= MOTO_FLASHMDM_BULKOUT_SIZE) { - dev_info(&serial->dev->dev, - "bulk_out_size %d\n", port->bulk_out_size); - return 0; - } - - kfree(port->bulk_out_buffer); - port->bulk_out_size = MOTO_FLASHMDM_BULKOUT_SIZE; - port->bulk_out_buffer = kmalloc(port->bulk_out_size, GFP_KERNEL); - if (!port->bulk_out_buffer) { - dev_err(&serial->dev->dev, - "Couldn't allocate bulk_out_buffer\n"); - return -ENOMEM; - } - usb_fill_bulk_urb(port->write_urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - port->bulk_out_buffer, port->bulk_out_size, - serial->type->write_bulk_callback, port); - - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { - kfree(port->bulk_out_buffers[i]); - port->bulk_out_buffers[i] = kmalloc(port->bulk_out_size, - GFP_KERNEL); - if (!port->bulk_out_buffers[i]) { - dev_err(&serial->dev->dev, - "Couldn't allocate bulk_out_buffer\n"); - return -ENOMEM; - } - usb_fill_bulk_urb(port->write_urbs[i], serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - port->bulk_out_buffers[i], port->bulk_out_size, - serial->type->write_bulk_callback, port); - } - -#if defined(CONFIG_ARCH_OMAP34XX) - /* need to disable the AUTO IDLE for the usb iclk */ - omap_flashmdm_disable_uhh_smart_idle(); -#endif - - return 0; -} - -static struct usb_driver moto_flashmdm_driver = { - .name = "moto-flashmdm", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, - -}; - -static struct usb_serial_driver moto_flashmdm_device = { - .driver = { - .owner = THIS_MODULE, - .name = "moto-flashmdm", - }, - .id_table = id_table, - .num_ports = 1, - .attach = moto_flashmdm_attach, -}; - -static int __init moto_flashmdm_init(void) -{ - int retval; - - retval = usb_serial_register(&moto_flashmdm_device); - if (retval) - return retval; - retval = usb_register(&moto_flashmdm_driver); - if (retval) - usb_serial_deregister(&moto_flashmdm_device); - return retval; -} - -static void __exit moto_flashmdm_exit(void) -{ - usb_deregister(&moto_flashmdm_driver); - usb_serial_deregister(&moto_flashmdm_device); -} - -module_init(moto_flashmdm_init); -module_exit(moto_flashmdm_exit); -MODULE_LICENSE("GPL"); - diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 9ff19c8a122e..ed01f3b2de8c 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -96,8 +96,8 @@ static void opticon_bulk_callback(struct urb *urb) /* real data, send it to the tty layer */ tty = tty_port_tty_get(&port->port); if (tty) { - tty_insert_flip_string(tty, data + 2, - data_length); + tty_insert_flip_string(tty, data, + data_length); tty_flip_buffer_push(tty); tty_kref_put(tty); } @@ -130,7 +130,7 @@ exit: priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, opticon_bulk_callback, priv); - result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 12d5f82616a3..c46911af282f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -512,7 +512,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, + { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, @@ -622,7 +622,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, @@ -634,52 +633,38 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, - /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, - /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0079, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, @@ -895,8 +880,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b993e8dd2957..7a2177c79bde 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -52,7 +52,6 @@ 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 @@ -1332,8 +1331,6 @@ 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/serial/visor.c b/drivers/usb/serial/visor.c index 15a5d89b7f39..eb76aaef4268 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -606,10 +606,6 @@ static int treo_attach(struct usb_serial *serial) static int clie_5_attach(struct usb_serial *serial) { - struct usb_serial_port *port; - unsigned int pipe; - int j; - dbg("%s", __func__); /* TH55 registers 2 ports. @@ -625,14 +621,9 @@ static int clie_5_attach(struct usb_serial *serial) return -1; /* port 0 now uses the modified endpoint Address */ - port = serial->port[0]; - port->bulk_out_endpointAddress = + serial->port[0]->bulk_out_endpointAddress = serial->port[1]->bulk_out_endpointAddress; - pipe = usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress); - for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) - port->write_urbs[j]->pipe = pipe; - return 0; } diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index ceba512f84d0..57fc2f532cab 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr, } return result; } -static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL); +static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL); int sierra_ms_init(struct us_data *us) { diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b51b121ae825..2c897eefadde 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -481,13 +481,6 @@ UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64), -/* Reported by Vitaly Kuznetsov */ -UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, - "Samsung", - "YP-CP3", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), - /* Entry and supporting patch by Theodore Kilgore . * 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/video/Kconfig b/drivers/video/Kconfig index d5ae62ca9645..cafde376dc10 100755 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2300,7 +2300,6 @@ config FB_JZ4740 source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" -source "drivers/video/tegra/Kconfig" source "drivers/video/backlight/Kconfig" source "drivers/video/display/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 1f4d80baac48..ffe6a6c7d442 100755 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -135,7 +135,6 @@ obj-$(CONFIG_FB_MB862XX) += mb862xx/ obj-$(CONFIG_FB_MSM) += msm/ obj-$(CONFIG_FB_NUC900) += nuc900fb.o obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o -obj-y += tegra/ # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 08703299ef61..e207810bba3c 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state) { struct backlight_device *bd = to_backlight_device(dev); - mutex_lock(&bd->ops_lock); - if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { + if (bd->ops->options & BL_CORE_SUSPENDRESUME) { + mutex_lock(&bd->ops_lock); bd->props.state |= BL_CORE_SUSPENDED; backlight_update_status(bd); + mutex_unlock(&bd->ops_lock); } - mutex_unlock(&bd->ops_lock); return 0; } @@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev) { struct backlight_device *bd = to_backlight_device(dev); - mutex_lock(&bd->ops_lock); - if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { + if (bd->ops->options & BL_CORE_SUSPENDRESUME) { + mutex_lock(&bd->ops_lock); bd->props.state &= ~BL_CORE_SUSPENDED; backlight_update_status(bd); + mutex_unlock(&bd->ops_lock); } - mutex_unlock(&bd->ops_lock); return 0; } diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 18dad1dd9fb7..563a98b88e9b 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -973,99 +973,6 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) DPRINTK("========================================\n"); } -void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) -{ - unsigned char *block; - unsigned char *dtd_block; - struct fb_videomode *mode, *m; - int num = 0, i, first = 1; - - if (edid == NULL) - return; - - if (!edid_checksum(edid)) - return; - - if (edid[0] != 0x2) - return; - - mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); - if (mode == NULL) - return; - - block = edid + 0x4; - dtd_block = edid + edid[0x2]; - - DPRINTK(" Short Video Modes\n"); - while (block < dtd_block) { - unsigned tag = block[0] >> 5; - unsigned len = block[0] & 0x1f; - - block++; - if (dtd_block - block < len) - break; - - if (tag == 0x2) { - for (i = 0; i < len; i++) { - unsigned m = block[i]; - if (m > 0 && m < CEA_MODEDB_SIZE) { - memcpy(&mode[num], &cea_modes[m], - sizeof(mode[num])); - DPRINTK(" %d: %dx%d @ %d\n", m, - cea_modes[m].xres, cea_modes[m].yres, - cea_modes[m].refresh); - - num++; - } - } - } else if (tag == 0x3) { - if (len >= 3) { - u32 ieee_reg = block[0] | (block[1] << 8) | - (block[2] << 16); - if (ieee_reg == 0x000c03) - specs->misc |= FB_MISC_HDMI; - } - } - - block += len; - } - - DPRINTK(" Extended Detailed Timings\n"); - - for (i = 0; i < (128 - edid[0x2]) / DETAILED_TIMING_DESCRIPTION_SIZE; - i++, dtd_block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if (!(dtd_block[0] == 0x00 && dtd_block[1] == 0x00)) { - get_detailed_timing(dtd_block, &mode[num]); - if (first) { - mode[num].flag |= FB_MODE_IS_FIRST; - first = 0; - } - num++; - } - } - - /* Yikes, EDID data is totally useless */ - if (!num) { - kfree(mode); - return; - } - - m = kzalloc((specs->modedb_len + num) * - sizeof(struct fb_videomode), GFP_KERNEL); - - if (!m) { - kfree(mode); - return; - } - - memmove(m, specs->modedb, specs->modedb_len * sizeof(struct fb_videomode)); - memmove(m + specs->modedb_len, mode, num * sizeof(struct fb_videomode)); - kfree(mode); - kfree(specs->modedb); - specs->modedb = m; - specs->modedb_len = specs->modedb_len + num; -} - /* * VESA Generalized Timing Formula (GTF) */ diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 209e6be1163e..0a4dbdc1693a 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -402,459 +402,6 @@ const struct fb_videomode vesa_modes[] = { FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, }; EXPORT_SYMBOL(vesa_modes); - -const struct fb_videomode cea_modes[CEA_MODEDB_SIZE] = { - {}, - /* 1: 640x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 640, .yres = 480, .pixclock = 39721, - .left_margin = 48, .right_margin = 16, - .upper_margin = 33, .lower_margin = 1, - .hsync_len = 96, .vsync_len = 2, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 2: 720x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 720, .yres = 480, .pixclock = 37037, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 3: 720x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 720, .yres = 480, .pixclock = 37037, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 4: 1280x720p @ 59.94Hz/60Hz */ - {.refresh = 60, .xres = 1280, .yres = 720, .pixclock = 13468, - .left_margin = 220, .right_margin = 110, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 5: 1920x1080i @ 59.94Hz/60Hz */ - {.refresh = 60, .xres = 1920, .yres = 1080, .pixclock = 13468, - .left_margin = 148, .right_margin = 88, - .upper_margin = 15, .lower_margin = 2, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_INTERLACED}, - /* 6: 720(1440)x480i @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 37037, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 7: 720(1440)x480i @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 37037, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 8: 720(1440)x240p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 240, .pixclock = 37037, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 5, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 9: 720(1440)x240p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 240, .pixclock = 37037, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 5, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 10: 2880x480i @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 18518, - .left_margin = 228, .right_margin = 76, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 248, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 11: 2880x480i @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 18518, - .left_margin = 228, .right_margin = 76, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 248, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 12: 2880x240p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 240, .pixclock = 18518, - .left_margin = 228, .right_margin = 76, - .upper_margin = 15, .lower_margin = 5, - .hsync_len = 248, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 13: 2880x240p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 240, .pixclock = 18518, - .left_margin = 228, .right_margin = 76, - .upper_margin = 15, .lower_margin = 5, - .hsync_len = 248, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 14: 1440x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 18518, - .left_margin = 120, .right_margin = 32, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 124, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 15: 1440x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 18518, - .left_margin = 120, .right_margin = 32, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 124, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 16: 1920x1080p @ 59.94Hz/60Hz */ - {.refresh = 60, .xres = 1920, .yres = 1080, .pixclock = 6734, - .left_margin = 148, .right_margin = 88, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 17: 720x576p @ 50Hz */ - {.refresh = 50, .xres = 720, .yres = 576, .pixclock = 37037, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 18: 720x576p @ 50Hz */ - {.refresh = 50, .xres = 720, .yres = 576, .pixclock = 37037, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 19: 1280x720p @ 50Hz */ - {.refresh = 50, .xres = 1280, .yres = 720, .pixclock = 13468, - .left_margin = 220, .right_margin = 440, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 20: 1920x1080i @ 50Hz */ - {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 13468, - .left_margin = 148, .right_margin = 528, - .upper_margin = 15, .lower_margin = 2, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_INTERLACED}, - /* 21: 720(1440)x576i @ 50Hz */ - {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 37037, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 22: 720(1440)x576i @ 50Hz */ - {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 37037, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 23: 720(1440)x288p @ 50Hz */ - {.refresh = 49, .xres = 1440, .yres = 288, .pixclock = 37037, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 4, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 24: 720(1440)x288p @ 50Hz */ - {.refresh = 49, .xres = 1440, .yres = 288, .pixclock = 37037, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 4, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 25: 2880x576i @ 50Hz */ - {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 18518, - .left_margin = 276, .right_margin = 48, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 252, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 26: 2880x576i @ 50Hz */ - {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 18518, - .left_margin = 276, .right_margin = 48, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 252, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 27: 2880x288p @ 50Hz */ - {.refresh = 49, .xres = 2880, .yres = 288, .pixclock = 18518, - .left_margin = 276, .right_margin = 48, - .upper_margin = 19, .lower_margin = 4, - .hsync_len = 252, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 28: 2880x288p @ 50Hz */ - {.refresh = 49, .xres = 2880, .yres = 288, .pixclock = 18518, - .left_margin = 276, .right_margin = 48, - .upper_margin = 19, .lower_margin = 4, - .hsync_len = 252, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 29: 1440x576p @ 50Hz */ - {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 18518, - .left_margin = 136, .right_margin = 24, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 128, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 30: 1440x576p @ 50Hz */ - {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 18518, - .left_margin = 136, .right_margin = 24, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 128, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 31: 1920x1080p @ 50Hz */ - {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 6734, - .left_margin = 148, .right_margin = 528, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 32: 1920x1080p @ 23.97Hz/24Hz */ - {.refresh = 24, .xres = 1920, .yres = 1080, .pixclock = 13468, - .left_margin = 148, .right_margin = 638, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 33: 1920x1080p @ 25Hz */ - {.refresh = 25, .xres = 1920, .yres = 1080, .pixclock = 13468, - .left_margin = 148, .right_margin = 528, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 34: 1920x1080p @ 29.97Hz/30Hz */ - {.refresh = 30, .xres = 1920, .yres = 1080, .pixclock = 13468, - .left_margin = 148, .right_margin = 88, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 35: 2880x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 9259, - .left_margin = 240, .right_margin = 64, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 248, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 36: 2880x480p @ 59.94Hz/60Hz */ - {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 9259, - .left_margin = 240, .right_margin = 64, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 248, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 37: 2880x576p @ 50Hz */ - {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 9259, - .left_margin = 272, .right_margin = 48, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 256, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 38: 2880x576p @ 50Hz */ - {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 9259, - .left_margin = 272, .right_margin = 48, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 256, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 39: 1920x1080i @ 50Hz */ - {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 13888, - .left_margin = 184, .right_margin = 32, - .upper_margin = 57, .lower_margin = 2, - .hsync_len = 168, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT, - .vmode = FB_VMODE_INTERLACED}, - /* 40: 1920x1080i @ 100Hz */ - {.refresh = 100, .xres = 1920, .yres = 1080, .pixclock = 6734, - .left_margin = 148, .right_margin = 528, - .upper_margin = 15, .lower_margin = 2, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_INTERLACED}, - /* 41: 1280x720p @ 100Hz */ - {.refresh = 100, .xres = 1280, .yres = 720, .pixclock = 6734, - .left_margin = 220, .right_margin = 440, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 42: 720x576p @ 100Hz */ - {.refresh = 100, .xres = 720, .yres = 576, .pixclock = 18518, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 43: 720x576p @ 100Hz */ - {.refresh = 100, .xres = 720, .yres = 576, .pixclock = 18518, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 44: 720(1440)x576i @ 100Hz */ - {.refresh = 100, .xres = 1440, .yres = 576, .pixclock = 18518, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 45: 720(1440)x576i @ 100Hz */ - {.refresh = 100, .xres = 1440, .yres = 576, .pixclock = 18518, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 46: 1920x1080i @ 119.88/120Hz */ - {.refresh = 120, .xres = 1920, .yres = 1080, .pixclock = 6734, - .left_margin = 148, .right_margin = 88, - .upper_margin = 15, .lower_margin = 2, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_INTERLACED}, - /* 47: 1280x720p @ 119.88/120Hz */ - {.refresh = 120, .xres = 1280, .yres = 720, .pixclock = 6734, - .left_margin = 220, .right_margin = 110, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 48: 720x480p @ 119.88/120Hz */ - {.refresh = 119, .xres = 720, .yres = 480, .pixclock = 18518, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 49: 720x480p @ 119.88/120Hz */ - {.refresh = 119, .xres = 720, .yres = 480, .pixclock = 18518, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 50: 720(1440)x480i @ 119.88/120Hz */ - {.refresh = 119, .xres = 1440, .yres = 480, .pixclock = 18518, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 51: 720(1440)x480i @ 119.88/120Hz */ - {.refresh = 119, .xres = 1440, .yres = 480, .pixclock = 18518, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 52: 720x576p @ 200Hz */ - {.refresh = 200, .xres = 720, .yres = 576, .pixclock = 9259, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 53: 720x576p @ 200Hz */ - {.refresh = 200, .xres = 720, .yres = 576, .pixclock = 9259, - .left_margin = 68, .right_margin = 12, - .upper_margin = 39, .lower_margin = 5, - .hsync_len = 64, .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 54: 720(1440)x576i @ 200Hz */ - {.refresh = 200, .xres = 1440, .yres = 576, .pixclock = 9259, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 55: 720(1440)x576i @ 200Hz */ - {.refresh = 200, .xres = 1440, .yres = 576, .pixclock = 9259, - .left_margin = 138, .right_margin = 24, - .upper_margin = 19, .lower_margin = 2, - .hsync_len = 126, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 56: 720x480p @ 239.76/240Hz */ - {.refresh = 239, .xres = 720, .yres = 480, .pixclock = 9259, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 57: 720x480p @ 239.76/240Hz */ - {.refresh = 239, .xres = 720, .yres = 480, .pixclock = 9259, - .left_margin = 60, .right_margin = 16, - .upper_margin = 30, .lower_margin = 9, - .hsync_len = 62, .vsync_len = 6, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED}, - /* 58: 720(1440)x480i @ 239.76/240Hz */ - {.refresh = 239, .xres = 1440, .yres = 480, .pixclock = 9259, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 59: 720(1440)x480i @ 239.76/240Hz */ - {.refresh = 239, .xres = 1440, .yres = 480, .pixclock = 9259, - .left_margin = 114, .right_margin = 38, - .upper_margin = 15, .lower_margin = 4, - .hsync_len = 124, .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_INTERLACED}, - /* 60: 1280x720p @ 23.97Hz/24Hz */ - {.refresh = 24, .xres = 1280, .yres = 720, .pixclock = 16835, - .left_margin = 220, .right_margin = 1760, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 61: 1280x720p @ 25Hz */ - {.refresh = 25, .xres = 1280, .yres = 720, .pixclock = 13468, - .left_margin = 220, .right_margin = 2420, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 62: 1280x720p @ 29.97Hz/30Hz */ - {.refresh = 30, .xres = 1280, .yres = 720, .pixclock = 13468, - .left_margin = 220, .right_margin = 1760, - .upper_margin = 20, .lower_margin = 5, - .hsync_len = 40, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 63: 1920x1080p @ 119.88/120Hz */ - {.refresh = 120, .xres = 1920, .yres = 1080, .pixclock = 3367, - .left_margin = 148, .right_margin = 88, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, - /* 64: 1920x1080p @ 100Hz */ - {.refresh = 100, .xres = 1920, .yres = 1080, .pixclock = 3367, - .left_margin = 148, .right_margin = 528, - .upper_margin = 36, .lower_margin = 4, - .hsync_len = 44, .vsync_len = 5, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED}, -}; -EXPORT_SYMBOL(cea_modes); #endif /* CONFIG_FB_MODE_HELPERS */ /** @@ -1376,7 +923,7 @@ int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head) if (!modelist) return -ENOMEM; modelist->mode = *mode; - list_add_tail(&modelist->list, head); + list_add(&modelist->list, head); } return 0; } diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig deleted file mode 100644 index c431cc670a46..000000000000 --- a/drivers/video/tegra/Kconfig +++ /dev/null @@ -1,74 +0,0 @@ -if ARCH_TEGRA - -comment "NVIDIA Tegra Display Driver options" - -config TEGRA_GRHOST - tristate "Tegra graphics host driver" - depends on TEGRA_IOVMM - default n - help - Driver for the Tegra graphics host hardware. - -config TEGRA_DC - tristate "Tegra Display Contoller" - depends on ARCH_TEGRA - select FB_MODE_HELPERS - select I2C - help - Tegra display controller support. - -config FB_TEGRA - tristate "Tegra Framebuffer driver" - depends on TEGRA_DC && FB = y - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default FB - help - Framebuffer device support for the Tegra display controller. - -config TEGRA_NVMAP - bool "Tegra GPU memory management driver (nvmap)" - default y - help - Say Y here to include the memory management driver for the Tegra - GPU, multimedia and display subsystems - -config NVMAP_RECLAIM_UNPINNED_VM - bool "Virtualize IOVMM memory in nvmap" - depends on TEGRA_NVMAP && TEGRA_IOVMM - default y - help - Say Y here to enable nvmap to reclaim I/O virtual memory after - it has been unpinned, and re-use it for other handles. This can - allow a larger virtual I/O VM space than would normally be - supported by the hardware, at a slight cost in performance. - -config NVMAP_ALLOW_SYSMEM - bool "Allow physical system memory to be used by nvmap" - depends on TEGRA_NVMAP - default y - help - Say Y here to allow nvmap to use physical system memory (i.e., - shared with the operating system but not translated through - an IOVMM device) for allocations. - -config NVMAP_HIGHMEM_ONLY - bool "Use only HIGHMEM for nvmap" - depends on TEGRA_NVMAP && (NVMAP_ALLOW_SYSMEM || TEGRA_IOVMM) && HIGHMEM - default n - help - Say Y here to restrict nvmap system memory allocations (both - physical system memory and IOVMM) to just HIGHMEM pages. - -config NVMAP_CARVEOUT_KILLER - bool "Reclaim nvmap carveout by killing processes" - depends on TEGRA_NVMAP - default n - help - Say Y here to allow the system to reclaim carveout space by killing - processes. This will kill the largest consumers of lowest priority - first. - -endif - diff --git a/drivers/video/tegra/Makefile b/drivers/video/tegra/Makefile deleted file mode 100644 index ef9e709303df..000000000000 --- a/drivers/video/tegra/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_TEGRA_GRHOST) += host/ -obj-$(CONFIG_TEGRA_DC) += dc/ -obj-$(CONFIG_FB_TEGRA) += fb.o -obj-$(CONFIG_TEGRA_NVMAP) += nvmap/ diff --git a/drivers/video/tegra/dc/Makefile b/drivers/video/tegra/dc/Makefile deleted file mode 100644 index 4567eba8cb93..000000000000 --- a/drivers/video/tegra/dc/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-y += dc.o -obj-y += rgb.o -obj-y += hdmi.o -obj-y += nvhdcp.o -obj-y += edid.o diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c deleted file mode 100644 index 53f52df2e0f8..000000000000 --- a/drivers/video/tegra/dc/dc.c +++ /dev/null @@ -1,1447 +0,0 @@ -/* - * drivers/video/tegra/dc/dc.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "dc_reg.h" -#include "dc_priv.h" - -static int no_vsync; - -module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR); - -struct tegra_dc *tegra_dcs[TEGRA_MAX_DC]; - -DEFINE_MUTEX(tegra_dc_lock); - -static inline int tegra_dc_fmt_bpp(int fmt) -{ - switch (fmt) { - case TEGRA_WIN_FMT_P1: - return 1; - - case TEGRA_WIN_FMT_P2: - return 2; - - case TEGRA_WIN_FMT_P4: - return 4; - - case TEGRA_WIN_FMT_P8: - return 8; - - case TEGRA_WIN_FMT_B4G4R4A4: - case TEGRA_WIN_FMT_B5G5R5A: - case TEGRA_WIN_FMT_B5G6R5: - case TEGRA_WIN_FMT_AB5G5R5: - return 16; - - case TEGRA_WIN_FMT_B8G8R8A8: - case TEGRA_WIN_FMT_R8G8B8A8: - case TEGRA_WIN_FMT_B6x2G6x2R6x2A8: - case TEGRA_WIN_FMT_R6x2G6x2B6x2A8: - return 32; - - /* for planar formats, size of the Y plane, 8bit */ - case TEGRA_WIN_FMT_YCbCr420P: - case TEGRA_WIN_FMT_YUV420P: - case TEGRA_WIN_FMT_YCbCr422P: - case TEGRA_WIN_FMT_YUV422P: - return 8; - - case TEGRA_WIN_FMT_YCbCr422: - case TEGRA_WIN_FMT_YUV422: - case TEGRA_WIN_FMT_YCbCr422R: - case TEGRA_WIN_FMT_YUV422R: - case TEGRA_WIN_FMT_YCbCr422RA: - case TEGRA_WIN_FMT_YUV422RA: - /* FIXME: need to know the bpp of these formats */ - return 0; - } - return 0; -} - -static inline bool tegra_dc_is_yuv_planar(int fmt) -{ - switch (fmt) { - case TEGRA_WIN_FMT_YUV420P: - case TEGRA_WIN_FMT_YCbCr420P: - case TEGRA_WIN_FMT_YCbCr422P: - case TEGRA_WIN_FMT_YUV422P: - return true; - } - return false; -} - -#define DUMP_REG(a) do { \ - snprintf(buff, sizeof(buff), "%-32s\t%03x\t%08lx\n", \ - #a, a, tegra_dc_readl(dc, a)); \ - print(data, buff); \ - } while (0) - -static void _dump_regs(struct tegra_dc *dc, void *data, - void (* print)(void *data, const char *str)) -{ - int i; - char buff[256]; - - tegra_dc_io_start(dc); - clk_enable(dc->clk); - - DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0); - DUMP_REG(DC_CMD_DISPLAY_COMMAND); - DUMP_REG(DC_CMD_SIGNAL_RAISE); - DUMP_REG(DC_CMD_INT_STATUS); - DUMP_REG(DC_CMD_INT_MASK); - DUMP_REG(DC_CMD_INT_ENABLE); - DUMP_REG(DC_CMD_INT_TYPE); - DUMP_REG(DC_CMD_INT_POLARITY); - DUMP_REG(DC_CMD_SIGNAL_RAISE1); - DUMP_REG(DC_CMD_SIGNAL_RAISE2); - DUMP_REG(DC_CMD_SIGNAL_RAISE3); - DUMP_REG(DC_CMD_STATE_ACCESS); - DUMP_REG(DC_CMD_STATE_CONTROL); - DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); - DUMP_REG(DC_CMD_REG_ACT_CONTROL); - - DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0); - DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1); - DUMP_REG(DC_DISP_DISP_WIN_OPTIONS); - DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY); - DUMP_REG(DC_DISP_MEM_HIGH_PRIORITY_TIMER); - DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS); - DUMP_REG(DC_DISP_REF_TO_SYNC); - DUMP_REG(DC_DISP_SYNC_WIDTH); - DUMP_REG(DC_DISP_BACK_PORCH); - DUMP_REG(DC_DISP_DISP_ACTIVE); - DUMP_REG(DC_DISP_FRONT_PORCH); - DUMP_REG(DC_DISP_H_PULSE0_CONTROL); - DUMP_REG(DC_DISP_H_PULSE0_POSITION_A); - DUMP_REG(DC_DISP_H_PULSE0_POSITION_B); - DUMP_REG(DC_DISP_H_PULSE0_POSITION_C); - DUMP_REG(DC_DISP_H_PULSE0_POSITION_D); - DUMP_REG(DC_DISP_H_PULSE1_CONTROL); - DUMP_REG(DC_DISP_H_PULSE1_POSITION_A); - DUMP_REG(DC_DISP_H_PULSE1_POSITION_B); - DUMP_REG(DC_DISP_H_PULSE1_POSITION_C); - DUMP_REG(DC_DISP_H_PULSE1_POSITION_D); - DUMP_REG(DC_DISP_H_PULSE2_CONTROL); - DUMP_REG(DC_DISP_H_PULSE2_POSITION_A); - DUMP_REG(DC_DISP_H_PULSE2_POSITION_B); - DUMP_REG(DC_DISP_H_PULSE2_POSITION_C); - DUMP_REG(DC_DISP_H_PULSE2_POSITION_D); - DUMP_REG(DC_DISP_V_PULSE0_CONTROL); - DUMP_REG(DC_DISP_V_PULSE0_POSITION_A); - DUMP_REG(DC_DISP_V_PULSE0_POSITION_B); - DUMP_REG(DC_DISP_V_PULSE0_POSITION_C); - DUMP_REG(DC_DISP_V_PULSE1_CONTROL); - DUMP_REG(DC_DISP_V_PULSE1_POSITION_A); - DUMP_REG(DC_DISP_V_PULSE1_POSITION_B); - DUMP_REG(DC_DISP_V_PULSE1_POSITION_C); - DUMP_REG(DC_DISP_V_PULSE2_CONTROL); - DUMP_REG(DC_DISP_V_PULSE2_POSITION_A); - DUMP_REG(DC_DISP_V_PULSE3_CONTROL); - DUMP_REG(DC_DISP_V_PULSE3_POSITION_A); - DUMP_REG(DC_DISP_M0_CONTROL); - DUMP_REG(DC_DISP_M1_CONTROL); - DUMP_REG(DC_DISP_DI_CONTROL); - DUMP_REG(DC_DISP_PP_CONTROL); - DUMP_REG(DC_DISP_PP_SELECT_A); - DUMP_REG(DC_DISP_PP_SELECT_B); - DUMP_REG(DC_DISP_PP_SELECT_C); - DUMP_REG(DC_DISP_PP_SELECT_D); - DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL); - DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL); - DUMP_REG(DC_DISP_DISP_COLOR_CONTROL); - DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS); - DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS); - DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS); - DUMP_REG(DC_DISP_LCD_SPI_OPTIONS); - DUMP_REG(DC_DISP_BORDER_COLOR); - DUMP_REG(DC_DISP_COLOR_KEY0_LOWER); - DUMP_REG(DC_DISP_COLOR_KEY0_UPPER); - DUMP_REG(DC_DISP_COLOR_KEY1_LOWER); - DUMP_REG(DC_DISP_COLOR_KEY1_UPPER); - DUMP_REG(DC_DISP_CURSOR_FOREGROUND); - DUMP_REG(DC_DISP_CURSOR_BACKGROUND); - DUMP_REG(DC_DISP_CURSOR_START_ADDR); - DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS); - DUMP_REG(DC_DISP_CURSOR_POSITION); - DUMP_REG(DC_DISP_CURSOR_POSITION_NS); - DUMP_REG(DC_DISP_INIT_SEQ_CONTROL); - DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A); - DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B); - DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C); - DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D); - DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL); - DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST); - DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST); - DUMP_REG(DC_DISP_MCCIF_DISPLAY0C_HYST); - DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST); - DUMP_REG(DC_DISP_DAC_CRT_CTRL); - DUMP_REG(DC_DISP_DISP_MISC_CONTROL); - - - for (i = 0; i < 3; i++) { - print(data, "\n"); - snprintf(buff, sizeof(buff), "WINDOW %c:\n", 'A' + i); - print(data, buff); - - tegra_dc_writel(dc, WINDOW_A_SELECT << i, - DC_CMD_DISPLAY_WINDOW_HEADER); - DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); - DUMP_REG(DC_WIN_WIN_OPTIONS); - DUMP_REG(DC_WIN_BYTE_SWAP); - DUMP_REG(DC_WIN_BUFFER_CONTROL); - DUMP_REG(DC_WIN_COLOR_DEPTH); - DUMP_REG(DC_WIN_POSITION); - DUMP_REG(DC_WIN_SIZE); - DUMP_REG(DC_WIN_PRESCALED_SIZE); - DUMP_REG(DC_WIN_H_INITIAL_DDA); - DUMP_REG(DC_WIN_V_INITIAL_DDA); - DUMP_REG(DC_WIN_DDA_INCREMENT); - DUMP_REG(DC_WIN_LINE_STRIDE); - DUMP_REG(DC_WIN_BUF_STRIDE); - DUMP_REG(DC_WIN_UV_BUF_STRIDE); - DUMP_REG(DC_WIN_BLEND_NOKEY); - DUMP_REG(DC_WIN_BLEND_1WIN); - DUMP_REG(DC_WIN_BLEND_2WIN_X); - DUMP_REG(DC_WIN_BLEND_2WIN_Y); - DUMP_REG(DC_WIN_BLEND_3WIN_XY); - DUMP_REG(DC_WINBUF_START_ADDR); - DUMP_REG(DC_WINBUF_START_ADDR_U); - DUMP_REG(DC_WINBUF_START_ADDR_V); - DUMP_REG(DC_WINBUF_ADDR_H_OFFSET); - DUMP_REG(DC_WINBUF_ADDR_V_OFFSET); - DUMP_REG(DC_WINBUF_UFLOW_STATUS); - DUMP_REG(DC_WIN_CSC_YOF); - DUMP_REG(DC_WIN_CSC_KYRGB); - DUMP_REG(DC_WIN_CSC_KUR); - DUMP_REG(DC_WIN_CSC_KVR); - DUMP_REG(DC_WIN_CSC_KUG); - DUMP_REG(DC_WIN_CSC_KVG); - DUMP_REG(DC_WIN_CSC_KUB); - DUMP_REG(DC_WIN_CSC_KVB); - } - - clk_disable(dc->clk); - tegra_dc_io_end(dc); -} - -#undef DUMP_REG - -#ifdef DEBUG -static void dump_regs_print(void *data, const char *str) -{ - struct tegra_dc *dc = data; - dev_dbg(&dc->ndev->dev, "%s", str); -} - -static void dump_regs(struct tegra_dc *dc) -{ - _dump_regs(dc, dc, dump_regs_print); -} -#else - -static void dump_regs(struct tegra_dc *dc) {} - -#endif - -#ifdef CONFIG_DEBUG_FS - -static void dbg_regs_print(void *data, const char *str) -{ - struct seq_file *s = data; - - seq_printf(s, "%s", str); -} - -#undef DUMP_REG - -static int dbg_dc_show(struct seq_file *s, void *unused) -{ - struct tegra_dc *dc = s->private; - - _dump_regs(dc, s, dbg_regs_print); - - return 0; -} - - -static int dbg_dc_open(struct inode *inode, struct file *file) -{ - return single_open(file, dbg_dc_show, inode->i_private); -} - -static const struct file_operations dbg_fops = { - .open = dbg_dc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void tegra_dc_dbg_add(struct tegra_dc *dc) -{ - char name[32]; - - snprintf(name, sizeof(name), "tegra_dc%d_regs", dc->ndev->id); - (void) debugfs_create_file(name, S_IRUGO, NULL, dc, &dbg_fops); -} -#else -static void tegra_dc_dbg_add(struct tegra_dc *dc) {} - -#endif - - -static int tegra_dc_add(struct tegra_dc *dc, int index) -{ - int ret = 0; - - mutex_lock(&tegra_dc_lock); - if (index >= TEGRA_MAX_DC) { - ret = -EINVAL; - goto out; - } - - if (tegra_dcs[index] != NULL) { - ret = -EBUSY; - goto out; - } - - tegra_dcs[index] = dc; - -out: - mutex_unlock(&tegra_dc_lock); - - return ret; -} - -struct tegra_dc *tegra_dc_get_dc(unsigned idx) -{ - if (idx < TEGRA_MAX_DC) - return tegra_dcs[idx]; - else - return NULL; -} -EXPORT_SYMBOL(tegra_dc_get_dc); - -struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win) -{ - if (win >= dc->n_windows) - return NULL; - - return &dc->windows[win]; -} -EXPORT_SYMBOL(tegra_dc_get_window); - -static int get_topmost_window(u32 *depths, unsigned long *wins) -{ - int idx, best = -1; - - for_each_set_bit(idx, wins, DC_N_WINDOWS) { - if (best == -1 || depths[idx] < depths[best]) - best = idx; - } - clear_bit(best, wins); - return best; -} - -static u32 blend_topwin(u32 flags) -{ - if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE) - return BLEND(NOKEY, ALPHA, 0xff, 0xff); - else if (flags & TEGRA_WIN_FLAG_BLEND_PREMULT) - return BLEND(NOKEY, PREMULT, 0xff, 0xff); - else - return BLEND(NOKEY, FIX, 0xff, 0xff); -} - -static u32 blend_2win(int idx, unsigned long behind_mask, u32* flags, int xy) -{ - int other; - - for (other = 0; other < DC_N_WINDOWS; other++) { - if (other != idx && (xy-- == 0)) - break; - } - if (BIT(other) & behind_mask) - return blend_topwin(flags[idx]); - else if (flags[other]) - return BLEND(NOKEY, DEPENDANT, 0x00, 0x00); - else - return BLEND(NOKEY, FIX, 0x00, 0x00); -} - -static u32 blend_3win(int idx, unsigned long behind_mask, u32* flags) -{ - unsigned long infront_mask; - int first; - - infront_mask = ~(behind_mask | BIT(idx)); - infront_mask &= (BIT(DC_N_WINDOWS) - 1); - first = ffs(infront_mask) - 1; - - if (!infront_mask) - return blend_topwin(flags[idx]); - else if (behind_mask && first != -1 && flags[first]) - return BLEND(NOKEY, DEPENDANT, 0x00, 0x00); - else - return BLEND(NOKEY, FIX, 0x0, 0x0); -} - -static void tegra_dc_set_blending(struct tegra_dc *dc, struct tegra_dc_blend *blend) -{ - unsigned long mask = BIT(DC_N_WINDOWS) - 1; - - while (mask) { - int idx = get_topmost_window(blend->z, &mask); - - tegra_dc_writel(dc, WINDOW_A_SELECT << idx, - DC_CMD_DISPLAY_WINDOW_HEADER); - tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), - DC_WIN_BLEND_NOKEY); - tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), - DC_WIN_BLEND_1WIN); - tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0), - DC_WIN_BLEND_2WIN_X); - tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1), - DC_WIN_BLEND_2WIN_Y); - tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags), - DC_WIN_BLEND_3WIN_XY); - } -} - -static void tegra_dc_set_csc(struct tegra_dc *dc) -{ - tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF); - tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB); - tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR); - tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR); - tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG); - tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG); - tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB); - tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB); -} - -static void tegra_dc_set_scaling_filter(struct tegra_dc *dc) -{ - unsigned i; - unsigned v0 = 128; - unsigned v1 = 0; - /* linear horizontal and vertical filters */ - for (i = 0; i < 16; i++) { - tegra_dc_writel(dc, (v1 << 16) | (v0 << 8), - DC_WIN_H_FILTER_P(i)); - - tegra_dc_writel(dc, v0, - DC_WIN_V_FILTER_P(i)); - v0 -= 8; - v1 += 8; - } -} - -/* does not support updating windows on multiple dcs in one call */ -int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) -{ - struct tegra_dc *dc; - unsigned long update_mask = GENERAL_ACT_REQ; - unsigned long val; - bool update_blend = false; - int i; - - dc = windows[0]->dc; - - mutex_lock(&dc->lock); - - if (!dc->enabled) { - mutex_unlock(&dc->lock); - return -EFAULT; - } - - if (no_vsync) - tegra_dc_writel(dc, WRITE_MUX_ACTIVE | READ_MUX_ACTIVE, DC_CMD_STATE_ACCESS); - else - tegra_dc_writel(dc, WRITE_MUX_ASSEMBLY | READ_MUX_ASSEMBLY, DC_CMD_STATE_ACCESS); - - for (i = 0; i < n; i++) { - struct tegra_dc_win *win = windows[i]; - unsigned h_dda; - unsigned v_dda; - unsigned h_offset; - unsigned v_offset; - bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0; - bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0; - bool yuvp = tegra_dc_is_yuv_planar(win->fmt); - - if (win->z != dc->blend.z[win->idx]) { - dc->blend.z[win->idx] = win->z; - update_blend = true; - } - if ((win->flags & TEGRA_WIN_BLEND_FLAGS_MASK) != - dc->blend.flags[win->idx]) { - dc->blend.flags[win->idx] = - win->flags & TEGRA_WIN_BLEND_FLAGS_MASK; - update_blend = true; - } - - tegra_dc_writel(dc, WINDOW_A_SELECT << win->idx, - DC_CMD_DISPLAY_WINDOW_HEADER); - - if (!no_vsync) - update_mask |= WIN_A_ACT_REQ << win->idx; - - if (!(win->flags & TEGRA_WIN_FLAG_ENABLED)) { - tegra_dc_writel(dc, 0, DC_WIN_WIN_OPTIONS); - continue; - } - - tegra_dc_writel(dc, win->fmt, DC_WIN_COLOR_DEPTH); - tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP); - - tegra_dc_writel(dc, - V_POSITION(win->out_y) | H_POSITION(win->out_x), - DC_WIN_POSITION); - tegra_dc_writel(dc, - V_SIZE(win->out_h) | H_SIZE(win->out_w), - DC_WIN_SIZE); - tegra_dc_writel(dc, - V_PRESCALED_SIZE(win->h) | - H_PRESCALED_SIZE(win->w * tegra_dc_fmt_bpp(win->fmt) / 8), - DC_WIN_PRESCALED_SIZE); - - h_dda = ((win->w - 1) * 0x1000) / max_t(int, win->out_w - 1, 1); - v_dda = ((win->h - 1) * 0x1000) / max_t(int, win->out_h - 1, 1); - tegra_dc_writel(dc, V_DDA_INC(v_dda) | H_DDA_INC(h_dda), - DC_WIN_DDA_INCREMENT); - tegra_dc_writel(dc, 0, DC_WIN_H_INITIAL_DDA); - tegra_dc_writel(dc, 0, DC_WIN_V_INITIAL_DDA); - - tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE); - tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE); - tegra_dc_writel(dc, (unsigned long)win->phys_addr, - DC_WINBUF_START_ADDR); - - if (!yuvp) { - tegra_dc_writel(dc, win->stride, DC_WIN_LINE_STRIDE); - } else { - tegra_dc_writel(dc, - (unsigned long)win->phys_addr + - (unsigned long)win->offset_u, - DC_WINBUF_START_ADDR_U); - tegra_dc_writel(dc, - (unsigned long)win->phys_addr + - (unsigned long)win->offset_v, - DC_WINBUF_START_ADDR_V); - tegra_dc_writel(dc, - LINE_STRIDE(win->stride) | - UV_LINE_STRIDE(win->stride_uv), - DC_WIN_LINE_STRIDE); - } - - h_offset = win->x; - if (invert_h) { - h_offset += win->w - 1; - } - h_offset *= tegra_dc_fmt_bpp(win->fmt) / 8; - - v_offset = win->y; - if (invert_v) { - v_offset += win->h - 1; - } - - tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); - tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); - - if (win->flags & TEGRA_WIN_FLAG_TILED) - tegra_dc_writel(dc, - DC_WIN_BUFFER_ADDR_MODE_TILE | - DC_WIN_BUFFER_ADDR_MODE_TILE_UV, - DC_WIN_BUFFER_ADDR_MODE); - else - tegra_dc_writel(dc, - DC_WIN_BUFFER_ADDR_MODE_LINEAR | - DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV, - DC_WIN_BUFFER_ADDR_MODE); - - val = WIN_ENABLE; - if (yuvp) - val |= CSC_ENABLE; - else if (tegra_dc_fmt_bpp(win->fmt) < 24) - val |= COLOR_EXPAND; - - if (win->w != win->out_w) - val |= H_FILTER_ENABLE; - if (win->h != win->out_h) - val |= V_FILTER_ENABLE; - - if (invert_h) - val |= H_DIRECTION_DECREMENT; - if (invert_v) - val |= V_DIRECTION_DECREMENT; - - tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS); - - win->dirty = no_vsync ? 0 : 1; - } - - if (update_blend) { - tegra_dc_set_blending(dc, &dc->blend); - for (i = 0; i < DC_N_WINDOWS; i++) { - if (!no_vsync) - dc->windows[i].dirty = 1; - update_mask |= WIN_A_ACT_REQ << i; - } - } - - tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL); - - if (!no_vsync) { - val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val |= FRAME_END_INT; - tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); - - val = tegra_dc_readl(dc, DC_CMD_INT_MASK); - val |= FRAME_END_INT; - tegra_dc_writel(dc, val, DC_CMD_INT_MASK); - } - - tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL); - mutex_unlock(&dc->lock); - - return 0; -} -EXPORT_SYMBOL(tegra_dc_update_windows); - -u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc) -{ - return dc->syncpt_id; -} -EXPORT_SYMBOL(tegra_dc_get_syncpt_id); - -u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc) -{ - u32 max; - - mutex_lock(&dc->lock); - max = nvhost_syncpt_incr_max(&dc->ndev->host->syncpt, dc->syncpt_id, 1); - dc->syncpt_max = max; - mutex_unlock(&dc->lock); - - return max; -} - -void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, u32 val) -{ - mutex_lock(&dc->lock); - while (dc->syncpt_min < val) { - dc->syncpt_min++; - nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt, dc->syncpt_id); - } - mutex_unlock(&dc->lock); -} - -static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[], - int n) -{ - int i; - - for (i = 0; i < n; i++) { - if (windows[i]->dirty) - return false; - } - - return true; -} - -/* does not support syncing windows on multiple dcs in one call */ -int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n) -{ - if (n < 1 || n > DC_N_WINDOWS) - return -EINVAL; - - if (!windows[0]->dc->enabled) - return -EFAULT; - - return wait_event_interruptible_timeout(windows[0]->dc->wq, - tegra_dc_windows_are_clean(windows, n), - HZ); -} -EXPORT_SYMBOL(tegra_dc_sync_windows); - -static unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk) -{ - unsigned long rate; - unsigned long div; - - rate = clk_get_rate(dc->clk); - - div = DIV_ROUND_CLOSEST(rate * 2, pclk); - - if (div < 2) - return 0; - - return rate * 2 / div; -} - -void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk) -{ - int pclk; - - if (dc->out->type == TEGRA_DC_OUT_HDMI) { - unsigned long rate; - struct clk *pll_d_out0_clk = - clk_get_sys(NULL, "pll_d_out0"); - struct clk *pll_d_clk = - clk_get_sys(NULL, "pll_d"); - - if (dc->mode.pclk > 70000000) - rate = 594000000; - else - rate = 216000000; - - if (rate != clk_get_rate(pll_d_clk)) - clk_set_rate(pll_d_clk, rate); - - if (clk_get_parent(clk) != pll_d_out0_clk) - clk_set_parent(clk, pll_d_out0_clk); - } - - pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk); - tegra_dvfs_set_rate(clk, pclk); - -} - -static int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode) -{ - unsigned long val; - unsigned long rate; - unsigned long div; - unsigned long pclk; - - tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS); - tegra_dc_writel(dc, mode->h_ref_to_sync | (mode->v_ref_to_sync << 16), - DC_DISP_REF_TO_SYNC); - tegra_dc_writel(dc, mode->h_sync_width | (mode->v_sync_width << 16), - DC_DISP_SYNC_WIDTH); - tegra_dc_writel(dc, mode->h_back_porch | (mode->v_back_porch << 16), - DC_DISP_BACK_PORCH); - tegra_dc_writel(dc, mode->h_active | (mode->v_active << 16), - DC_DISP_DISP_ACTIVE); - tegra_dc_writel(dc, mode->h_front_porch | (mode->v_front_porch << 16), - DC_DISP_FRONT_PORCH); - - tegra_dc_writel(dc, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL, - DC_DISP_DATA_ENABLE_OPTIONS); - - val = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY1); - if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_V_SYNC) - val |= PIN1_LVS_OUTPUT; - else - val &= ~PIN1_LVS_OUTPUT; - - if (mode->flags & TEGRA_DC_MODE_FLAG_NEG_H_SYNC) - val |= PIN1_LHS_OUTPUT; - else - val &= ~PIN1_LHS_OUTPUT; - tegra_dc_writel(dc, val, DC_COM_PIN_OUTPUT_POLARITY1); - - /* TODO: MIPI/CRT/HDMI clock cals */ - - val = DISP_DATA_FORMAT_DF1P1C; - - if (dc->out->align == TEGRA_DC_ALIGN_MSB) - val |= DISP_DATA_ALIGNMENT_MSB; - else - val |= DISP_DATA_ALIGNMENT_LSB; - - if (dc->out->order == TEGRA_DC_ORDER_RED_BLUE) - val |= DISP_DATA_ORDER_RED_BLUE; - else - val |= DISP_DATA_ORDER_BLUE_RED; - - tegra_dc_writel(dc, val, DC_DISP_DISP_INTERFACE_CONTROL); - - rate = clk_get_rate(dc->clk); - - pclk = tegra_dc_pclk_round_rate(dc, mode->pclk); - if (pclk < (mode->pclk / 100 * 99) || - pclk > (mode->pclk / 100 * 109)) { - dev_err(&dc->ndev->dev, - "can't divide %ld clock to %d -1/+9%% %ld %d %d\n", - rate, mode->pclk, - pclk, (mode->pclk / 100 * 99), - (mode->pclk / 100 * 109)); - return -EINVAL; - } - - div = (rate * 2 / pclk) - 2; - - tegra_dc_writel(dc, 0x00010001, - DC_DISP_SHIFT_CLOCK_OPTIONS); - tegra_dc_writel(dc, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(div), - DC_DISP_DISP_CLOCK_CONTROL); - - return 0; -} - - -int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode) -{ - memcpy(&dc->mode, mode, sizeof(dc->mode)); - - return 0; -} -EXPORT_SYMBOL(tegra_dc_set_mode); - -static void tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out) -{ - dc->out = out; - - if (out->n_modes > 0) - tegra_dc_set_mode(dc, &dc->out->modes[0]); - - switch (out->type) { - case TEGRA_DC_OUT_RGB: - dc->out_ops = &tegra_dc_rgb_ops; - break; - - case TEGRA_DC_OUT_HDMI: - dc->out_ops = &tegra_dc_hdmi_ops; - break; - - default: - dc->out_ops = NULL; - break; - } - - if (dc->out_ops && dc->out_ops->init) - dc->out_ops->init(dc); - -} - -unsigned tegra_dc_get_out_height(struct tegra_dc *dc) -{ - if (dc->out) - return dc->out->height; - else - return 0; -} -EXPORT_SYMBOL(tegra_dc_get_out_height); - -unsigned tegra_dc_get_out_width(struct tegra_dc *dc) -{ - if (dc->out) - return dc->out->width; - else - return 0; -} -EXPORT_SYMBOL(tegra_dc_get_out_width); - -static irqreturn_t tegra_dc_irq(int irq, void *ptr) -{ - struct tegra_dc *dc = ptr; - unsigned long status; - unsigned long val; - unsigned long underflow_mask; - int i; - - status = tegra_dc_readl(dc, DC_CMD_INT_STATUS); - tegra_dc_writel(dc, status, DC_CMD_INT_STATUS); - - if (status & FRAME_END_INT) { - int completed = 0; - int dirty = 0; - - val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); - for (i = 0; i < DC_N_WINDOWS; i++) { - if (!(val & (WIN_A_UPDATE << i))) { - dc->windows[i].dirty = 0; - completed = 1; - } else { - dirty = 1; - } - } - - if (!dirty) { - val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val &= ~FRAME_END_INT; - tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); - } - - if (completed) - wake_up(&dc->wq); - } - - - /* - * Overlays can get thier internal state corrupted during and underflow - * condition. The only way to fix this state is to reset the DC. - * if we get 4 consecutive frames with underflows, assume we're - * hosed and reset. - */ - underflow_mask = status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT); - if (underflow_mask) { - val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val |= V_BLANK_INT; - tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); - dc->underflow_mask |= underflow_mask; - } - - if (status & V_BLANK_INT) { - int i; - - for (i = 0; i< DC_N_WINDOWS; i++) { - if (dc->underflow_mask & (WIN_A_UF_INT <windows[i].underflows++; - - if (dc->windows[i].underflows > 4) - schedule_work(&dc->reset_work); - } else { - dc->windows[i].underflows = 0; - } - } - - if (!dc->underflow_mask) { - val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val &= ~V_BLANK_INT; - tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); - } - - dc->underflow_mask = 0; - } - - - return IRQ_HANDLED; -} - -static void tegra_dc_set_color_control(struct tegra_dc *dc) -{ - u32 color_control; - - switch (dc->out->depth) { - case 3: - color_control = BASE_COLOR_SIZE111; - break; - - case 6: - color_control = BASE_COLOR_SIZE222; - break; - - case 8: - color_control = BASE_COLOR_SIZE332; - break; - - case 9: - color_control = BASE_COLOR_SIZE333; - break; - - case 12: - color_control = BASE_COLOR_SIZE444; - break; - - case 15: - color_control = BASE_COLOR_SIZE555; - break; - - case 16: - color_control = BASE_COLOR_SIZE565; - break; - - case 18: - color_control = BASE_COLOR_SIZE666; - break; - - default: - color_control = BASE_COLOR_SIZE888; - break; - } - - tegra_dc_writel(dc, color_control, DC_DISP_DISP_COLOR_CONTROL); -} - -static void tegra_dc_init(struct tegra_dc *dc) -{ - u32 disp_syncpt; - u32 vblank_syncpt; - int i; - - tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); - if (dc->ndev->id == 0) { - disp_syncpt = NVSYNCPT_DISP0; - vblank_syncpt = NVSYNCPT_VBLANK0; - - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0A, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0B, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0C, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1B, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHC, - TEGRA_MC_PRIO_HIGH); - } else if (dc->ndev->id == 1) { - disp_syncpt = NVSYNCPT_DISP1; - vblank_syncpt = NVSYNCPT_VBLANK1; - - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0AB, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0BB, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0CB, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY1BB, - TEGRA_MC_PRIO_MED); - tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAYHCB, - TEGRA_MC_PRIO_HIGH); - } - tegra_dc_writel(dc, 0x00000100 | vblank_syncpt, DC_CMD_CONT_SYNCPT_VSYNC); - tegra_dc_writel(dc, 0x00004700, DC_CMD_INT_TYPE); - tegra_dc_writel(dc, 0x0001c700, DC_CMD_INT_POLARITY); - tegra_dc_writel(dc, 0x00202020, DC_DISP_MEM_HIGH_PRIORITY); - tegra_dc_writel(dc, 0x00010101, DC_DISP_MEM_HIGH_PRIORITY_TIMER); - - tegra_dc_writel(dc, (FRAME_END_INT | - V_BLANK_INT | - WIN_A_UF_INT | - WIN_B_UF_INT | - WIN_C_UF_INT), DC_CMD_INT_MASK); - tegra_dc_writel(dc, (WIN_A_UF_INT | - WIN_B_UF_INT | - WIN_C_UF_INT), DC_CMD_INT_ENABLE); - - tegra_dc_writel(dc, 0x00000000, DC_DISP_BORDER_COLOR); - - tegra_dc_set_color_control(dc); - for (i = 0; i < DC_N_WINDOWS; i++) { - tegra_dc_writel(dc, WINDOW_A_SELECT << i, - DC_CMD_DISPLAY_WINDOW_HEADER); - tegra_dc_set_csc(dc); - tegra_dc_set_scaling_filter(dc); - } - - - dc->syncpt_id = disp_syncpt; - - dc->syncpt_min = dc->syncpt_max = - nvhost_syncpt_read(&dc->ndev->host->syncpt, disp_syncpt); - - if (dc->mode.pclk) - tegra_dc_program_mode(dc, &dc->mode); -} - -static bool _tegra_dc_enable(struct tegra_dc *dc) -{ - if (dc->mode.pclk == 0) - return false; - - tegra_dc_io_start(dc); - - if (dc->out && dc->out->enable) - dc->out->enable(); - - tegra_dc_setup_clk(dc, dc->clk); - clk_enable(dc->clk); - clk_enable(dc->emc_clk); - tegra_periph_reset_deassert(dc->clk); - msleep(10); - - enable_irq(dc->irq); - - tegra_dc_init(dc); - - if (dc->out_ops && dc->out_ops->enable) - dc->out_ops->enable(dc); - - /* force a full blending update */ - dc->blend.z[0] = -1; - - return true; -} - -void tegra_dc_enable(struct tegra_dc *dc) -{ - mutex_lock(&dc->lock); - - if (!dc->enabled) - dc->enabled = _tegra_dc_enable(dc); - - mutex_unlock(&dc->lock); -} - -static void _tegra_dc_disable(struct tegra_dc *dc) -{ - disable_irq(dc->irq); - - if (dc->out_ops && dc->out_ops->disable) - dc->out_ops->disable(dc); - - clk_disable(dc->emc_clk); - clk_disable(dc->clk); - tegra_dvfs_set_rate(dc->clk, 0); - - if (dc->out && dc->out->disable) - dc->out->disable(); - - /* flush any pending syncpt waits */ - while (dc->syncpt_min < dc->syncpt_max) { - dc->syncpt_min++; - nvhost_syncpt_cpu_incr(&dc->ndev->host->syncpt, dc->syncpt_id); - } - - tegra_dc_io_end(dc); -} - - -void tegra_dc_disable(struct tegra_dc *dc) -{ - mutex_lock(&dc->lock); - - if (dc->enabled) { - dc->enabled = false; - - if (!dc->suspended) - _tegra_dc_disable(dc); - } - - mutex_unlock(&dc->lock); -} - -static void tegra_dc_reset_worker(struct work_struct *work) -{ - struct tegra_dc *dc = - container_of(work, struct tegra_dc, reset_work); - - dev_warn(&dc->ndev->dev, "overlay stuck in underflow state. resetting.\n"); - - mutex_lock(&dc->lock); - if (dc->enabled && !dc->suspended) { - _tegra_dc_disable(dc); - - /* A necessary wait. */ - msleep(100); - tegra_periph_reset_assert(dc->clk); - - /* _tegra_dc_enable deasserts reset */ - _tegra_dc_enable(dc); - } - mutex_unlock(&dc->lock); -} - - -static int tegra_dc_probe(struct nvhost_device *ndev) -{ - struct tegra_dc *dc; - struct clk *clk; - struct clk *emc_clk; - struct resource *res; - struct resource *base_res; - struct resource *fb_mem = NULL; - int ret = 0; - void __iomem *base; - int irq; - int i; - unsigned long emc_clk_rate; - - if (!ndev->dev.platform_data) { - dev_err(&ndev->dev, "no platform data\n"); - return -ENOENT; - } - - dc = kzalloc(sizeof(struct tegra_dc), GFP_KERNEL); - if (!dc) { - dev_err(&ndev->dev, "can't allocate memory for tegra_dc\n"); - return -ENOMEM; - } - - irq = nvhost_get_irq_byname(ndev, "irq"); - if (irq <= 0) { - dev_err(&ndev->dev, "no irq\n"); - ret = -ENOENT; - goto err_free; - } - - res = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "regs"); - if (!res) { - dev_err(&ndev->dev, "no mem resource\n"); - ret = -ENOENT; - goto err_free; - } - - base_res = request_mem_region(res->start, resource_size(res), ndev->name); - if (!base_res) { - dev_err(&ndev->dev, "request_mem_region failed\n"); - ret = -EBUSY; - goto err_free; - } - - base = ioremap(res->start, resource_size(res)); - if (!base) { - dev_err(&ndev->dev, "registers can't be mapped\n"); - ret = -EBUSY; - goto err_release_resource_reg; - } - - fb_mem = nvhost_get_resource_byname(ndev, IORESOURCE_MEM, "fbmem"); - - clk = clk_get(&ndev->dev, NULL); - if (IS_ERR_OR_NULL(clk)) { - dev_err(&ndev->dev, "can't get clock\n"); - ret = -ENOENT; - goto err_iounmap_reg; - } - - emc_clk = clk_get(&ndev->dev, "emc"); - if (IS_ERR_OR_NULL(emc_clk)) { - dev_err(&ndev->dev, "can't get emc clock\n"); - ret = -ENOENT; - goto err_put_clk; - } - - dc->clk = clk; - dc->emc_clk = emc_clk; - dc->base_res = base_res; - dc->base = base; - dc->irq = irq; - dc->ndev = ndev; - dc->pdata = ndev->dev.platform_data; - - /* - * The emc is a shared clock, it will be set based on - * the requirements for each user on the bus. - */ - emc_clk_rate = dc->pdata->emc_clk_rate; - clk_set_rate(emc_clk, emc_clk_rate ? emc_clk_rate : ULONG_MAX); - - if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED) - dc->enabled = true; - - mutex_init(&dc->lock); - init_waitqueue_head(&dc->wq); - INIT_WORK(&dc->reset_work, tegra_dc_reset_worker); - - dc->n_windows = DC_N_WINDOWS; - for (i = 0; i < dc->n_windows; i++) { - dc->windows[i].idx = i; - dc->windows[i].dc = dc; - } - - if (request_irq(irq, tegra_dc_irq, IRQF_DISABLED, - dev_name(&ndev->dev), dc)) { - dev_err(&ndev->dev, "request_irq %d failed\n", irq); - ret = -EBUSY; - goto err_put_emc_clk; - } - - /* hack to ballence enable_irq calls in _tegra_dc_enable() */ - disable_irq(dc->irq); - - ret = tegra_dc_add(dc, ndev->id); - if (ret < 0) { - dev_err(&ndev->dev, "can't add dc\n"); - goto err_free_irq; - } - - nvhost_set_drvdata(ndev, dc); - - if (dc->pdata->default_out) - tegra_dc_set_out(dc, dc->pdata->default_out); - else - dev_err(&ndev->dev, "No default output specified. Leaving output disabled.\n"); - - if (dc->enabled) - _tegra_dc_enable(dc); - - tegra_dc_dbg_add(dc); - - dev_info(&ndev->dev, "probed\n"); - - if (dc->pdata->fb) { - if (dc->pdata->fb->bits_per_pixel == -1) { - unsigned long fmt; - tegra_dc_writel(dc, - WINDOW_A_SELECT << dc->pdata->fb->win, - DC_CMD_DISPLAY_WINDOW_HEADER); - - fmt = tegra_dc_readl(dc, DC_WIN_COLOR_DEPTH); - dc->pdata->fb->bits_per_pixel = - tegra_dc_fmt_bpp(fmt); - } - - dc->fb = tegra_fb_register(ndev, dc, dc->pdata->fb, fb_mem); - if (IS_ERR_OR_NULL(dc->fb)) - dc->fb = NULL; - } - - if (dc->out_ops && dc->out_ops->detect) - dc->out_ops->detect(dc); - - return 0; - -err_free_irq: - free_irq(irq, dc); -err_put_emc_clk: - clk_put(emc_clk); -err_put_clk: - clk_put(clk); -err_iounmap_reg: - iounmap(base); - if (fb_mem) - release_resource(fb_mem); -err_release_resource_reg: - release_resource(base_res); -err_free: - kfree(dc); - - return ret; -} - -static int tegra_dc_remove(struct nvhost_device *ndev) -{ - struct tegra_dc *dc = nvhost_get_drvdata(ndev); - - if (dc->fb) { - tegra_fb_unregister(dc->fb); - if (dc->fb_mem) - release_resource(dc->fb_mem); - } - - - if (dc->enabled) - _tegra_dc_disable(dc); - - free_irq(dc->irq, dc); - clk_put(dc->emc_clk); - clk_put(dc->clk); - iounmap(dc->base); - if (dc->fb_mem) - release_resource(dc->base_res); - kfree(dc); - return 0; -} - -#ifdef CONFIG_PM -static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state) -{ - struct tegra_dc *dc = nvhost_get_drvdata(ndev); - - dev_info(&ndev->dev, "suspend\n"); - - mutex_lock(&dc->lock); - - if (dc->out_ops && dc->out_ops->suspend) - dc->out_ops->suspend(dc); - - if (dc->enabled) { - tegra_fb_suspend(dc->fb); - _tegra_dc_disable(dc); - - dc->suspended = true; - } - mutex_unlock(&dc->lock); - - return 0; -} - -static int tegra_dc_resume(struct nvhost_device *ndev) -{ - struct tegra_dc *dc = nvhost_get_drvdata(ndev); - - dev_info(&ndev->dev, "resume\n"); - - mutex_lock(&dc->lock); - dc->suspended = false; - - if (dc->enabled) - _tegra_dc_enable(dc); - - if (dc->out_ops && dc->out_ops->resume) - dc->out_ops->resume(dc); - mutex_unlock(&dc->lock); - - return 0; -} - -#endif - -extern int suspend_set(const char *val, struct kernel_param *kp) -{ - if (!strcmp(val, "dump")) - dump_regs(tegra_dcs[0]); -#ifdef CONFIG_PM - else if (!strcmp(val, "suspend")) - tegra_dc_suspend(tegra_dcs[0]->ndev, PMSG_SUSPEND); - else if (!strcmp(val, "resume")) - tegra_dc_resume(tegra_dcs[0]->ndev); -#endif - - return 0; -} - -extern int suspend_get(char *buffer, struct kernel_param *kp) -{ - return 0; -} - -int suspend; - -module_param_call(suspend, suspend_set, suspend_get, &suspend, 0644); - -struct nvhost_driver tegra_dc_driver = { - .driver = { - .name = "tegradc", - .owner = THIS_MODULE, - }, - .probe = tegra_dc_probe, - .remove = tegra_dc_remove, -#ifdef CONFIG_PM - .suspend = tegra_dc_suspend, - .resume = tegra_dc_resume, -#endif -}; - -static int __init tegra_dc_module_init(void) -{ - return nvhost_driver_register(&tegra_dc_driver); -} - -static void __exit tegra_dc_module_exit(void) -{ - nvhost_driver_unregister(&tegra_dc_driver); -} - -module_exit(tegra_dc_module_exit); -module_init(tegra_dc_module_init); diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h deleted file mode 100644 index c8476f8b5ffc..000000000000 --- a/drivers/video/tegra/dc/dc_priv.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * drivers/video/tegra/dc/dc_priv.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H -#define __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_H - -#include -#include -#include -#include -#include "../host/dev.h" - -struct tegra_dc; - -struct tegra_dc_blend { - unsigned z[DC_N_WINDOWS]; - unsigned flags[DC_N_WINDOWS]; -}; - -struct tegra_dc_out_ops { - /* initialize output. dc clocks are not on at this point */ - int (*init)(struct tegra_dc *dc); - /* destroy output. dc clocks are not on at this point */ - void (*destroy)(struct tegra_dc *dc); - /* detect connected display. can sleep.*/ - bool (*detect)(struct tegra_dc *dc); - /* enable output. dc clocks are on at this point */ - void (*enable)(struct tegra_dc *dc); - /* disable output. dc clocks are on at this point */ - void (*disable)(struct tegra_dc *dc); - - /* suspend output. dc clocks are on at this point */ - void (*suspend)(struct tegra_dc *dc); - /* resume output. dc clocks are on at this point */ - void (*resume)(struct tegra_dc *dc); -}; - -struct tegra_dc { - struct list_head list; - - struct nvhost_device *ndev; - struct tegra_dc_platform_data *pdata; - - struct resource *base_res; - void __iomem *base; - int irq; - - struct clk *clk; - struct clk *emc_clk; - - bool enabled; - bool suspended; - - struct tegra_dc_out *out; - struct tegra_dc_out_ops *out_ops; - void *out_data; - - struct tegra_dc_mode mode; - - struct tegra_dc_win windows[DC_N_WINDOWS]; - struct tegra_dc_blend blend; - int n_windows; - - wait_queue_head_t wq; - - struct mutex lock; - - struct resource *fb_mem; - struct tegra_fb_info *fb; - - u32 syncpt_id; - u32 syncpt_min; - u32 syncpt_max; - - unsigned long underflow_mask; - struct work_struct reset_work; -}; - -static inline void tegra_dc_io_start(struct tegra_dc *dc) -{ - nvhost_module_busy(&dc->ndev->host->mod); -} - -static inline void tegra_dc_io_end(struct tegra_dc *dc) -{ - nvhost_module_idle(&dc->ndev->host->mod); -} - -static inline unsigned long tegra_dc_readl(struct tegra_dc *dc, - unsigned long reg) -{ - BUG_ON(!nvhost_module_powered(&dc->ndev->host->mod)); - return readl(dc->base + reg * 4); -} - -static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long val, - unsigned long reg) -{ - BUG_ON(!nvhost_module_powered(&dc->ndev->host->mod)); - writel(val, dc->base + reg * 4); -} - -static inline void _tegra_dc_write_table(struct tegra_dc *dc, const u32 *table, - unsigned len) -{ - int i; - - for (i = 0; i < len; i++) - tegra_dc_writel(dc, table[i * 2 + 1], table[i * 2]); -} - -#define tegra_dc_write_table(dc, table) \ - _tegra_dc_write_table(dc, table, ARRAY_SIZE(table) / 2) - -static inline void tegra_dc_set_outdata(struct tegra_dc *dc, void *data) -{ - dc->out_data = data; -} - -static inline void *tegra_dc_get_outdata(struct tegra_dc *dc) -{ - return dc->out_data; -} - -void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk); - -extern struct tegra_dc_out_ops tegra_dc_rgb_ops; -extern struct tegra_dc_out_ops tegra_dc_hdmi_ops; - -#endif diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h deleted file mode 100644 index df1333e31d14..000000000000 --- a/drivers/video/tegra/dc/dc_reg.h +++ /dev/null @@ -1,423 +0,0 @@ -/* - * drivers/video/tegra/dc/dc_reg.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_REG_H -#define __DRIVERS_VIDEO_TEGRA_DC_DC_REG_H - -#define DC_CMD_GENERAL_INCR_SYNCPT 0x000 -#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 -#define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002 -#define DC_CMD_WIN_A_INCR_SYNCPT 0x008 -#define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009 -#define DC_CMD_WIN_A_INCR_SYNCPT_ERROR 0x00a -#define DC_CMD_WIN_B_INCR_SYNCPT 0x010 -#define DC_CMD_WIN_B_INCR_SYNCPT_CNTRL 0x011 -#define DC_CMD_WIN_B_INCR_SYNCPT_ERROR 0x012 -#define DC_CMD_WIN_C_INCR_SYNCPT 0x018 -#define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019 -#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a -#define DC_CMD_CONT_SYNCPT_VSYNC 0x028 -#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 -#define DC_CMD_DISPLAY_COMMAND 0x032 -#define DISP_COMMAND_RAISE (1 << 0) -#define DISP_CTRL_MODE_STOP (0 << 5) -#define DISP_CTRL_MODE_C_DISPLAY (1 << 5) -#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5) -#define DISP_COMMAND_RAISE_VECTOR(x) (((x) & 0x1f) << 22) -#define DISP_COMMAND_RAISE_CHANNEL_ID(x) (((x) & 0xf) << 27) - -#define DC_CMD_SIGNAL_RAISE 0x033 -#define DC_CMD_DISPLAY_POWER_CONTROL 0x036 -#define PW0_ENABLE (1 << 0) -#define PW1_ENABLE (1 << 2) -#define PW2_ENABLE (1 << 4) -#define PW3_ENABLE (1 << 6) -#define PW4_ENABLE (1 << 8) -#define PM0_ENABLE (1 << 16) -#define PM1_ENABLE (1 << 18) -#define SPI_ENABLE (1 << 24) -#define HSPI_ENABLE (1 << 25) - -#define DC_CMD_INT_STATUS 0x037 -#define DC_CMD_INT_MASK 0x038 -#define DC_CMD_INT_ENABLE 0x039 -#define DC_CMD_INT_TYPE 0x03a -#define DC_CMD_INT_POLARITY 0x03b -#define CTXSW_INT (1 << 0) -#define FRAME_END_INT (1 << 1) -#define V_BLANK_INT (1 << 2) -#define H_BLANK_INT (1 << 3) -#define V_PULSE3_INT (1 << 4) -#define SPI_BUSY_INT (1 << 7) -#define WIN_A_UF_INT (1 << 8) -#define WIN_B_UF_INT (1 << 9) -#define WIN_C_UF_INT (1 << 10) -#define MSF_INT (1 << 12) -#define SSF_INT (1 << 13) -#define WIN_A_OF_INT (1 << 14) -#define WIN_B_OF_INT (1 << 15) -#define WIN_C_OF_INT (1 << 16) -#define GPIO_0_INT (1 << 18) -#define GPIO_1_INT (1 << 19) -#define GPIO_2_INT (1 << 20) - -#define DC_CMD_SIGNAL_RAISE1 0x03c -#define DC_CMD_SIGNAL_RAISE2 0x03d -#define DC_CMD_SIGNAL_RAISE3 0x03e -#define DC_CMD_STATE_ACCESS 0x040 -#define READ_MUX_ASSEMBLY (0 << 0) -#define READ_MUX_ACTIVE (1 << 0) -#define WRITE_MUX_ASSEMBLY (0 << 2) -#define WRITE_MUX_ACTIVE (1 << 2) - -#define DC_CMD_STATE_CONTROL 0x041 -#define GENERAL_ACT_REQ (1 << 0) -#define WIN_A_ACT_REQ (1 << 1) -#define WIN_B_ACT_REQ (1 << 2) -#define WIN_C_ACT_REQ (1 << 3) -#define GENERAL_UPDATE (1 << 8) -#define WIN_A_UPDATE (1 << 9) -#define WIN_B_UPDATE (1 << 10) -#define WIN_C_UPDATE (1 << 11) - -#define DC_CMD_DISPLAY_WINDOW_HEADER 0x042 -#define WINDOW_A_SELECT (1 << 4) -#define WINDOW_B_SELECT (1 << 5) -#define WINDOW_C_SELECT (1 << 6) - -#define DC_CMD_REG_ACT_CONTROL 0x043 - -#define DC_COM_CRC_CONTROL 0x300 -#define DC_COM_CRC_CHECKSUM 0x301 -#define DC_COM_PIN_OUTPUT_ENABLE0 0x302 -#define DC_COM_PIN_OUTPUT_ENABLE1 0x303 -#define DC_COM_PIN_OUTPUT_ENABLE2 0x304 -#define DC_COM_PIN_OUTPUT_ENABLE3 0x305 -#define DC_COM_PIN_OUTPUT_POLARITY0 0x306 -#define DC_COM_PIN_OUTPUT_POLARITY1 0x307 -#define DC_COM_PIN_OUTPUT_POLARITY2 0x308 -#define DC_COM_PIN_OUTPUT_POLARITY3 0x309 -#define DC_COM_PIN_OUTPUT_DATA0 0x30a -#define DC_COM_PIN_OUTPUT_DATA1 0x30b -#define DC_COM_PIN_OUTPUT_DATA2 0x30c -#define DC_COM_PIN_OUTPUT_DATA3 0x30d -#define DC_COM_PIN_INPUT_ENABLE0 0x30e -#define DC_COM_PIN_INPUT_ENABLE1 0x30f -#define DC_COM_PIN_INPUT_ENABLE2 0x310 -#define DC_COM_PIN_INPUT_ENABLE3 0x311 -#define DC_COM_PIN_INPUT_DATA0 0x312 -#define DC_COM_PIN_INPUT_DATA1 0x313 -#define DC_COM_PIN_OUTPUT_SELECT0 0x314 -#define DC_COM_PIN_OUTPUT_SELECT1 0x315 -#define DC_COM_PIN_OUTPUT_SELECT2 0x316 -#define DC_COM_PIN_OUTPUT_SELECT3 0x317 -#define DC_COM_PIN_OUTPUT_SELECT4 0x318 -#define DC_COM_PIN_OUTPUT_SELECT5 0x319 -#define DC_COM_PIN_OUTPUT_SELECT6 0x31a - -#define PIN1_LHS_OUTPUT (1 << 30) -#define PIN1_LVS_OUTPUT (1 << 28) - -#define DC_COM_PIN_MISC_CONTROL 0x31b -#define DC_COM_PM0_CONTROL 0x31c -#define DC_COM_PM0_DUTY_CYCLE 0x31d -#define DC_COM_PM1_CONTROL 0x31e -#define DC_COM_PM1_DUTY_CYCLE 0x31f -#define DC_COM_SPI_CONTROL 0x320 -#define DC_COM_SPI_START_BYTE 0x321 -#define DC_COM_HSPI_WRITE_DATA_AB 0x322 -#define DC_COM_HSPI_WRITE_DATA_CD 0x323 -#define DC_COM_HSPI_CS_DC 0x324 -#define DC_COM_SCRATCH_REGISTER_A 0x325 -#define DC_COM_SCRATCH_REGISTER_B 0x326 -#define DC_COM_GPIO_CTRL 0x327 -#define DC_COM_GPIO_DEBOUNCE_COUNTER 0x328 -#define DC_COM_CRC_CHECKSUM_LATCHED 0x329 - -#define DC_DISP_DISP_SIGNAL_OPTIONS0 0x400 -#define H_PULSE_0_ENABLE (1 << 8) -#define H_PULSE_1_ENABLE (1 << 10) -#define H_PULSE_2_ENABLE (1 << 12) -#define V_PULSE_0_ENABLE (1 << 16) -#define V_PULSE_1_ENABLE (1 << 18) -#define V_PULSE_2_ENABLE (1 << 19) -#define V_PULSE_3_ENABLE (1 << 20) -#define M0_ENABLE (1 << 24) -#define M1_ENABLE (1 << 26) - -#define DC_DISP_DISP_SIGNAL_OPTIONS1 0x401 -#define DI_ENABLE (1 << 16) -#define PP_ENABLE (1 << 18) - -#define DC_DISP_DISP_WIN_OPTIONS 0x402 -#define CURSOR_ENABLE (1 << 16) -#define TVO_ENABLE (1 << 28) -#define DSI_ENABLE (1 << 29) -#define HDMI_ENABLE (1 << 30) - -#define DC_DISP_MEM_HIGH_PRIORITY 0x403 -#define DC_DISP_MEM_HIGH_PRIORITY_TIMER 0x404 -#define DC_DISP_DISP_TIMING_OPTIONS 0x405 -#define VSYNC_H_POSITION(x) ((x) & 0xfff) - -#define DC_DISP_REF_TO_SYNC 0x406 -#define DC_DISP_SYNC_WIDTH 0x407 -#define DC_DISP_BACK_PORCH 0x408 -#define DC_DISP_DISP_ACTIVE 0x409 -#define DC_DISP_FRONT_PORCH 0x40a -#define DC_DISP_H_PULSE0_CONTROL 0x40b -#define DC_DISP_H_PULSE0_POSITION_A 0x40c -#define DC_DISP_H_PULSE0_POSITION_B 0x40d -#define DC_DISP_H_PULSE0_POSITION_C 0x40e -#define DC_DISP_H_PULSE0_POSITION_D 0x40f -#define DC_DISP_H_PULSE1_CONTROL 0x410 -#define DC_DISP_H_PULSE1_POSITION_A 0x411 -#define DC_DISP_H_PULSE1_POSITION_B 0x412 -#define DC_DISP_H_PULSE1_POSITION_C 0x413 -#define DC_DISP_H_PULSE1_POSITION_D 0x414 -#define DC_DISP_H_PULSE2_CONTROL 0x415 -#define DC_DISP_H_PULSE2_POSITION_A 0x416 -#define DC_DISP_H_PULSE2_POSITION_B 0x417 -#define DC_DISP_H_PULSE2_POSITION_C 0x418 -#define DC_DISP_H_PULSE2_POSITION_D 0x419 -#define DC_DISP_V_PULSE0_CONTROL 0x41a -#define DC_DISP_V_PULSE0_POSITION_A 0x41b -#define DC_DISP_V_PULSE0_POSITION_B 0x41c -#define DC_DISP_V_PULSE0_POSITION_C 0x41d -#define DC_DISP_V_PULSE1_CONTROL 0x41e -#define DC_DISP_V_PULSE1_POSITION_A 0x41f -#define DC_DISP_V_PULSE1_POSITION_B 0x420 -#define DC_DISP_V_PULSE1_POSITION_C 0x421 -#define DC_DISP_V_PULSE2_CONTROL 0x422 -#define DC_DISP_V_PULSE2_POSITION_A 0x423 -#define DC_DISP_V_PULSE3_CONTROL 0x424 -#define DC_DISP_V_PULSE3_POSITION_A 0x425 -#define DC_DISP_M0_CONTROL 0x426 -#define DC_DISP_M1_CONTROL 0x427 -#define DC_DISP_DI_CONTROL 0x428 -#define DC_DISP_PP_CONTROL 0x429 -#define DC_DISP_PP_SELECT_A 0x42a -#define DC_DISP_PP_SELECT_B 0x42b -#define DC_DISP_PP_SELECT_C 0x42c -#define DC_DISP_PP_SELECT_D 0x42d - -#define PULSE_MODE_NORMAL (0 << 3) -#define PULSE_MODE_ONE_CLOCK (1 << 3) -#define PULSE_POLARITY_HIGH (0 << 4) -#define PULSE_POLARITY_LOW (1 << 4) -#define PULSE_QUAL_ALWAYS (0 << 6) -#define PULSE_QUAL_VACTIVE (2 << 6) -#define PULSE_QUAL_VACTIVE1 (3 << 6) -#define PULSE_LAST_START_A (0 << 8) -#define PULSE_LAST_END_A (1 << 8) -#define PULSE_LAST_START_B (2 << 8) -#define PULSE_LAST_END_B (3 << 8) -#define PULSE_LAST_START_C (4 << 8) -#define PULSE_LAST_END_C (5 << 8) -#define PULSE_LAST_START_D (6 << 8) -#define PULSE_LAST_END_D (7 << 8) - -#define PULSE_START(x) ((x) & 0xfff) -#define PULSE_END(x) (((x) & 0xfff) << 16) - -#define DC_DISP_DISP_CLOCK_CONTROL 0x42e -#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8) -#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8) -#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8) -#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8) -#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8) -#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8) -#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8) -#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8) -#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8) -#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8) -#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8) -#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8) -#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8) -#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff) - -#define DC_DISP_DISP_INTERFACE_CONTROL 0x42f -#define DISP_DATA_FORMAT_DF1P1C (0 << 0) -#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0) -#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0) -#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0) -#define DISP_DATA_FORMAT_DF2S (5 << 0) -#define DISP_DATA_FORMAT_DF3S (6 << 0) -#define DISP_DATA_FORMAT_DFSPI (7 << 0) -#define DISP_DATA_FORMAT_DF1P3C24B (8 << 0) -#define DISP_DATA_FORMAT_DF1P3C18B (9 << 0) -#define DISP_DATA_ALIGNMENT_MSB (0 << 8) -#define DISP_DATA_ALIGNMENT_LSB (1 << 8) -#define DISP_DATA_ORDER_RED_BLUE (0 << 9) -#define DISP_DATA_ORDER_BLUE_RED (1 << 9) - -#define DC_DISP_DISP_COLOR_CONTROL 0x430 -#define BASE_COLOR_SIZE666 (0 << 0) -#define BASE_COLOR_SIZE111 (1 << 0) -#define BASE_COLOR_SIZE222 (2 << 0) -#define BASE_COLOR_SIZE333 (3 << 0) -#define BASE_COLOR_SIZE444 (4 << 0) -#define BASE_COLOR_SIZE555 (5 << 0) -#define BASE_COLOR_SIZE565 (6 << 0) -#define BASE_COLOR_SIZE332 (7 << 0) -#define BASE_COLOR_SIZE888 (8 << 0) - -#define DITHER_CONTROL_DISABLE (0 << 8) -#define DITHER_CONTROL_ORDERED (2 << 8) -#define DITHER_CONTROL_ERRDIFF (3 << 8) - -#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431 -#define DC_DISP_DATA_ENABLE_OPTIONS 0x432 -#define DE_SELECT_ACTIVE_BLANK 0x0 -#define DE_SELECT_ACTIVE 0x1 -#define DE_SELECT_ACTIVE_IS 0x2 -#define DE_CONTROL_ONECLK (0 << 2) -#define DE_CONTROL_NORMAL (1 << 2) -#define DE_CONTROL_EARLY_EXT (2 << 2) -#define DE_CONTROL_EARLY (3 << 2) -#define DE_CONTROL_ACTIVE_BLANK (4 << 2) - -#define DC_DISP_SERIAL_INTERFACE_OPTIONS 0x433 -#define DC_DISP_LCD_SPI_OPTIONS 0x434 -#define DC_DISP_BORDER_COLOR 0x435 -#define DC_DISP_COLOR_KEY0_LOWER 0x436 -#define DC_DISP_COLOR_KEY0_UPPER 0x437 -#define DC_DISP_COLOR_KEY1_LOWER 0x438 -#define DC_DISP_COLOR_KEY1_UPPER 0x439 -#define DC_DISP_CURSOR_FOREGROUND 0x43c -#define DC_DISP_CURSOR_BACKGROUND 0x43d -#define DC_DISP_CURSOR_START_ADDR 0x43e -#define DC_DISP_CURSOR_START_ADDR_NS 0x43f -#define DC_DISP_CURSOR_POSITION 0x440 -#define DC_DISP_CURSOR_POSITION_NS 0x441 -#define DC_DISP_INIT_SEQ_CONTROL 0x442 -#define DC_DISP_SPI_INIT_SEQ_DATA_A 0x443 -#define DC_DISP_SPI_INIT_SEQ_DATA_B 0x444 -#define DC_DISP_SPI_INIT_SEQ_DATA_C 0x445 -#define DC_DISP_SPI_INIT_SEQ_DATA_D 0x446 -#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480 -#define DC_DISP_MCCIF_DISPLAY0A_HYST 0x481 -#define DC_DISP_MCCIF_DISPLAY0B_HYST 0x482 -#define DC_DISP_MCCIF_DISPLAY0C_HYST 0x483 -#define DC_DISP_MCCIF_DISPLAY1B_HYST 0x484 -#define DC_DISP_DAC_CRT_CTRL 0x4c0 -#define DC_DISP_DISP_MISC_CONTROL 0x4c1 - -#define DC_WIN_COLOR_PALETTE(x) (0x500 + (x)) - -#define DC_WIN_PALETTE_COLOR_EXT 0x600 -#define DC_WIN_H_FILTER_P(x) (0x601 + (x)) -#define DC_WIN_CSC_YOF 0x611 -#define DC_WIN_CSC_KYRGB 0x612 -#define DC_WIN_CSC_KUR 0x613 -#define DC_WIN_CSC_KVR 0x614 -#define DC_WIN_CSC_KUG 0x615 -#define DC_WIN_CSC_KVG 0x616 -#define DC_WIN_CSC_KUB 0x617 -#define DC_WIN_CSC_KVB 0x618 -#define DC_WIN_V_FILTER_P(x) (0x619 + (x)) -#define DC_WIN_WIN_OPTIONS 0x700 -#define H_DIRECTION_INCREMENT (0 << 0) -#define H_DIRECTION_DECREMENT (1 << 0) -#define V_DIRECTION_INCREMENT (0 << 2) -#define V_DIRECTION_DECREMENT (1 << 2) -#define COLOR_EXPAND (1 << 6) -#define H_FILTER_ENABLE (1 << 8) -#define V_FILTER_ENABLE (1 << 10) -#define CP_ENABLE (1 << 16) -#define CSC_ENABLE (1 << 18) -#define DV_ENABLE (1 << 20) -#define WIN_ENABLE (1 << 30) - -#define DC_WIN_BYTE_SWAP 0x701 -#define BYTE_SWAP_NOSWAP 0 -#define BYTE_SWAP_SWAP2 1 -#define BYTE_SWAP_SWAP4 2 -#define BYTE_SWAP_SWAP4HW 3 - -#define DC_WIN_BUFFER_CONTROL 0x702 -#define BUFFER_CONTROL_HOST 0 -#define BUFFER_CONTROL_VI 1 -#define BUFFER_CONTROL_EPP 2 -#define BUFFER_CONTROL_MPEGE 3 -#define BUFFER_CONTROL_SB2D 4 - -#define DC_WIN_COLOR_DEPTH 0x703 - -#define DC_WIN_POSITION 0x704 -#define H_POSITION(x) (((x) & 0xfff) << 0) -#define V_POSITION(x) (((x) & 0xfff) << 16) - -#define DC_WIN_SIZE 0x705 -#define H_SIZE(x) (((x) & 0xfff) << 0) -#define V_SIZE(x) (((x) & 0xfff) << 16) - -#define DC_WIN_PRESCALED_SIZE 0x706 -#define H_PRESCALED_SIZE(x) (((x) & 0x3fff) << 0) -#define V_PRESCALED_SIZE(x) (((x) & 0xfff) << 16) - -#define DC_WIN_H_INITIAL_DDA 0x707 -#define DC_WIN_V_INITIAL_DDA 0x708 -#define DC_WIN_DDA_INCREMENT 0x709 -#define H_DDA_INC(x) (((x) & 0xffff) << 0) -#define V_DDA_INC(x) (((x) & 0xffff) << 16) - -#define DC_WIN_LINE_STRIDE 0x70a -#define LINE_STRIDE(x) (x) -#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16) -#define DC_WIN_BUF_STRIDE 0x70b -#define DC_WIN_UV_BUF_STRIDE 0x70c -#define DC_WIN_BUFFER_ADDR_MODE 0x70d -#define DC_WIN_BUFFER_ADDR_MODE_LINEAR (0 << 0) -#define DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV (0 << 16) -#define DC_WIN_BUFFER_ADDR_MODE_TILE (1 << 0) -#define DC_WIN_BUFFER_ADDR_MODE_TILE_UV (1 << 16) -#define DC_WIN_DV_CONTROL 0x70e -#define DC_WIN_BLEND_NOKEY 0x70f -#define DC_WIN_BLEND_1WIN 0x710 -#define DC_WIN_BLEND_2WIN_X 0x711 -#define DC_WIN_BLEND_2WIN_Y 0x712 -#define DC_WIN_BLEND_3WIN_XY 0x713 -#define CKEY_NOKEY (0 << 0) -#define CKEY_KEY0 (1 << 0) -#define CKEY_KEY1 (2 << 0) -#define CKEY_KEY01 (3 << 0) -#define BLEND_CONTROL_FIX (0 << 2) -#define BLEND_CONTROL_ALPHA (1 << 2) -#define BLEND_CONTROL_DEPENDANT (2 << 2) -#define BLEND_CONTROL_PREMULT (3 << 2) -#define BLEND_WEIGHT0(x) (((x) & 0xff) << 8) -#define BLEND_WEIGHT1(x) (((x) & 0xff) << 16) -#define BLEND(key, control, weight0, weight1) \ - (CKEY_ ## key | BLEND_CONTROL_ ## control | \ - BLEND_WEIGHT0(weight0) | BLEND_WEIGHT1(weight1)) - - -#define DC_WIN_HP_FETCH_CONTROL 0x714 -#define DC_WINBUF_START_ADDR 0x800 -#define DC_WINBUF_START_ADDR_NS 0x801 -#define DC_WINBUF_START_ADDR_U 0x802 -#define DC_WINBUF_START_ADDR_U_NS 0x803 -#define DC_WINBUF_START_ADDR_V 0x804 -#define DC_WINBUF_START_ADDR_V_NS 0x805 -#define DC_WINBUF_ADDR_H_OFFSET 0x806 -#define DC_WINBUF_ADDR_H_OFFSET_NS 0x807 -#define DC_WINBUF_ADDR_V_OFFSET 0x808 -#define DC_WINBUF_ADDR_V_OFFSET_NS 0x809 -#define DC_WINBUF_UFLOW_STATUS 0x80a - -#endif diff --git a/drivers/video/tegra/dc/edid.c b/drivers/video/tegra/dc/edid.c deleted file mode 100644 index 47f05e6ac31c..000000000000 --- a/drivers/video/tegra/dc/edid.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * drivers/video/tegra/dc/edid.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * 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. - * - */ - -#define DEBUG - -#include -#include -#include -#include -#include - -#include "edid.h" - -struct tegra_edid { - struct i2c_client *client; - struct i2c_board_info info; - int bus; - - u8 *data; - unsigned len; -}; - -#if defined(DEBUG) || defined(CONFIG_DEBUG_FS) -static int tegra_edid_show(struct seq_file *s, void *unused) -{ - struct tegra_edid *edid = s->private; - int i; - - for (i = 0; i < edid->len; i++) { - if (i % 16 == 0) - seq_printf(s, "edid[%03x] =", i); - - seq_printf(s, " %02x", edid->data[i]); - - if (i % 16 == 15) - seq_printf(s, "\n"); - } - - return 0; -} -#endif - -#ifdef CONFIG_DEBUG_FS -static int tegra_edid_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, tegra_edid_show, inode->i_private); -} - -static const struct file_operations tegra_edid_debug_fops = { - .open = tegra_edid_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -void tegra_edid_debug_add(struct tegra_edid *edid) -{ - char name[] = "edidX"; - - snprintf(name, sizeof(name), "edid%1d", edid->bus); - debugfs_create_file(name, S_IRUGO, NULL, edid, &tegra_edid_debug_fops); -} -#else -void tegra_edid_debug_add(struct tegra_edid *edid) -{ -} -#endif - -#ifdef DEBUG -static char tegra_edid_dump_buff[16 * 1024]; - -static void tegra_edid_dump(struct tegra_edid *edid) -{ - struct seq_file s; - int i; - char c; - - memset(&s, 0x0, sizeof(s)); - - s.buf = tegra_edid_dump_buff; - s.size = sizeof(tegra_edid_dump_buff); - s.private = edid; - - tegra_edid_show(&s, NULL); - - i = 0; - while (i < s.count ) { - if ((s.count - i) > 256) { - c = s.buf[i + 256]; - s.buf[i + 256] = 0; - printk("%s", s.buf + i); - s.buf[i + 256] = c; - } else { - printk("%s", s.buf + i); - } - i += 256; - } -} -#else -static void tegra_edid_dump(struct tegra_edid *edid) -{ -} -#endif - -int tegra_edid_read_block(struct tegra_edid *edid, int block, u8 *data) -{ - u8 block_buf[] = {block >> 1}; - u8 cmd_buf[] = {(block & 0x1) * 128}; - int status; - struct i2c_msg msg[] = { - { - .addr = 0x30, - .flags = 0, - .len = 1, - .buf = block_buf, - }, - { - .addr = 0x50, - .flags = 0, - .len = 1, - .buf = cmd_buf, - }, - { - .addr = 0x50, - .flags = I2C_M_RD, - .len = 128, - .buf = data, - }}; - struct i2c_msg *m; - int msg_len; - - if (block > 1) { - msg_len = 3; - m = msg; - } else { - msg_len = 2; - m = &msg[1]; - } - - status = i2c_transfer(edid->client->adapter, m, msg_len); - - if (status < 0) - return status; - - if (status != msg_len) - return -EIO; - - return 0; -} - - -int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs) -{ - int i; - int ret; - int extension_blocks; - - ret = tegra_edid_read_block(edid, 0, edid->data); - if (ret) - return ret; - - memset(specs, 0x0, sizeof(struct fb_monspecs)); - fb_edid_to_monspecs(edid->data, specs); - if (specs->modedb == NULL) - return -EINVAL; - - extension_blocks = edid->data[0x7e]; - - for (i = 1; i <= extension_blocks; i++) { - ret = tegra_edid_read_block(edid, i, edid->data + i * 128); - if (ret < 0) - break; - - if (edid->data[i * 128] == 0x2) - fb_edid_add_monspecs(edid->data + i * 128, specs); - } - - edid->len = i * 128; - - tegra_edid_dump(edid); - - return 0; -} - -struct tegra_edid *tegra_edid_create(int bus) -{ - struct tegra_edid *edid; - struct i2c_adapter *adapter; - int err; - - edid = kzalloc(sizeof(struct tegra_edid), GFP_KERNEL); - if (!edid) - return ERR_PTR(-ENOMEM); - - edid->data = vmalloc(SZ_32K); - if (!edid->data) { - err = -ENOMEM; - goto free_edid; - } - strlcpy(edid->info.type, "tegra_edid", sizeof(edid->info.type)); - edid->bus = bus; - edid->info.addr = 0x50; - edid->info.platform_data = edid; - - adapter = i2c_get_adapter(bus); - if (!adapter) { - pr_err("can't get adpater for bus %d\n", bus); - err = -EBUSY; - goto free_edid; - } - - edid->client = i2c_new_device(adapter, &edid->info); - i2c_put_adapter(adapter); - - if (!edid->client) { - pr_err("can't create new device\n"); - err = -EBUSY; - goto free_edid; - } - - tegra_edid_debug_add(edid); - - return edid; - -free_edid: - vfree(edid->data); - kfree(edid); - - return ERR_PTR(err); -} - -void tegra_edid_destroy(struct tegra_edid *edid) -{ - i2c_release_client(edid->client); - vfree(edid->data); - kfree(edid); -} - -static const struct i2c_device_id tegra_edid_id[] = { - { "tegra_edid", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, tegra_edid_id); - -static struct i2c_driver tegra_edid_driver = { - .id_table = tegra_edid_id, - .driver = { - .name = "tegra_edid", - }, -}; - -static int __init tegra_edid_init(void) -{ - return i2c_add_driver(&tegra_edid_driver); -} - -static void __exit tegra_edid_exit(void) -{ - i2c_del_driver(&tegra_edid_driver); -} - -module_init(tegra_edid_init); -module_exit(tegra_edid_exit); diff --git a/drivers/video/tegra/dc/edid.h b/drivers/video/tegra/dc/edid.h deleted file mode 100644 index 821da90a8b4f..000000000000 --- a/drivers/video/tegra/dc/edid.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * drivers/video/tegra/dc/edid.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DRIVERS_VIDEO_TEGRA_DC_EDID_H -#define __DRIVERS_VIDEO_TEGRA_DC_EDID_H - -#include -#include - -struct tegra_edid; - -struct tegra_edid *tegra_edid_create(int bus); -void tegra_edid_destroy(struct tegra_edid *edid); - -int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs); - -#endif diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c deleted file mode 100644 index 62fad97c6a90..000000000000 --- a/drivers/video/tegra/dc/hdmi.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* - * drivers/video/tegra/dc/hdmi.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Erik Gilling - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include