]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Jun 2010 22:47:22 +0000 (15:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Jun 2010 22:47:22 +0000 (15:47 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, smpboot: Fix cores per node printing on boot
  x86/amd-iommu: Fall back to GART if initialization fails
  x86/amd-iommu: Fix crash when request_mem_region fails
  x86/mm: Remove unused DBG() macro
  arch/x86/kernel: Add missing spin_unlock

406 files changed:
.gitignore
Documentation/.gitignore [new file with mode: 0644]
Documentation/DocBook/drm.tmpl
Documentation/i2c/busses/i2c-ali1535
Documentation/i2c/busses/i2c-ali1563
Documentation/i2c/busses/i2c-ali15x3
Documentation/i2c/busses/i2c-pca-isa
Documentation/i2c/busses/i2c-sis5595
Documentation/i2c/busses/i2c-sis630
Documentation/i2c/ten-bit-addresses
Documentation/kbuild/kbuild.txt
Documentation/mutex-design.txt
Documentation/timers/Makefile
MAINTAINERS
Makefile
arch/cris/arch-v10/drivers/ds1302.c
arch/cris/arch-v10/drivers/pcf8563.c
arch/cris/arch-v10/kernel/irq.c
arch/cris/arch-v10/lib/dmacopy.c
arch/cris/arch-v10/lib/hw_settings.S
arch/cris/arch-v32/drivers/Kconfig
arch/cris/arch-v32/drivers/i2c.c
arch/cris/arch-v32/drivers/pcf8563.c
arch/cris/arch-v32/kernel/crisksyms.c
arch/cris/arch-v32/kernel/irq.c
arch/cris/arch-v32/kernel/smp.c
arch/cris/include/arch-v10/arch/irq.h
arch/cris/include/arch-v32/arch/irq.h
arch/cris/include/asm/param.h
arch/frv/kernel/break.S
arch/frv/kernel/entry.S
arch/frv/kernel/head.S
arch/frv/kernel/vmlinux.lds.S
arch/frv/mm/tlb-miss.S
arch/h8300/boot/compressed/head.S
arch/h8300/boot/compressed/vmlinux.lds
arch/ia64/include/asm/asmmacro.h
arch/ia64/include/asm/cache.h
arch/ia64/include/asm/percpu.h
arch/ia64/kernel/Makefile.gate
arch/ia64/kernel/gate-data.S
arch/ia64/kernel/gate.S
arch/ia64/kernel/gate.lds.S
arch/ia64/kernel/init_task.c
arch/ia64/kernel/ivt.S
arch/ia64/kernel/minstate.h
arch/ia64/kernel/paravirtentry.S
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/kvm/vmm_ivt.S
arch/ia64/scripts/unwcheck.py
arch/ia64/xen/gate-data.S
arch/ia64/xen/xensetup.S
arch/m68knommu/kernel/vmlinux.lds.S
arch/m68knommu/platform/68360/head-ram.S
arch/m68knommu/platform/68360/head-rom.S
arch/mips/lasat/image/head.S
arch/mips/lasat/image/romscript.normal
arch/parisc/include/asm/cache.h
arch/parisc/include/asm/system.h
arch/parisc/kernel/head.S
arch/parisc/kernel/init_task.c
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/4xx.c
arch/powerpc/boot/dts/icon.dts [new file with mode: 0644]
arch/powerpc/boot/dts/katmai.dts
arch/powerpc/boot/dts/mpc8548cds.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
arch/powerpc/boot/dts/p1021mds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/redwood.dts
arch/powerpc/configs/44x/icon_defconfig [new file with mode: 0644]
arch/powerpc/include/asm/cache.h
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/kexec.h
arch/powerpc/include/asm/macio.h
arch/powerpc/include/asm/page_64.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/fsl_booke_entry_mapping.S [new file with mode: 0644]
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/swsusp_booke.S [new file with mode: 0644]
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/44x/ppc44x_simple.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_msi.h
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/ppc4xx_pci.h
arch/s390/include/asm/cache.h
arch/s390/kernel/swsusp_asm64.S
arch/sh/boot/compressed/vmlinux.scr
arch/sh/include/asm/cache.h
arch/sparc/boot/btfixupprep.c
arch/sparc/include/asm/cache.h
arch/um/kernel/dyn.lds.S
arch/um/kernel/init_task.c
arch/um/kernel/uml.lds.S
arch/x86/.gitignore [new file with mode: 0644]
arch/x86/boot/compressed/mkpiggy.c
arch/x86/boot/compressed/vmlinux.lds.S
arch/x86/include/asm/cache.h
arch/x86/kernel/acpi/wakeup_32.S
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/init_task.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/xen/suspend.c
drivers/ata/pata_macio.c
drivers/block/swim3.c
drivers/block/virtio_blk.c
drivers/char/agp/intel-gtt.c
drivers/char/agp/uninorth-agp.c
drivers/char/virtio_console.c
drivers/crypto/amcc/crypto4xx_core.c
drivers/crypto/n2_core.c
drivers/dma/mpc512x_dma.c
drivers/dma/ppc4xx/adma.c
drivers/edac/mpc85xx_edac.c
drivers/edac/ppc4xx_edac.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_trace.h
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_ringbuffer.c [new file with mode: 0644]
drivers/gpu/drm/i915/intel_ringbuffer.h [new file with mode: 0644]
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_crtc.h
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_cursor.c
drivers/gpu/drm/nouveau/nv50_cursor.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_cs.c [new file with mode: 0644]
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/reg_srcs/evergreen [new file with mode: 0644]
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_page_alloc.c
drivers/gpu/drm/vmwgfx/Makefile
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c [new file with mode: 0644]
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
drivers/gpu/vga/vgaarb.c
drivers/hwmon/adt7411.c
drivers/hwmon/asc7621.c
drivers/hwmon/f75375s.c
drivers/hwmon/g760a.c
drivers/hwmon/lm73.c
drivers/hwmon/lm75.c
drivers/hwmon/lm95241.c
drivers/hwmon/tmp102.c
drivers/hwmon/tmp421.c
drivers/hwmon/w83781d.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/i2c-core.c
drivers/i2c/i2c-smbus.c
drivers/ide/pmac.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/lm8323.c
drivers/input/keyboard/max7359_keypad.c
drivers/input/keyboard/qt2160.c
drivers/input/keyboard/tca6416-keypad.c
drivers/input/misc/ad714x-i2c.c
drivers/input/misc/pcf8574_keypad.c
drivers/input/mouse/synaptics_i2c.c
drivers/input/touchscreen/ad7879.c
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/mcs5000_ts.c
drivers/input/touchscreen/tsc2007.c
drivers/isdn/hardware/mISDN/hfcsusb.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/leds/leds-bd2802.c
drivers/leds/leds-lp3944.c
drivers/leds/leds-pca9532.c
drivers/leds/leds-pca955x.c
drivers/macintosh/macio_asic.c
drivers/macintosh/mediabay.c
drivers/macintosh/rack-meter.c
drivers/macintosh/therm_adt746x.c
drivers/macintosh/windfarm_lm75_sensor.c
drivers/macintosh/windfarm_max6690_sensor.c
drivers/macintosh/windfarm_smu_sat.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/video/mt9m001.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9t031.c
drivers/media/video/mt9t112.c
drivers/media/video/mt9v022.c
drivers/media/video/ov772x.c
drivers/media/video/ov9640.c
drivers/media/video/rj54n1cb0c.c
drivers/media/video/tcm825x.c
drivers/media/video/tw9910.c
drivers/mfd/88pm860x-i2c.c
drivers/mfd/ab3100-core.c
drivers/mfd/ab3550-core.c
drivers/mfd/adp5520.c
drivers/mfd/da903x.c
drivers/mfd/max8925-i2c.c
drivers/mfd/menelaus.c
drivers/mfd/pcf50633-core.c
drivers/mfd/tc35892.c
drivers/mfd/tps65010.c
drivers/mfd/wm8350-i2c.c
drivers/mfd/wm8400-core.c
drivers/misc/eeprom/at24.c
drivers/mtd/maps/pismo.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/socrates_nand.c
drivers/net/benet/be_cmds.c
drivers/net/bmac.c
drivers/net/can/mscan/mpc5xxx_can.c
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mii-bitbang.c
drivers/net/greth.c
drivers/net/ksz884x.c
drivers/net/mace.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ar9170/usb.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/orinoco/airport.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/platform/x86/intel_scu_ipc.c
drivers/power/max17040_battery.c
drivers/regulator/lp3971.c
drivers/regulator/max1586.c
drivers/regulator/max8649.c
drivers/regulator/max8660.c
drivers/regulator/tps65023-regulator.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-mpc5121.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-s35390a.c
drivers/scsi/mac53c94.c
drivers/scsi/mesh.c
drivers/serial/pmac_zilog.c
drivers/spi/mpc512x_psc_spi.c
drivers/spi/spi_ppc4xx.c
drivers/ssb/pci.c
drivers/ssb/sprom.c
drivers/staging/dream/synaptics_i2c_rmi.c
drivers/staging/go7007/wis-saa7113.c
drivers/staging/go7007/wis-saa7115.c
drivers/staging/go7007/wis-sony-tuner.c
drivers/staging/go7007/wis-tw2804.c
drivers/staging/go7007/wis-tw9903.c
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/light/tsl2563.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/host/ehci-xilinx-of.c
drivers/video/aty/mach64_accel.c
drivers/video/backlight/adp8860_bl.c
drivers/video/backlight/tosa_bl.c
drivers/video/bw2.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/leo.c
drivers/video/mb862xx/mb862xxfb.c
drivers/video/p9100.c
drivers/video/tcx.c
drivers/watchdog/gef_wdt.c
drivers/watchdog/mpc8xxx_wdt.c
drivers/xen/xenbus/xenbus_xs.c
fs/afs/server.c
fs/binfmt_elf_fdpic.c
fs/cifs/file.c
fs/fscache/page.c
include/asm-generic/percpu.h
include/asm-generic/vmlinux.lds.h
include/drm/drm_crtc_helper.h
include/drm/i915_drm.h
include/drm/nouveau_drm.h
include/drm/vmwgfx_drm.h
include/linux/cache.h
include/linux/init.h
include/linux/init_task.h
include/linux/linkage.h
include/linux/netfilter/x_tables.h
include/linux/percpu-defs.h
include/linux/perf_event.h
include/linux/skbuff.h
include/linux/spinlock.h
include/linux/vgaarb.h
include/net/sock.h
include/trace/ftrace.h
init/Kconfig
kernel/cpu.c
kernel/module.c
kernel/perf_event.c
kernel/trace/blktrace.c
kernel/trace/trace_event_perf.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_syscalls.c
net/caif/cfserl.c
net/core/skbuff.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/tcp_input.c
net/ipv4/udp.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/route.c
net/mac80211/chan.c
net/netfilter/x_tables.c
net/phonet/pep.c
net/rds/ib_cm.c
net/rds/iw_cm.c
scripts/Makefile.build
scripts/Makefile.lib
scripts/checkincludes.pl
scripts/checkstack.pl
scripts/checkversion.pl
scripts/decodecode
scripts/export_report.pl
scripts/gen_initramfs_list.sh
scripts/genksyms/genksyms.c
scripts/headerdep.pl
scripts/headers_check.pl
scripts/headers_install.pl
scripts/kallsyms.c
scripts/kconfig/Makefile
scripts/kconfig/expr.c
scripts/kconfig/expr.h
scripts/kconfig/gconf.c
scripts/kconfig/gconf.glade
scripts/kconfig/lkc.h
scripts/kconfig/lkc_proto.h
scripts/kconfig/lxdialog/inputbox.c
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
scripts/kconfig/nconf.c [new file with mode: 0644]
scripts/kconfig/nconf.gui.c [new file with mode: 0644]
scripts/kconfig/nconf.h [new file with mode: 0644]
scripts/kconfig/symbol.c
scripts/kconfig/util.c
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y
scripts/markup_oops.pl
scripts/mkcompile_h
scripts/mod/modpost.c
scripts/namespace.pl
scripts/package/builddeb
scripts/package/mkspec
scripts/profile2linkerlist.pl
scripts/rt-tester/rt-tester.py
scripts/show_delta
scripts/tags.sh
sound/aoa/soundbus/i2sbus/core.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-record.c
tools/perf/builtin-sched.c
tools/perf/scripts/python/check-perf-trace.py
tools/perf/util/event.c
tools/perf/util/hist.c
tools/perf/util/scripting-engines/trace-event-python.c

index a2939fc10b225d3727d6501831fad647553f11c8..8faa6c02b39ec3896bd4e989c82ce7f6dbdaf04a 100644 (file)
@@ -28,6 +28,7 @@ modules.builtin
 *.gz
 *.bz2
 *.lzma
+*.lzo
 *.patch
 *.gcno
 
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
new file mode 100644 (file)
index 0000000..bcd907b
--- /dev/null
@@ -0,0 +1,7 @@
+filesystems/dnotify_test
+laptops/dslm
+timers/hpet_example
+vm/hugepage-mmap
+vm/hugepage-shm
+vm/map_hugetlb
+
index 7583dc7cf64d5b321cd9e50aba766087e07a9fc5..910c923a9b86fe5bbd4e38abd6ad2eb593a25e2b 100644 (file)
       </para>
       <para>
        If your driver supports memory management (it should!), you'll
-       need to set that up at load time as well.  How you intialize
+       need to set that up at load time as well.  How you initialize
        it depends on which memory manager you're using, TTM or GEM.
       </para>
       <sect3>
          aperture space for graphics devices. TTM supports both UMA devices
          and devices with dedicated video RAM (VRAM), i.e. most discrete
          graphics devices.  If your device has dedicated RAM, supporting
-         TTM is desireable.  TTM also integrates tightly with your
+         TTM is desirable.  TTM also integrates tightly with your
          driver specific buffer execution function.  See the radeon
          driver for examples.
        </para>
          likely eventually calling ttm_bo_global_init and
          ttm_bo_global_release, respectively.  Also like the previous
          object, ttm_global_item_ref is used to create an initial reference
-         count for the TTM, which will call your initalization function.
+         count for the TTM, which will call your initialization function.
        </para>
       </sect3>
       <sect3>
@@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *dev)
          CRT connector and encoder combination is created.  A device
          specific i2c bus is also created, for fetching EDID data and
          performing monitor detection.  Once the process is complete,
-         the new connector is regsitered with sysfs, to make its
+         the new connector is registered with sysfs, to make its
          properties available to applications.
        </para>
        <sect4>
@@ -581,12 +581,12 @@ void intel_crt_init(struct drm_device *dev)
        <para>
          For each encoder, CRTC and connector, several functions must
          be provided, depending on the object type.  Encoder objects
-         need should provide a DPMS (basically on/off) function, mode fixup
+         need to provide a DPMS (basically on/off) function, mode fixup
          (for converting requested modes into native hardware timings),
          and prepare, set and commit functions for use by the core DRM
          helper functions.  Connector helpers need to provide mode fetch and
          validity functions as well as an encoder matching function for
-         returing an ideal encoder for a given connector.  The core
+         returning an ideal encoder for a given connector.  The core
          connector functions include a DPMS callback, (deprecated)
          save/restore routines, detection, mode probing, property handling,
          and cleanup functions.
index 0db3b4c74ad11109ac59e1486388b5675d49bc56..acbc65a08097777c41d5e400602bde9ed04ae160 100644 (file)
@@ -6,12 +6,12 @@ Supported adapters:
        http://www.ali.com.tw/eng/support/datasheet_request.php
 
 Authors:
-       Frodo Looijaard <frodol@dds.nl>, 
+       Frodo Looijaard <frodol@dds.nl>,
        Philip Edelbrock <phil@netroedge.com>,
        Mark D. Studebaker <mdsxyz123@yahoo.com>,
        Dan Eaton <dan.eaton@rocketlogix.com>,
        Stephen Rousset<stephen.rousset@rocketlogix.com>
-                                                                                               
+
 Description
 -----------
 
index 99ad4b9bcc32ec945235298ee1b9ffd8fbaa3e69..54691698d2ddd465f2a5e9ecd7a1e99ae1da57e5 100644 (file)
@@ -18,7 +18,7 @@ For an overview of these chips see http://www.acerlabs.com
 The M1563 southbridge is deceptively similar to the M1533, with a few
 notable exceptions. One of those happens to be the fact they upgraded the
 i2c core to be SMBus 2.0 compliant, and happens to be almost identical to
-the i2c controller found in the Intel 801 south bridges. 
+the i2c controller found in the Intel 801 south bridges.
 
 Features
 --------
index ff28d381bebe8daa880e344c767e4dad7ff4be14..600da90b8f12138fbf0bd5eb78c2bf0922317443 100644 (file)
@@ -6,8 +6,8 @@ Supported adapters:
        http://www.ali.com.tw/eng/support/datasheet_request.php
 
 Authors:
-       Frodo Looijaard <frodol@dds.nl>, 
-       Philip Edelbrock <phil@netroedge.com>, 
+       Frodo Looijaard <frodol@dds.nl>,
+       Philip Edelbrock <phil@netroedge.com>,
        Mark D. Studebaker <mdsxyz123@yahoo.com>
 
 Module Parameters
@@ -40,10 +40,10 @@ M1541 and M1543C South Bridges.
 The M1543C is a South bridge for desktop systems.
 The M1541 is a South bridge for portable systems.
 They are part of the following ALI chipsets:
-   
- * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and 
+
+ * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and
                100MHz CPU Front Side bus
- * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz 
+ * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz
                CPU Front Side bus
    Some Aladdin V motherboards:
        Asus P5A
@@ -77,7 +77,7 @@ output of lspci will show something similar to the following:
 ** then run lspci.
 ** If you see the 1533 and 5229 devices but NOT the 7101 device,
 ** then you must enable ACPI, the PMU, SMB, or something similar
-** in the BIOS. 
+** in the BIOS.
 ** The driver won't work if it can't find the M7101 device.
 
 The SMB controller is part of the M7101 device, which is an ACPI-compliant
@@ -87,8 +87,8 @@ The whole M7101 device has to be enabled for the SMB to work. You can't
 just enable the SMB alone. The SMB and the ACPI have separate I/O spaces.
 We make sure that the SMB is enabled. We leave the ACPI alone.
 
-Features 
--------- 
+Features
+--------
 
 This driver controls the SMB Host only. The SMB Slave
 controller on the M15X3 is not enabled. This driver does not use
index 6fc8f4c27c3ce58a12470e11efed3435dede8d85..b044e52654886c05dd37d16212a4cd2cf80419a3 100644 (file)
@@ -1,10 +1,10 @@
 Kernel driver i2c-pca-isa
 
 Supported adapters:
-This driver supports ISA boards using the Philips PCA 9564 
-Parallel bus to I2C bus controller 
+This driver supports ISA boards using the Philips PCA 9564
+Parallel bus to I2C bus controller
 
-Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems 
+Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems
 
 Module Parameters
 -----------------
@@ -12,12 +12,12 @@ Module Parameters
 * base int
  I/O base address
 * irq int
- IRQ interrupt 
-* clock int 
+ IRQ interrupt
+* clock int
  Clock rate as described in table 1 of PCA9564 datasheet
 
 Description
 -----------
 
-This driver supports ISA boards using the Philips PCA 9564 
-Parallel bus to I2C bus controller 
+This driver supports ISA boards using the Philips PCA 9564
+Parallel bus to I2C bus controller
index cc47db7d00a989da91f6cf99b1578a76ff7cc577..ecd21fb49a8f0c7cd780def05f3ca5408983c3c5 100644 (file)
@@ -1,41 +1,41 @@
 Kernel driver i2c-sis5595
 
-Authors: 
+Authors:
        Frodo Looijaard <frodol@dds.nl>,
         Mark D. Studebaker <mdsxyz123@yahoo.com>,
-       Philip Edelbrock <phil@netroedge.com> 
+       Philip Edelbrock <phil@netroedge.com>
 
 Supported adapters:
   * Silicon Integrated Systems Corp. SiS5595 Southbridge
     Datasheet: Publicly available at the Silicon Integrated Systems Corp. site.
 
-Note: all have mfr. ID 0x1039. 
-
-   SUPPORTED            PCI ID           
-        5595            0008 
-   Note: these chips contain a 0008 device which is incompatible with the 
-         5595. We recognize these by the presence of the listed 
-         "blacklist" PCI ID and refuse to load. 
-   NOT SUPPORTED        PCI ID          BLACKLIST PCI ID         
-         540            0008            0540 
-         550            0008            0550 
-        5513            0008            5511 
-        5581            0008            5597 
-        5582            0008            5597 
-        5597            0008            5597 
-        5598            0008            5597/5598 
-         630            0008            0630 
-         645            0008            0645 
-         646            0008            0646 
-         648            0008            0648 
-         650            0008            0650 
-         651            0008            0651 
-         730            0008            0730 
-         735            0008            0735 
-         745            0008            0745 
-         746            0008            0746 
+Note: all have mfr. ID 0x1039.
+
+   SUPPORTED            PCI ID
+        5595            0008
+
+   Note: these chips contain a 0008 device which is incompatible with the
+         5595. We recognize these by the presence of the listed
+         "blacklist" PCI ID and refuse to load.
+
+   NOT SUPPORTED        PCI ID          BLACKLIST PCI ID
+         540            0008            0540
+         550            0008            0550
+        5513            0008            5511
+        5581            0008            5597
+        5582            0008            5597
+        5597            0008            5597
+        5598            0008            5597/5598
+         630            0008            0630
+         645            0008            0645
+         646            0008            0646
+         648            0008            0648
+         650            0008            0650
+         651            0008            0651
+         730            0008            0730
+         735            0008            0735
+         745            0008            0745
+         746            0008            0746
 
 Module Parameters
 -----------------
index 9aca6889f748e2479052c5c42e9144f852ea42b7..629ea2c356fdb1d00594f57865cbe148c283ee82 100644 (file)
@@ -14,9 +14,9 @@ Module Parameters
 * force = [1|0] Forcibly enable the SIS630. DANGEROUS!
                This can be interesting for chipsets not named
                above to check if it works for you chipset, but DANGEROUS!
-               
-* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default, 
-                       what your BIOS use). DANGEROUS! This should be a bit 
+
+* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default,
+                       what your BIOS use). DANGEROUS! This should be a bit
                        faster, but freeze some systems (i.e. my Laptop).
 
 
@@ -44,6 +44,6 @@ Philip Edelbrock <phil@netroedge.com>
 - testing SiS730 support
 Mark M. Hoffman <mhoffman@lightlink.com>
 - bug fixes
+
 To anyone else which I forgot here ;), thanks!
 
index 200074f8136073bf988463272e0ea269020ac980..e9890709c508b25ed9878ab979797d1fc58a7a4b 100644 (file)
@@ -1,17 +1,17 @@
-The I2C protocol knows about two kinds of device addresses: normal 7 bit 
+The I2C protocol knows about two kinds of device addresses: normal 7 bit
 addresses, and an extended set of 10 bit addresses. The sets of addresses
 do not intersect: the 7 bit address 0x10 is not the same as the 10 bit
 address 0x10 (though a single device could respond to both of them). You
 select a 10 bit address by adding an extra byte after the address
 byte:
-  S Addr7 Rd/Wr ....  
+  S Addr7 Rd/Wr ....
 becomes
   S 11110 Addr10 Rd/Wr
 S is the start bit, Rd/Wr the read/write bit, and if you count the number
 of bits, you will see the there are 8 after the S bit for 7 bit addresses,
 and 16 after the S bit for 10 bit addresses.
 
-WARNING! The current 10 bit address support is EXPERIMENTAL. There are 
+WARNING! The current 10 bit address support is EXPERIMENTAL. There are
 several places in the code that will cause SEVERE PROBLEMS with 10 bit
 addresses, even though there is some basic handling and hooks. Also,
 almost no supported adapter handles the 10 bit addresses correctly.
index 6f8c1cabbc5d1fefe2a18d3c77354b54426d3363..634c625da8ce3435e23118e442c47d2d5b903898 100644 (file)
@@ -65,7 +65,7 @@ CROSS_COMPILE
 Specify an optional fixed part of the binutils filename.
 CROSS_COMPILE can be a part of the filename or the full path.
 
-CROSS_COMPILE is also used for ccache is some setups.
+CROSS_COMPILE is also used for ccache in some setups.
 
 CF
 --------------------------------------------------
@@ -162,3 +162,7 @@ For tags/TAGS/cscope targets, you can specify more than one arch
 to be included in the databases, separated by blank space. E.g.:
 
     $ make ALLSOURCE_ARCHS="x86 mips arm" tags
+
+To get all available archs you can also specify all. E.g.:
+
+    $ make ALLSOURCE_ARCHS=all tags
index aa60d1f627e523929dff9e787498e96ef661cfe6..c91ccc0720fa97f42a1a616fd83e23628ae85ab1 100644 (file)
@@ -66,14 +66,14 @@ of advantages of mutexes:
 
     c0377ccb <mutex_lock>:
     c0377ccb:       f0 ff 08                lock decl (%eax)
-    c0377cce:       78 0e                   js     c0377cde <.text.lock.mutex>
+    c0377cce:       78 0e                   js     c0377cde <.text..lock.mutex>
     c0377cd0:       c3                      ret
 
    the unlocking fastpath is equally tight:
 
     c0377cd1 <mutex_unlock>:
     c0377cd1:       f0 ff 00                lock incl (%eax)
-    c0377cd4:       7e 0f                   jle    c0377ce5 <.text.lock.mutex+0x7>
+    c0377cd4:       7e 0f                   jle    c0377ce5 <.text..lock.mutex+0x7>
     c0377cd6:       c3                      ret
 
  - 'struct mutex' semantics are well-defined and are enforced if
index c85625f4ab257c38d8522c7b669a6a9b82306e89..73f75f8a87dc099f0e788aeb353eb9c3eae50f12 100644 (file)
@@ -2,7 +2,7 @@
 obj- := dummy.o
 
 # List of programs to build
-hostprogs-y := hpet_example
+hostprogs-$(CONFIG_X86) := hpet_example
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
index 13608bd2e7913941bae445f08c201912f798c2fd..a73dd8030afa5f823d9e210a04778b6b3498993c 100644 (file)
@@ -3242,7 +3242,7 @@ L:        autofs@linux.kernel.org
 S:     Maintained
 F:     fs/autofs4/
 
-KERNEL BUILD
+KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
 M:     Michal Marek <mmarek@suse.cz>
 T:     git git://repo.or.cz/linux-kbuild.git for-next
 T:     git git://repo.or.cz/linux-kbuild.git for-linus
@@ -3251,6 +3251,9 @@ S:        Maintained
 F:     Documentation/kbuild/
 F:     Makefile
 F:     scripts/Makefile.*
+F:     scripts/basic/
+F:     scripts/mk*
+F:     scripts/package/
 
 KERNEL JANITORS
 L:     kernel-janitors@vger.kernel.org
@@ -3500,9 +3503,8 @@ F:        arch/powerpc/platforms/83xx/
 
 LINUX FOR POWERPC PA SEMI PWRFICIENT
 M:     Olof Johansson <olof@lixom.net>
-W:     http://www.pasemi.com/
 L:     linuxppc-dev@ozlabs.org
-S:     Supported
+S:     Maintained
 F:     arch/powerpc/platforms/pasemi/
 F:     drivers/*/*pasemi*
 F:     drivers/*/*/*pasemi*
index 6e39ec701cbfd06565e765af97ca84bdba4f9809..efdc3d0d8e60be647fedfb224d265c1b184b4d70 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -183,11 +183,14 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 # CROSS_COMPILE can be set on the command line
 # make CROSS_COMPILE=ia64-linux-
 # Alternatively CROSS_COMPILE can be set in the environment.
+# A third alternative is to store a setting in .config so that plain
+# "make" in the configured kernel build directory always uses that.
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 export KBUILD_BUILDHOST := $(SUBARCH)
 ARCH           ?= $(SUBARCH)
 CROSS_COMPILE  ?=
+CROSS_COMPILE  ?= $(CONFIG_CROSS_COMPILE:"%"=%)
 
 # Architecture as present in compile.h
 UTS_MACHINE    := $(ARCH)
@@ -576,9 +579,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
 # disable invalid "can't wrap" optimizations for signed / pointers
 KBUILD_CFLAGS  += $(call cc-option,-fno-strict-overflow)
 
-# revert to pre-gcc-4.4 behaviour of .eh_frame
-KBUILD_CFLAGS  += $(call cc-option,-fno-dwarf2-cfi-asm)
-
 # conserve stack if available
 KBUILD_CFLAGS   += $(call cc-option,-fconserve-stack)
 
@@ -882,9 +882,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
 PHONY += $(vmlinux-dirs)
 $(vmlinux-dirs): prepare scripts
        $(Q)$(MAKE) $(build)=$@
-ifdef CONFIG_MODULES
-       $(Q)$(MAKE) $(modbuiltin)=$@
-endif
 
 # Build the kernel release string
 #
@@ -907,14 +904,19 @@ endif
 #        $(localver)
 #          localversion*               (files without backups, containing '~')
 #          $(CONFIG_LOCALVERSION)      (from kernel config setting)
-#        $(localver-auto)              (only if CONFIG_LOCALVERSION_AUTO is set)
-#          ./scripts/setlocalversion   (SCM tag, if one exists)
-#          $(LOCALVERSION)             (from make command line if provided)
+#        $(LOCALVERSION)               (from make command line, if provided)
+#        $(localver-extra)
+#          $(scm-identifier)           (unique SCM tag, if one exists)
+#            ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO)
+#            .scmversion               (only with CONFIG_LOCALVERSION_AUTO)
+#          +                           (only without CONFIG_LOCALVERSION_AUTO
+#                                       and without LOCALVERSION= and
+#                                       repository is at non-tagged commit)
 #
-#  Note how the final $(localver-auto) string is included *only* if the
-# kernel config option CONFIG_LOCALVERSION_AUTO is selected.  Also, at the
-# moment, only git is supported but other SCMs can edit the script
-# scripts/setlocalversion and add the appropriate checks as needed.
+# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has
+# been revised beyond a tagged commit, `+' is appended to the version string
+# when not overridden by using "make LOCALVERSION=".  This indicates that the
+# kernel is not a vanilla release version and has been modified.
 
 pattern = ".*/localversion[^~]*"
 string  = $(shell cat /dev/null \
@@ -923,26 +925,32 @@ string  = $(shell cat /dev/null \
 localver = $(subst $(space),, $(string) \
                              $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
 
-# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
-# and if the SCM is know a tag from the SCM is appended.
-# The appended tag is determined by the SCM used.
+# scripts/setlocalversion is called to create a unique identifier if the source
+# is managed by a known SCM and the repository has been revised since the last
+# tagged (release) commit.  The format of the identifier is determined by the
+# SCM's implementation.
 #
 # .scmversion is used when generating rpm packages so we do not loose
 # the version information from the SCM when we do the build of the kernel
 # from the copied source
-ifdef CONFIG_LOCALVERSION_AUTO
-
 ifeq ($(wildcard .scmversion),)
-        _localver-auto = $(shell $(CONFIG_SHELL) \
+        scm-identifier = $(shell $(CONFIG_SHELL) \
                          $(srctree)/scripts/setlocalversion $(srctree))
 else
-        _localver-auto = $(shell cat .scmversion 2> /dev/null)
+        scm-identifier = $(shell cat .scmversion 2> /dev/null)
 endif
 
-       localver-auto  = $(LOCALVERSION)$(_localver-auto)
+ifdef CONFIG_LOCALVERSION_AUTO
+       localver-extra = $(scm-identifier)
+else
+       ifneq ($(scm-identifier),)
+               ifeq ($(LOCALVERSION),)
+                       localver-extra = +
+               endif
+       endif
 endif
 
-localver-full = $(localver)$(localver-auto)
+localver-full = $(localver)$(LOCALVERSION)$(localver-extra)
 
 # Store (new) KERNELRELASE string in include/config/kernel.release
 kernelrelease = $(KERNELVERSION)$(localver-full)
@@ -1089,11 +1097,16 @@ all: modules
 PHONY += modules
 modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
        $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
-       $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin
        @$(kecho) '  Building modules, stage 2.';
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
 
+modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
+       $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
+
+%/modules.builtin: include/config/auto.conf
+       $(Q)$(MAKE) $(modbuiltin)=$*
+
 
 # Target to prepare building external modules
 PHONY += modules_prepare
@@ -1104,7 +1117,7 @@ PHONY += modules_install
 modules_install: _modinst_ _modinst_post
 
 PHONY += _modinst_
-_modinst_:
+_modinst_: modules.builtin
        @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
                echo "Warning: you may need to install module-init-tools"; \
                echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
@@ -1247,7 +1260,9 @@ help:
        @echo  '  firmware_install- Install all firmware to INSTALL_FW_PATH'
        @echo  '                    (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
        @echo  '  dir/            - Build all files in dir and below'
-       @echo  '  dir/file.[ois]  - Build specified target only'
+       @echo  '  dir/file.[oisS] - Build specified target only'
+       @echo  '  dir/file.lst    - Build specified mixed source/assembly target only'
+       @echo  '                    (requires a recent binutils and recent build (System.map))'
        @echo  '  dir/file.ko     - Build module including final link'
        @echo  '  modules_prepare - Set up for building external modules'
        @echo  '  tags/TAGS       - Generate tags file for editors'
index 77630df94343672e8b3aceeceb2b6f7416e05db5..884275629ef7405dfbbb901e0758fdc75594fd3e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
+#include <linux/smp_lock.h>
 #include <linux/bcd.h>
 #include <linux/capability.h>
 
@@ -238,9 +239,7 @@ static unsigned char days_in_mo[] =
 
 /* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
 
-static int
-rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-         unsigned long arg) 
+static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        unsigned long flags;
 
@@ -354,6 +353,17 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 }
 
+static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       ret = rtc_ioctl(file, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 static void
 print_rtc_status(void)
 {
@@ -375,8 +385,8 @@ print_rtc_status(void)
 /* The various file operations we support. */
 
 static const struct file_operations rtc_fops = {
-       .owner =        THIS_MODULE,
-       .ioctl =        rtc_ioctl,
+       .owner          = THIS_MODULE,
+       .unlocked_ioctl = rtc_unlocked_ioctl,
 }; 
 
 /* Probe for the chip by writing something to its RAM and try reading it back. */
index 1e90c1a9c849bd4453b462e3b611808171e5c475..7dcb1f85f42b157c93eaaac921381e8ae163ca84 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/bcd.h>
 #include <linux/mutex.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -53,7 +54,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
 static const unsigned char days_in_month[] =
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
-int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long);
 
 /* Cache VL bit value read at driver init since writing the RTC_SECOND
  * register clears the VL status.
@@ -62,7 +63,7 @@ static int voltage_low;
 
 static const struct file_operations pcf8563_fops = {
        .owner = THIS_MODULE,
-       .ioctl = pcf8563_ioctl,
+       .unlocked_ioctl = pcf8563_unlocked_ioctl,
 };
 
 unsigned char
@@ -212,8 +213,7 @@ pcf8563_exit(void)
  * ioctl calls for this driver. Why return -ENOTTY upon error? Because
  * POSIX says so!
  */
-int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
+static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        /* Some sanity checks. */
        if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -339,6 +339,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
+static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       return pcf8563_ioctl(filp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 static int __init pcf8563_register(void)
 {
        if (pcf8563_init() < 0) {
index 1a61efc139826870b156eabc26987f9a3319852a..a0c0df8be9c8d966f34b026a078b4f150b6c4139 100644 (file)
@@ -17,8 +17,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
-#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
+#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
+#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
 
 /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
  * global just so that the kernel gdb can use it.
@@ -116,12 +116,12 @@ static unsigned int startup_crisv10_irq(unsigned int irq)
 
 static void enable_crisv10_irq(unsigned int irq)
 {
-       unmask_irq(irq);
+       crisv10_unmask_irq(irq);
 }
 
 static void disable_crisv10_irq(unsigned int irq)
 {
-       mask_irq(irq);
+       crisv10_mask_irq(irq);
 }
 
 static void ack_crisv10_irq(unsigned int irq)
index e5fb44f505c541f63950f162a933b979dcd00d20..49f5b8ca5b47bd595e78393914571c7442c756e2 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: dmacopy.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ 
- *
+/*
  * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax
  */
 
@@ -13,11 +12,11 @@ void *dma_memcpy(void *pdst,
                 unsigned int pn)
 {
        static etrax_dma_descr indma, outdma;
-       
-       D(printk("dma_memcpy %d bytes... ", pn));
+
+       D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn));
 
 #if 0
-       *R_GEN_CONFIG = genconfig_shadow = 
+       *R_GEN_CONFIG = genconfig_shadow =
                (genconfig_shadow & ~0x3c0000) |
                IO_STATE(R_GEN_CONFIG, dma6, intdma7) |
                IO_STATE(R_GEN_CONFIG, dma7, intdma6);
@@ -32,11 +31,11 @@ void *dma_memcpy(void *pdst,
        *R_DMA_CH7_FIRST = &outdma;
        *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
        *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);
-       
-       while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ;
 
-       D(printk("done\n"));
+       while (*R_DMA_CH7_CMD == 1)
+               /* wait for completion */;
 
+       D(printk(KERN_DEBUG "done\n"));
 }
 
 
index 56905aaa7b6e6b287bd3ad131833dd35903513fd..c09f19f478a586b04c252ca6d2ed43433cdaa049 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * $Id: hw_settings.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
- * 
  * This table is used by some tools to extract hardware parameters.
  * The table should be included in the kernel and the decompressor.
  * Don't forget to update the tools if you change this table.
  *
  * Copyright (C) 2001 Axis Communications AB
  *
- * Authors:  Mikael Starvik (starvik@axis.com) 
+ * Authors:  Mikael Starvik (starvik@axis.com)
  */
 
 #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
 #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
                (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
                (CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
-       
+
        .ascii "HW_PARAM_MAGIC" ; Magic number
        .dword 0xc0004000       ; Kernel start address
 
        ; Debug port
 #ifdef CONFIG_ETRAX_DEBUG_PORT0
-       .dword 0                
+       .dword 0
 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
        .dword 1
 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
@@ -30,7 +28,7 @@
        .dword 3
 #else
        .dword 4 ; No debug
-#endif                 
+#endif
 
        ; SDRAM or EDO DRAM?
 #ifdef CONFIG_ETRAX_SDRAM
@@ -39,7 +37,7 @@
        .dword 0
 #endif
 
-       ; Register values 
+       ; Register values
        .dword R_WAITSTATES
        .dword CONFIG_ETRAX_DEF_R_WAITSTATES
        .dword R_BUS_CONFIG
@@ -56,7 +54,7 @@
        .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING
 #endif
        .dword R_PORT_PA_SET
-       .dword PA_SET_VALUE 
+       .dword PA_SET_VALUE
        .dword R_PORT_PB_SET
        .dword PB_SET_VALUE
        .dword 0 ; No more register values
index b9e328e688be8d70837d895698c4d87ee71e696f..a2dd740c5907868f54985a1176ea73df3d752c63 100644 (file)
@@ -360,24 +360,10 @@ config ETRAX_SER4_DSR_BIT
        string "Ser 4 DSR bit (empty = not used)"
        depends on ETRAX_SERIAL_PORT4
 
-config ETRAX_SER3_CD_BIT
+config ETRAX_SER4_CD_BIT
        string "Ser 4 CD bit (empty = not used)"
        depends on ETRAX_SERIAL_PORT4
 
-config ETRAX_RS485
-       bool "RS-485 support"
-       depends on ETRAXFS_SERIAL
-       help
-         Enables support for RS-485 serial communication.  For a primer on
-         RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
-
-config ETRAX_RS485_DISABLE_RECEIVER
-       bool "Disable serial receiver"
-       depends on ETRAX_RS485
-       help
-         It is necessary to disable the serial receiver to avoid serial
-         loopback.  Not all products are able to do this in software only.
-
 config ETRAX_SYNCHRONOUS_SERIAL
        bool "Synchronous serial-port support"
        depends on ETRAX_ARCH_V32
index 506826399ae72edbcca777b79898a1c886475f59..2fd6a740d895ab2c1e1b2fe02fbf97857dccbdae 100644 (file)
@@ -649,10 +649,10 @@ i2c_release(struct inode *inode, struct file *filp)
 /* Main device API. ioctl's to write or read to/from i2c registers.
  */
 
-static int
-i2c_ioctl(struct inode *inode, struct file *file,
-         unsigned int cmd, unsigned long arg)
+static long
+i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
+       int ret;
        if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
                return -ENOTTY;
        }
@@ -665,9 +665,13 @@ i2c_ioctl(struct inode *inode, struct file *file,
                                 I2C_ARGREG(arg),
                                 I2C_ARGVALUE(arg)));
 
-                       return i2c_writereg(I2C_ARGSLAVE(arg),
+                       lock_kernel();
+                       ret = i2c_writereg(I2C_ARGSLAVE(arg),
                                            I2C_ARGREG(arg),
                                            I2C_ARGVALUE(arg));
+                       unlock_kernel();
+                       return ret;
+
                case I2C_READREG:
                {
                        unsigned char val;
@@ -675,7 +679,9 @@ i2c_ioctl(struct inode *inode, struct file *file,
                        D(printk("i2cr %d %d ",
                                I2C_ARGSLAVE(arg),
                                I2C_ARGREG(arg)));
+                       lock_kernel();
                        val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
+                       unlock_kernel();
                        D(printk("= %d\n", val));
                        return val;
                }
@@ -688,10 +694,10 @@ i2c_ioctl(struct inode *inode, struct file *file,
 }
 
 static const struct file_operations i2c_fops = {
-       .owner =    THIS_MODULE,
-       .ioctl =    i2c_ioctl,
-       .open =     i2c_open,
-       .release  i2c_release,
+       .owner          = THIS_MODULE,
+       .unlocked_ioctl = i2c_ioctl,
+       .open           = i2c_open,
+       .release        = i2c_release,
 };
 
 static int __init i2c_init(void)
index f4478506e52ca1df58b52180ffd871e77c51e726..bef6eb53b1539b9e6974b1e472aa638187e6ca6c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/ioctl.h>
+#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/bcd.h>
 #include <linux/mutex.h>
@@ -49,7 +50,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
 static const unsigned char days_in_month[] =
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
-int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
 /* Cache VL bit value read at driver init since writing the RTC_SECOND
  * register clears the VL status.
@@ -57,8 +58,8 @@ int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 static int voltage_low;
 
 static const struct file_operations pcf8563_fops = {
-       .owner =        THIS_MODULE,
-       .ioctl =        pcf8563_ioctl
+       .owner          = THIS_MODULE,
+       .unlocked_ioctl = pcf8563_unlocked_ioctl,
 };
 
 unsigned char
@@ -208,8 +209,7 @@ pcf8563_exit(void)
  * ioctl calls for this driver. Why return -ENOTTY upon error? Because
  * POSIX says so!
  */
-int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
+static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        /* Some sanity checks. */
        if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -335,6 +335,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
+static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       return pcf8563_ioctl(filp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 static int __init pcf8563_register(void)
 {
        if (pcf8563_init() < 0) {
index 64933e2c0f5b88e4ead5e5d5f23bbb1c5421182a..bde8d1a10cadd31edb5b0120b0bc3feab73e07f9 100644 (file)
@@ -24,5 +24,5 @@ EXPORT_SYMBOL(crisv32_io_get_name);
 EXPORT_SYMBOL(crisv32_io_get);
 
 /* Functions masking/unmasking interrupts */
-EXPORT_SYMBOL(mask_irq);
-EXPORT_SYMBOL(unmask_irq);
+EXPORT_SYMBOL(crisv32_mask_irq);
+EXPORT_SYMBOL(crisv32_unmask_irq);
index b6241198fb98d86c72ab48999e40989fdf552411..0b1febe44aa3a5b61967253b2549b927cb5a1055 100644 (file)
@@ -280,8 +280,7 @@ out:
        return cpu;
 }
 
-void
-mask_irq(int irq)
+void crisv32_mask_irq(int irq)
 {
        int cpu;
 
@@ -289,8 +288,7 @@ mask_irq(int irq)
                block_irq(irq, cpu);
 }
 
-void
-unmask_irq(int irq)
+void crisv32_unmask_irq(int irq)
 {
        unblock_irq(irq, irq_cpu(irq));
 }
@@ -298,23 +296,23 @@ unmask_irq(int irq)
 
 static unsigned int startup_crisv32_irq(unsigned int irq)
 {
-       unmask_irq(irq);
+       crisv32_unmask_irq(irq);
        return 0;
 }
 
 static void shutdown_crisv32_irq(unsigned int irq)
 {
-       mask_irq(irq);
+       crisv32_mask_irq(irq);
 }
 
 static void enable_crisv32_irq(unsigned int irq)
 {
-       unmask_irq(irq);
+       crisv32_unmask_irq(irq);
 }
 
 static void disable_crisv32_irq(unsigned int irq)
 {
-       mask_irq(irq);
+       crisv32_mask_irq(irq);
 }
 
 static void ack_crisv32_irq(unsigned int irq)
index 058adddf4e4b1f39c981304cd2f3856f4edc850b..84fed3b4b0799dd35991e57eaa22aca18767c6a3 100644 (file)
@@ -168,8 +168,8 @@ void __init smp_callin(void)
 
        /* Enable IRQ and idle */
        REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
-       unmask_irq(IPI_INTR_VECT);
-       unmask_irq(TIMER0_INTR_VECT);
+       crisv32_unmask_irq(IPI_INTR_VECT);
+       crisv32_unmask_irq(TIMER0_INTR_VECT);
        preempt_disable();
        notify_cpu_starting(cpu);
        local_irq_enable();
index 6248004eca1c3b74b32e643e4b7e631e340179ba..7d345947b3ee271f0bc9d5206431d419d56f470c 100644 (file)
@@ -93,15 +93,16 @@ void set_break_vector(int n, irqvectptr addr);
   "push $r10\n\t"       /* push orig_r10 */ \
   "clear.d [$sp=$sp-4]\n\t"  /* frametype - this is a normal stackframe */
 
-  /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq */
+/* BLOCK_IRQ and UNBLOCK_IRQ do the same as
+ * crisv10_mask_irq and crisv10_unmask_irq */
 
 #define BLOCK_IRQ(mask,nr) \
   "move.d " #mask ",$r0\n\t" \
-  "move.d $r0,[0xb00000d8]\n\t" 
-  
+  "move.d $r0,[0xb00000d8]\n\t"
+
 #define UNBLOCK_IRQ(mask) \
   "move.d " #mask ",$r0\n\t" \
-  "move.d $r0,[0xb00000dc]\n\t" 
+  "move.d $r0,[0xb00000dc]\n\t"
 
 #define IRQ_NAME2(nr) nr##_interrupt(void)
 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
index 9e4c9fbdfddf63a905ad9e9c71bac6cbda6a8764..b31e9984f84964570b16e743892f4432af730269 100644 (file)
@@ -23,8 +23,8 @@ struct etrax_interrupt_vector {
 
 extern struct etrax_interrupt_vector *etrax_irv;       /* head.S */
 
-void mask_irq(int irq);
-void unmask_irq(int irq);
+void crisv32_mask_irq(int irq);
+void crisv32_unmask_irq(int irq);
 
 void set_exception_vector(int n, irqvectptr addr);
 
index 0e47994e40be536de84bcb6ed85a37770fb6015a..484fcf8667c01500fa46d71dcdbef0a7fce314f8 100644 (file)
@@ -2,22 +2,9 @@
 #define _ASMCRIS_PARAM_H
 
 /* Currently we assume that HZ=100 is good for CRIS. */
-#ifdef __KERNEL__
-# define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
-# define USER_HZ       100             /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
 
 #define EXEC_PAGESIZE  8192
 
-#ifndef NOGROUP
-#define NOGROUP                (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64      /* max length of hostname */
+#include <asm-generic/param.h>
 
-#endif
+#endif /* _ASMCRIS_PARAM_H */
index bd0bdf908d937c58323f35fb8e7acb7897e2c0bf..cbb6958a31471f8348604822c74224f29511fb25 100644 (file)
@@ -21,7 +21,7 @@
 #
 # the break handler has its own stack
 #
-       .section        .bss.stack
+       .section        .bss..stack
        .globl          __break_user_context
        .balign         THREAD_SIZE
 __break_stack:
@@ -63,7 +63,7 @@ __break_trace_through_exceptions:
 # entry point for Break Exceptions/Interrupts
 #
 ###############################################################################
-       .section        .text.break
+       .section        .text..break
        .balign         4
        .globl          __entry_break
 __entry_break:
index 189397ec012aca45f87cc983ec414b18c9caf3bf..63d579bf1c2974d6cec4972af17ee1db812519c5 100644 (file)
@@ -38,7 +38,7 @@
 
 #define nr_syscalls ((syscall_table_size)/4)
 
-       .section        .text.entry
+       .section        .text..entry
        .balign         4
 
 .macro LEDS val
index b825ef3f2d548970e2d2745de5cf7c6165d5f70f..e9a8cc63ac9413a0233f6f55ec0d91693ee3cf57 100644 (file)
@@ -542,7 +542,7 @@ __head_end:
        .size           _boot, .-_boot
 
        # provide a point for GDB to place a break
-       .section        .text.start,"ax"
+       .section        .text..start,"ax"
        .globl          _start
        .balign         4
 _start:
index cbe811fccfcca0f2ef765a00c5924d2294ece358..8b973f3cc90e432ba2ac4a72dc602f5e4e5e3db3 100644 (file)
@@ -57,10 +57,10 @@ SECTIONS
   _text = .;
   _stext = .;
   .text : {
-       *(.text.start)
-       *(.text.entry)
-       *(.text.break)
-       *(.text.tlbmiss)
+       *(.text..start)
+       *(.text..entry)
+       *(.text..break)
+       *(.text..tlbmiss)
        TEXT_TEXT
        SCHED_TEXT
        LOCK_TEXT
@@ -114,7 +114,7 @@ SECTIONS
 
   .sbss                : { *(.sbss .sbss.*) }
   .bss         : { *(.bss .bss.*) }
-  .bss.stack   : { *(.bss) }
+  .bss..stack  : { *(.bss) }
 
   __bss_stop = .;
   _end = . ;
index 7f392bc651a358ad062dff38233f4f204d0dc4aa..f3ac019bb18bf401155d254d2cbcb6a426fbbf1a 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/spr-regs.h>
 
-       .section        .text.tlbmiss
+       .section        .text..tlbmiss
        .balign         4
 
        .globl          __entry_insn_mmu_miss
index 985a81a2435a08715fc89a5fa6da5b322d041b90..10e9a2d1cc6c747586a2be624eec01849fd53c87 100644 (file)
@@ -9,7 +9,7 @@
 
 #define SRAM_START 0xff4000
 
-       .section        .text.startup
+       .section        .text..startup
        .global startup
 startup:
        mov.l   #SRAM_START+0x8000, sp
index 65e2a0d1ae396bd52e72f28270dcc935966675e5..a0a3a0ed54ef17450ae9dbe7f7a38e0789098fdd 100644 (file)
@@ -4,7 +4,7 @@ SECTIONS
         {
         __stext = . ;
        __text = .;
-              *(.text.startup)
+              *(.text..startup)
               *(.text)
         __etext = . ;
         }
index c1642fd640297b0796dec52172b80d8e0652f7dc..3ab6d75aa3dbdd68e59cc7dab789ab60ccd9d356 100644 (file)
@@ -70,12 +70,12 @@ name:
  * path (ivt.S - TLB miss processing) or in places where it might not be
  * safe to use a "tpa" instruction (mca_asm.S - error recovery).
  */
-       .section ".data.patch.vtop", "a"        // declare section & section attributes
+       .section ".data..patch.vtop", "a"       // declare section & section attributes
        .previous
 
 #define        LOAD_PHYSICAL(pr, reg, obj)             \
 [1:](pr)movl reg = obj;                                \
-       .xdata4 ".data.patch.vtop", 1b-.
+       .xdata4 ".data..patch.vtop", 1b-.
 
 /*
  * For now, we always put in the McKinley E9 workaround.  On CPUs that don't need it,
@@ -84,11 +84,11 @@ name:
 #define DO_MCKINLEY_E9_WORKAROUND
 
 #ifdef DO_MCKINLEY_E9_WORKAROUND
-       .section ".data.patch.mckinley_e9", "a"
+       .section ".data..patch.mckinley_e9", "a"
        .previous
 /* workaround for Itanium 2 Errata 9: */
 # define FSYS_RETURN                                   \
-       .xdata4 ".data.patch.mckinley_e9", 1f-.;        \
+       .xdata4 ".data..patch.mckinley_e9", 1f-.;       \
 1:{ .mib;                                              \
        nop.m 0;                                        \
        mov r16=ar.pfs;                                 \
@@ -107,11 +107,11 @@ name:
  * If physical stack register size is different from DEF_NUM_STACK_REG,
  * dynamically patch the kernel for correct size.
  */
-       .section ".data.patch.phys_stack_reg", "a"
+       .section ".data..patch.phys_stack_reg", "a"
        .previous
 #define LOAD_PHYS_STACK_REG_SIZE(reg)                  \
 [1:]   adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0;        \
-       .xdata4 ".data.patch.phys_stack_reg", 1b-.
+       .xdata4 ".data..patch.phys_stack_reg", 1b-.
 
 /*
  * Up until early 2004, use of .align within a function caused bad unwind info.
index e7482bd628ff21ab21d98277d1c2d79f14cfea38..988254a7d34944d5e0cc8f22bb66823af349c86f 100644 (file)
@@ -24,6 +24,6 @@
 # define SMP_CACHE_BYTES       (1 << 3)
 #endif
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 #endif /* _ASM_IA64_CACHE_H */
index 1bd4082656940709a715b69b339b86ea3b80db1e..14aa1c58912b6ff70a62d35f77c052fa80ee2930 100644 (file)
@@ -31,7 +31,7 @@ extern void *per_cpu_init(void);
 
 #endif /* SMP */
 
-#define PER_CPU_BASE_SECTION ".data.percpu"
+#define PER_CPU_BASE_SECTION ".data..percpu"
 
 /*
  * Be extremely careful when taking the address of this variable!  Due to virtual
index ab9b03a9adcc4680fd369730e319eeac8fde4728..ceeffc50976462812dec9b9f18105052600862f4 100644 (file)
@@ -21,7 +21,7 @@ GATECFLAGS_gate-syms.o = -r
 $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
        $(call if_changed,gate)
 
-# gate-data.o contains the gate DSO image as data in section .data.gate.
+# gate-data.o contains the gate DSO image as data in section .data..gate.
 # We must build gate.so before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/gate-data.o: $(obj)/gate.so
index 258c0a3238fb1984b5cf771261e9d7a185e3e06d..b3ef1c72e132b44e00ade63410380370e25114e2 100644 (file)
@@ -1,3 +1,3 @@
-       .section .data.gate, "aw"
+       .section .data..gate, "aw"
 
        .incbin "arch/ia64/kernel/gate.so"
index cf5e0a105e16521cf20f1fc6aa1957cf5af2e97f..245d3e1ec7e1b00dc97f125f4ef0cc90e45b0aa8 100644 (file)
  * to targets outside the shared object) and to avoid multi-phase kernel builds, we
  * simply create minimalistic "patch lists" in special ELF sections.
  */
-       .section ".data.patch.fsyscall_table", "a"
+       .section ".data..patch.fsyscall_table", "a"
        .previous
 #define LOAD_FSYSCALL_TABLE(reg)                       \
 [1:]   movl reg=0;                                     \
-       .xdata4 ".data.patch.fsyscall_table", 1b-.
+       .xdata4 ".data..patch.fsyscall_table", 1b-.
 
-       .section ".data.patch.brl_fsys_bubble_down", "a"
+       .section ".data..patch.brl_fsys_bubble_down", "a"
        .previous
 #define BRL_COND_FSYS_BUBBLE_DOWN(pr)                  \
 [1:](pr)brl.cond.sptk 0;                               \
        ;;                                              \
-       .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
+       .xdata4 ".data..patch.brl_fsys_bubble_down", 1b-.
 
 GLOBAL_ENTRY(__kernel_syscall_via_break)
        .prologue
index 88c64ed47c36bb8d20e9166775bd14cc55f166ed..d32b0855110ae96e358547c9f0c835ae7000f0c2 100644 (file)
@@ -33,21 +33,21 @@ SECTIONS
         */
        . = GATE_ADDR + 0x600;
 
-       .data.patch             : {
+       .data..patch            : {
                __paravirt_start_gate_mckinley_e9_patchlist = .;
-               *(.data.patch.mckinley_e9)
+               *(.data..patch.mckinley_e9)
                __paravirt_end_gate_mckinley_e9_patchlist = .;
 
                __paravirt_start_gate_vtop_patchlist = .;
-               *(.data.patch.vtop)
+               *(.data..patch.vtop)
                __paravirt_end_gate_vtop_patchlist = .;
 
                __paravirt_start_gate_fsyscall_patchlist = .;
-               *(.data.patch.fsyscall_table)
+               *(.data..patch.fsyscall_table)
                __paravirt_end_gate_fsyscall_patchlist = .;
 
                __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
-               *(.data.patch.brl_fsys_bubble_down)
+               *(.data..patch.brl_fsys_bubble_down)
                __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
        }                                               :readable
 
index e253ab8fcbc8923a789dc12e0afae0dcbf7891b7..f9efe9739d3fe5da25621d278e4c7a2e6a8110e5 100644 (file)
@@ -23,7 +23,7 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
  * Initial task structure.
  *
  * We need to make sure that this is properly aligned due to the way process stacks are
- * handled. This is done by having a special ".data.init_task" section...
+ * handled. This is done by having a special ".data..init_task" section...
  */
 #define init_thread_info       init_task_mem.s.thread_info
 
index 179fd122e837dadf5bdc153e47aa288592e47ed6..d93e396bf5998813114d0ac1cbbd92551d964551 100644 (file)
@@ -82,7 +82,7 @@
        mov r19=n;;                     /* prepare to save predicates */                \
        br.sptk.many dispatch_to_fault_handler
 
-       .section .text.ivt,"ax"
+       .section .text..ivt,"ax"
 
        .align 32768    // align on 32KB boundary
        .global ia64_ivt
index 292e214a3b84ab323c959e4f7b68283d0275bd2f..d56753a11636b723b402a32df60fc762af3c5e38 100644 (file)
@@ -16,7 +16,7 @@
 #define ACCOUNT_SYS_ENTER
 #endif
 
-.section ".data.patch.rse", "a"
+.section ".data..patch.rse", "a"
 .previous
 
 /*
 (pUStk) extr.u r17=r18,3,6;                    \
 (pUStk)        sub r16=r18,r22;                        \
 [1:](pKStk)    br.cond.sptk.many 1f;           \
-       .xdata4 ".data.patch.rse",1b-.          \
+       .xdata4 ".data..patch.rse",1b-.         \
        ;;                                      \
        cmp.ge p6,p7 = 33,r17;                  \
        ;;                                      \
index 6158560d7f1738993ee4fa00437cd809c8854661..92d880c4d3d1158711759f6b9885fc3c5171f380 100644 (file)
@@ -28,7 +28,7 @@
 #include "entry.h"
 
 #define DATA8(sym, init_value)                 \
-       .pushsection .data.read_mostly ;        \
+       .pushsection .data..read_mostly ;       \
        .align 8 ;                              \
        .global sym ;                           \
        sym: ;                                  \
index 1295ba327f6ff2728f422079aedd6090bc51013b..e07218a2577fc9c797e5237580c510dba23e83e2 100644 (file)
@@ -8,7 +8,7 @@
 
 #define IVT_TEXT                                                       \
                VMLINUX_SYMBOL(__start_ivt_text) = .;                   \
-               *(.text.ivt)                                            \
+               *(.text..ivt)                                           \
                VMLINUX_SYMBOL(__end_ivt_text) = .;
 
 OUTPUT_FORMAT("elf64-ia64-little")
@@ -54,8 +54,8 @@ SECTIONS
   .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
        { *(.text2) }
 #ifdef CONFIG_SMP
-  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET)
-       { *(.text.lock) }
+  .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET)
+       { *(.text..lock) }
 #endif
   _etext = .;
 
@@ -75,10 +75,10 @@ SECTIONS
          __stop___mca_table = .;
        }
 
-  .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET)
+  .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET)
        {
          __start___phys_stack_reg_patchlist = .;
-         *(.data.patch.phys_stack_reg)
+         *(.data..patch.phys_stack_reg)
          __end___phys_stack_reg_patchlist = .;
        }
 
@@ -110,24 +110,24 @@ SECTIONS
   INIT_TEXT_SECTION(PAGE_SIZE)
   INIT_DATA_SECTION(16)
 
-  .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
+  .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET)
        {
          __start___vtop_patchlist = .;
-         *(.data.patch.vtop)
+         *(.data..patch.vtop)
          __end___vtop_patchlist = .;
        }
 
-  .data.patch.rse : AT(ADDR(.data.patch.rse) - LOAD_OFFSET)
+  .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET)
        {
          __start___rse_patchlist = .;
-         *(.data.patch.rse)
+         *(.data..patch.rse)
          __end___rse_patchlist = .;
        }
 
-  .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
+  .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET)
        {
          __start___mckinley_e9_bundles = .;
-         *(.data.patch.mckinley_e9)
+         *(.data..patch.mckinley_e9)
          __end___mckinley_e9_bundles = .;
        }
 
@@ -175,17 +175,17 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
-  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET)
+  .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET)
         {
        PAGE_ALIGNED_DATA(PAGE_SIZE)
          . = ALIGN(PAGE_SIZE);
          __start_gate_section = .;
-         *(.data.gate)
+         *(.data..gate)
          __stop_gate_section = .;
 #ifdef CONFIG_XEN
          . = ALIGN(PAGE_SIZE);
          __xen_start_gate_section = .;
-         *(.data.gate.xen)
+         *(.data..gate.xen)
          __xen_stop_gate_section = .;
 #endif
        }
index 40920c630649c3affa7556c355fea302b614f2a3..24018484c6e93391060e0157540d804867bb6f58 100644 (file)
@@ -104,7 +104,7 @@ GLOBAL_ENTRY(kvm_vmm_panic)
        br.call.sptk.many b6=vmm_panic_handler;
 END(kvm_vmm_panic)
 
-    .section .text.ivt,"ax"
+    .section .text..ivt,"ax"
 
     .align 32768    // align on 32KB boundary
     .global kvm_ia64_ivt
index c27849889e193f4d3a8479b5e5db470cccc2493d..2bfd941ff7c7cdb5a96622875e5d7507125623b3 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python
 #
 # Usage: unwcheck.py FILE
 #
index 7d4830afc91dc3351e6e5599f8c6173991178b1b..6f95b6b32a4efdb1af974875475b607a3deb91db 100644 (file)
@@ -1,3 +1,3 @@
-       .section .data.gate.xen, "aw"
+       .section .data..gate.xen, "aw"
 
        .incbin "arch/ia64/xen/gate.so"
index aff8346ea193536f035fe81f2c5490707256b537..b820ed02ab9f67b0452136326da826e0cc977261 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/init.h>
 #include <xen/interface/elfnote.h>
 
-       .section .data.read_mostly
+       .section .data..read_mostly
        .align 8
        .global xen_domain_type
 xen_domain_type:
index 9f1784f586b95db2d35227189762f8ed22a63517..a91b2713451da0e5290a3889e1bcebbb530c0e4b 100644 (file)
@@ -57,7 +57,7 @@ SECTIONS {
        .romvec : {
                __rom_start = . ;
                _romvec = .;
-               *(.data.initvect)
+               *(.data..initvect)
        } > romvec
 #endif
 
@@ -68,7 +68,7 @@ SECTIONS {
                TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
-               *(.text.lock)
+               *(.text..lock)
 
                . = ALIGN(16);          /* Exception table              */
                __start___ex_table = .;
index 2ef06242398bf8bbad01b207f6436ff38cfe6ddb..8eb94fb6b971a3c35867f558096af9a6f7cd6b0e 100644 (file)
@@ -280,7 +280,7 @@ _dprbase:
      * and then overwritten as needed.
      */
  
-.section ".data.initvect","awx"
+.section ".data..initvect","awx"
     .long   RAMEND     /* Reset: Initial Stack Pointer                 - 0.  */
     .long   _start      /* Reset: Initial Program Counter               - 1.  */
     .long   buserr      /* Bus Error                                    - 2.  */
index 62ecf4144b3ba3ad2df0ebecbb13adca1feff5b6..97510e55b802a587ad547c9f36005540ae2c8fc5 100644 (file)
@@ -291,7 +291,7 @@ _dprbase:
      * and then overwritten as needed.
      */
  
-.section ".data.initvect","awx"
+.section ".data..initvect","awx"
     .long   RAMEND     /* Reset: Initial Stack Pointer                 - 0.  */
     .long   _start      /* Reset: Initial Program Counter               - 1.  */
     .long   buserr      /* Bus Error                                    - 2.  */
index efb95f2609c2a1cb1a52e8b21a3ee2eae3f50566..e0ecda92c40a86603293911e657b3a850ed3ade8 100644 (file)
@@ -1,7 +1,7 @@
 #include <asm/lasat/head.h>
 
        .text
-       .section .text.start, "ax"
+       .section .text..start, "ax"
        .set noreorder
        .set mips3
 
index 988f8ad189cb19d29c47a489f07e10190b934985..0864c963e188d6872385606ecaeb917d23319ccb 100644 (file)
@@ -4,7 +4,7 @@ SECTIONS
 {
   .text :
   {
-    *(.text.start)
+    *(.text..start)
   }
 
   /* Data in ROM */
index 32c2cca74345995d9cdbc80fc46c59081f734871..45effe6978faaa766203c085e6a458faea7800be 100644 (file)
@@ -28,7 +28,7 @@
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 void parisc_cache_init(void);  /* initializes cache-flushing */
 void disable_sr_hashing_asm(int); /* low level support for above */
index 4653c77bf9d13398c6dd6777786a20c3a821c2dd..2ab4af58ecb9ca20cf13751868c917fe09b36a7b 100644 (file)
@@ -174,7 +174,7 @@ static inline void set_eiem(unsigned long val)
 })
 
 #ifdef CONFIG_SMP
-# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
+# define __lock_aligned __attribute__((__section__(".data..lock_aligned")))
 #endif
 
 #define arch_align_stack(x) (x)
index 0e3d9f9b9e33e97680190e3752cea063fce9c251..4dbdf0ed6fa0f08b37bd4ac77e205c9d7e6af2ad 100644 (file)
@@ -345,7 +345,7 @@ smp_slave_stext:
 ENDPROC(stext)
 
 #ifndef CONFIG_64BIT
-       .section .data.read_mostly
+       .section .data..read_mostly
 
        .align  4
        .export $global$,data
index d020eae6525c4a200e9bcab86b6b8beb3e2ef5b3..4a91e433416f17b4f0df48a7e66035cde928303f 100644 (file)
@@ -53,11 +53,11 @@ union thread_union init_thread_union __init_task_data
  * guarantee that global objects will be laid out in memory in the same order 
  * as the order of declaration, so put these in different sections and use
  * the linker script to order them. */
-pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE)));
+pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE)));
 #endif
 
-pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE)));
-pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE)));
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE)));
+pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE)));
 
 /*
  * Initial task structure.
index 9dab4a4e09f7af86d5dbe6a5a8e129393d619a42..d64a6bbec2aa0585b380e485c600db818219b51e 100644 (file)
@@ -94,8 +94,8 @@ SECTIONS
 
        /* PA-RISC locks requires 16-byte alignment */
        . = ALIGN(16);
-       .data.lock_aligned : {
-               *(.data.lock_aligned)
+       .data..lock_aligned : {
+               *(.data..lock_aligned)
        }
 
        /* End of data section */
@@ -105,10 +105,10 @@ SECTIONS
        __bss_start = .;
        /* page table entries need to be PAGE_SIZE aligned */
        . = ALIGN(PAGE_SIZE);
-       .data.vmpages : {
-               *(.data.vm0.pmd)
-               *(.data.vm0.pgd)
-               *(.data.vm0.pte)
+       .data..vmpages : {
+               *(.data..vm0.pmd)
+               *(.data..vm0.pgd)
+               *(.data..vm0.pte)
        }
        .bss : {
                *(.bss)
index 66a315e06dce88691322901a7ab7c6d38c702f4b..328774bd41ee171706de902d5640721bfc49b0d2 100644 (file)
@@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on PPC_BOOK3S && EXPERIMENTAL
+       depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
index 1a54a3b3a3fa8da5397842d5cbbd2e370dc6d40b..42dcd3f4ad7b5d45241e7057804a100cb6df9375 100644 (file)
@@ -112,6 +112,11 @@ KBUILD_CFLAGS += $(call cc-option,-mspe=no)
 # kernel considerably.
 KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
 
+# FIXME: the module load should be taught about the additional relocs
+# generated by this.
+# revert to pre-gcc-4.4 behaviour of .eh_frame
+KBUILD_CFLAGS  += $(call cc-option,-fno-dwarf2-cfi-asm)
+
 # Never use string load/store instructions as they are
 # often slow when they are implemented at all
 KBUILD_CFLAGS          += -mno-string
index 27db8938827aee7381cc065fade0d12fb0c2d528..9d3bd4c45a2406992005018d70f1db1e1f56b591 100644 (file)
@@ -519,7 +519,7 @@ void ibm440ep_fixup_clocks(unsigned int sys_clk,
 {
        unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0);
 
-       /* serial clocks beed fixup based on int/ext */
+       /* serial clocks need fixup based on int/ext */
        eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk);
        eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk);
        eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk);
@@ -532,7 +532,7 @@ void ibm440gx_fixup_clocks(unsigned int sys_clk,
 {
        unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
 
-       /* serial clocks beed fixup based on int/ext */
+       /* serial clocks need fixup based on int/ext */
        eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk);
        eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk);
 }
@@ -543,10 +543,10 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk,
 {
        unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
 
-       /* serial clocks beed fixup based on int/ext */
-       eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk);
-       eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk);
-       eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk);
+       /* serial clocks need fixup based on int/ext */
+       eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk);
+       eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk);
+       eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk);
 }
 
 void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
diff --git a/arch/powerpc/boot/dts/icon.dts b/arch/powerpc/boot/dts/icon.dts
new file mode 100644 (file)
index 0000000..abcd0ca
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Device Tree Source for Mosaix Technologies, Inc. ICON board
+ *
+ * Copyright 2010 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <2>;
+       model = "mosaixtech,icon";
+       compatible = "mosaixtech,icon";
+       dcr-parent = <&{/cpus/cpu@0}>;
+
+       aliases {
+               ethernet0 = &EMAC0;
+               serial0 = &UART0;
+               serial1 = &UART1;
+               serial2 = &UART2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,440SPe";
+                       reg = <0x00000000>;
+                       clock-frequency = <0>; /* Filled in by U-Boot */
+                       timebase-frequency = <0>; /* Filled in by U-Boot */
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       reset-type = <2>;       /* Use chip-reset */
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x00000000 0x0 0x00000000>; /* Filled in by U-Boot */
+       };
+
+       UIC0: interrupt-controller0 {
+               compatible = "ibm,uic-440spe","ibm,uic";
+               interrupt-controller;
+               cell-index = <0>;
+               dcr-reg = <0x0c0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+       };
+
+       UIC1: interrupt-controller1 {
+               compatible = "ibm,uic-440spe","ibm,uic";
+               interrupt-controller;
+               cell-index = <1>;
+               dcr-reg = <0x0d0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       UIC2: interrupt-controller2 {
+               compatible = "ibm,uic-440spe","ibm,uic";
+               interrupt-controller;
+               cell-index = <2>;
+               dcr-reg = <0x0e0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       UIC3: interrupt-controller3 {
+               compatible = "ibm,uic-440spe","ibm,uic";
+               interrupt-controller;
+               cell-index = <3>;
+               dcr-reg = <0x0f0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       SDR0: sdr {
+               compatible = "ibm,sdr-440spe";
+               dcr-reg = <0x00e 0x002>;
+       };
+
+       CPR0: cpr {
+               compatible = "ibm,cpr-440spe";
+               dcr-reg = <0x00c 0x002>;
+       };
+
+       MQ0: mq {
+               compatible = "ibm,mq-440spe";
+               dcr-reg = <0x040 0x020>;
+       };
+
+       plb {
+               compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               /*        addr-child     addr-parent    size */
+               ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000
+                         0x4 0x00200000 0x4 0x00200000 0x00000400
+                         0x4 0xe0000000 0x4 0xe0000000 0x20000000
+                         0xc 0x00000000 0xc 0x00000000 0x20000000
+                         0xd 0x00000000 0xd 0x00000000 0x80000000
+                         0xd 0x80000000 0xd 0x80000000 0x80000000
+                         0xe 0x00000000 0xe 0x00000000 0x80000000
+                         0xe 0x80000000 0xe 0x80000000 0x80000000
+                         0xf 0x00000000 0xf 0x00000000 0x80000000
+                         0xf 0x80000000 0xf 0x80000000 0x80000000>;
+               clock-frequency = <0>; /* Filled in by U-Boot */
+
+               SDRAM0: sdram {
+                       compatible = "ibm,sdram-440spe", "ibm,sdram-405gp";
+                       dcr-reg = <0x010 0x002>;
+               };
+
+               MAL0: mcmal {
+                       compatible = "ibm,mcmal-440spe", "ibm,mcmal2";
+                       dcr-reg = <0x180 0x062>;
+                       num-tx-chans = <2>;
+                       num-rx-chans = <1>;
+                       interrupt-parent = <&MAL0>;
+                       interrupts = <0x0 0x1 0x2 0x3 0x4>;
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = </*TXEOB*/ 0x0 &UIC1 0x6 0x4
+                                        /*RXEOB*/ 0x1 &UIC1 0x7 0x4
+                                        /*SERR*/  0x2 &UIC1 0x1 0x4
+                                        /*TXDE*/  0x3 &UIC1 0x2 0x4
+                                        /*RXDE*/  0x4 &UIC1 0x3 0x4>;
+               };
+
+               POB0: opb {
+                       compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>;
+                       clock-frequency = <0>; /* Filled in by U-Boot */
+
+                       EBC0: ebc {
+                               compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
+                               dcr-reg = <0x012 0x002>;
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               clock-frequency = <0>; /* Filled in by U-Boot */
+                               /* ranges property is supplied by U-Boot */
+                               interrupts = <0x5 0x1>;
+                               interrupt-parent = <&UIC1>;
+
+                               nor_flash@0,0 {
+                                       compatible = "cfi-flash";
+                                       bank-width = <2>;
+                                       reg = <0x00000000 0x00000000 0x01000000>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       partition@0 {
+                                               label = "kernel";
+                                               reg = <0x00000000 0x001e0000>;
+                                       };
+                                       partition@1e0000 {
+                                               label = "dtb";
+                                               reg = <0x001e0000 0x00020000>;
+                                       };
+                                       partition@200000 {
+                                               label = "root";
+                                               reg = <0x00200000 0x00200000>;
+                                       };
+                                       partition@400000 {
+                                               label = "user";
+                                               reg = <0x00400000 0x00b60000>;
+                                       };
+                                       partition@f60000 {
+                                               label = "env";
+                                               reg = <0x00f60000 0x00040000>;
+                                       };
+                                       partition@fa0000 {
+                                               label = "u-boot";
+                                               reg = <0x00fa0000 0x00060000>;
+                                       };
+                               };
+
+                               SysACE_CompactFlash: sysace@1,0 {
+                                       compatible = "xlnx,sysace";
+                                       interrupt-parent = <&UIC2>;
+                                       interrupts = <24 0x4>;
+                                       reg = <0x00000001 0x00000000 0x10000>;
+                               };
+                       };
+
+                       UART0: serial@f0000200 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xf0000200 0x00000008>;
+                               virtual-reg = <0xa0000200>;
+                               clock-frequency = <0>; /* Filled in by U-Boot */
+                               current-speed = <115200>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x0 0x4>;
+                       };
+
+                       UART1: serial@f0000300 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xf0000300 0x00000008>;
+                               virtual-reg = <0xa0000300>;
+                               clock-frequency = <0>;
+                               current-speed = <0>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x1 0x4>;
+                       };
+
+
+                       UART2: serial@f0000600 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xf0000600 0x00000008>;
+                               virtual-reg = <0xa0000600>;
+                               clock-frequency = <0>;
+                               current-speed = <0>;
+                               interrupt-parent = <&UIC1>;
+                               interrupts = <0x5 0x4>;
+                       };
+
+                       IIC0: i2c@f0000400 {
+                               compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
+                               reg = <0xf0000400 0x00000014>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x2 0x4>;
+                       };
+
+                       IIC1: i2c@f0000500 {
+                               compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
+                               reg = <0xf0000500 0x00000014>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x3 0x4>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                                rtc@68 {
+                                        compatible = "stm,m41t00";
+                                        reg = <0x68>;
+                                };
+                       };
+
+                       EMAC0: ethernet@f0000800 {
+                               linux,network-index = <0x0>;
+                               device_type = "network";
+                               compatible = "ibm,emac-440spe", "ibm,emac4";
+                               interrupt-parent = <&UIC1>;
+                               interrupts = <0x1c 0x4 0x1d 0x4>;
+                               reg = <0xf0000800 0x00000074>;
+                               local-mac-address = [000000000000];
+                               mal-device = <&MAL0>;
+                               mal-tx-channel = <0>;
+                               mal-rx-channel = <0>;
+                               cell-index = <0>;
+                               max-frame-size = <9000>;
+                               rx-fifo-size = <4096>;
+                               tx-fifo-size = <2048>;
+                               phy-mode = "gmii";
+                               phy-map = <0x00000000>;
+                               has-inverted-stacr-oc;
+                               has-new-stacr-staopc;
+                       };
+               };
+
+               PCIX0: pci@c0ec00000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix";
+                       primary;
+                       large-inbound-windows;
+                       enable-msi-hole;
+                       reg = <0x0000000c 0x0ec00000 0x00000008   /* Config space access */
+                              0x00000000 0x00000000 0x00000000   /* no IACK cycles */
+                              0x0000000c 0x0ed00000 0x00000004   /* Special cycles */
+                              0x0000000c 0x0ec80000 0x00000100   /* Internal registers */
+                              0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
+
+                       /* Inbound 4GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
+
+                       /* This drives busses 0 to 0xf */
+                       bus-range = <0x0 0xf>;
+
+                       /* PCI-X interrupt (SM502) is routed to extIRQ10 (UIC1, 19) */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x0>;
+                       interrupt-map = <0x0 0x0 0x0 0x0 &UIC1 19 0x8>;
+               };
+
+               PCIE0: pciex@d00000000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
+                       primary;
+                       port = <0x0>; /* port number */
+                       reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */
+                              0x0000000c 0x10000000 0x00001000>;       /* Registers */
+                       dcr-reg = <0x100 0x020>;
+                       sdr-base = <0x300>;
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
+
+                       /* Inbound 4GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
+
+                       /* This drives busses 0x10 to 0x1f */
+                       bus-range = <0x10 0x1f>;
+
+                       /* Legacy interrupts (note the weird polarity, the bridge seems
+                        * to invert PCIe legacy interrupts).
+                        * We are de-swizzling here because the numbers are actually for
+                        * port of the root complex virtual P2P bridge. But I want
+                        * to avoid putting a node for it in the tree, so the numbers
+                        * below are basically de-swizzled numbers.
+                        * The real slot is on idsel 0, so the swizzling is 1:1
+                        */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */
+                               0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */
+                               0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */
+                               0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>;
+               };
+
+               PCIE1: pciex@d20000000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
+                       primary;
+                       port = <0x1>; /* port number */
+                       reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */
+                              0x0000000c 0x10001000 0x00001000>;       /* Registers */
+                       dcr-reg = <0x120 0x020>;
+                       sdr-base = <0x340>;
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
+
+                       /* Inbound 4GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
+
+                       /* This drives busses 0x20 to 0x2f */
+                       bus-range = <0x20 0x2f>;
+
+                       /* Legacy interrupts (note the weird polarity, the bridge seems
+                        * to invert PCIe legacy interrupts).
+                        * We are de-swizzling here because the numbers are actually for
+                        * port of the root complex virtual P2P bridge. But I want
+                        * to avoid putting a node for it in the tree, so the numbers
+                        * below are basically de-swizzled numbers.
+                        * The real slot is on idsel 0, so the swizzling is 1:1
+                        */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */
+                               0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */
+                               0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */
+                               0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>;
+               };
+
+               I2O: i2o@400100000 {
+                       compatible = "ibm,i2o-440spe";
+                       reg = <0x00000004 0x00100000 0x100>;
+                       dcr-reg = <0x060 0x020>;
+               };
+
+               DMA0: dma0@400100100 {
+                       compatible = "ibm,dma-440spe";
+                       cell-index = <0>;
+                       reg = <0x00000004 0x00100100 0x100>;
+                       dcr-reg = <0x060 0x020>;
+                       interrupt-parent = <&DMA0>;
+                       interrupts = <0 1>;
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <
+                               0 &UIC0 0x14 4
+                               1 &UIC1 0x16 4>;
+               };
+
+               DMA1: dma1@400100200 {
+                       compatible = "ibm,dma-440spe";
+                       cell-index = <1>;
+                       reg = <0x00000004 0x00100200 0x100>;
+                       dcr-reg = <0x060 0x020>;
+                       interrupt-parent = <&DMA1>;
+                       interrupts = <0 1>;
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <
+                               0 &UIC0 0x16 4
+                               1 &UIC1 0x16 4>;
+               };
+
+               xor-accel@400200000 {
+                       compatible = "amcc,xor-accelerator";
+                       reg = <0x00000004 0x00200000 0x400>;
+                       interrupt-parent = <&UIC1>;
+                       interrupts = <0x1f 4>;
+               };
+       };
+
+       chosen {
+               linux,stdout-path = "/plb/opb/serial@f0000200";
+       };
+};
index 8cf2c0c88c0584d5ced42fe26cde120bcdba7580..7c3be5e45748e4abdaa2605b70c68fe851c50b21 100644 (file)
@@ -44,6 +44,7 @@
                        d-cache-size = <32768>;
                        dcr-controller;
                        dcr-access-method = "native";
+                       reset-type = <2>;       /* Use chip-reset */
                };
        };
 
index 4173af387c6355ae8c50aa4d7141d98ad0901e76..0f5262452682ebf6e25719b90efee5f6d5a92aa4 100644 (file)
        aliases {
                ethernet0 = &enet0;
                ethernet1 = &enet1;
-/*
                ethernet2 = &enet2;
                ethernet3 = &enet3;
-*/
                serial0 = &serial0;
                serial1 = &serial1;
                pci0 = &pci0;
                        };
                };
 
-/* eTSEC 3/4 are currently broken
                enet2: ethernet@26000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
                                };
                        };
                };
- */
 
                serial0: serial@4500 {
                        cell-index = <0>;
index 5bd1011fde960d083d4ab496736eaf48388e0221..3375c2ab0c32862ca9111a5e9b08267c5a089ba6 100644 (file)
                        clock-frequency = <0>;
                };
 
+               msi@41600 {
+                       compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x80>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
                global-utilities@e0000 {        //global utilities block
                        compatible = "fsl,mpc8572-guts";
                        reg = <0xe0000 0x1000>;
                        protected-sources = <
                        31 32 33 37 38 39       /* enet2 enet3 */
                        76 77 78 79 26 42       /* dma2 pci2 serial*/
-                       0xe0 0xe1 0xe2 0xe3     /* msi */
-                       0xe4 0xe5 0xe6 0xe7
+                       0xe4 0xe5 0xe6 0xe7     /* msi */
                        >;
                };
        };
index 0efc3456e2976e6ee67673aabb5232fe69589b34..e7b477f6a3fea32d68aaceb623469c9f8bd0053a 100644 (file)
                msi@41600 {
                        compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
                        reg = <0x41600 0x80>;
-                       msi-available-ranges = <0 0x100>;
+                       msi-available-ranges = <0x80 0x80>;
                        interrupts = <
-                               0xe0 0
-                               0xe1 0
-                               0xe2 0
-                               0xe3 0
                                0xe4 0
                                0xe5 0
                                0xe6 0
                        0x1 0x2 0x3 0x4         /* pci slot */
                        0x9 0xa 0xb 0xc         /* usb */
                        0x6 0x7 0xe 0x5         /* Audio elgacy SATA */
+                       0xe0 0xe1 0xe2 0xe3     /* msi */
                        >;
                };
        };
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
new file mode 100644 (file)
index 0000000..7fad2df
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * P1021 MDS Device Tree Source
+ *
+ * Copyright 2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+       model = "fsl,P1021";
+       compatible = "fsl,P1021MDS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               serial0 = &serial0;
+               serial1 = &serial1;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               ethernet4 = &enet4;
+               pci0 = &pci0;
+               pci1 = &pci1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,P1021@0 {
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       next-level-cache = <&L2>;
+               };
+
+               PowerPC,P1021@1 {
+                       device_type = "cpu";
+                       reg = <0x1>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       localbus@ffe05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus";
+               reg = <0 0xffe05000 0 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               /* NAND Flash, BCSR, PMC0/1*/
+               ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
+                         0x1 0x0 0x0 0xf8000000 0x00008000
+                         0x2 0x0 0x0 0xf8010000 0x00020000
+                         0x3 0x0 0x0 0xf8020000 0x00020000>;
+
+               nand@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p1021-fcm-nand",
+                                    "fsl,elbc-fcm-nand";
+                       reg = <0x0 0x0 0x40000>;
+
+                       partition@0 {
+                               /* This location must not be altered  */
+                               /* 1MB for u-boot Bootloader Image */
+                               reg = <0x0 0x00100000>;
+                               label = "NAND (RO) U-Boot Image";
+                               read-only;
+                       };
+
+                       partition@100000 {
+                               /* 1MB for DTB Image */
+                               reg = <0x00100000 0x00100000>;
+                               label = "NAND (RO) DTB Image";
+                               read-only;
+                       };
+
+                       partition@200000 {
+                               /* 4MB for Linux Kernel Image */
+                               reg = <0x00200000 0x00400000>;
+                               label = "NAND (RO) Linux Kernel Image";
+                               read-only;
+                       };
+
+                       partition@600000 {
+                               /* 5MB for Compressed Root file System Image */
+                               reg = <0x00600000 0x00500000>;
+                               label = "NAND (RO) Compressed RFS Image";
+                               read-only;
+                       };
+
+                       partition@b00000 {
+                               /* 6MB for JFFS2 based Root file System */
+                               reg = <0x00a00000 0x00600000>;
+                               label = "NAND (RW) JFFS2 Root File System";
+                       };
+
+                       partition@1100000 {
+                               /* 14MB for JFFS2 based Root file System */
+                               reg = <0x01100000 0x00e00000>;
+                               label = "NAND (RW) Writable User area";
+                       };
+
+                       partition@1f00000 {
+                               /* 1MB for microcode */
+                               reg = <0x01f00000 0x00100000>;
+                               label = "NAND (RO) QE Ucode";
+                               read-only;
+                       };
+               };
+
+               bcsr@1,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p1021mds-bcsr";
+                       reg = <1 0 0x8000>;
+                       ranges = <0 1 0 0x8000>;
+               };
+
+               pib@2,0 {
+                       compatible = "fsl,p1021mds-pib";
+                       reg = <2 0 0x10000>;
+               };
+
+               pib@3,0 {
+                       compatible = "fsl,p1021mds-pib";
+                       reg = <3 0 0x10000>;
+               };
+       };
+
+       soc@ffe00000 {
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "fsl,p1021-immr", "simple-bus";
+               ranges = <0x0  0x0 0xffe00000 0x100000>;
+               bus-frequency = <0>;            // Filled out by uboot.
+
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,p1021-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <16 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               memory-controller@2000 {
+                       compatible = "fsl,p1021-memory-controller";
+                       reg = <0x2000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                       };
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               spi@7000 {
+                       cell-index = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,espi";
+                       reg = <0x7000 0x1000>;
+                       interrupts = <59 0x2>;
+                       interrupt-parent = <&mpic>;
+                       espi,num-ss-bits = <4>;
+                       mode = "cpu";
+
+                       fsl_m25p80@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "fsl,espi-flash";
+                               reg = <0>;
+                               linux,modalias = "fsl_m25p80";
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@u-boot {
+                                       label = "u-boot-spi";
+                                       reg = <0x00000000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@kernel {
+                                       label = "kernel-spi";
+                                       reg = <0x00100000 0x00500000>;
+                                       read-only;
+                               };
+                               partition@dtb {
+                                       label = "dtb-spi";
+                                       reg = <0x00600000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@fs {
+                                       label = "file system-spi";
+                                       reg = <0x00700000 0x00900000>;
+                               };
+                       };
+               };
+
+               gpio: gpio-controller@f000 {
+                       #gpio-cells = <2>;
+                       compatible = "fsl,mpc8572-gpio";
+                       reg = <0xf000 0x100>;
+                       interrupts = <47 0x2>;
+                       interrupt-parent = <&mpic>;
+                       gpio-controller;
+               };
+
+               L2: l2-cache-controller@20000 {
+                       compatible = "fsl,p1021-l2-cache-controller";
+                       reg = <0x20000 0x1000>;
+                       cache-line-size = <32>; // 32 bytes
+                       cache-size = <0x40000>; // L2,256K
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               usb@22000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl-usb2-dr";
+                       reg = <0x22000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <28 0x2>;
+                       phy_type = "ulpi";
+               };
+
+                mdio@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,etsec2-mdio";
+                       reg = <0x24000 0x1000 0xb0030 0x4>;
+
+                       phy0: ethernet-phy@0 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <1 1>;
+                               reg = <0x0>;
+                       };
+                       phy1: ethernet-phy@1 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <2 1>;
+                               reg = <0x1>;
+                       };
+                       phy4: ethernet-phy@4 {
+                               interrupt-parent = <&mpic>;
+                               reg = <0x4>;
+                       };
+               };
+
+               mdio@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,etsec2-tbi";
+                       reg = <0x25000 0x1000 0xb1030 0x4>;
+                       tbi0: tbi-phy@11 {
+                               reg = <0x11>;
+                               device_type = "tbi-phy";
+                       };
+               };
+
+               enet0: ethernet@B0000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "rgmii-id";
+                       queue-group@0{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB0000 0x1000>;
+                               interrupts = <29 2 30 2 34 2>;
+                       };
+                       queue-group@1{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB4000 0x1000>;
+                               interrupts = <17 2 18 2 24 2>;
+                       };
+               };
+
+               enet1: ethernet@B1000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy4>;
+                       tbi-handle = <&tbi0>;
+                       phy-connection-type = "sgmii";
+                       queue-group@0{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB1000 0x1000>;
+                               interrupts = <35 2 36 2 40 2>;
+                       };
+                       queue-group@1{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB5000 0x1000>;
+                               interrupts = <51 2 52 2 67 2>;
+                       };
+               };
+
+               enet2: ethernet@B2000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+                       queue-group@0{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB2000 0x1000>;
+                               interrupts = <31 2 32 2 33 2>;
+                       };
+                       queue-group@1{
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xB6000 0x1000>;
+                               interrupts = <25 2 26 2 27 2>;
+                       };
+               };
+
+               sdhci@2e000 {
+                       compatible = "fsl,p1021-esdhc", "fsl,esdhc";
+                       reg = <0x2e000 0x1000>;
+                       interrupts = <72 0x2>;
+                       interrupt-parent = <&mpic>;
+                       /* Filled in by U-Boot */
+                       clock-frequency = <0>;
+               };
+
+               crypto@30000 {
+                       compatible = "fsl,sec3.3", "fsl,sec3.1",
+                                    "fsl,sec3.0", "fsl,sec2.4",
+                                    "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+                       reg = <0x30000 0x10000>;
+                       interrupts = <45 2 58 2>;
+                       interrupt-parent = <&mpic>;
+                       fsl,num-channels = <4>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0x97c>;
+                       fsl,descriptor-types-mask = <0x3a30abf>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi@41600 {
+                       compatible = "fsl,p1021-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               global-utilities@e0000 {        //global utilities block
+                       compatible = "fsl,p1021-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+
+               par_io@e0100 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xe0100 0x60>;
+                       ranges = <0x0 0xe0100 0x60>;
+                       device_type = "par_io";
+                       num-ports = <3>;
+                       pio1: ucc_pin@01 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x1  0x13 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x1  0x14 0x3  0x0  0x1  0x0    /* QE_MUX_MDIO */
+                                       0x0  0x17 0x2  0x0  0x2  0x0    /* CLK12 */
+                                       0x0  0x18 0x2  0x0  0x1  0x0    /* CLK9
+*/
+                                       0x0  0x7  0x1  0x0  0x2  0x0    /* ENET1_TXD0_SER1_TXD0 */
+                                       0x0  0x9  0x1  0x0  0x2  0x0    /* ENET1_TXD1_SER1_TXD1 */
+                                       0x0  0xb  0x1  0x0  0x2  0x0    /* ENET1_TXD2_SER1_TXD2 */
+                                       0x0  0xc  0x1  0x0  0x2  0x0    /* ENET1_TXD3_SER1_TXD3 */
+                                       0x0  0x6  0x2  0x0  0x2  0x0    /* ENET1_RXD0_SER1_RXD0 */
+                                       0x0  0xa  0x2  0x0  0x2  0x0    /* ENET1_RXD1_SER1_RXD1 */
+                                       0x0  0xe  0x2  0x0  0x2  0x0    /* ENET1_RXD2_SER1_RXD2 */
+                                       0x0  0xf  0x2  0x0  0x2  0x0    /* ENET1_RXD3_SER1_RXD3 */
+                                       0x0  0x5  0x1  0x0  0x2  0x0    /* ENET1_TX_EN_SER1_RTS_B */
+                                       0x0  0xd  0x1  0x0  0x2  0x0    /* ENET1_TX_ER */
+                                       0x0  0x4  0x2  0x0  0x2  0x0    /* ENET1_RX_DV_SER1_CTS_B */
+                                       0x0  0x8  0x2  0x0  0x2  0x0    /* ENET1_RX_ER_SER1_CD_B */
+                                       0x0  0x11 0x2  0x0  0x2  0x0    /* ENET1_CRS */
+                                       0x0  0x10 0x2  0x0  0x2  0x0>;    /* ENET1_COL */
+                       };
+
+                       pio2: ucc_pin@02 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x1  0x13 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x1  0x14 0x3  0x0  0x1  0x0    /* QE_MUX_MDIO */
+                                       0x1  0xb  0x2  0x0  0x1  0x0    /* CLK13 */
+                                       0x1  0x7  0x1  0x0  0x2  0x0    /* ENET5_TXD0_SER5_TXD0 */
+                                       0x1  0xa  0x1  0x0  0x2  0x0    /* ENET5_TXD1_SER5_TXD1 */
+                                       0x1  0x6  0x2  0x0  0x2  0x0    /* ENET5_RXD0_SER5_RXD0 */
+                                       0x1  0x9  0x2  0x0  0x2  0x0    /* ENET5_RXD1_SER5_RXD1 */
+                                       0x1  0x5  0x1  0x0  0x2  0x0    /* ENET5_TX_EN_SER5_RTS_B */
+                                       0x1  0x4  0x2  0x0  0x2  0x0    /* ENET5_RX_DV_SER5_CTS_B */
+                                       0x1  0x8  0x2  0x0  0x2  0x0>;    /* ENET5_RX_ER_SER5_CD_B */
+                       };
+               };
+       };
+
+       pci0: pcie@ffe09000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe09000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <16 2>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0 0 1 &mpic 4 1
+                       0000 0 0 2 &mpic 5 1
+                       0000 0 0 3 &mpic 6 1
+                       0000 0 0 4 &mpic 7 1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xa0000000
+                                 0x2000000 0x0 0xa0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       pci1: pcie@ffe0a000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe0a000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <16 2>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0 0 1 &mpic 0 1
+                       0000 0 0 2 &mpic 1 1
+                       0000 0 0 3 &mpic 2 1
+                       0000 0 0 4 &mpic 3 1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xc0000000
+                                 0x2000000 0x0 0xc0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       qe@ffe80000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "qe";
+               compatible = "fsl,qe";
+               ranges = <0x0 0x0 0xffe80000 0x40000>;
+               reg = <0 0xffe80000 0 0x480>;
+               brg-frequency = <0>;
+               bus-frequency = <0>;
+               fsl,qe-num-riscs = <1>;
+               fsl,qe-num-snums = <28>;
+
+               qeic: interrupt-controller@80 {
+                       interrupt-controller;
+                       compatible = "fsl,qe-ic";
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <0x80 0x80>;
+                       interrupts = <63 2 60 2>; //high:47 low:44
+                       interrupt-parent = <&mpic>;
+               };
+
+               enet3: ucc@2000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <1>;
+                       reg = <0x2000 0x200>;
+                       interrupts = <32>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "clk12";
+                       tx-clock-name = "clk9";
+                       pio-handle = <&pio1>;
+                       phy-handle = <&qe_phy0>;
+                       phy-connection-type = "mii";
+               };
+
+               mdio@2120 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x2120 0x18>;
+                       compatible = "fsl,ucc-mdio";
+
+                       qe_phy0: ethernet-phy@0 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <4 1>;
+                               reg = <0x0>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy1: ethernet-phy@03 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <5 1>;
+                               reg = <0x3>;
+                               device_type = "ethernet-phy";
+                       };
+                       tbi-phy@11 {
+                               reg = <0x11>;
+                               device_type = "tbi-phy";
+                       };
+               };
+
+               enet4: ucc@2400 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <5>;
+                       reg = <0x2400 0x200>;
+                       interrupts = <40>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk13";
+                       pio-handle = <&pio2>;
+                       phy-handle = <&qe_phy1>;
+                       phy-connection-type = "rmii";
+               };
+
+               muram@10000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,qe-muram", "fsl,cpm-muram";
+                       ranges = <0x0 0x10000 0x6000>;
+
+                       data-only@0 {
+                               compatible = "fsl,qe-muram-data",
+                               "fsl,cpm-muram-data";
+                               reg = <0x0 0x6000>;
+                       };
+               };
+       };
+};
index d2af32e2bf7a78e83d1b700697f5aff8599b7cf6..81636c01d90652d2bc9082a872c4ba1594a0ac5d 100644 (file)
                                has-inverted-stacr-oc;
                                has-new-stacr-staopc;
                        };
+               };
+               PCIE0: pciex@d00000000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
+                       primary;
+                       port = <0x0>; /* port number */
+                       reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */
+                              0x0000000c 0x10000000 0x00001000>;       /* Registers */
+                       dcr-reg = <0x100 0x020>;
+                       sdr-base = <0x300>;
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
+
+                       /* Inbound 2GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
 
+                       /* This drives busses 10 to 0x1f */
+                       bus-range = <0x10 0x1f>;
+
+                       /* Legacy interrupts (note the weird polarity, the bridge seems
+                        * to invert PCIe legacy interrupts).
+                        * We are de-swizzling here because the numbers are actually for
+                        * port of the root complex virtual P2P bridge. But I want
+                        * to avoid putting a node for it in the tree, so the numbers
+                        * below are basically de-swizzled numbers.
+                        * The real slot is on idsel 0, so the swizzling is 1:1
+                        */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */
+                               0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */
+                               0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */
+                               0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>;
+               };
+
+               PCIE1: pciex@d20000000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
+                       primary;
+                       port = <0x1>; /* port number */
+                       reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */
+                              0x0000000c 0x10001000 0x00001000>;       /* Registers */
+                       dcr-reg = <0x120 0x020>;
+                       sdr-base = <0x340>;
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
+
+                       /* Inbound 2GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+
+                       /* This drives busses 10 to 0x1f */
+                       bus-range = <0x20 0x2f>;
+
+                       /* Legacy interrupts (note the weird polarity, the bridge seems
+                        * to invert PCIe legacy interrupts).
+                        * We are de-swizzling here because the numbers are actually for
+                        * port of the root complex virtual P2P bridge. But I want
+                        * to avoid putting a node for it in the tree, so the numbers
+                        * below are basically de-swizzled numbers.
+                        * The real slot is on idsel 0, so the swizzling is 1:1
+                        */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */
+                               0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */
+                               0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */
+                               0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>;
+               };
+
+               PCIE2: pciex@d40000000 {
+                       device_type = "pci";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex";
+                       primary;
+                       port = <0x2>; /* port number */
+                       reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */
+                              0x0000000c 0x10002000 0x00001000>;       /* Registers */
+                       dcr-reg = <0x140 0x020>;
+                       sdr-base = <0x370>;
+
+                       /* Outbound ranges, one memory and one IO,
+                        * later cannot be changed
+                        */
+                       ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000
+                                 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>;
+
+                       /* Inbound 2GB range starting at 0 */
+                       dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+
+                       /* This drives busses 10 to 0x1f */
+                       bus-range = <0x30 0x3f>;
+
+                       /* Legacy interrupts (note the weird polarity, the bridge seems
+                        * to invert PCIe legacy interrupts).
+                        * We are de-swizzling here because the numbers are actually for
+                        * port of the root complex virtual P2P bridge. But I want
+                        * to avoid putting a node for it in the tree, so the numbers
+                        * below are basically de-swizzled numbers.
+                        * The real slot is on idsel 0, so the swizzling is 1:1
+                        */
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */
+                               0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */
+                               0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */
+                               0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
                };
 
        };
+
        chosen {
                linux,stdout-path = "/plb/opb/serial@ef600200";
        };
diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig
new file mode 100644 (file)
index 0000000..277f88c
--- /dev/null
@@ -0,0 +1,1451 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc7
+# Fri May 21 17:40:22 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_32 is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=4
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=2
+CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+# CONFIG_LOGBUFFER is not set
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
+# CONFIG_YOSEMITE is not set
+CONFIG_ICON=y
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+CONFIG_PPC44x_SIMPLE=y
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_440SPe=y
+CONFIG_STDBINUTILS=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=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_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_ARCH_HAS_NMI_WATCHDOG is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+# CONFIG_PCIEAER_INJECT is not set
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=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_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_XILINX_SYSACE=y
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_FUSION=y
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=y
+CONFIG_FUSION_LOGGING=y
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG 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=y
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
+# CONFIG_MOUSE_PS2_SYNAPTICS is not set
+# CONFIG_MOUSE_PS2_TRACKPOINT is not set
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_BOOTCOUNT is not set
+# CONFIG_DISPLAY_PDSP1880 is not set
+# CONFIG_MUCMC52_IO is not set
+# CONFIG_UC101_IO is not set
+# CONFIG_SRAM is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# 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_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_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=y
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+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_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_SM501=y
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 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_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_YAFFS_FS is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_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=y
+# 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=y
+# 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
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index 725634fc18c653d2a868262a84d450a7d3d3edab..4b509411ad8afcf52cf1ea5beca482b9fc282d22 100644 (file)
@@ -42,7 +42,7 @@ extern struct ppc64_caches ppc64_caches;
 #endif /* __powerpc64__ && ! __ASSEMBLY__ */
 
 #if !defined(__ASSEMBLY__)
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 #endif
 
 #endif /* __KERNEL__ */
index e3cba4e1eb347368307c83906c3845a017bc8aee..b0b21134f61a8f6fb30305b46d4f2cd07aae132f 100644 (file)
@@ -70,6 +70,7 @@ struct pt_regs;
 extern int machine_check_generic(struct pt_regs *regs);
 extern int machine_check_4xx(struct pt_regs *regs);
 extern int machine_check_440A(struct pt_regs *regs);
+extern int machine_check_e500mc(struct pt_regs *regs);
 extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
 extern int machine_check_47x(struct pt_regs *regs);
index a6ca6da1430bd60506af9b5babc62df147c8c9f7..2a9cd74a841e3e234b6d1a4bb6beb8e5cd1b207b 100644 (file)
@@ -2,6 +2,18 @@
 #define _ASM_POWERPC_KEXEC_H
 #ifdef __KERNEL__
 
+#ifdef CONFIG_FSL_BOOKE
+
+/*
+ * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
+ * and therefore we can only deal with memory within this range
+ */
+#define KEXEC_SOURCE_MEMORY_LIMIT      (2 * 1024 * 1024 * 1024UL)
+#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
+#define KEXEC_CONTROL_MEMORY_LIMIT     (2 * 1024 * 1024 * 1024UL)
+
+#else
+
 /*
  * Maximum page that is mapped directly into kernel memory.
  * XXX: Since we copy virt we can use any page we allocate
@@ -21,6 +33,7 @@
 /* TASK_SIZE, probably left over from use_mm ?? */
 #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
 #endif
+#endif
 
 #define KEXEC_CONTROL_PAGE_SIZE 4096
 
index 19a661b4cb98205f6304c3c449062e6ca20e3c94..675e159b5ef42decbf2617870963547f07016870 100644 (file)
@@ -123,10 +123,6 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev)
  */
 struct macio_driver
 {
-       char                    *name;
-       struct of_device_id     *match_table;
-       struct module           *owner;
-
        int     (*probe)(struct macio_dev* dev, const struct of_device_id *match);
        int     (*remove)(struct macio_dev* dev);
 
index bfc4e027e2adf75640e99cd4c35555fc2834f3d8..358ff14ea25ed2d917f442576dba3ac841a1f9b5 100644 (file)
@@ -162,14 +162,6 @@ do {                                               \
 
 #endif /* !CONFIG_HUGETLB_PAGE */
 
-#ifdef MODULE
-#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
-#else
-#define __page_aligned \
-       __attribute__((__aligned__(PAGE_SIZE), \
-               __section__(".data.page_aligned")))
-#endif
-
 #define VM_DATA_DEFAULT_FLAGS \
        (test_thread_flag(TIF_32BIT) ? \
         VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
index 5304a37ba425c42b17a0384616f00b977d7f0b3a..2360317179a9163412449bcecb62efd976acd20a 100644 (file)
@@ -4,6 +4,12 @@
  * are not true Book E PowerPCs, they borrowed a number of features
  * before Book E was finalized, and are included here as well.  Unfortunatly,
  * they sometimes used different locations than true Book E CPUs did.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
  */
 #ifdef __KERNEL__
 #ifndef __ASM_POWERPC_REG_BOOKE_H__
@@ -88,6 +94,7 @@
 #define SPRN_IVOR35    0x213   /* Interrupt Vector Offset Register 35 */
 #define SPRN_IVOR36    0x214   /* Interrupt Vector Offset Register 36 */
 #define SPRN_IVOR37    0x215   /* Interrupt Vector Offset Register 37 */
+#define SPRN_MCARU     0x239   /* Machine Check Address Register Upper */
 #define SPRN_MCSRR0    0x23A   /* Machine Check Save and Restore Register 0 */
 #define SPRN_MCSRR1    0x23B   /* Machine Check Save and Restore Register 1 */
 #define SPRN_MCSR      0x23C   /* Machine Check Status Register */
 #define PPC47x_MCSR_IPR        0x00400000 /* Imprecise Machine Check Exception */
 
 #ifdef CONFIG_E500
+/* All e500 */
 #define MCSR_MCP       0x80000000UL /* Machine Check Input Pin */
 #define MCSR_ICPERR    0x40000000UL /* I-Cache Parity Error */
+
+/* e500v1/v2 */
 #define MCSR_DCP_PERR  0x20000000UL /* D-Cache Push Parity Error */
 #define MCSR_DCPERR    0x10000000UL /* D-Cache Parity Error */
 #define MCSR_BUS_IAERR         0x00000080UL /* Instruction Address Error */
 #define MCSR_BUS_IPERR         0x00000002UL /* Instruction parity Error */
 #define MCSR_BUS_RPERR         0x00000001UL /* Read parity Error */
 
-/* e500 parts may set unused bits in MCSR; mask these off */
-#define MCSR_MASK      (MCSR_MCP | MCSR_ICPERR | MCSR_DCP_PERR | \
-                       MCSR_DCPERR | MCSR_BUS_IAERR | MCSR_BUS_RAERR | \
-                       MCSR_BUS_WAERR | MCSR_BUS_IBERR | MCSR_BUS_RBERR | \
-                       MCSR_BUS_WBERR | MCSR_BUS_IPERR | MCSR_BUS_RPERR)
+/* e500mc */
+#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */
+#define MCSR_L2MMU_MHIT        0x04000000UL /* Hit on multiple TLB entries */
+#define MCSR_NMI       0x00100000UL /* Non-Maskable Interrupt */
+#define MCSR_MAV       0x00080000UL /* MCAR address valid */
+#define MCSR_MEA       0x00040000UL /* MCAR is effective address */
+#define MCSR_IF                0x00010000UL /* Instruction Fetch */
+#define MCSR_LD                0x00008000UL /* Load */
+#define MCSR_ST                0x00004000UL /* Store */
+#define MCSR_LDG       0x00002000UL /* Guarded Load */
+#define MCSR_TLBSYNC   0x00000002UL /* Multiple tlbsyncs detected */
+#define MCSR_BSL2_ERR  0x00000001UL /* Backside L2 cache error */
 #endif
+
 #ifdef CONFIG_E200
 #define MCSR_MCP       0x80000000UL /* Machine Check Input Pin */
 #define MCSR_CP_PERR   0x20000000UL /* Cache Push Parity Error */
 #define MCSR_BUS_DRERR         0x00000008UL /* Read Bus Error on data load */
 #define MCSR_BUS_WRERR         0x00000004UL /* Write Bus Error on buffered
                                        store or cache line push */
-
-/* e200 parts may set unused bits in MCSR; mask these off */
-#define MCSR_MASK      (MCSR_MCP | MCSR_CP_PERR | MCSR_CPERR | \
-                       MCSR_EXCP_ERR | MCSR_BUS_IRERR | MCSR_BUS_DRERR | \
-                       MCSR_BUS_WRERR)
 #endif
 
 /* Bit definitions for the DBSR. */
index 877326320e74197802c4eeb4855d60f66344c6ff..58d0572de6f9b13f4b74035d323cefc83b8dce04 100644 (file)
@@ -57,8 +57,12 @@ obj-$(CONFIG_CRASH_DUMP)     += crash_dump.o
 obj-$(CONFIG_E500)             += idle_e500.o
 obj-$(CONFIG_6xx)              += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
 obj-$(CONFIG_TAU)              += tau_6xx.o
-obj-$(CONFIG_HIBERNATION)      += swsusp.o suspend.o \
-                                  swsusp_$(CONFIG_WORD_SIZE).o
+obj-$(CONFIG_HIBERNATION)      += swsusp.o suspend.o
+ifeq ($(CONFIG_FSL_BOOKE),y)
+obj-$(CONFIG_HIBERNATION)      += swsusp_booke.o
+else
+obj-$(CONFIG_HIBERNATION)      += swsusp_$(CONFIG_WORD_SIZE).o
+endif
 obj64-$(CONFIG_HIBERNATION)    += swsusp_asm64.o
 obj-$(CONFIG_MODULES)          += module.o module_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_44x)              += cpu_setup_44x.o
index 9556be903e9638e8fcadc898e81328f0772c7c3d..87aa0f3c60475aeaa71474ded7d46c2f34078ffb 100644 (file)
@@ -1840,7 +1840,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .oprofile_cpu_type      = "ppc/e500mc",
                .oprofile_type          = PPC_OPROFILE_FSL_EMB,
                .cpu_setup              = __setup_cpu_e500mc,
-               .machine_check          = machine_check_e500,
+               .machine_check          = machine_check_e500mc,
                .platform               = "ppce500mc",
        },
        {       /* default match */
index 8c066d6a8e4b4ee015bc8ccf93bf5fc321267bbe..b46f2e09bd81df4bea175401fe4f70fbf45bfb35 100644 (file)
@@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu)
 }
 
 /* wait for all the CPUs to hit real mode but timeout if they don't come in */
+#ifdef CONFIG_PPC_STD_MMU_64
 static void crash_kexec_wait_realmode(int cpu)
 {
        unsigned int msecs;
@@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu)
        }
        mb();
 }
+#endif
 
 /*
  * This function will be called by secondary cpus or by kexec cpu
@@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
        crash_kexec_prepare_cpus(crashing_cpu);
        cpu_set(crashing_cpu, cpus_in_crash);
        crash_kexec_stop_spus();
+#ifdef CONFIG_PPC_STD_MMU_64
        crash_kexec_wait_realmode(crashing_cpu);
+#endif
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(1, 0);
 }
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
new file mode 100644 (file)
index 0000000..beb4d78
--- /dev/null
@@ -0,0 +1,237 @@
+
+/* 1. Find the index of the entry we're executing in */
+       bl      invstr                          /* Find our address */
+invstr:        mflr    r6                              /* Make it accessible */
+       mfmsr   r7
+       rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
+       mfspr   r7, SPRN_PID0
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
+       mfspr   r7,SPRN_MAS1
+       andis.  r7,r7,MAS1_VALID@h
+       bne     match_TLB
+
+       mfspr   r7,SPRN_MMUCFG
+       rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
+       cmpwi   r7,3
+       bne     match_TLB                       /* skip if NPIDS != 3 */
+
+       mfspr   r7,SPRN_PID1
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
+       mfspr   r7,SPRN_MAS1
+       andis.  r7,r7,MAS1_VALID@h
+       bne     match_TLB
+       mfspr   r7, SPRN_PID2
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* Fall through, we had to match */
+
+match_TLB:
+       mfspr   r7,SPRN_MAS0
+       rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */
+
+       mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
+       oris    r7,r7,MAS1_IPROT@h
+       mtspr   SPRN_MAS1,r7
+       tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in */
+       mfspr   r9,SPRN_TLB1CFG
+       andi.   r9,r9,0xfff
+       li      r6,0                            /* Set Entry counter to 0 */
+1:     lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       mfspr   r7,SPRN_MAS1
+       rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
+       cmpw    r3,r6
+       beq     skpinv                          /* Dont update the current execution TLB */
+       mtspr   SPRN_MAS1,r7
+       tlbwe
+       isync
+skpinv:        addi    r6,r6,1                         /* Increment */
+       cmpw    r6,r9                           /* Are we done? */
+       bne     1b                              /* If not, repeat */
+
+       /* Invalidate TLB0 */
+       li      r6,0x04
+       tlbivax 0,r6
+       TLBSYNC
+       /* Invalidate TLB1 */
+       li      r6,0x0c
+       tlbivax 0,r6
+       TLBSYNC
+
+/* 3. Setup a temp mapping and jump to it */
+       andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
+       addi    r5, r5, 0x1
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+
+       /* grab and fixup the RPN */
+       mfspr   r6,SPRN_MAS1    /* extract MAS1[SIZE] */
+       rlwinm  r6,r6,25,27,31
+       li      r8,-1
+       addi    r6,r6,10
+       slw     r6,r8,r6        /* convert to mask */
+
+       bl      1f              /* Find our address */
+1:     mflr    r7
+
+       mfspr   r8,SPRN_MAS3
+#ifdef CONFIG_PHYS_64BIT
+       mfspr   r23,SPRN_MAS7
+#endif
+       and     r8,r6,r8
+       subfic  r9,r6,-4096
+       and     r9,r9,r7
+
+       or      r25,r8,r9
+       ori     r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
+
+       /* Just modify the entry ID and EPN for the temp mapping */
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
+       mtspr   SPRN_MAS0,r7
+       xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
+       slwi    r6,r6,12
+       oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
+       mtspr   SPRN_MAS1,r6
+       mfspr   r6,SPRN_MAS2
+       li      r7,0            /* temp EPN = 0 */
+       rlwimi  r7,r6,0,20,31
+       mtspr   SPRN_MAS2,r7
+       mtspr   SPRN_MAS3,r8
+       tlbwe
+
+       xori    r6,r4,1
+       slwi    r6,r6,5         /* setup new context with other address space */
+       bl      1f              /* Find our address */
+1:     mflr    r9
+       rlwimi  r7,r9,0,20,31
+       addi    r7,r7,(2f - 1b)
+       mtspr   SPRN_SRR0,r7
+       mtspr   SPRN_SRR1,r6
+       rfi
+2:
+/* 4. Clear out PIDs & Search info */
+       li      r6,0
+       mtspr   SPRN_MAS6,r6
+       mtspr   SPRN_PID0,r6
+
+       mfspr   r7,SPRN_MMUCFG
+       rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
+       cmpwi   r7,3
+       bne     2f                              /* skip if NPIDS != 3 */
+
+       mtspr   SPRN_PID1,r6
+       mtspr   SPRN_PID2,r6
+
+/* 5. Invalidate mapping we started in */
+2:
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       mfspr   r6,SPRN_MAS1
+       rlwinm  r6,r6,0,2,0     /* clear IPROT */
+       mtspr   SPRN_MAS1,r6
+       tlbwe
+       /* Invalidate TLB1 */
+       li      r9,0x0c
+       tlbivax 0,r9
+       TLBSYNC
+
+/* The mapping only needs to be cache-coherent on SMP */
+#ifdef CONFIG_SMP
+#define M_IF_SMP       MAS2_M
+#else
+#define M_IF_SMP       0
+#endif
+
+#if defined(ENTRY_MAPPING_BOOT_SETUP)
+
+/* 6. Setup KERNELBASE mapping in TLB1[0] */
+       lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
+       mtspr   SPRN_MAS0,r6
+       lis     r6,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
+       mtspr   SPRN_MAS1,r6
+       lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
+       ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
+       mtspr   SPRN_MAS2,r6
+       mtspr   SPRN_MAS3,r8
+       tlbwe
+
+/* 7. Jump to KERNELBASE mapping */
+       lis     r6,(KERNELBASE & ~0xfff)@h
+       ori     r6,r6,(KERNELBASE & ~0xfff)@l
+
+#elif defined(ENTRY_MAPPING_KEXEC_SETUP)
+/*
+ * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
+ * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
+ * will cover the first 2GiB of memory.
+ */
+
+       lis r10, (MAS1_VALID|MAS1_IPROT)@h
+       ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
+       li  r11, 0
+       li  r0, 8
+       mtctr   r0
+
+next_tlb_setup:
+       addi    r0, r11, 3
+       rlwinm  r0, r0, 16, 4, 15  // Compute esel
+       rlwinm  r9, r11, 28, 0, 3   // Compute [ER]PN
+       oris    r0, r0, (MAS0_TLBSEL(1))@h
+       mtspr   SPRN_MAS0,r0
+       mtspr   SPRN_MAS1,r10
+       mtspr   SPRN_MAS2,r9
+       ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
+       mtspr   SPRN_MAS3,r9
+       tlbwe
+       addi    r11, r11, 1
+       bdnz+   next_tlb_setup
+
+/* 7. Jump to our 1:1 mapping */
+       li      r6, 0
+
+#else
+       #error You need to specify the mapping or not use this at all.
+#endif
+
+       lis     r7,MSR_KERNEL@h
+       ori     r7,r7,MSR_KERNEL@l
+       bl      1f                      /* Find our address */
+1:     mflr    r9
+       rlwimi  r6,r9,0,20,31
+       addi    r6,r6,(2f - 1b)
+       add     r6, r6, r25
+       mtspr   SPRN_SRR0,r6
+       mtspr   SPRN_SRR1,r7
+       rfi                             /* start execution out of TLB1[0] entry */
+
+/* 8. Clear out the temp mapping */
+2:     lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       mfspr   r8,SPRN_MAS1
+       rlwinm  r8,r8,0,2,0     /* clear IPROT */
+       mtspr   SPRN_MAS1,r8
+       tlbwe
+       /* Invalidate TLB1 */
+       li      r9,0x0c
+       tlbivax 0,r9
+       TLBSYNC
index edd4a57fd29e154b9dc90fe1aea1cae29fb2513b..4faeba247854c038078ef4362836d50b37f4f44a 100644 (file)
@@ -94,204 +94,10 @@ _ENTRY(_start);
  */
 
 _ENTRY(__early_start)
-/* 1. Find the index of the entry we're executing in */
-       bl      invstr                          /* Find our address */
-invstr:        mflr    r6                              /* Make it accessible */
-       mfmsr   r7
-       rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
-       mfspr   r7, SPRN_PID0
-       slwi    r7,r7,16
-       or      r7,r7,r4
-       mtspr   SPRN_MAS6,r7
-       tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
-       mfspr   r7,SPRN_MAS1
-       andis.  r7,r7,MAS1_VALID@h
-       bne     match_TLB
-
-       mfspr   r7,SPRN_MMUCFG
-       rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
-       cmpwi   r7,3
-       bne     match_TLB                       /* skip if NPIDS != 3 */
-
-       mfspr   r7,SPRN_PID1
-       slwi    r7,r7,16
-       or      r7,r7,r4
-       mtspr   SPRN_MAS6,r7
-       tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
-       mfspr   r7,SPRN_MAS1
-       andis.  r7,r7,MAS1_VALID@h
-       bne     match_TLB
-       mfspr   r7, SPRN_PID2
-       slwi    r7,r7,16
-       or      r7,r7,r4
-       mtspr   SPRN_MAS6,r7
-       tlbsx   0,r6                            /* Fall through, we had to match */
-
-match_TLB:
-       mfspr   r7,SPRN_MAS0
-       rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */
-
-       mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
-       oris    r7,r7,MAS1_IPROT@h
-       mtspr   SPRN_MAS1,r7
-       tlbwe
-
-/* 2. Invalidate all entries except the entry we're executing in */
-       mfspr   r9,SPRN_TLB1CFG
-       andi.   r9,r9,0xfff
-       li      r6,0                            /* Set Entry counter to 0 */
-1:     lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
-       rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
-       mtspr   SPRN_MAS0,r7
-       tlbre
-       mfspr   r7,SPRN_MAS1
-       rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
-       cmpw    r3,r6
-       beq     skpinv                          /* Dont update the current execution TLB */
-       mtspr   SPRN_MAS1,r7
-       tlbwe
-       isync
-skpinv:        addi    r6,r6,1                         /* Increment */
-       cmpw    r6,r9                           /* Are we done? */
-       bne     1b                              /* If not, repeat */
-
-       /* Invalidate TLB0 */
-       li      r6,0x04
-       tlbivax 0,r6
-       TLBSYNC
-       /* Invalidate TLB1 */
-       li      r6,0x0c
-       tlbivax 0,r6
-       TLBSYNC
-
-/* 3. Setup a temp mapping and jump to it */
-       andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
-       addi    r5, r5, 0x1
-       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
-       rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
-       mtspr   SPRN_MAS0,r7
-       tlbre
-
-       /* grab and fixup the RPN */
-       mfspr   r6,SPRN_MAS1    /* extract MAS1[SIZE] */
-       rlwinm  r6,r6,25,27,31
-       li      r8,-1
-       addi    r6,r6,10
-       slw     r6,r8,r6        /* convert to mask */
-
-       bl      1f              /* Find our address */
-1:     mflr    r7
-
-       mfspr   r8,SPRN_MAS3
-#ifdef CONFIG_PHYS_64BIT
-       mfspr   r23,SPRN_MAS7
-#endif
-       and     r8,r6,r8
-       subfic  r9,r6,-4096
-       and     r9,r9,r7
-
-       or      r25,r8,r9
-       ori     r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
-
-       /* Just modify the entry ID and EPN for the temp mapping */
-       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
-       rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
-       mtspr   SPRN_MAS0,r7
-       xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
-       slwi    r6,r6,12
-       oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
-       ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
-       mtspr   SPRN_MAS1,r6
-       mfspr   r6,SPRN_MAS2
-       li      r7,0            /* temp EPN = 0 */
-       rlwimi  r7,r6,0,20,31
-       mtspr   SPRN_MAS2,r7
-       mtspr   SPRN_MAS3,r8
-       tlbwe
-
-       xori    r6,r4,1
-       slwi    r6,r6,5         /* setup new context with other address space */
-       bl      1f              /* Find our address */
-1:     mflr    r9
-       rlwimi  r7,r9,0,20,31
-       addi    r7,r7,(2f - 1b)
-       mtspr   SPRN_SRR0,r7
-       mtspr   SPRN_SRR1,r6
-       rfi
-2:
-/* 4. Clear out PIDs & Search info */
-       li      r6,0
-       mtspr   SPRN_MAS6,r6
-       mtspr   SPRN_PID0,r6
-
-       mfspr   r7,SPRN_MMUCFG
-       rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
-       cmpwi   r7,3
-       bne     2f                              /* skip if NPIDS != 3 */
 
-       mtspr   SPRN_PID1,r6
-       mtspr   SPRN_PID2,r6
-
-/* 5. Invalidate mapping we started in */
-2:
-       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
-       rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
-       mtspr   SPRN_MAS0,r7
-       tlbre
-       mfspr   r6,SPRN_MAS1
-       rlwinm  r6,r6,0,2,0     /* clear IPROT */
-       mtspr   SPRN_MAS1,r6
-       tlbwe
-       /* Invalidate TLB1 */
-       li      r9,0x0c
-       tlbivax 0,r9
-       TLBSYNC
-
-/* The mapping only needs to be cache-coherent on SMP */
-#ifdef CONFIG_SMP
-#define M_IF_SMP       MAS2_M
-#else
-#define M_IF_SMP       0
-#endif
-
-/* 6. Setup KERNELBASE mapping in TLB1[0] */
-       lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
-       mtspr   SPRN_MAS0,r6
-       lis     r6,(MAS1_VALID|MAS1_IPROT)@h
-       ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
-       mtspr   SPRN_MAS1,r6
-       lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
-       ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
-       mtspr   SPRN_MAS2,r6
-       mtspr   SPRN_MAS3,r8
-       tlbwe
-
-/* 7. Jump to KERNELBASE mapping */
-       lis     r6,(KERNELBASE & ~0xfff)@h
-       ori     r6,r6,(KERNELBASE & ~0xfff)@l
-       lis     r7,MSR_KERNEL@h
-       ori     r7,r7,MSR_KERNEL@l
-       bl      1f                      /* Find our address */
-1:     mflr    r9
-       rlwimi  r6,r9,0,20,31
-       addi    r6,r6,(2f - 1b)
-       mtspr   SPRN_SRR0,r6
-       mtspr   SPRN_SRR1,r7
-       rfi                             /* start execution out of TLB1[0] entry */
-
-/* 8. Clear out the temp mapping */
-2:     lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
-       rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
-       mtspr   SPRN_MAS0,r7
-       tlbre
-       mfspr   r8,SPRN_MAS1
-       rlwinm  r8,r8,0,2,0     /* clear IPROT */
-       mtspr   SPRN_MAS1,r8
-       tlbwe
-       /* Invalidate TLB1 */
-       li      r9,0x0c
-       tlbivax 0,r9
-       TLBSYNC
+#define ENTRY_MAPPING_BOOT_SETUP
+#include "fsl_booke_entry_mapping.S"
+#undef ENTRY_MAPPING_BOOT_SETUP
 
        /* Establish the interrupt vector offsets */
        SET_IVOR(0,  CriticalInput);
index c533525ca56a67840aeb6a24001506a90175ca3d..bc47352deb1fec8f76fc1ac9f094c941cc2a9e4f 100644 (file)
@@ -378,17 +378,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
  * single-stepped a copy of the instruction.  The address of this
  * copy is p->ainsn.insn.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
-{
-       int ret;
-       unsigned int insn = *p->ainsn.insn;
-
-       regs->nip = (unsigned long)p->addr;
-       ret = emulate_step(regs, insn);
-       if (ret == 0)
-               regs->nip = (unsigned long)p->addr + 4;
-}
-
 static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *cur = kprobe_running();
@@ -406,7 +395,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
                cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(cur, regs);
+       /* Adjust nip to after the single-stepped instruction */
+       regs->nip = (unsigned long)cur->addr + 4;
        regs->msr |= kcb->kprobe_saved_msr;
 
        /*Restore back the original saved kprobes variables and continue. */
index 8043d1b73cf0cbe98186b3e38aadbf908b283d3e..dc66d52dcff56b8be102b6ed25f160d9b44eaf87 100644 (file)
@@ -711,6 +711,22 @@ relocate_new_kernel:
        /* r4 = reboot_code_buffer */
        /* r5 = start_address      */
 
+#ifdef CONFIG_FSL_BOOKE
+
+       mr      r29, r3
+       mr      r30, r4
+       mr      r31, r5
+
+#define ENTRY_MAPPING_KEXEC_SETUP
+#include "fsl_booke_entry_mapping.S"
+#undef ENTRY_MAPPING_KEXEC_SETUP
+
+       mr      r3, r29
+       mr      r4, r30
+       mr      r5, r31
+
+       li      r0, 0
+#else
        li      r0, 0
 
        /*
@@ -727,6 +743,7 @@ relocate_new_kernel:
        rfi
 
 1:
+#endif
        /* from this point address translation is turned off */
        /* and interrupts are disabled */
 
index bc9f39d2598bcf7df0e26c95eaa2f5054e005ca9..3b4dcc82a4c1f43ab1f26a29506591e0d4aa4369 100644 (file)
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(kernel_thread);
 
-#ifndef CONFIG_BOOKE
+#ifdef CONFIG_PPC_FPU
 EXPORT_SYMBOL_GPL(cvt_df);
 EXPORT_SYMBOL_GPL(cvt_fd);
 #endif
diff --git a/arch/powerpc/kernel/swsusp_booke.S b/arch/powerpc/kernel/swsusp_booke.S
new file mode 100644 (file)
index 0000000..11a3930
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Based on swsusp_32.S, modified for FSL BookE by
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ * Copyright (c) 2009-2010 MontaVista Software, LLC.
+ */
+
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/mmu.h>
+
+/*
+ * Structure for storing CPU registers on the save area.
+ */
+#define SL_SP          0
+#define SL_PC          4
+#define SL_MSR         8
+#define SL_TCR         0xc
+#define SL_SPRG0       0x10
+#define SL_SPRG1       0x14
+#define SL_SPRG2       0x18
+#define SL_SPRG3       0x1c
+#define SL_SPRG4       0x20
+#define SL_SPRG5       0x24
+#define SL_SPRG6       0x28
+#define SL_SPRG7       0x2c
+#define SL_TBU         0x30
+#define SL_TBL         0x34
+#define SL_R2          0x38
+#define SL_CR          0x3c
+#define SL_LR          0x40
+#define SL_R12         0x44    /* r12 to r31 */
+#define SL_SIZE                (SL_R12 + 80)
+
+       .section .data
+       .align  5
+
+_GLOBAL(swsusp_save_area)
+       .space  SL_SIZE
+
+
+       .section .text
+       .align  5
+
+_GLOBAL(swsusp_arch_suspend)
+       lis     r11,swsusp_save_area@h
+       ori     r11,r11,swsusp_save_area@l
+
+       mflr    r0
+       stw     r0,SL_LR(r11)
+       mfcr    r0
+       stw     r0,SL_CR(r11)
+       stw     r1,SL_SP(r11)
+       stw     r2,SL_R2(r11)
+       stmw    r12,SL_R12(r11)
+
+       /* Save MSR & TCR */
+       mfmsr   r4
+       stw     r4,SL_MSR(r11)
+       mfspr   r4,SPRN_TCR
+       stw     r4,SL_TCR(r11)
+
+       /* Get a stable timebase and save it */
+1:     mfspr   r4,SPRN_TBRU
+       stw     r4,SL_TBU(r11)
+       mfspr   r5,SPRN_TBRL
+       stw     r5,SL_TBL(r11)
+       mfspr   r3,SPRN_TBRU
+       cmpw    r3,r4
+       bne     1b
+
+       /* Save SPRGs */
+       mfsprg  r4,0
+       stw     r4,SL_SPRG0(r11)
+       mfsprg  r4,1
+       stw     r4,SL_SPRG1(r11)
+       mfsprg  r4,2
+       stw     r4,SL_SPRG2(r11)
+       mfsprg  r4,3
+       stw     r4,SL_SPRG3(r11)
+       mfsprg  r4,4
+       stw     r4,SL_SPRG4(r11)
+       mfsprg  r4,5
+       stw     r4,SL_SPRG5(r11)
+       mfsprg  r4,6
+       stw     r4,SL_SPRG6(r11)
+       mfsprg  r4,7
+       stw     r4,SL_SPRG7(r11)
+
+       /* Call the low level suspend stuff (we should probably have made
+        * a stackframe...
+        */
+       bl      swsusp_save
+
+       /* Restore LR from the save area */
+       lis     r11,swsusp_save_area@h
+       ori     r11,r11,swsusp_save_area@l
+       lwz     r0,SL_LR(r11)
+       mtlr    r0
+
+       blr
+
+_GLOBAL(swsusp_arch_resume)
+       sync
+
+       /* Load ptr the list of pages to copy in r3 */
+       lis     r11,(restore_pblist)@h
+       ori     r11,r11,restore_pblist@l
+       lwz     r3,0(r11)
+
+       /* Copy the pages. This is a very basic implementation, to
+        * be replaced by something more cache efficient */
+1:
+       li      r0,256
+       mtctr   r0
+       lwz     r5,pbe_address(r3)      /* source */
+       lwz     r6,pbe_orig_address(r3) /* destination */
+2:
+       lwz     r8,0(r5)
+       lwz     r9,4(r5)
+       lwz     r10,8(r5)
+       lwz     r11,12(r5)
+       addi    r5,r5,16
+       stw     r8,0(r6)
+       stw     r9,4(r6)
+       stw     r10,8(r6)
+       stw     r11,12(r6)
+       addi    r6,r6,16
+       bdnz    2b
+       lwz     r3,pbe_next(r3)
+       cmpwi   0,r3,0
+       bne     1b
+
+       bl flush_dcache_L1
+       bl flush_instruction_cache
+
+       lis     r11,swsusp_save_area@h
+       ori     r11,r11,swsusp_save_area@l
+
+       lwz     r4,SL_SPRG0(r11)
+       mtsprg  0,r4
+       lwz     r4,SL_SPRG1(r11)
+       mtsprg  1,r4
+       lwz     r4,SL_SPRG2(r11)
+       mtsprg  2,r4
+       lwz     r4,SL_SPRG3(r11)
+       mtsprg  3,r4
+       lwz     r4,SL_SPRG4(r11)
+       mtsprg  4,r4
+       lwz     r4,SL_SPRG5(r11)
+       mtsprg  5,r4
+       lwz     r4,SL_SPRG6(r11)
+       mtsprg  6,r4
+       lwz     r4,SL_SPRG7(r11)
+       mtsprg  7,r4
+
+       /* restore the MSR */
+       lwz     r3,SL_MSR(r11)
+       mtmsr   r3
+
+       /* Restore TB */
+       li      r3,0
+       mtspr   SPRN_TBWL,r3
+       lwz     r3,SL_TBU(r11)
+       lwz     r4,SL_TBL(r11)
+       mtspr   SPRN_TBWU,r3
+       mtspr   SPRN_TBWL,r4
+
+       /* Restore TCR and clear any pending bits in TSR. */
+       lwz     r4,SL_TCR(r11)
+       mtspr   SPRN_TCR,r4
+       lis     r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
+       mtspr   SPRN_TSR,r4
+
+       /* Kick decrementer */
+       li      r0,1
+       mtdec   r0
+
+       /* Restore the callee-saved registers and return */
+       lwz     r0,SL_CR(r11)
+       mtcr    r0
+       lwz     r2,SL_R2(r11)
+       lmw     r12,SL_R12(r11)
+       lwz     r1,SL_SP(r11)
+       lwz     r0,SL_LR(r11)
+       mtlr    r0
+
+       li      r3,0
+       blr
index 3031fc712ad03fec600e0caa042c16c5ae6d691a..25fc33984c2bc02d614d641a7668033ba51711bf 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *  Copyright 2007-2010 Freescale Semiconductor, Inc.
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -305,7 +306,7 @@ static inline int check_io_access(struct pt_regs *regs)
 #ifndef CONFIG_FSL_BOOKE
 #define get_mc_reason(regs)    ((regs)->dsisr)
 #else
-#define get_mc_reason(regs)    (mfspr(SPRN_MCSR) & MCSR_MASK)
+#define get_mc_reason(regs)    (mfspr(SPRN_MCSR))
 #endif
 #define REASON_FP              ESR_FP
 #define REASON_ILLEGAL         (ESR_PIL | ESR_PUO)
@@ -421,6 +422,91 @@ int machine_check_47x(struct pt_regs *regs)
        return 0;
 }
 #elif defined(CONFIG_E500)
+int machine_check_e500mc(struct pt_regs *regs)
+{
+       unsigned long mcsr = mfspr(SPRN_MCSR);
+       unsigned long reason = mcsr;
+       int recoverable = 1;
+
+       printk("Machine check in kernel mode.\n");
+       printk("Caused by (from MCSR=%lx): ", reason);
+
+       if (reason & MCSR_MCP)
+               printk("Machine Check Signal\n");
+
+       if (reason & MCSR_ICPERR) {
+               printk("Instruction Cache Parity Error\n");
+
+               /*
+                * This is recoverable by invalidating the i-cache.
+                */
+               mtspr(SPRN_L1CSR1, mfspr(SPRN_L1CSR1) | L1CSR1_ICFI);
+               while (mfspr(SPRN_L1CSR1) & L1CSR1_ICFI)
+                       ;
+
+               /*
+                * This will generally be accompanied by an instruction
+                * fetch error report -- only treat MCSR_IF as fatal
+                * if it wasn't due to an L1 parity error.
+                */
+               reason &= ~MCSR_IF;
+       }
+
+       if (reason & MCSR_DCPERR_MC) {
+               printk("Data Cache Parity Error\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_L2MMU_MHIT) {
+               printk("Hit on multiple TLB entries\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_NMI)
+               printk("Non-maskable interrupt\n");
+
+       if (reason & MCSR_IF) {
+               printk("Instruction Fetch Error Report\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_LD) {
+               printk("Load Error Report\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_ST) {
+               printk("Store Error Report\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_LDG) {
+               printk("Guarded Load Error Report\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_TLBSYNC)
+               printk("Simultaneous tlbsync operations\n");
+
+       if (reason & MCSR_BSL2_ERR) {
+               printk("Level 2 Cache Error\n");
+               recoverable = 0;
+       }
+
+       if (reason & MCSR_MAV) {
+               u64 addr;
+
+               addr = mfspr(SPRN_MCAR);
+               addr |= (u64)mfspr(SPRN_MCARU) << 32;
+
+               printk("Machine Check %s Address: %#llx\n",
+                      reason & MCSR_MEA ? "Effective" : "Physical", addr);
+       }
+
+       mtspr(SPRN_MCSR, mcsr);
+       return mfspr(SPRN_MCSR) == 0 && recoverable;
+}
+
 int machine_check_e500(struct pt_regs *regs)
 {
        unsigned long reason = get_mc_reason(regs);
index dcd01c82e7013c8e08f797eaa40c9543d5f2fc01..8a0deefac08d216c2ebd127add50ce8117f74f79 100644 (file)
@@ -223,19 +223,17 @@ SECTIONS
 #endif
 
        /* The initial task and kernel stack */
-       .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-               INIT_TASK_DATA(THREAD_SIZE)
-       }
+       INIT_TASK_DATA_SECTION(THREAD_SIZE)
 
-       .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+       .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
                PAGE_ALIGNED_DATA(PAGE_SIZE)
        }
 
-       .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+       .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
                CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
        }
 
-       .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
+       .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
                READ_MOSTLY_DATA(L1_CACHE_BYTES)
        }
 
index eeba0a70e466f6d4d293fdaba9bc0cdf27af4c07..69d668c072aeab579aab54182d0c9bd544dac956 100644 (file)
@@ -171,6 +171,17 @@ config ISS4xx
        help
          This option enables support for the IBM ISS simulation environment
 
+config ICON
+       bool "Icon"
+       depends on 44x
+       default n
+       select PPC44x_SIMPLE
+       select 440SPe
+       select PCI
+       select PPC4xx_PCI_EXPRESS
+       help
+         This option enables support for the AMCC PPC440SPe evaluation board.
+
 #config LUAN
 #      bool "Luan"
 #      depends on 44x
index e8c23ccaa1fcfc628744d4490f408860352d0969..5f7a29d7f59091fa958e063b661421aa447e48fa 100644 (file)
@@ -61,7 +61,8 @@ static char *board[] __initdata = {
        "amcc,redwood",
        "amcc,sequoia",
        "amcc,taishan",
-       "amcc,yosemite"
+       "amcc,yosemite",
+       "mosaixtech,icon"
 };
 
 static int __init ppc44x_probe(void)
index f0684c8ac960ef602726f012715772c672628745..8fe87fc61485bdc1c48c4bf430ed626933ce8b22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved.
+ * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved.
  *
  * Author: Andy Fleming <afleming@freescale.com>
  *
@@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
  * Setup the architecture
  *
  */
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+
 static void __init mpc85xx_mds_setup_arch(void)
 {
        struct device_node *np;
@@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void)
        }
 #endif
 
+#ifdef CONFIG_SMP
+       mpc85xx_smp_init();
+#endif
+
 #ifdef CONFIG_QUICC_ENGINE
        np = of_find_compatible_node(NULL, NULL, "fsl,qe");
        if (!np) {
@@ -271,9 +279,49 @@ static void __init mpc85xx_mds_setup_arch(void)
                                                BCSR_UCC_RGMII, BCSR_UCC_RTBI);
                        }
 
+               } else if (machine_is(p1021_mds)) {
+#define BCSR11_ENET_MICRST     (0x1 << 5)
+                       /* Reset Micrel PHY */
+                       clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
+                       setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
                }
+
                iounmap(bcsr_regs);
        }
+
+       if (machine_is(p1021_mds)) {
+#define MPC85xx_PMUXCR_OFFSET           0x60
+#define MPC85xx_PMUXCR_QE0              0x00008000
+#define MPC85xx_PMUXCR_QE3              0x00001000
+#define MPC85xx_PMUXCR_QE9              0x00000040
+#define MPC85xx_PMUXCR_QE12             0x00000008
+               static __be32 __iomem *pmuxcr;
+
+               np = of_find_node_by_name(NULL, "global-utilities");
+
+               if (np) {
+                       pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;
+
+                       if (!pmuxcr)
+                               printk(KERN_EMERG "Error: Alternate function"
+                                       " signal multiplex control register not"
+                                       " mapped!\n");
+                       else
+                       /* P1021 has pins muxed for QE and other functions. To
+                        * enable QE UEC mode, we need to set bit QE0 for UCC1
+                        * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
+                        * and QE12 for QE MII management singals in PMUXCR
+                        * register.
+                        */
+                               setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 |
+                                                 MPC85xx_PMUXCR_QE3 |
+                                                 MPC85xx_PMUXCR_QE9 |
+                                                 MPC85xx_PMUXCR_QE12);
+
+                       of_node_put(np);
+               }
+
+       }
 #endif /* CONFIG_QUICC_ENGINE */
 
 #ifdef CONFIG_SWIOTLB
@@ -330,6 +378,16 @@ static struct of_device_id mpc85xx_ids[] = {
        {},
 };
 
+static struct of_device_id p1021_ids[] = {
+       { .type = "soc", },
+       { .compatible = "soc", },
+       { .compatible = "simple-bus", },
+       { .type = "qe", },
+       { .compatible = "fsl,qe", },
+       { .compatible = "gianfar", },
+       {},
+};
+
 static int __init mpc85xx_publish_devices(void)
 {
        if (machine_is(mpc8568_mds))
@@ -342,11 +400,22 @@ static int __init mpc85xx_publish_devices(void)
 
        return 0;
 }
+
+static int __init p1021_publish_devices(void)
+{
+       /* Publish the QE devices */
+       of_platform_bus_probe(NULL, p1021_ids, NULL);
+
+       return 0;
+}
+
 machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
 machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
+machine_device_initcall(p1021_mds, p1021_publish_devices);
 
 machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
 machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
 
 static void __init mpc85xx_mds_pic_init(void)
 {
@@ -366,7 +435,7 @@ static void __init mpc85xx_mds_pic_init(void)
 
        mpic = mpic_alloc(np, r.start,
                        MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
-                       MPIC_BROKEN_FRR_NIRQS,
+                       MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
                        0, 256, " OpenPIC  ");
        BUG_ON(mpic == NULL);
        of_node_put(np);
@@ -380,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void)
                if (!np)
                        return;
        }
-       qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
+       if (machine_is(p1021_mds))
+               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
+                               qe_ic_cascade_high_mpic);
+       else
+               qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
        of_node_put(np);
 #endif                         /* CONFIG_QUICC_ENGINE */
 }
@@ -426,3 +499,26 @@ define_machine(mpc8569_mds) {
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 #endif
 };
+
+static int __init p1021_mds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
+
+}
+
+define_machine(p1021_mds) {
+       .name           = "P1021 MDS",
+       .probe          = p1021_mds_probe,
+       .setup_arch     = mpc85xx_mds_setup_arch,
+       .init_IRQ       = mpc85xx_mds_pic_init,
+       .get_irq        = mpic_get_irq,
+       .restart        = fsl_rstcr_restart,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+};
+
index 22667a09d40eee6276eff723a8e4523e2b2e5bd2..4326b737d913e02d4541320c5bb3cecc45f7220b 100644 (file)
@@ -1066,7 +1066,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
        fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT);
        fsize = lmb_phys_mem_size();
 
-       if ((fbase + fsize) <= 0x800000000)
+       if ((fbase + fsize) <= 0x800000000ul)
                hbase = 0; /* use the device tree window */
        else {
                /* If we're over 32 GB we need to cheat. We can't map all of
index a7be144f5874335da103e0af4c33b3b3d1e1f3fe..962c2d8dd8d927e0d2e03336dff954e42935ef86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc.
  *
  * Author: Tony Li <tony.li@freescale.com>
  *        Jason Jin <Jason.jin@freescale.com>
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
+#include <asm/mpic.h>
 #include "fsl_msi.h"
 
+LIST_HEAD(msi_head);
+
 struct fsl_msi_feature {
        u32 fsl_pic_ip;
        u32 msiir_offset;
 };
 
-static struct fsl_msi *fsl_msi;
+struct fsl_msi_cascade_data {
+       struct fsl_msi *msi_data;
+       int index;
+};
 
 static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
 {
@@ -54,10 +60,12 @@ static struct irq_chip fsl_msi_chip = {
 static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
                                irq_hw_number_t hw)
 {
+       struct fsl_msi *msi_data = h->host_data;
        struct irq_chip *chip = &fsl_msi_chip;
 
        irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
 
+       set_irq_chip_data(virq, msi_data);
        set_irq_chip_and_handler(virq, chip, handle_edge_irq);
 
        return 0;
@@ -96,11 +104,12 @@ static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
 {
        struct msi_desc *entry;
-       struct fsl_msi *msi_data = fsl_msi;
+       struct fsl_msi *msi_data;
 
        list_for_each_entry(entry, &pdev->msi_list, list) {
                if (entry->irq == NO_IRQ)
                        continue;
+               msi_data = get_irq_data(entry->irq);
                set_irq_msi(entry->irq, NULL);
                msi_bitmap_free_hwirqs(&msi_data->bitmap,
                                       virq_to_hw(entry->irq), 1);
@@ -111,9 +120,10 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
 }
 
 static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
-                                 struct msi_msg *msg)
+                               struct msi_msg *msg,
+                               struct fsl_msi *fsl_msi_data)
 {
-       struct fsl_msi *msi_data = fsl_msi;
+       struct fsl_msi *msi_data = fsl_msi_data;
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
        u32 base = 0;
 
@@ -130,14 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 
 static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
-       int rc, hwirq;
+       int rc, hwirq = -ENOMEM;
        unsigned int virq;
        struct msi_desc *entry;
        struct msi_msg msg;
-       struct fsl_msi *msi_data = fsl_msi;
+       struct fsl_msi *msi_data;
 
        list_for_each_entry(entry, &pdev->msi_list, list) {
-               hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
+               list_for_each_entry(msi_data, &msi_head, list) {
+                       hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
+                       if (hwirq >= 0)
+                               break;
+               }
+
                if (hwirq < 0) {
                        rc = hwirq;
                        pr_debug("%s: fail allocating msi interrupt\n",
@@ -154,25 +169,31 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                        rc = -ENOSPC;
                        goto out_free;
                }
+               set_irq_data(virq, msi_data);
                set_irq_msi(virq, entry);
 
-               fsl_compose_msi_msg(pdev, hwirq, &msg);
+               fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
                write_msi_msg(virq, &msg);
        }
        return 0;
 
 out_free:
+       /* free by the caller of this function */
        return rc;
 }
 
 static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 {
        unsigned int cascade_irq;
-       struct fsl_msi *msi_data = fsl_msi;
+       struct fsl_msi *msi_data;
        int msir_index = -1;
        u32 msir_value = 0;
        u32 intr_index;
        u32 have_shift = 0;
+       struct fsl_msi_cascade_data *cascade_data;
+
+       cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq);
+       msi_data = cascade_data->msi_data;
 
        raw_spin_lock(&desc->lock);
        if ((msi_data->feature &  FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
@@ -187,13 +208,13 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
        if (unlikely(desc->status & IRQ_INPROGRESS))
                goto unlock;
 
-       msir_index = (int)desc->handler_data;
+       msir_index = cascade_data->index;
 
        if (msir_index >= NR_MSI_REG)
                cascade_irq = NO_IRQ;
 
        desc->status |= IRQ_INPROGRESS;
-       switch (fsl_msi->feature & FSL_PIC_IP_MASK) {
+       switch (msi_data->feature & FSL_PIC_IP_MASK) {
        case FSL_PIC_IP_MPIC:
                msir_value = fsl_msi_read(msi_data->msi_regs,
                        msir_index * 0x10);
@@ -229,6 +250,30 @@ unlock:
        raw_spin_unlock(&desc->lock);
 }
 
+static int fsl_of_msi_remove(struct of_device *ofdev)
+{
+       struct fsl_msi *msi = ofdev->dev.platform_data;
+       int virq, i;
+       struct fsl_msi_cascade_data *cascade_data;
+
+       if (msi->list.prev != NULL)
+               list_del(&msi->list);
+       for (i = 0; i < NR_MSI_REG; i++) {
+               virq = msi->msi_virqs[i];
+               if (virq != NO_IRQ) {
+                       cascade_data = get_irq_data(virq);
+                       kfree(cascade_data);
+                       irq_dispose_mapping(virq);
+               }
+       }
+       if (msi->bitmap.bitmap)
+               msi_bitmap_free(&msi->bitmap);
+       iounmap(msi->msi_regs);
+       kfree(msi);
+
+       return 0;
+}
+
 static int __devinit fsl_of_msi_probe(struct of_device *dev,
                                const struct of_device_id *match)
 {
@@ -239,15 +284,18 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
        int virt_msir;
        const u32 *p;
        struct fsl_msi_feature *features = match->data;
+       struct fsl_msi_cascade_data *cascade_data = NULL;
+       int len;
+       u32 offset;
 
        printk(KERN_DEBUG "Setting up Freescale MSI support\n");
 
        msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
        if (!msi) {
                dev_err(&dev->dev, "No memory for MSI structure\n");
-               err = -ENOMEM;
-               goto error_out;
+               return -ENOMEM;
        }
+       dev->dev.platform_data = msi;
 
        msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
                                      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
@@ -298,27 +346,47 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
                err = -EINVAL;
                goto error_out;
        }
+       offset = 0;
+       p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
+       if (p)
+               offset = *p / IRQS_PER_MSI_REG;
 
        count /= sizeof(u32);
-       for (i = 0; i < count / 2; i++) {
-               if (i > NR_MSI_REG)
-                       break;
+       for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
                virt_msir = irq_of_parse_and_map(dev->dev.of_node, i);
                if (virt_msir != NO_IRQ) {
-                       set_irq_data(virt_msir, (void *)i);
+                       cascade_data = kzalloc(
+                                       sizeof(struct fsl_msi_cascade_data),
+                                       GFP_KERNEL);
+                       if (!cascade_data) {
+                               dev_err(&dev->dev,
+                                       "No memory for MSI cascade data\n");
+                               err = -ENOMEM;
+                               goto error_out;
+                       }
+                       msi->msi_virqs[i] = virt_msir;
+                       cascade_data->index = i + offset;
+                       cascade_data->msi_data = msi;
+                       set_irq_data(virt_msir, (void *)cascade_data);
                        set_irq_chained_handler(virt_msir, fsl_msi_cascade);
                }
        }
 
-       fsl_msi = msi;
+       list_add_tail(&msi->list, &msi_head);
 
-       WARN_ON(ppc_md.setup_msi_irqs);
-       ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
-       ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
-       ppc_md.msi_check_device = fsl_msi_check_device;
+       /* The multiple setting ppc_md.setup_msi_irqs will not harm things */
+       if (!ppc_md.setup_msi_irqs) {
+               ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
+               ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
+               ppc_md.msi_check_device = fsl_msi_check_device;
+       } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
+               dev_err(&dev->dev, "Different MSI driver already installed!\n");
+               err = -ENODEV;
+               goto error_out;
+       }
        return 0;
 error_out:
-       kfree(msi);
+       fsl_of_msi_remove(dev);
        return err;
 }
 
@@ -351,6 +419,7 @@ static struct of_platform_driver fsl_of_msi_driver = {
                .of_match_table = fsl_of_msi_ids,
        },
        .probe = fsl_of_msi_probe,
+       .remove = fsl_of_msi_remove,
 };
 
 static __init int fsl_of_msi_init(void)
index 331c7e7025b786bf7d3ed071038ceb6330f971fc..624580c252d75029a9f551f53a6c8efca973c4bd 100644 (file)
@@ -32,8 +32,11 @@ struct fsl_msi {
        u32 msi_addr_hi;
        void __iomem *msi_regs;
        u32 feature;
+       int msi_virqs[NR_MSI_REG];
 
        struct msi_bitmap bitmap;
+
+       struct list_head list;          /* support multiple MSI banks */
 };
 
 #endif /* _POWERPC_SYSDEV_FSL_MSI_H */
index cd37e49e70349d05cc82c48e83b0bd6a42faa9ce..30e1626b2e850c9f2d5f9d2137f3025cf05f4ea8 100644 (file)
@@ -1426,7 +1426,7 @@ int fsl_rio_setup(struct of_device *dev)
        port->iores.flags = IORESOURCE_MEM;
        port->iores.name = "rio_io_win";
 
-       priv->pwirq   = irq_of_parse_and_map(dev->node, 0);
+       priv->pwirq   = irq_of_parse_and_map(dev->dev.of_node, 0);
        priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2);
        priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3);
        priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4);
index 106d767bf65bfd1c7d4e7332d6459de8a338eec4..156aa7d362584048945c8f10475edcf801eb0e8b 100644 (file)
@@ -974,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata =
        .setup_utl      = ppc460ex_pciex_init_utl,
 };
 
+static int __init ppc460sx_pciex_core_init(struct device_node *np)
+{
+       /* HSS drive amplitude */
+       mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211);
+
+       mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211);
+
+       mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211);
+       mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211);
+
+       /* HSS TX pre-emphasis */
+       mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987);
+
+       mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987);
+
+       mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987);
+       mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987);
+
+       /* HSS TX calibration control */
+       mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222);
+       mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000);
+       mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000);
+
+       /* HSS TX slew control */
+       mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF);
+       mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
+       mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
+
+       udelay(100);
+
+       /* De-assert PLLRESET */
+       dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0);
+
+       /* Reset DL, UTL, GPL before configuration */
+       mtdcri(SDR0, PESDR0_460SX_RCSSET,
+                       PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+       mtdcri(SDR0, PESDR1_460SX_RCSSET,
+                       PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+       mtdcri(SDR0, PESDR2_460SX_RCSSET,
+                       PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+
+       udelay(100);
+
+       /*
+        * If bifurcation is not enabled, u-boot would have disabled the
+        * third PCIe port
+        */
+       if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) ==
+                               0x00000001)) {
+               printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n");
+               printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n");
+               return 3;
+       }
+
+       printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n");
+       return 2;
+}
+
+static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+{
+
+       if (port->endpoint)
+               dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
+                               0x01000000, 0);
+       else
+               dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
+                               0, 0x01000000);
+
+       /*Gen-1*/
+       mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
+
+       dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
+                       (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
+                       PESDRx_RCSSET_RSTPYN);
+
+       port->has_ibpre = 1;
+
+       return 0;
+}
+
+static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
+{
+       /* Max 128 Bytes */
+       out_be32 (port->utl_base + PEUTL_PBBSZ,   0x00000000);
+       return 0;
+}
+
+static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
+       .core_init      = ppc460sx_pciex_core_init,
+       .port_init_hw   = ppc460sx_pciex_init_port_hw,
+       .setup_utl      = ppc460sx_pciex_init_utl,
+};
+
 #endif /* CONFIG_44x */
 
 #ifdef CONFIG_40x
@@ -1089,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
        }
        if (of_device_is_compatible(np, "ibm,plb-pciex-460ex"))
                ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops;
+       if (of_device_is_compatible(np, "ibm,plb-pciex-460sx"))
+               ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops;
 #endif /* CONFIG_44x    */
 #ifdef CONFIG_40x
        if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
index d04e40b306fbdfdaf254a16993f4eb79431e3c96..56d9e5deccbf5e7ccff3e6b1cc62ef23b9e10a9c 100644 (file)
 #define PESDR0_460EX_IHS1              0x036C
 #define PESDR0_460EX_IHS2              0x036D
 
+/*
+ * 460SX addtional DCRs
+ */
+#define PESDRn_460SX_RCEI              0x02
+
+#define PESDR0_460SX_HSSL0DAMP         0x320
+#define PESDR0_460SX_HSSL1DAMP         0x321
+#define PESDR0_460SX_HSSL2DAMP         0x322
+#define PESDR0_460SX_HSSL3DAMP         0x323
+#define PESDR0_460SX_HSSL4DAMP         0x324
+#define PESDR0_460SX_HSSL5DAMP         0x325
+#define PESDR0_460SX_HSSL6DAMP         0x326
+#define PESDR0_460SX_HSSL7DAMP         0x327
+
+#define PESDR1_460SX_HSSL0DAMP         0x354
+#define PESDR1_460SX_HSSL1DAMP         0x355
+#define PESDR1_460SX_HSSL2DAMP         0x356
+#define PESDR1_460SX_HSSL3DAMP         0x357
+
+#define PESDR2_460SX_HSSL0DAMP         0x384
+#define PESDR2_460SX_HSSL1DAMP         0x385
+#define PESDR2_460SX_HSSL2DAMP         0x386
+#define PESDR2_460SX_HSSL3DAMP         0x387
+
+#define PESDR0_460SX_HSSL0COEFA                0x328
+#define PESDR0_460SX_HSSL1COEFA                0x329
+#define PESDR0_460SX_HSSL2COEFA                0x32A
+#define PESDR0_460SX_HSSL3COEFA                0x32B
+#define PESDR0_460SX_HSSL4COEFA                0x32C
+#define PESDR0_460SX_HSSL5COEFA                0x32D
+#define PESDR0_460SX_HSSL6COEFA                0x32E
+#define PESDR0_460SX_HSSL7COEFA                0x32F
+
+#define PESDR1_460SX_HSSL0COEFA                0x358
+#define PESDR1_460SX_HSSL1COEFA                0x359
+#define PESDR1_460SX_HSSL2COEFA                0x35A
+#define PESDR1_460SX_HSSL3COEFA                0x35B
+
+#define PESDR2_460SX_HSSL0COEFA                0x388
+#define PESDR2_460SX_HSSL1COEFA                0x389
+#define PESDR2_460SX_HSSL2COEFA                0x38A
+#define PESDR2_460SX_HSSL3COEFA                0x38B
+
+#define PESDR0_460SX_HSSL1CALDRV       0x339
+#define PESDR1_460SX_HSSL1CALDRV       0x361
+#define PESDR2_460SX_HSSL1CALDRV       0x391
+
+#define PESDR0_460SX_HSSSLEW           0x338
+#define PESDR1_460SX_HSSSLEW           0x360
+#define PESDR2_460SX_HSSSLEW           0x390
+
+#define PESDR0_460SX_HSSCTLSET         0x31E
+#define PESDR1_460SX_HSSCTLSET         0x352
+#define PESDR2_460SX_HSSCTLSET         0x382
+
+#define PESDR0_460SX_RCSSET            0x304
+#define PESDR1_460SX_RCSSET            0x344
+#define PESDR2_460SX_RCSSET            0x374
 /*
  * Of the above, some are common offsets from the base
  */
index 9b866816863c89a76069d1d3b9f857067a1aa27f..24aafa68b64367a8ff1e68c91981d15c2ee51afd 100644 (file)
@@ -14,6 +14,6 @@
 #define L1_CACHE_BYTES     256
 #define L1_CACHE_SHIFT     8
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 #endif
index c56d3f56d020224583bfcee76790dd761fa39c78..1f066e46e83e69775e8494023feae5f7b337d685 100644 (file)
@@ -264,7 +264,7 @@ restore_registers:
        lghi    %r2,0
        br      %r14
 
-       .section .data.nosave,"aw",@progbits
+       .section .data..nosave,"aw",@progbits
        .align  8
 .Ldisabled_wait_31:
        .long  0x000a0000,0x00000000
index f02382ae5c48b1cd319a4cb1e755fa060f03cfdc..862d748082369a24eee471b493c4b07d3220ed36 100644 (file)
@@ -1,6 +1,6 @@
 SECTIONS
 {
-  .rodata.compressed : {
+  .rodata..compressed : {
        input_len = .;
        LONG(input_data_end - input_data) input_data = .;
        *(.data)
index e461d67f03c3ff18f40151860121798e09471aea..ef9e555aafba5bad5247d0baeae0d256064b1620 100644 (file)
@@ -14,7 +14,7 @@
 
 #define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 #ifndef __ASSEMBLY__
 struct cache_info {
index bbf91b9c3d39fc0bc770eed6fb629001a6f7c630..e7f2940bd270f5ab481e513880019c3b34a7bb2a 100644 (file)
@@ -325,7 +325,7 @@ main1:
                (*rr)->next = NULL;
        }
        printf("! Generated by btfixupprep. Do not edit.\n\n");
-       printf("\t.section\t\".data.init\",#alloc,#write\n\t.align\t4\n\n");
+       printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n");
        printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
        for (i = 0; i < last; i++) {
                f = array + i;
index 78b07009f60a9d52c8042fc1c9124fef9d6a2f16..0588b8c7faa26b5eb596a1c52a1bcbf77a53bc92 100644 (file)
@@ -21,7 +21,7 @@
 
 #define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 #ifdef CONFIG_SPARC32
 #include <asm/asi.h>
index 7fcad58e216db26022eb32bd581134a67849af8b..69268014dd8e966860f7faa323b394961b6f6428 100644 (file)
@@ -94,7 +94,7 @@ SECTIONS
   .data           : {
     INIT_TASK_DATA(KERNEL_STACK_SIZE)
     . = ALIGN(KERNEL_STACK_SIZE);
-    *(.data.init_irqstack)
+    *(.data..init_irqstack)
     DATA_DATA
     *(.data.* .gnu.linkonce.d.*)
     SORT(CONSTRUCTORS)
index 8aa77b61a5ff09458786c249b1419c8b9dac68ef..ddc9698b66edc71d5da6508c8c40bb523df84760 100644 (file)
@@ -34,5 +34,5 @@ union thread_union init_thread_union __init_task_data =
        { INIT_THREAD_INFO(init_task) };
 
 union thread_union cpu0_irqstack
-       __attribute__((__section__(".data.init_irqstack"))) =
+       __attribute__((__section__(".data..init_irqstack"))) =
                { INIT_THREAD_INFO(init_task) };
index e7a6cca667aa5c0a6ec0a8df5392976d8d97aea9..ec63785506714f8059c9c7a31cf44d4875466698 100644 (file)
@@ -50,7 +50,7 @@ SECTIONS
   {
     INIT_TASK_DATA(KERNEL_STACK_SIZE)
     . = ALIGN(KERNEL_STACK_SIZE);
-    *(.data.init_irqstack)
+    *(.data..init_irqstack)
     DATA_DATA
     *(.gnu.linkonce.d*)
     CONSTRUCTORS
diff --git a/arch/x86/.gitignore b/arch/x86/.gitignore
new file mode 100644 (file)
index 0000000..0280790
--- /dev/null
@@ -0,0 +1,3 @@
+boot/compressed/vmlinux
+tools/test_get_len
+
index bcbd36c414321257217cfefdc1520f1ba924d273..5c228129d175779976b1985f8af86c5b9d80a668 100644 (file)
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
        offs += 32*1024 + 18;   /* Add 32K + 18 bytes slack */
        offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
 
-       printf(".section \".rodata.compressed\",\"a\",@progbits\n");
+       printf(".section \".rodata..compressed\",\"a\",@progbits\n");
        printf(".globl z_input_len\n");
        printf("z_input_len = %lu\n", ilen);
        printf(".globl z_output_len\n");
index a6f1a59a5b0cc491e772eb04d2d1570d9e32bf85..5ddabceee12408d55f22b6412bbd4617dc684c55 100644 (file)
@@ -26,8 +26,8 @@ SECTIONS
                HEAD_TEXT
                _ehead = . ;
        }
-       .rodata.compressed : {
-               *(.rodata.compressed)
+       .rodata..compressed : {
+               *(.rodata..compressed)
        }
        .text : {
                _text = .;      /* Text */
index 2f9047cfaacafe0bfcf90e09d514fff0e948224f..48f99f15452e7d111e8bad21a4830d21231071cc 100644 (file)
@@ -7,7 +7,7 @@
 #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
 #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
index 8ded418b05939f1fc2f9ef6512fd21281bd2b10a..13ab720573e3e31e317ac52f977e168401552f17 100644 (file)
@@ -1,4 +1,4 @@
-       .section .text.page_aligned
+       .section .text..page_aligned
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/page_types.h>
index c77586061bcbc7642d2f7662f487f4432d2e3ff0..5db5b7d65a180f6a7f0c2cb970d63e04129add2a 100644 (file)
@@ -106,6 +106,7 @@ struct cpu_hw_events {
 
        int                     n_events;
        int                     n_added;
+       int                     n_txn;
        int                     assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
        u64                     tags[X86_PMC_IDX_MAX];
        struct perf_event       *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
@@ -983,6 +984,7 @@ static int x86_pmu_enable(struct perf_event *event)
 out:
        cpuc->n_events = n;
        cpuc->n_added += n - n0;
+       cpuc->n_txn += n - n0;
 
        return 0;
 }
@@ -1089,6 +1091,14 @@ static void x86_pmu_disable(struct perf_event *event)
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        int i;
 
+       /*
+        * If we're called during a txn, we don't need to do anything.
+        * The events never got scheduled and ->cancel_txn will truncate
+        * the event_list.
+        */
+       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+               return;
+
        x86_pmu_stop(event);
 
        for (i = 0; i < cpuc->n_events; i++) {
@@ -1379,6 +1389,7 @@ static void x86_pmu_start_txn(const struct pmu *pmu)
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
        cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuc->n_txn = 0;
 }
 
 /*
@@ -1391,6 +1402,11 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu)
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
        cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
+       /*
+        * Truncate the collected events.
+        */
+       cpuc->n_added -= cpuc->n_txn;
+       cpuc->n_events -= cpuc->n_txn;
 }
 
 /*
@@ -1419,6 +1435,12 @@ static int x86_pmu_commit_txn(const struct pmu *pmu)
         */
        memcpy(cpuc->assign, assign, n*sizeof(int));
 
+       /*
+        * Clear out the txn count so that ->cancel_txn() which gets
+        * run after ->commit_txn() doesn't undo things.
+        */
+       cpuc->n_txn = 0;
+
        return 0;
 }
 
index 3a54dcb9cd0e6c82b8b9231e88afd7305be6e5da..43e9ccf449471286fd0013ae1bc28ce83778b9a6 100644 (file)
@@ -34,7 +34,7 @@ EXPORT_SYMBOL(init_task);
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
  * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
+ * so they are allowed to end up in the .data..cacheline_aligned
  * section. Since TSS's are completely CPU-local, we want them
  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
  */
index 401ff1085a4d265579192c038714acfe6831ddec..de3b63ae3da26300297e315a6f7a9b5157d429ee 100644 (file)
@@ -241,7 +241,7 @@ void __init setup_per_cpu_areas(void)
 #endif
 #endif
                /*
-                * Up to this point, the boot CPU has been using .data.init
+                * Up to this point, the boot CPU has been using .init.data
                 * area.  Reload any changed state for the boot CPU.
                 */
                if (cpu == boot_cpu_id)
index 2cc249718c46e47ca28dd9e48ff1691a3c39d185..d0bb52296fa3a8f564cdb1964107e677494859ed 100644 (file)
@@ -97,7 +97,7 @@ SECTIONS
                HEAD_TEXT
 #ifdef CONFIG_X86_32
                . = ALIGN(PAGE_SIZE);
-               *(.text.page_aligned)
+               *(.text..page_aligned)
 #endif
                . = ALIGN(8);
                _stext = .;
@@ -305,7 +305,7 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
                __bss_start = .;
-               *(.bss.page_aligned)
+               *(.bss..page_aligned)
                *(.bss)
                . = ALIGN(4);
                __bss_stop = .;
index 987267f79bf5154648cb729cedf29e712fa58ab3..a9c6611080347bd4368beff2ab582d07347fa256 100644 (file)
@@ -60,6 +60,6 @@ static void xen_vcpu_notify_restore(void *data)
 
 void xen_arch_resume(void)
 {
-       smp_call_function(xen_vcpu_notify_restore,
-                              (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
+       on_each_cpu(xen_vcpu_notify_restore,
+                   (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
 }
index 76640ac76888ff88ae7a330423d6bf475149282a..75b49d01780bbf1933b59852abbca49d88fa29d5 100644 (file)
@@ -1355,8 +1355,11 @@ static struct of_device_id pata_macio_match[] =
 
 static struct macio_driver pata_macio_driver =
 {
-       .name           = "pata-macio",
-       .match_table    = pata_macio_match,
+       .driver = {
+               .name           = "pata-macio",
+               .owner          = THIS_MODULE,
+               .of_match_table = pata_macio_match,
+       },
        .probe          = pata_macio_attach,
        .remove         = pata_macio_detach,
 #ifdef CONFIG_PM
@@ -1366,9 +1369,6 @@ static struct macio_driver pata_macio_driver =
 #ifdef CONFIG_PMAC_MEDIABAY
        .mediabay_event = pata_macio_mb_event,
 #endif
-       .driver = {
-               .owner          = THIS_MODULE,
-       },
 };
 
 static const struct pci_device_id pata_macio_pci_match[] = {
index 52f2d11bc7b975e55c49881f42e49f5552fc4371..ed6fb91123abb67577f6f309f0171a6d7e0cb142 100644 (file)
@@ -1159,8 +1159,10 @@ static struct of_device_id swim3_match[] =
 
 static struct macio_driver swim3_driver =
 {
-       .name           = "swim3",
-       .match_table    = swim3_match,
+       .driver = {
+               .name           = "swim3",
+               .of_match_table = swim3_match,
+       },
        .probe          = swim3_attach,
 #if 0
        .suspend        = swim3_suspend,
index 83fa09a836ca8574a3696c888d7574a833b35447..258bc2ae2885625a1650cebcabb4b9eb975092bb 100644 (file)
@@ -298,7 +298,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
                                offsetof(struct virtio_blk_config, seg_max),
                                &sg_elems);
-       if (err)
+
+       /* We need at least one SG element, whatever they say. */
+       if (err || !sg_elems)
                sg_elems = 1;
 
        /* We need an extra sg elements at head and tail. */
index e8ea6825822ce8ccb04f25a444c7880b1b6da170..9344216183a433a84210b5ebaef0efd57e6aa9c7 100644 (file)
@@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void)
        }
 }
 
-static int intel_i915_configure(void)
+static int intel_i9xx_configure(void)
 {
        struct aper_size_info_fixed *current_size;
        u32 temp;
@@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void)
        return 0;
 }
 
+static int intel_i915_get_gtt_size(void)
+{
+       int size;
+
+       if (IS_G33) {
+               u16 gmch_ctrl;
+
+               /* G33's GTT size defined in gmch_ctrl */
+               pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &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;
+               }
+       } else {
+               /* On previous hardware, the GTT size was just what was
+                * required to map the aperture.
+                */
+               size = agp_bridge->driver->fetch_size();
+       }
+
+       return KB(size);
+}
+
 /* The intel i915 automatically initializes the agp aperture during POST.
  * Use the memory already set aside for in the GTT.
  */
@@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
        struct aper_size_info_fixed *size;
        int num_entries;
        u32 temp, temp2;
-       int gtt_map_size = 256 * 1024;
+       int gtt_map_size;
 
        size = agp_bridge->current_size;
        page_order = size->page_order;
@@ -1226,8 +1258,8 @@ 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);
 
-       if (IS_G33)
-           gtt_map_size = 1024 * 1024; /* 1M on G33 */
+       gtt_map_size = intel_i915_get_gtt_size();
+
        intel_private.gtt = ioremap(temp2, gtt_map_size);
        if (!intel_private.gtt)
                return -ENOMEM;
@@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = {
        .size_type              = FIXED_APER_SIZE,
        .num_aperture_sizes     = 4,
        .needs_scratch_page     = true,
-       .configure              = intel_i915_configure,
+       .configure              = intel_i9xx_configure,
        .fetch_size             = intel_i9xx_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .mask_memory            = intel_i810_mask_memory,
@@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = {
        .size_type              = FIXED_APER_SIZE,
        .num_aperture_sizes     = 4,
        .needs_scratch_page     = true,
-       .configure              = intel_i915_configure,
+       .configure              = intel_i9xx_configure,
        .fetch_size             = intel_i9xx_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .mask_memory            = intel_i965_mask_memory,
@@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = {
        .size_type              = FIXED_APER_SIZE,
        .num_aperture_sizes     = 4,
        .needs_scratch_page     = true,
-       .configure              = intel_i915_configure,
+       .configure              = intel_i9xx_configure,
        .fetch_size             = intel_i9xx_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .mask_memory            = intel_i965_mask_memory,
index 95db71360d2416b437c0447c7ffd64b582ff6b5b..f845a8f718b39af2bd1277e331d50143e24ae9fc 100644 (file)
@@ -415,7 +415,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
        bridge->gatt_table_real = (u32 *) table;
        /* Need to clear out any dirty data still sitting in caches */
        flush_dcache_range((unsigned long)table,
-                          (unsigned long)(table_end + PAGE_SIZE));
+                          (unsigned long)table_end + 1);
        bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
 
        if (bridge->gatt_table == NULL)
index 8c99bf1b5e9fde218dab95f2091b807a7fbb4623..942a9826bd23ed64b83095fcdeb65ed059c9ce02 100644 (file)
@@ -529,6 +529,10 @@ static bool will_write_block(struct port *port)
 {
        bool ret;
 
+       if (!port->guest_connected) {
+               /* Port got hot-unplugged. Let's exit. */
+               return false;
+       }
        if (!port->host_connected)
                return true;
 
@@ -1099,6 +1103,13 @@ static int remove_port(struct port *port)
 {
        struct port_buffer *buf;
 
+       if (port->guest_connected) {
+               port->guest_connected = false;
+               port->host_connected = false;
+               wake_up_interruptible(&port->waitqueue);
+               send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
+       }
+
        spin_lock_irq(&port->portdev->ports_lock);
        list_del(&port->list);
        spin_unlock_irq(&port->portdev->ports_lock);
@@ -1120,9 +1131,6 @@ static int remove_port(struct port *port)
                hvc_remove(port->cons.hvc);
 #endif
        }
-       if (port->guest_connected)
-               send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
-
        sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
        device_destroy(pdrvdata.class, port->dev->devt);
        cdev_del(&port->cdev);
index 9d65b371de64cced72bcb0f1e483913962277552..983530ba04a7e932c3a70ec692e719fe44cccb21 100644 (file)
@@ -1158,7 +1158,7 @@ static int __init crypto4xx_probe(struct of_device *ofdev,
        struct device *dev = &ofdev->dev;
        struct crypto4xx_core_device *core_dev;
 
-       rc = of_address_to_resource(ofdev->node, 0, &res);
+       rc = of_address_to_resource(ofdev->dev.of_node, 0, &res);
        if (rc)
                return -ENODEV;
 
@@ -1215,13 +1215,13 @@ static int __init crypto4xx_probe(struct of_device *ofdev,
                     (unsigned long) dev);
 
        /* Register for Crypto isr, Crypto Engine IRQ */
-       core_dev->irq = irq_of_parse_and_map(ofdev->node, 0);
+       core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
        rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
                         core_dev->dev->name, dev);
        if (rc)
                goto err_request_irq;
 
-       core_dev->dev->ce_base = of_iomap(ofdev->node, 0);
+       core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0);
        if (!core_dev->dev->ce_base) {
                dev_err(dev, "failed to of_iomap\n");
                goto err_iomap;
index 8566be832f5172b7fab29ccf134442d109681170..23163fda5035357a50c892c1a65a35e7ae3a89ea 100644 (file)
@@ -251,16 +251,10 @@ static void n2_base_ctx_init(struct n2_base_ctx *ctx)
 struct n2_hash_ctx {
        struct n2_base_ctx              base;
 
-       struct crypto_ahash             *fallback;
+       struct crypto_ahash             *fallback_tfm;
+};
 
-       /* These next three members must match the layout created by
-        * crypto_init_shash_ops_async.  This allows us to properly
-        * plumb requests we can't do in hardware down to the fallback
-        * operation, providing all of the data structures and layouts
-        * expected by those paths.
-        */
-       struct ahash_request            fallback_req;
-       struct shash_desc               fallback_desc;
+struct n2_hash_req_ctx {
        union {
                struct md5_state        md5;
                struct sha1_state       sha1;
@@ -269,56 +263,62 @@ struct n2_hash_ctx {
 
        unsigned char                   hash_key[64];
        unsigned char                   keyed_zero_hash[32];
+
+       struct ahash_request            fallback_req;
 };
 
 static int n2_hash_async_init(struct ahash_request *req)
 {
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
        struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
        struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
 
-       ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback);
-       ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+       ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
+       rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
-       return crypto_ahash_init(&ctx->fallback_req);
+       return crypto_ahash_init(&rctx->fallback_req);
 }
 
 static int n2_hash_async_update(struct ahash_request *req)
 {
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
        struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
        struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
 
-       ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback);
-       ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-       ctx->fallback_req.nbytes = req->nbytes;
-       ctx->fallback_req.src = req->src;
+       ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
+       rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+       rctx->fallback_req.nbytes = req->nbytes;
+       rctx->fallback_req.src = req->src;
 
-       return crypto_ahash_update(&ctx->fallback_req);
+       return crypto_ahash_update(&rctx->fallback_req);
 }
 
 static int n2_hash_async_final(struct ahash_request *req)
 {
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
        struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
        struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
 
-       ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback);
-       ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-       ctx->fallback_req.result = req->result;
+       ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
+       rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+       rctx->fallback_req.result = req->result;
 
-       return crypto_ahash_final(&ctx->fallback_req);
+       return crypto_ahash_final(&rctx->fallback_req);
 }
 
 static int n2_hash_async_finup(struct ahash_request *req)
 {
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
        struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
        struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
 
-       ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback);
-       ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-       ctx->fallback_req.nbytes = req->nbytes;
-       ctx->fallback_req.src = req->src;
-       ctx->fallback_req.result = req->result;
+       ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
+       rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+       rctx->fallback_req.nbytes = req->nbytes;
+       rctx->fallback_req.src = req->src;
+       rctx->fallback_req.result = req->result;
 
-       return crypto_ahash_finup(&ctx->fallback_req);
+       return crypto_ahash_finup(&rctx->fallback_req);
 }
 
 static int n2_hash_cra_init(struct crypto_tfm *tfm)
@@ -338,7 +338,10 @@ static int n2_hash_cra_init(struct crypto_tfm *tfm)
                goto out;
        }
 
-       ctx->fallback = fallback_tfm;
+       crypto_ahash_set_reqsize(ahash, (sizeof(struct n2_hash_req_ctx) +
+                                        crypto_ahash_reqsize(fallback_tfm)));
+
+       ctx->fallback_tfm = fallback_tfm;
        return 0;
 
 out:
@@ -350,7 +353,7 @@ static void n2_hash_cra_exit(struct crypto_tfm *tfm)
        struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
        struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 
-       crypto_free_ahash(ctx->fallback);
+       crypto_free_ahash(ctx->fallback_tfm);
 }
 
 static unsigned long wait_for_tail(struct spu_queue *qp)
@@ -399,14 +402,16 @@ static int n2_hash_async_digest(struct ahash_request *req,
         * exceed 2^16.
         */
        if (unlikely(req->nbytes > (1 << 16))) {
-               ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback);
-               ctx->fallback_req.base.flags =
+               struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
+
+               ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
+               rctx->fallback_req.base.flags =
                        req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-               ctx->fallback_req.nbytes = req->nbytes;
-               ctx->fallback_req.src = req->src;
-               ctx->fallback_req.result = req->result;
+               rctx->fallback_req.nbytes = req->nbytes;
+               rctx->fallback_req.src = req->src;
+               rctx->fallback_req.result = req->result;
 
-               return crypto_ahash_digest(&ctx->fallback_req);
+               return crypto_ahash_digest(&rctx->fallback_req);
        }
 
        n2_base_ctx_init(&ctx->base);
@@ -472,9 +477,8 @@ out:
 
 static int n2_md5_async_digest(struct ahash_request *req)
 {
-       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-       struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
-       struct md5_state *m = &ctx->u.md5;
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
+       struct md5_state *m = &rctx->u.md5;
 
        if (unlikely(req->nbytes == 0)) {
                static const char md5_zero[MD5_DIGEST_SIZE] = {
@@ -497,9 +501,8 @@ static int n2_md5_async_digest(struct ahash_request *req)
 
 static int n2_sha1_async_digest(struct ahash_request *req)
 {
-       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-       struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
-       struct sha1_state *s = &ctx->u.sha1;
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
+       struct sha1_state *s = &rctx->u.sha1;
 
        if (unlikely(req->nbytes == 0)) {
                static const char sha1_zero[SHA1_DIGEST_SIZE] = {
@@ -524,9 +527,8 @@ static int n2_sha1_async_digest(struct ahash_request *req)
 
 static int n2_sha256_async_digest(struct ahash_request *req)
 {
-       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-       struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
-       struct sha256_state *s = &ctx->u.sha256;
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
+       struct sha256_state *s = &rctx->u.sha256;
 
        if (req->nbytes == 0) {
                static const char sha256_zero[SHA256_DIGEST_SIZE] = {
@@ -555,9 +557,8 @@ static int n2_sha256_async_digest(struct ahash_request *req)
 
 static int n2_sha224_async_digest(struct ahash_request *req)
 {
-       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-       struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm);
-       struct sha256_state *s = &ctx->u.sha256;
+       struct n2_hash_req_ctx *rctx = ahash_request_ctx(req);
+       struct sha256_state *s = &rctx->u.sha256;
 
        if (req->nbytes == 0) {
                static const char sha224_zero[SHA224_DIGEST_SIZE] = {
@@ -1398,7 +1399,7 @@ static int find_devino_index(struct of_device *dev, struct spu_mdesc_info *ip,
 
        intr = ip->ino_table[i].intr;
 
-       dev_intrs = of_get_property(dev->node, "interrupts", NULL);
+       dev_intrs = of_get_property(dev->dev.of_node, "interrupts", NULL);
        if (!dev_intrs)
                return -ENODEV;
 
@@ -1449,7 +1450,7 @@ static int queue_cache_init(void)
 {
        if (!queue_cache[HV_NCS_QTYPE_MAU - 1])
                queue_cache[HV_NCS_QTYPE_MAU - 1] =
-                       kmem_cache_create("cwq_queue",
+                       kmem_cache_create("mau_queue",
                                          (MAU_NUM_ENTRIES *
                                           MAU_ENTRY_SIZE),
                                          MAU_ENTRY_SIZE, 0, NULL);
@@ -1574,7 +1575,7 @@ static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc,
                id = mdesc_get_property(mdesc, tgt, "id", NULL);
                if (table[*id] != NULL) {
                        dev_err(&dev->dev, "%s: SPU cpu slot already set.\n",
-                               dev->node->full_name);
+                               dev->dev.of_node->full_name);
                        return -EINVAL;
                }
                cpu_set(*id, p->sharing);
@@ -1595,7 +1596,7 @@ static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list,
        p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL);
        if (!p) {
                dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n",
-                       dev->node->full_name);
+                       dev->dev.of_node->full_name);
                return -ENOMEM;
        }
 
@@ -1684,7 +1685,7 @@ static int __devinit grab_mdesc_irq_props(struct mdesc_handle *mdesc,
        const unsigned int *reg;
        u64 node;
 
-       reg = of_get_property(dev->node, "reg", NULL);
+       reg = of_get_property(dev->dev.of_node, "reg", NULL);
        if (!reg)
                return -ENODEV;
 
@@ -1836,7 +1837,7 @@ static int __devinit n2_crypto_probe(struct of_device *dev,
 
        n2_spu_driver_version();
 
-       full_name = dev->node->full_name;
+       full_name = dev->dev.of_node->full_name;
        pr_info("Found N2CP at %s\n", full_name);
 
        np = alloc_n2cp();
@@ -1948,7 +1949,7 @@ static int __devinit n2_mau_probe(struct of_device *dev,
 
        n2_spu_driver_version();
 
-       full_name = dev->node->full_name;
+       full_name = dev->dev.of_node->full_name;
        pr_info("Found NCP at %s\n", full_name);
 
        mp = alloc_ncp();
@@ -2034,8 +2035,11 @@ static struct of_device_id n2_crypto_match[] = {
 MODULE_DEVICE_TABLE(of, n2_crypto_match);
 
 static struct of_platform_driver n2_crypto_driver = {
-       .name           =       "n2cp",
-       .match_table    =       n2_crypto_match,
+       .driver = {
+               .name           =       "n2cp",
+               .owner          =       THIS_MODULE,
+               .of_match_table =       n2_crypto_match,
+       },
        .probe          =       n2_crypto_probe,
        .remove         =       __devexit_p(n2_crypto_remove),
 };
@@ -2055,8 +2059,11 @@ static struct of_device_id n2_mau_match[] = {
 MODULE_DEVICE_TABLE(of, n2_mau_match);
 
 static struct of_platform_driver n2_mau_driver = {
-       .name           =       "ncp",
-       .match_table    =       n2_mau_match,
+       .driver = {
+               .name           =       "ncp",
+               .owner          =       THIS_MODULE,
+               .of_match_table =       n2_mau_match,
+       },
        .probe          =       n2_mau_probe,
        .remove         =       __devexit_p(n2_mau_remove),
 };
index 201e6e19c344d1cfe1ca2ff7402027bf6ca3ba54..14a8c0f1698e4fd1c5e33e33b6f28244741273be 100644 (file)
@@ -630,7 +630,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
 static int __devinit mpc_dma_probe(struct of_device *op,
                                        const struct of_device_id *match)
 {
-       struct device_node *dn = op->node;
+       struct device_node *dn = op->dev.of_node;
        struct device *dev = &op->dev;
        struct dma_device *dma;
        struct mpc_dma *mdma;
@@ -771,12 +771,12 @@ static struct of_device_id mpc_dma_match[] = {
 };
 
 static struct of_platform_driver mpc_dma_driver = {
-       .match_table    = mpc_dma_match,
        .probe          = mpc_dma_probe,
        .remove         = __devexit_p(mpc_dma_remove),
-       .driver         = {
-               .name   = DRV_NAME,
-               .owner  = THIS_MODULE,
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = mpc_dma_match,
        },
 };
 
index fa98abe4686fb06598c6f8b318e4866dff1f41be..5a22ca6927e5da6bd10b1abe04736218e0b31459 100644 (file)
@@ -4394,7 +4394,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev,
 static int __devinit ppc440spe_adma_probe(struct of_device *ofdev,
                                          const struct of_device_id *match)
 {
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct resource res;
        struct ppc440spe_adma_device *adev;
        struct ppc440spe_adma_chan *chan;
@@ -4626,7 +4626,7 @@ out:
 static int __devexit ppc440spe_adma_remove(struct of_device *ofdev)
 {
        struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev);
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct resource res;
        struct dma_chan *chan, *_chan;
        struct ppc_dma_chan_ref *ref, *_ref;
index 6c1886b497ff673add09b99809f065c9a294090b..52ca09bf4726ae9cb5984d38c79d86705c5b51f8 100644 (file)
@@ -229,7 +229,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
 
        pdata->edac_idx = edac_pci_idx++;
 
-       res = of_address_to_resource(op->node, 0, &r);
+       res = of_address_to_resource(op->dev.of_node, 0, &r);
        if (res) {
                printk(KERN_ERR "%s: Unable to get resource for "
                       "PCI err regs\n", __func__);
@@ -274,7 +274,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
        }
 
        if (edac_op_state == EDAC_OPSTATE_INT) {
-               pdata->irq = irq_of_parse_and_map(op->node, 0);
+               pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
                res = devm_request_irq(&op->dev, pdata->irq,
                                       mpc85xx_pci_isr, IRQF_DISABLED,
                                       "[EDAC] PCI err", pci);
@@ -529,7 +529,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
        edac_dev->ctl_name = pdata->name;
        edac_dev->dev_name = pdata->name;
 
-       res = of_address_to_resource(op->node, 0, &r);
+       res = of_address_to_resource(op->dev.of_node, 0, &r);
        if (res) {
                printk(KERN_ERR "%s: Unable to get resource for "
                       "L2 err regs\n", __func__);
@@ -576,7 +576,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
        }
 
        if (edac_op_state == EDAC_OPSTATE_INT) {
-               pdata->irq = irq_of_parse_and_map(op->node, 0);
+               pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
                res = devm_request_irq(&op->dev, pdata->irq,
                                       mpc85xx_l2_isr, IRQF_DISABLED,
                                       "[EDAC] L2 err", edac_dev);
@@ -978,7 +978,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
        mci->ctl_name = pdata->name;
        mci->dev_name = pdata->name;
 
-       res = of_address_to_resource(op->node, 0, &r);
+       res = of_address_to_resource(op->dev.of_node, 0, &r);
        if (res) {
                printk(KERN_ERR "%s: Unable to get resource for MC err regs\n",
                       __func__);
@@ -1052,7 +1052,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
                out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000);
 
                /* register interrupts */
-               pdata->irq = irq_of_parse_and_map(op->node, 0);
+               pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
                res = devm_request_irq(&op->dev, pdata->irq,
                                       mpc85xx_mc_isr,
                                        IRQF_DISABLED | IRQF_SHARED,
index 9d6f6783328c80357cb794614ff79dca1e0b84d0..e78839e89a067400726b26a302eb05f317200b02 100644 (file)
@@ -1022,7 +1022,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci,
        int status = 0;
        const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
        struct ppc4xx_edac_pdata *pdata = NULL;
-       const struct device_node *np = op->node;
+       const struct device_node *np = op->dev.of_node;
 
        if (match == NULL)
                return -EINVAL;
@@ -1113,7 +1113,7 @@ ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci)
        int status = 0;
        int ded_irq, sec_irq;
        struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
-       struct device_node *np = op->node;
+       struct device_node *np = op->dev.of_node;
 
        ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX);
        sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX);
@@ -1243,7 +1243,7 @@ ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match)
        int status = 0;
        u32 mcopt1, memcheck;
        dcr_host_t dcr_host;
-       const struct device_node *np = op->node;
+       const struct device_node *np = op->dev.of_node;
        struct mem_ctl_info *mci = NULL;
        static int ppc4xx_edac_instance;
 
index 764401951041910692901ea9c1489962de3277b8..9b2a54117c91c0a306c41c7eb437b641bbd58b31 100644 (file)
@@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work)
        }
 }
 
-void drm_kms_helper_poll_init(struct drm_device *dev)
+void drm_kms_helper_poll_disable(struct drm_device *dev)
+{
+       if (!dev->mode_config.poll_enabled)
+               return;
+       delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_disable);
+
+void drm_kms_helper_poll_enable(struct drm_device *dev)
 {
-       struct drm_connector *connector;
        bool poll = false;
+       struct drm_connector *connector;
        int ret;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                if (connector->polled)
                        poll = true;
        }
-       slow_work_register_user(THIS_MODULE);
-       delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
-                              &output_poll_ops);
 
        if (poll) {
                ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
@@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev)
                        DRM_ERROR("delayed enqueue failed %d\n", ret);
        }
 }
+EXPORT_SYMBOL(drm_kms_helper_poll_enable);
+
+void drm_kms_helper_poll_init(struct drm_device *dev)
+{
+       slow_work_register_user(THIS_MODULE);
+       delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
+                              &output_poll_ops);
+       dev->mode_config.poll_enabled = true;
+
+       drm_kms_helper_poll_enable(dev);
+}
 EXPORT_SYMBOL(drm_kms_helper_poll_init);
 
 void drm_kms_helper_poll_fini(struct drm_device *dev)
 {
-       delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
+       drm_kms_helper_poll_disable(dev);
        slow_work_unregister_user(THIS_MODULE);
 }
 EXPORT_SYMBOL(drm_kms_helper_poll_fini);
index 95639017bdbe732ef9765f28905189966bb77182..da78f2c0d90949b57b067d97a038a324337bb65e 100644 (file)
@@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
          intel_fb.o \
          intel_tv.o \
          intel_dvo.o \
+         intel_ringbuffer.o \
          intel_overlay.o \
          dvo_ch7xxx.o \
          dvo_ch7017.o \
index 322070c0c631966afe72abdc2113f67aa787a0e4..52510ad8b25d3e89f7f920af0a65978512b28209 100644 (file)
@@ -77,7 +77,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
        case ACTIVE_LIST:
                seq_printf(m, "Active:\n");
                lock = &dev_priv->mm.active_list_lock;
-               head = &dev_priv->mm.active_list;
+               head = &dev_priv->render_ring.active_list;
                break;
        case INACTIVE_LIST:
                seq_printf(m, "Inactive:\n");
@@ -129,7 +129,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
        struct drm_i915_gem_request *gem_request;
 
        seq_printf(m, "Request:\n");
-       list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
+       list_for_each_entry(gem_request, &dev_priv->render_ring.request_list,
+                       list) {
                seq_printf(m, "    %d @ %d\n",
                           gem_request->seqno,
                           (int) (jiffies - gem_request->emitted_jiffies));
@@ -143,9 +144,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       if (dev_priv->hw_status_page != NULL) {
+       if (dev_priv->render_ring.status_page.page_addr != NULL) {
                seq_printf(m, "Current sequence: %d\n",
-                          i915_get_gem_seqno(dev));
+                          i915_get_gem_seqno(dev,  &dev_priv->render_ring));
        } else {
                seq_printf(m, "Current sequence: hws uninitialized\n");
        }
@@ -195,9 +196,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
        }
        seq_printf(m, "Interrupts received: %d\n",
                   atomic_read(&dev_priv->irq_received));
-       if (dev_priv->hw_status_page != NULL) {
+       if (dev_priv->render_ring.status_page.page_addr != NULL) {
                seq_printf(m, "Current sequence:    %d\n",
-                          i915_get_gem_seqno(dev));
+                          i915_get_gem_seqno(dev,  &dev_priv->render_ring));
        } else {
                seq_printf(m, "Current sequence:    hws uninitialized\n");
        }
@@ -251,7 +252,7 @@ static int i915_hws_info(struct seq_file *m, void *data)
        int i;
        volatile u32 *hws;
 
-       hws = (volatile u32 *)dev_priv->hw_status_page;
+       hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr;
        if (hws == NULL)
                return 0;
 
@@ -287,7 +288,8 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data)
 
        spin_lock(&dev_priv->mm.active_list_lock);
 
-       list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+       list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list,
+                       list) {
                obj = &obj_priv->base;
                if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
                    ret = i915_gem_object_get_pages(obj, 0);
@@ -317,14 +319,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data)
        u8 *virt;
        uint32_t *ptr, off;
 
-       if (!dev_priv->ring.ring_obj) {
+       if (!dev_priv->render_ring.gem_object) {
                seq_printf(m, "No ringbuffer setup\n");
                return 0;
        }
 
-       virt = dev_priv->ring.virtual_start;
+       virt = dev_priv->render_ring.virtual_start;
 
-       for (off = 0; off < dev_priv->ring.Size; off += 4) {
+       for (off = 0; off < dev_priv->render_ring.size; off += 4) {
                ptr = (uint32_t *)(virt + off);
                seq_printf(m, "%08x :  %08x\n", off, *ptr);
        }
@@ -344,7 +346,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
 
        seq_printf(m, "RingHead :  %08x\n", head);
        seq_printf(m, "RingTail :  %08x\n", tail);
-       seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
+       seq_printf(m, "RingSize :  %08lx\n", dev_priv->render_ring.size);
        seq_printf(m, "Acthd :     %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
 
        return 0;
@@ -489,11 +491,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u16 rgvswctl = I915_READ16(MEMSWCTL);
+       u16 rgvstat = I915_READ16(MEMSTAT_ILK);
 
-       seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3);
-       seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1);
-       seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf,
-                  rgvswctl & 0x3f);
+       seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf);
+       seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f);
+       seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >>
+                  MEMSTAT_VID_SHIFT);
+       seq_printf(m, "Current P-state: %d\n",
+                  (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
 
        return 0;
 }
@@ -508,7 +513,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
 
        for (i = 0; i < 16; i++) {
                delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
-               seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq);
+               seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq,
+                          (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
        }
 
        return 0;
@@ -541,6 +547,8 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 rgvmodectl = I915_READ(MEMMODECTL);
+       u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY);
+       u16 crstandvid = I915_READ16(CRSTANDVID);
 
        seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
                   "yes" : "no");
@@ -555,9 +563,13 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
                   rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no");
        seq_printf(m, "Starting frequency: P%d\n",
                   (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
-       seq_printf(m, "Max frequency: P%d\n",
+       seq_printf(m, "Max P-state: P%d\n",
                   (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT);
-       seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
+       seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
+       seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f));
+       seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f));
+       seq_printf(m, "Render standby enabled: %s\n",
+                  (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes");
 
        return 0;
 }
@@ -621,6 +633,36 @@ static int i915_sr_status(struct seq_file *m, void *unused)
        return 0;
 }
 
+static int i915_emon_status(struct seq_file *m, void *unused)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long temp, chipset, gfx;
+
+       temp = i915_mch_val(dev_priv);
+       chipset = i915_chipset_val(dev_priv);
+       gfx = i915_gfx_val(dev_priv);
+
+       seq_printf(m, "GMCH temp: %ld\n", temp);
+       seq_printf(m, "Chipset power: %ld\n", chipset);
+       seq_printf(m, "GFX power: %ld\n", gfx);
+       seq_printf(m, "Total power: %ld\n", chipset + gfx);
+
+       return 0;
+}
+
+static int i915_gfxec(struct seq_file *m, void *unused)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+
+       seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
+
+       return 0;
+}
+
 static int
 i915_wedged_open(struct inode *inode,
                 struct file *filp)
@@ -743,6 +785,8 @@ static struct drm_info_list i915_debugfs_list[] = {
        {"i915_delayfreq_table", i915_delayfreq_table, 0},
        {"i915_inttoext_table", i915_inttoext_table, 0},
        {"i915_drpc_info", i915_drpc_info, 0},
+       {"i915_emon_status", i915_emon_status, 0},
+       {"i915_gfxec", i915_gfxec, 0},
        {"i915_fbc_status", i915_fbc_status, 0},
        {"i915_sr_status", i915_sr_status, 0},
 };
index 2a6b5de5ae5d07330232b8aff6b0b989300147a2..b2ebf02e4f8a738a00bf9089c212db8d3fc468ee 100644 (file)
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
 
-/* Really want an OS-independent resettable timer.  Would like to have
- * this loop run for (eg) 3 sec, but have the timer reset every time
- * the head pointer changes, so that EBUSY only happens if the ring
- * actually stalls for (eg) 3 seconds.
- */
-int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
-       u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
-       u32 last_acthd = I915_READ(acthd_reg);
-       u32 acthd;
-       u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-       int i;
-
-       trace_i915_ring_wait_begin (dev);
-
-       for (i = 0; i < 100000; i++) {
-               ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-               acthd = I915_READ(acthd_reg);
-               ring->space = ring->head - (ring->tail + 8);
-               if (ring->space < 0)
-                       ring->space += ring->Size;
-               if (ring->space >= n) {
-                       trace_i915_ring_wait_end (dev);
-                       return 0;
-               }
-
-               if (dev->primary->master) {
-                       struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
-                       if (master_priv->sarea_priv)
-                               master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
-               }
-
-
-               if (ring->head != last_head)
-                       i = 0;
-               if (acthd != last_acthd)
-                       i = 0;
-
-               last_head = ring->head;
-               last_acthd = acthd;
-               msleep_interruptible(10);
-
-       }
-
-       trace_i915_ring_wait_end (dev);
-       return -EBUSY;
-}
-
-/* As a ringbuffer is only allowed to wrap between instructions, fill
- * the tail with NOOPs.
- */
-int i915_wrap_ring(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       volatile unsigned int *virt;
-       int rem;
-
-       rem = dev_priv->ring.Size - dev_priv->ring.tail;
-       if (dev_priv->ring.space < rem) {
-               int ret = i915_wait_ring(dev, rem, __func__);
-               if (ret)
-                       return ret;
-       }
-       dev_priv->ring.space -= rem;
-
-       virt = (unsigned int *)
-               (dev_priv->ring.virtual_start + dev_priv->ring.tail);
-       rem /= 4;
-       while (rem--)
-               *virt++ = MI_NOOP;
-
-       dev_priv->ring.tail = 0;
-
-       return 0;
-}
-
 /**
  * Sets up the hardware status page for devices that need a physical address
  * in the register.
@@ -133,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev)
                DRM_ERROR("Can not allocate hardware status page\n");
                return -ENOMEM;
        }
-       dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+       dev_priv->render_ring.status_page.page_addr
+               = dev_priv->status_page_dmah->vaddr;
        dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
 
-       memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+       memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE);
 
        if (IS_I965G(dev))
                dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) &
@@ -159,8 +82,8 @@ static void i915_free_hws(struct drm_device *dev)
                dev_priv->status_page_dmah = NULL;
        }
 
-       if (dev_priv->status_gfx_addr) {
-               dev_priv->status_gfx_addr = 0;
+       if (dev_priv->render_ring.status_page.gfx_addr) {
+               dev_priv->render_ring.status_page.gfx_addr = 0;
                drm_core_ioremapfree(&dev_priv->hws_map, dev);
        }
 
@@ -172,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv;
-       drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
+       struct intel_ring_buffer *ring = &dev_priv->render_ring;
 
        /*
         * We should never lose context on the ring with modesetting
@@ -185,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
        ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
        ring->space = ring->head - (ring->tail + 8);
        if (ring->space < 0)
-               ring->space += ring->Size;
+               ring->space += ring->size;
 
        if (!dev->primary->master)
                return;
@@ -205,12 +128,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
        if (dev->irq_enabled)
                drm_irq_uninstall(dev);
 
-       if (dev_priv->ring.virtual_start) {
-               drm_core_ioremapfree(&dev_priv->ring.map, dev);
-               dev_priv->ring.virtual_start = NULL;
-               dev_priv->ring.map.handle = NULL;
-               dev_priv->ring.map.size = 0;
-       }
+       intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+       if (HAS_BSD(dev))
+               intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
 
        /* Clear the HWS virtual address at teardown */
        if (I915_NEED_GFX_HWS(dev))
@@ -233,24 +153,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
        }
 
        if (init->ring_size != 0) {
-               if (dev_priv->ring.ring_obj != NULL) {
+               if (dev_priv->render_ring.gem_object != NULL) {
                        i915_dma_cleanup(dev);
                        DRM_ERROR("Client tried to initialize ringbuffer in "
                                  "GEM mode\n");
                        return -EINVAL;
                }
 
-               dev_priv->ring.Size = init->ring_size;
+               dev_priv->render_ring.size = init->ring_size;
 
-               dev_priv->ring.map.offset = init->ring_start;
-               dev_priv->ring.map.size = init->ring_size;
-               dev_priv->ring.map.type = 0;
-               dev_priv->ring.map.flags = 0;
-               dev_priv->ring.map.mtrr = 0;
+               dev_priv->render_ring.map.offset = init->ring_start;
+               dev_priv->render_ring.map.size = init->ring_size;
+               dev_priv->render_ring.map.type = 0;
+               dev_priv->render_ring.map.flags = 0;
+               dev_priv->render_ring.map.mtrr = 0;
 
-               drm_core_ioremap_wc(&dev_priv->ring.map, dev);
+               drm_core_ioremap_wc(&dev_priv->render_ring.map, dev);
 
-               if (dev_priv->ring.map.handle == NULL) {
+               if (dev_priv->render_ring.map.handle == NULL) {
                        i915_dma_cleanup(dev);
                        DRM_ERROR("can not ioremap virtual address for"
                                  " ring buffer\n");
@@ -258,7 +178,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
                }
        }
 
-       dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+       dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle;
 
        dev_priv->cpp = init->cpp;
        dev_priv->back_offset = init->back_offset;
@@ -278,26 +198,29 @@ static int i915_dma_resume(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
+       struct intel_ring_buffer *ring;
        DRM_DEBUG_DRIVER("%s\n", __func__);
 
-       if (dev_priv->ring.map.handle == NULL) {
+       ring = &dev_priv->render_ring;
+
+       if (ring->map.handle == NULL) {
                DRM_ERROR("can not ioremap virtual address for"
                          " ring buffer\n");
                return -ENOMEM;
        }
 
        /* Program Hardware Status Page */
-       if (!dev_priv->hw_status_page) {
+       if (!ring->status_page.page_addr) {
                DRM_ERROR("Can not find hardware status page\n");
                return -EINVAL;
        }
        DRM_DEBUG_DRIVER("hw status page @ %p\n",
-                               dev_priv->hw_status_page);
-
-       if (dev_priv->status_gfx_addr != 0)
-               I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
+                               ring->status_page.page_addr);
+       if (ring->status_page.gfx_addr != 0)
+               ring->setup_status_page(dev, ring);
        else
                I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
+
        DRM_DEBUG_DRIVER("Enabled hardware status page\n");
 
        return 0;
@@ -407,9 +330,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        int i;
-       RING_LOCALS;
 
-       if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
+       if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8)
                return -EINVAL;
 
        BEGIN_LP_RING((dwords+1)&~1);
@@ -442,9 +364,7 @@ i915_emit_box(struct drm_device *dev,
              struct drm_clip_rect *boxes,
              int i, int DR1, int DR4)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_clip_rect box = boxes[i];
-       RING_LOCALS;
 
        if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
                DRM_ERROR("Bad box %d,%d..%d,%d\n",
@@ -481,7 +401,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
-       RING_LOCALS;
 
        dev_priv->counter++;
        if (dev_priv->counter > 0x7FFFFFFFUL)
@@ -535,10 +454,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
                                     drm_i915_batchbuffer_t * batch,
                                     struct drm_clip_rect *cliprects)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
        int nbox = batch->num_cliprects;
        int i = 0, count;
-       RING_LOCALS;
 
        if ((batch->start | batch->used) & 0x7) {
                DRM_ERROR("alignment");
@@ -587,7 +504,6 @@ static int i915_dispatch_flip(struct drm_device * dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv =
                dev->primary->master->driver_priv;
-       RING_LOCALS;
 
        if (!master_priv->sarea_priv)
                return -EINVAL;
@@ -640,7 +556,8 @@ static int i915_quiescent(struct drm_device * dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
 
        i915_kernel_lost_context(dev);
-       return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
+       return intel_wait_ring_buffer(dev, &dev_priv->render_ring,
+                                     dev_priv->render_ring.size - 8);
 }
 
 static int i915_flush_ioctl(struct drm_device *dev, void *data,
@@ -827,6 +744,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
                /* depends on GEM */
                value = dev_priv->has_gem;
                break;
+       case I915_PARAM_HAS_BSD:
+               value = HAS_BSD(dev);
+               break;
        default:
                DRM_DEBUG_DRIVER("Unknown parameter %d\n",
                                 param->param);
@@ -882,6 +802,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        drm_i915_hws_addr_t *hws = data;
+       struct intel_ring_buffer *ring = &dev_priv->render_ring;
 
        if (!I915_NEED_GFX_HWS(dev))
                return -EINVAL;
@@ -898,7 +819,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 
        DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
 
-       dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
+       ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12);
 
        dev_priv->hws_map.offset = dev->agp->base + hws->addr;
        dev_priv->hws_map.size = 4*1024;
@@ -909,19 +830,19 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
        drm_core_ioremap_wc(&dev_priv->hws_map, dev);
        if (dev_priv->hws_map.handle == NULL) {
                i915_dma_cleanup(dev);
-               dev_priv->status_gfx_addr = 0;
+               ring->status_page.gfx_addr = 0;
                DRM_ERROR("can not ioremap virtual address for"
                                " G33 hw status page\n");
                return -ENOMEM;
        }
-       dev_priv->hw_status_page = dev_priv->hws_map.handle;
+       ring->status_page.page_addr = dev_priv->hws_map.handle;
+       memset(ring->status_page.page_addr, 0, PAGE_SIZE);
+       I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
 
-       memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
-       I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
        DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
-                               dev_priv->status_gfx_addr);
+                        ring->status_page.gfx_addr);
        DRM_DEBUG_DRIVER("load hws at %p\n",
-                               dev_priv->hw_status_page);
+                        ring->status_page.page_addr);
        return 0;
 }
 
@@ -1399,12 +1320,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
        struct drm_device *dev = pci_get_drvdata(pdev);
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
-               printk(KERN_INFO "i915: switched off\n");
+               printk(KERN_INFO "i915: switched on\n");
                /* i915 resume handler doesn't set to D0 */
                pci_set_power_state(dev->pdev, PCI_D0);
                i915_resume(dev);
+               drm_kms_helper_poll_enable(dev);
        } else {
                printk(KERN_ERR "i915: switched off\n");
+               drm_kms_helper_poll_disable(dev);
                i915_suspend(dev, pmm);
        }
 }
@@ -1539,14 +1462,11 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
        master->driver_priv = NULL;
 }
 
-static void i915_get_mem_freq(struct drm_device *dev)
+static void i915_pineview_get_mem_freq(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 tmp;
 
-       if (!IS_PINEVIEW(dev))
-               return;
-
        tmp = I915_READ(CLKCFG);
 
        switch (tmp & CLKCFG_FSB_MASK) {
@@ -1575,8 +1495,525 @@ static void i915_get_mem_freq(struct drm_device *dev)
                dev_priv->mem_freq = 800;
                break;
        }
+
+       /* detect pineview DDR3 setting */
+       tmp = I915_READ(CSHRDDR3CTL);
+       dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
+}
+
+static void i915_ironlake_get_mem_freq(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       u16 ddrpll, csipll;
+
+       ddrpll = I915_READ16(DDRMPLL1);
+       csipll = I915_READ16(CSIPLL0);
+
+       switch (ddrpll & 0xff) {
+       case 0xc:
+               dev_priv->mem_freq = 800;
+               break;
+       case 0x10:
+               dev_priv->mem_freq = 1066;
+               break;
+       case 0x14:
+               dev_priv->mem_freq = 1333;
+               break;
+       case 0x18:
+               dev_priv->mem_freq = 1600;
+               break;
+       default:
+               DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n",
+                                ddrpll & 0xff);
+               dev_priv->mem_freq = 0;
+               break;
+       }
+
+       dev_priv->r_t = dev_priv->mem_freq;
+
+       switch (csipll & 0x3ff) {
+       case 0x00c:
+               dev_priv->fsb_freq = 3200;
+               break;
+       case 0x00e:
+               dev_priv->fsb_freq = 3733;
+               break;
+       case 0x010:
+               dev_priv->fsb_freq = 4266;
+               break;
+       case 0x012:
+               dev_priv->fsb_freq = 4800;
+               break;
+       case 0x014:
+               dev_priv->fsb_freq = 5333;
+               break;
+       case 0x016:
+               dev_priv->fsb_freq = 5866;
+               break;
+       case 0x018:
+               dev_priv->fsb_freq = 6400;
+               break;
+       default:
+               DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n",
+                                csipll & 0x3ff);
+               dev_priv->fsb_freq = 0;
+               break;
+       }
+
+       if (dev_priv->fsb_freq == 3200) {
+               dev_priv->c_m = 0;
+       } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
+               dev_priv->c_m = 1;
+       } else {
+               dev_priv->c_m = 2;
+       }
+}
+
+struct v_table {
+       u8 vid;
+       unsigned long vd; /* in .1 mil */
+       unsigned long vm; /* in .1 mil */
+       u8 pvid;
+};
+
+static struct v_table v_table[] = {
+       { 0, 16125, 15000, 0x7f, },
+       { 1, 16000, 14875, 0x7e, },
+       { 2, 15875, 14750, 0x7d, },
+       { 3, 15750, 14625, 0x7c, },
+       { 4, 15625, 14500, 0x7b, },
+       { 5, 15500, 14375, 0x7a, },
+       { 6, 15375, 14250, 0x79, },
+       { 7, 15250, 14125, 0x78, },
+       { 8, 15125, 14000, 0x77, },
+       { 9, 15000, 13875, 0x76, },
+       { 10, 14875, 13750, 0x75, },
+       { 11, 14750, 13625, 0x74, },
+       { 12, 14625, 13500, 0x73, },
+       { 13, 14500, 13375, 0x72, },
+       { 14, 14375, 13250, 0x71, },
+       { 15, 14250, 13125, 0x70, },
+       { 16, 14125, 13000, 0x6f, },
+       { 17, 14000, 12875, 0x6e, },
+       { 18, 13875, 12750, 0x6d, },
+       { 19, 13750, 12625, 0x6c, },
+       { 20, 13625, 12500, 0x6b, },
+       { 21, 13500, 12375, 0x6a, },
+       { 22, 13375, 12250, 0x69, },
+       { 23, 13250, 12125, 0x68, },
+       { 24, 13125, 12000, 0x67, },
+       { 25, 13000, 11875, 0x66, },
+       { 26, 12875, 11750, 0x65, },
+       { 27, 12750, 11625, 0x64, },
+       { 28, 12625, 11500, 0x63, },
+       { 29, 12500, 11375, 0x62, },
+       { 30, 12375, 11250, 0x61, },
+       { 31, 12250, 11125, 0x60, },
+       { 32, 12125, 11000, 0x5f, },
+       { 33, 12000, 10875, 0x5e, },
+       { 34, 11875, 10750, 0x5d, },
+       { 35, 11750, 10625, 0x5c, },
+       { 36, 11625, 10500, 0x5b, },
+       { 37, 11500, 10375, 0x5a, },
+       { 38, 11375, 10250, 0x59, },
+       { 39, 11250, 10125, 0x58, },
+       { 40, 11125, 10000, 0x57, },
+       { 41, 11000, 9875, 0x56, },
+       { 42, 10875, 9750, 0x55, },
+       { 43, 10750, 9625, 0x54, },
+       { 44, 10625, 9500, 0x53, },
+       { 45, 10500, 9375, 0x52, },
+       { 46, 10375, 9250, 0x51, },
+       { 47, 10250, 9125, 0x50, },
+       { 48, 10125, 9000, 0x4f, },
+       { 49, 10000, 8875, 0x4e, },
+       { 50, 9875, 8750, 0x4d, },
+       { 51, 9750, 8625, 0x4c, },
+       { 52, 9625, 8500, 0x4b, },
+       { 53, 9500, 8375, 0x4a, },
+       { 54, 9375, 8250, 0x49, },
+       { 55, 9250, 8125, 0x48, },
+       { 56, 9125, 8000, 0x47, },
+       { 57, 9000, 7875, 0x46, },
+       { 58, 8875, 7750, 0x45, },
+       { 59, 8750, 7625, 0x44, },
+       { 60, 8625, 7500, 0x43, },
+       { 61, 8500, 7375, 0x42, },
+       { 62, 8375, 7250, 0x41, },
+       { 63, 8250, 7125, 0x40, },
+       { 64, 8125, 7000, 0x3f, },
+       { 65, 8000, 6875, 0x3e, },
+       { 66, 7875, 6750, 0x3d, },
+       { 67, 7750, 6625, 0x3c, },
+       { 68, 7625, 6500, 0x3b, },
+       { 69, 7500, 6375, 0x3a, },
+       { 70, 7375, 6250, 0x39, },
+       { 71, 7250, 6125, 0x38, },
+       { 72, 7125, 6000, 0x37, },
+       { 73, 7000, 5875, 0x36, },
+       { 74, 6875, 5750, 0x35, },
+       { 75, 6750, 5625, 0x34, },
+       { 76, 6625, 5500, 0x33, },
+       { 77, 6500, 5375, 0x32, },
+       { 78, 6375, 5250, 0x31, },
+       { 79, 6250, 5125, 0x30, },
+       { 80, 6125, 5000, 0x2f, },
+       { 81, 6000, 4875, 0x2e, },
+       { 82, 5875, 4750, 0x2d, },
+       { 83, 5750, 4625, 0x2c, },
+       { 84, 5625, 4500, 0x2b, },
+       { 85, 5500, 4375, 0x2a, },
+       { 86, 5375, 4250, 0x29, },
+       { 87, 5250, 4125, 0x28, },
+       { 88, 5125, 4000, 0x27, },
+       { 89, 5000, 3875, 0x26, },
+       { 90, 4875, 3750, 0x25, },
+       { 91, 4750, 3625, 0x24, },
+       { 92, 4625, 3500, 0x23, },
+       { 93, 4500, 3375, 0x22, },
+       { 94, 4375, 3250, 0x21, },
+       { 95, 4250, 3125, 0x20, },
+       { 96, 4125, 3000, 0x1f, },
+       { 97, 4125, 3000, 0x1e, },
+       { 98, 4125, 3000, 0x1d, },
+       { 99, 4125, 3000, 0x1c, },
+       { 100, 4125, 3000, 0x1b, },
+       { 101, 4125, 3000, 0x1a, },
+       { 102, 4125, 3000, 0x19, },
+       { 103, 4125, 3000, 0x18, },
+       { 104, 4125, 3000, 0x17, },
+       { 105, 4125, 3000, 0x16, },
+       { 106, 4125, 3000, 0x15, },
+       { 107, 4125, 3000, 0x14, },
+       { 108, 4125, 3000, 0x13, },
+       { 109, 4125, 3000, 0x12, },
+       { 110, 4125, 3000, 0x11, },
+       { 111, 4125, 3000, 0x10, },
+       { 112, 4125, 3000, 0x0f, },
+       { 113, 4125, 3000, 0x0e, },
+       { 114, 4125, 3000, 0x0d, },
+       { 115, 4125, 3000, 0x0c, },
+       { 116, 4125, 3000, 0x0b, },
+       { 117, 4125, 3000, 0x0a, },
+       { 118, 4125, 3000, 0x09, },
+       { 119, 4125, 3000, 0x08, },
+       { 120, 1125, 0, 0x07, },
+       { 121, 1000, 0, 0x06, },
+       { 122, 875, 0, 0x05, },
+       { 123, 750, 0, 0x04, },
+       { 124, 625, 0, 0x03, },
+       { 125, 500, 0, 0x02, },
+       { 126, 375, 0, 0x01, },
+       { 127, 0, 0, 0x00, },
+};
+
+struct cparams {
+       int i;
+       int t;
+       int m;
+       int c;
+};
+
+static struct cparams cparams[] = {
+       { 1, 1333, 301, 28664 },
+       { 1, 1066, 294, 24460 },
+       { 1, 800, 294, 25192 },
+       { 0, 1333, 276, 27605 },
+       { 0, 1066, 276, 27605 },
+       { 0, 800, 231, 23784 },
+};
+
+unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
+{
+       u64 total_count, diff, ret;
+       u32 count1, count2, count3, m = 0, c = 0;
+       unsigned long now = jiffies_to_msecs(jiffies), diff1;
+       int i;
+
+       diff1 = now - dev_priv->last_time1;
+
+       count1 = I915_READ(DMIEC);
+       count2 = I915_READ(DDREC);
+       count3 = I915_READ(CSIEC);
+
+       total_count = count1 + count2 + count3;
+
+       /* FIXME: handle per-counter overflow */
+       if (total_count < dev_priv->last_count1) {
+               diff = ~0UL - dev_priv->last_count1;
+               diff += total_count;
+       } else {
+               diff = total_count - dev_priv->last_count1;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cparams); i++) {
+               if (cparams[i].i == dev_priv->c_m &&
+                   cparams[i].t == dev_priv->r_t) {
+                       m = cparams[i].m;
+                       c = cparams[i].c;
+                       break;
+               }
+       }
+
+       div_u64(diff, diff1);
+       ret = ((m * diff) + c);
+       div_u64(ret, 10);
+
+       dev_priv->last_count1 = total_count;
+       dev_priv->last_time1 = now;
+
+       return ret;
+}
+
+unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
+{
+       unsigned long m, x, b;
+       u32 tsfs;
+
+       tsfs = I915_READ(TSFS);
+
+       m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
+       x = I915_READ8(TR1);
+
+       b = tsfs & TSFS_INTR_MASK;
+
+       return ((m * x) / 127) - b;
+}
+
+static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
+{
+       unsigned long val = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(v_table); i++) {
+               if (v_table[i].pvid == pxvid) {
+                       if (IS_MOBILE(dev_priv->dev))
+                               val = v_table[i].vm;
+                       else
+                               val = v_table[i].vd;
+               }
+       }
+
+       return val;
+}
+
+void i915_update_gfx_val(struct drm_i915_private *dev_priv)
+{
+       struct timespec now, diff1;
+       u64 diff;
+       unsigned long diffms;
+       u32 count;
+
+       getrawmonotonic(&now);
+       diff1 = timespec_sub(now, dev_priv->last_time2);
+
+       /* Don't divide by 0 */
+       diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
+       if (!diffms)
+               return;
+
+       count = I915_READ(GFXEC);
+
+       if (count < dev_priv->last_count2) {
+               diff = ~0UL - dev_priv->last_count2;
+               diff += count;
+       } else {
+               diff = count - dev_priv->last_count2;
+       }
+
+       dev_priv->last_count2 = count;
+       dev_priv->last_time2 = now;
+
+       /* More magic constants... */
+       diff = diff * 1181;
+       div_u64(diff, diffms * 10);
+       dev_priv->gfx_power = diff;
 }
 
+unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
+{
+       unsigned long t, corr, state1, corr2, state2;
+       u32 pxvid, ext_v;
+
+       pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4));
+       pxvid = (pxvid >> 24) & 0x7f;
+       ext_v = pvid_to_extvid(dev_priv, pxvid);
+
+       state1 = ext_v;
+
+       t = i915_mch_val(dev_priv);
+
+       /* Revel in the empirically derived constants */
+
+       /* Correction factor in 1/100000 units */
+       if (t > 80)
+               corr = ((t * 2349) + 135940);
+       else if (t >= 50)
+               corr = ((t * 964) + 29317);
+       else /* < 50 */
+               corr = ((t * 301) + 1004);
+
+       corr = corr * ((150142 * state1) / 10000 - 78642);
+       corr /= 100000;
+       corr2 = (corr * dev_priv->corr);
+
+       state2 = (corr2 * state1) / 10000;
+       state2 /= 100; /* convert to mW */
+
+       i915_update_gfx_val(dev_priv);
+
+       return dev_priv->gfx_power + state2;
+}
+
+/* Global for IPS driver to get at the current i915 device */
+static struct drm_i915_private *i915_mch_dev;
+/*
+ * Lock protecting IPS related data structures
+ *   - i915_mch_dev
+ *   - dev_priv->max_delay
+ *   - dev_priv->min_delay
+ *   - dev_priv->fmax
+ *   - dev_priv->gpu_busy
+ */
+DEFINE_SPINLOCK(mchdev_lock);
+
+/**
+ * i915_read_mch_val - return value for IPS use
+ *
+ * Calculate and return a value for the IPS driver to use when deciding whether
+ * we have thermal and power headroom to increase CPU or GPU power budget.
+ */
+unsigned long i915_read_mch_val(void)
+{
+       struct drm_i915_private *dev_priv;
+       unsigned long chipset_val, graphics_val, ret = 0;
+
+       spin_lock(&mchdev_lock);
+       if (!i915_mch_dev)
+               goto out_unlock;
+       dev_priv = i915_mch_dev;
+
+       chipset_val = i915_chipset_val(dev_priv);
+       graphics_val = i915_gfx_val(dev_priv);
+
+       ret = chipset_val + graphics_val;
+
+out_unlock:
+       spin_unlock(&mchdev_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i915_read_mch_val);
+
+/**
+ * i915_gpu_raise - raise GPU frequency limit
+ *
+ * Raise the limit; IPS indicates we have thermal headroom.
+ */
+bool i915_gpu_raise(void)
+{
+       struct drm_i915_private *dev_priv;
+       bool ret = true;
+
+       spin_lock(&mchdev_lock);
+       if (!i915_mch_dev) {
+               ret = false;
+               goto out_unlock;
+       }
+       dev_priv = i915_mch_dev;
+
+       if (dev_priv->max_delay > dev_priv->fmax)
+               dev_priv->max_delay--;
+
+out_unlock:
+       spin_unlock(&mchdev_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i915_gpu_raise);
+
+/**
+ * i915_gpu_lower - lower GPU frequency limit
+ *
+ * IPS indicates we're close to a thermal limit, so throttle back the GPU
+ * frequency maximum.
+ */
+bool i915_gpu_lower(void)
+{
+       struct drm_i915_private *dev_priv;
+       bool ret = true;
+
+       spin_lock(&mchdev_lock);
+       if (!i915_mch_dev) {
+               ret = false;
+               goto out_unlock;
+       }
+       dev_priv = i915_mch_dev;
+
+       if (dev_priv->max_delay < dev_priv->min_delay)
+               dev_priv->max_delay++;
+
+out_unlock:
+       spin_unlock(&mchdev_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i915_gpu_lower);
+
+/**
+ * i915_gpu_busy - indicate GPU business to IPS
+ *
+ * Tell the IPS driver whether or not the GPU is busy.
+ */
+bool i915_gpu_busy(void)
+{
+       struct drm_i915_private *dev_priv;
+       bool ret = false;
+
+       spin_lock(&mchdev_lock);
+       if (!i915_mch_dev)
+               goto out_unlock;
+       dev_priv = i915_mch_dev;
+
+       ret = dev_priv->busy;
+
+out_unlock:
+       spin_unlock(&mchdev_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i915_gpu_busy);
+
+/**
+ * i915_gpu_turbo_disable - disable graphics turbo
+ *
+ * Disable graphics turbo by resetting the max frequency and setting the
+ * current frequency to the default.
+ */
+bool i915_gpu_turbo_disable(void)
+{
+       struct drm_i915_private *dev_priv;
+       bool ret = true;
+
+       spin_lock(&mchdev_lock);
+       if (!i915_mch_dev) {
+               ret = false;
+               goto out_unlock;
+       }
+       dev_priv = i915_mch_dev;
+
+       dev_priv->max_delay = dev_priv->fstart;
+
+       if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart))
+               ret = false;
+
+out_unlock:
+       spin_unlock(&mchdev_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
@@ -1594,7 +2031,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        resource_size_t base, size;
        int ret = 0, mmio_bar;
        uint32_t agp_size, prealloc_size, prealloc_start;
-
        /* i915 has 4 more counters */
        dev->counters += 4;
        dev->types[6] = _DRM_STAT_IRQ;
@@ -1672,6 +2108,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
                dev_priv->has_gem = 0;
        }
 
+       if (dev_priv->has_gem == 0 &&
+           drm_core_check_feature(dev, DRIVER_MODESET)) {
+               DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n");
+               ret = -ENODEV;
+               goto out_iomapfree;
+       }
+
        dev->driver->get_vblank_counter = i915_get_vblank_counter;
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
        if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) {
@@ -1691,7 +2134,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
                        goto out_workqueue_free;
        }
 
-       i915_get_mem_freq(dev);
+       if (IS_PINEVIEW(dev))
+               i915_pineview_get_mem_freq(dev);
+       else if (IS_IRONLAKE(dev))
+               i915_ironlake_get_mem_freq(dev);
 
        /* On the 945G/GM, the chipset reports the MSI capability on the
         * integrated graphics even though the support isn't actually there
@@ -1709,7 +2155,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        spin_lock_init(&dev_priv->user_irq_lock);
        spin_lock_init(&dev_priv->error_lock);
-       dev_priv->user_irq_refcount = 0;
        dev_priv->trace_irq_seqno = 0;
 
        ret = drm_vblank_init(dev, I915_NUM_PIPE);
@@ -1738,6 +2183,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
                    (unsigned long) dev);
+
+       spin_lock(&mchdev_lock);
+       i915_mch_dev = dev_priv;
+       dev_priv->mchdev_lock = &mchdev_lock;
+       spin_unlock(&mchdev_lock);
+
        return 0;
 
 out_workqueue_free:
@@ -1759,6 +2210,10 @@ int i915_driver_unload(struct drm_device *dev)
 
        i915_destroy_error_state(dev);
 
+       spin_lock(&mchdev_lock);
+       i915_mch_dev = NULL;
+       spin_unlock(&mchdev_lock);
+
        destroy_workqueue(dev_priv->wq);
        del_timer_sync(&dev_priv->hangcheck_timer);
 
index 5c51e45ab68de6e999946f4ea55d6c20ae24bc5c..423dc90c1e20589e7669f1ba41880308af9fb044 100644 (file)
@@ -60,95 +60,95 @@ extern int intel_agp_enabled;
        .subdevice = PCI_ANY_ID,                \
        .driver_data = (unsigned long) info }
 
-const static struct intel_device_info intel_i830_info = {
+static const struct intel_device_info intel_i830_info = {
        .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
 };
 
-const static struct intel_device_info intel_845g_info = {
+static const struct intel_device_info intel_845g_info = {
        .is_i8xx = 1,
 };
 
-const static struct intel_device_info intel_i85x_info = {
+static const struct intel_device_info intel_i85x_info = {
        .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
        .cursor_needs_physical = 1,
 };
 
-const static struct intel_device_info intel_i865g_info = {
+static const struct intel_device_info intel_i865g_info = {
        .is_i8xx = 1,
 };
 
-const static struct intel_device_info intel_i915g_info = {
+static const struct intel_device_info intel_i915g_info = {
        .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
 };
-const static struct intel_device_info intel_i915gm_info = {
+static const struct intel_device_info intel_i915gm_info = {
        .is_i9xx = 1,  .is_mobile = 1,
        .cursor_needs_physical = 1,
 };
-const static struct intel_device_info intel_i945g_info = {
+static const struct intel_device_info intel_i945g_info = {
        .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
 };
-const static struct intel_device_info intel_i945gm_info = {
+static const struct intel_device_info intel_i945gm_info = {
        .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
        .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 
-const static struct intel_device_info intel_i965g_info = {
+static const struct intel_device_info intel_i965g_info = {
        .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_i965gm_info = {
+static const struct intel_device_info intel_i965gm_info = {
        .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
        .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_g33_info = {
+static const struct intel_device_info intel_g33_info = {
        .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_g45_info = {
+static const struct intel_device_info intel_g45_info = {
        .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
        .has_pipe_cxsr = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_gm45_info = {
+static const struct intel_device_info intel_gm45_info = {
        .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
        .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
        .has_pipe_cxsr = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_pineview_info = {
+static const struct intel_device_info intel_pineview_info = {
        .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
        .need_gfx_hws = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_ironlake_d_info = {
+static const struct intel_device_info intel_ironlake_d_info = {
        .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
        .has_pipe_cxsr = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_ironlake_m_info = {
+static const struct intel_device_info intel_ironlake_m_info = {
        .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
        .need_gfx_hws = 1, .has_rc6 = 1,
        .has_hotplug = 1,
 };
 
-const static struct intel_device_info intel_sandybridge_d_info = {
+static const struct intel_device_info intel_sandybridge_d_info = {
        .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
        .has_hotplug = 1, .is_gen6 = 1,
 };
 
-const static struct intel_device_info intel_sandybridge_m_info = {
+static const struct intel_device_info intel_sandybridge_m_info = {
        .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
        .has_hotplug = 1, .is_gen6 = 1,
 };
 
-const static struct pci_device_id pciidlist[] = {
+static const struct pci_device_id pciidlist[] = {
        INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
        INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
        INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
@@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
        /*
         * Clear request list
         */
-       i915_gem_retire_requests(dev);
+       i915_gem_retire_requests(dev, &dev_priv->render_ring);
 
        if (need_display)
                i915_save_display(dev);
@@ -370,6 +370,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
                }
        } else {
                DRM_ERROR("Error occurred. Don't know how to reset this chip.\n");
+               mutex_unlock(&dev->struct_mutex);
                return -ENODEV;
        }
 
@@ -388,33 +389,10 @@ int i965_reset(struct drm_device *dev, u8 flags)
         * switched away).
         */
        if (drm_core_check_feature(dev, DRIVER_MODESET) ||
-           !dev_priv->mm.suspended) {
-               drm_i915_ring_buffer_t *ring = &dev_priv->ring;
-               struct drm_gem_object *obj = ring->ring_obj;
-               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+                       !dev_priv->mm.suspended) {
+               struct intel_ring_buffer *ring = &dev_priv->render_ring;
                dev_priv->mm.suspended = 0;
-
-               /* Stop the ring if it's running. */
-               I915_WRITE(PRB0_CTL, 0);
-               I915_WRITE(PRB0_TAIL, 0);
-               I915_WRITE(PRB0_HEAD, 0);
-
-               /* Initialize the ring. */
-               I915_WRITE(PRB0_START, obj_priv->gtt_offset);
-               I915_WRITE(PRB0_CTL,
-                          ((obj->size - 4096) & RING_NR_PAGES) |
-                          RING_NO_REPORT |
-                          RING_VALID);
-               if (!drm_core_check_feature(dev, DRIVER_MODESET))
-                       i915_kernel_lost_context(dev);
-               else {
-                       ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-                       ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
-                       ring->space = ring->head - (ring->tail + 8);
-                       if (ring->space < 0)
-                               ring->space += ring->Size;
-               }
-
+               ring->init(dev, ring);
                mutex_unlock(&dev->struct_mutex);
                drm_irq_uninstall(dev);
                drm_irq_install(dev);
index 7f797ef1ab391f59ea181b6e6eb82c794aad1249..9ed8ecd95801e94734716a2c64ba62d540d4600c 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "i915_reg.h"
 #include "intel_bios.h"
+#include "intel_ringbuffer.h"
 #include <linux/io-mapping.h>
 
 /* General customization:
@@ -55,6 +56,8 @@ enum plane {
 
 #define I915_NUM_PIPE  2
 
+#define I915_GEM_GPU_DOMAINS   (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
+
 /* Interface history:
  *
  * 1.1: Original.
@@ -89,16 +92,6 @@ struct drm_i915_gem_phys_object {
        struct drm_gem_object *cur_obj;
 };
 
-typedef struct _drm_i915_ring_buffer {
-       unsigned long Size;
-       u8 *virtual_start;
-       int head;
-       int tail;
-       int space;
-       drm_local_map_t map;
-       struct drm_gem_object *ring_obj;
-} drm_i915_ring_buffer_t;
-
 struct mem_block {
        struct mem_block *next;
        struct mem_block *prev;
@@ -241,17 +234,15 @@ typedef struct drm_i915_private {
        void __iomem *regs;
 
        struct pci_dev *bridge_dev;
-       drm_i915_ring_buffer_t ring;
+       struct intel_ring_buffer render_ring;
+       struct intel_ring_buffer bsd_ring;
 
        drm_dma_handle_t *status_page_dmah;
-       void *hw_status_page;
        void *seqno_page;
        dma_addr_t dma_status_page;
        uint32_t counter;
-       unsigned int status_gfx_addr;
        unsigned int seqno_gfx_addr;
        drm_local_map_t hws_map;
-       struct drm_gem_object *hws_obj;
        struct drm_gem_object *seqno_obj;
        struct drm_gem_object *pwrctx;
 
@@ -267,8 +258,6 @@ typedef struct drm_i915_private {
        atomic_t irq_received;
        /** Protects user_irq_refcount and irq_mask_reg */
        spinlock_t user_irq_lock;
-       /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
-       int user_irq_refcount;
        u32 trace_irq_seqno;
        /** Cached value of IMR to avoid reads in updating the bitfield */
        u32 irq_mask_reg;
@@ -334,7 +323,7 @@ typedef struct drm_i915_private {
        int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
        int num_fence_regs; /* 8 on pre-965, 16 otherwise */
 
-       unsigned int fsb_freq, mem_freq;
+       unsigned int fsb_freq, mem_freq, is_ddr3;
 
        spinlock_t error_lock;
        struct drm_i915_error_state *first_error;
@@ -514,18 +503,7 @@ typedef struct drm_i915_private {
                 */
                struct list_head shrink_list;
 
-               /**
-                * List of objects currently involved in rendering from the
-                * ringbuffer.
-                *
-                * Includes buffers having the contents of their GPU caches
-                * flushed, not necessarily primitives.  last_rendering_seqno
-                * represents when the rendering involved will be completed.
-                *
-                * A reference is held on the buffer while on this list.
-                */
                spinlock_t active_list_lock;
-               struct list_head active_list;
 
                /**
                 * List of objects which are not in the ringbuffer but which
@@ -562,12 +540,6 @@ typedef struct drm_i915_private {
                /** LRU list of objects with fence regs on them. */
                struct list_head fence_list;
 
-               /**
-                * List of breadcrumbs associated with GPU requests currently
-                * outstanding.
-                */
-               struct list_head request_list;
-
                /**
                 * We leave the user IRQ off as much as possible,
                 * but this means that requests will finish and never
@@ -644,6 +616,18 @@ typedef struct drm_i915_private {
        u8 cur_delay;
        u8 min_delay;
        u8 max_delay;
+       u8 fmax;
+       u8 fstart;
+
+       u64 last_count1;
+       unsigned long last_time1;
+       u64 last_count2;
+       struct timespec last_time2;
+       unsigned long gfx_power;
+       int c_m;
+       int r_t;
+       u8 corr;
+       spinlock_t *mchdev_lock;
 
        enum no_fbc_reason no_fbc_reason;
 
@@ -671,19 +655,64 @@ struct drm_i915_gem_object {
         * (has pending rendering), and is not set if it's on inactive (ready
         * to be unbound).
         */
-       int active;
+       unsigned int active : 1;
 
        /**
         * This is set if the object has been written to since last bound
         * to the GTT
         */
-       int dirty;
+       unsigned int dirty : 1;
+
+       /**
+        * Fence register bits (if any) for this object.  Will be set
+        * as needed when mapped into the GTT.
+        * Protected by dev->struct_mutex.
+        *
+        * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
+        */
+       int fence_reg : 5;
+
+       /**
+        * Used for checking the object doesn't appear more than once
+        * in an execbuffer object list.
+        */
+       unsigned int in_execbuffer : 1;
+
+       /**
+        * Advice: are the backing pages purgeable?
+        */
+       unsigned int madv : 2;
+
+       /**
+        * Refcount for the pages array. With the current locking scheme, there
+        * are at most two concurrent users: Binding a bo to the gtt and
+        * pwrite/pread using physical addresses. So two bits for a maximum
+        * of two users are enough.
+        */
+       unsigned int pages_refcount : 2;
+#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3
+
+       /**
+        * Current tiling mode for the object.
+        */
+       unsigned int tiling_mode : 2;
+
+       /** How many users have pinned this object in GTT space. The following
+        * users can each hold at most one reference: pwrite/pread, pin_ioctl
+        * (via user_pin_count), execbuffer (objects are not allowed multiple
+        * times for the same batchbuffer), and the framebuffer code. When
+        * switching/pageflipping, the framebuffer code has at most two buffers
+        * pinned per crtc.
+        *
+        * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
+        * bits with absolutely no headroom. So use 4 bits. */
+       int pin_count : 4;
+#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
 
        /** AGP memory structure for our GTT binding. */
        DRM_AGP_MEM *agp_mem;
 
        struct page **pages;
-       int pages_refcount;
 
        /**
         * Current offset of the object in GTT space.
@@ -692,26 +721,18 @@ struct drm_i915_gem_object {
         */
        uint32_t gtt_offset;
 
+       /* Which ring is refering to is this object */
+       struct intel_ring_buffer *ring;
+
        /**
         * Fake offset for use by mmap(2)
         */
        uint64_t mmap_offset;
 
-       /**
-        * Fence register bits (if any) for this object.  Will be set
-        * as needed when mapped into the GTT.
-        * Protected by dev->struct_mutex.
-        */
-       int fence_reg;
-
-       /** How many users have pinned this object in GTT space */
-       int pin_count;
-
        /** Breadcrumb of last rendering to the buffer. */
        uint32_t last_rendering_seqno;
 
-       /** Current tiling mode for the object. */
-       uint32_t tiling_mode;
+       /** Current tiling stride for the object, if it's tiled. */
        uint32_t stride;
 
        /** Record of address bit 17 of each page at last unbind. */
@@ -733,17 +754,6 @@ struct drm_i915_gem_object {
        /** for phy allocated objects */
        struct drm_i915_gem_phys_object *phys_obj;
 
-       /**
-        * Used for checking the object doesn't appear more than once
-        * in an execbuffer object list.
-        */
-       int in_execbuffer;
-
-       /**
-        * Advice: are the backing pages purgeable?
-        */
-       int madv;
-
        /**
         * Number of crtcs where this object is currently the fb, but
         * will be page flipped away on the next vblank.  When it
@@ -765,6 +775,9 @@ struct drm_i915_gem_object {
  * an emission time with seqnos for tracking how far ahead of the GPU we are.
  */
 struct drm_i915_gem_request {
+       /** On Which ring this request was generated */
+       struct intel_ring_buffer *ring;
+
        /** GEM sequence number associated with this request. */
        uint32_t seqno;
 
@@ -821,6 +834,11 @@ extern int i915_emit_box(struct drm_device *dev,
                         struct drm_clip_rect *boxes,
                         int i, int DR1, int DR4);
 extern int i965_reset(struct drm_device *dev, u8 flags);
+extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
+extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
+extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
+extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
+
 
 /* i915_irq.c */
 void i915_hangcheck_elapsed(unsigned long data);
@@ -829,9 +847,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
 extern int i915_irq_wait(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
-void i915_user_irq_get(struct drm_device *dev);
 void i915_trace_irq_get(struct drm_device *dev, u32 seqno);
-void i915_user_irq_put(struct drm_device *dev);
 extern void i915_enable_interrupt (struct drm_device *dev);
 
 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
@@ -849,6 +865,11 @@ extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int i915_vblank_swap(struct drm_device *dev, void *data,
                            struct drm_file *file_priv);
 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
+extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask);
+extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv,
+               u32 mask);
+extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv,
+               u32 mask);
 
 void
 i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
@@ -922,11 +943,13 @@ void i915_gem_object_unpin(struct drm_gem_object *obj);
 int i915_gem_object_unbind(struct drm_gem_object *obj);
 void i915_gem_release_mmap(struct drm_gem_object *obj);
 void i915_gem_lastclose(struct drm_device *dev);
-uint32_t i915_get_gem_seqno(struct drm_device *dev);
+uint32_t i915_get_gem_seqno(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
 bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
 int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
 int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
-void i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_requests(struct drm_device *dev,
+                struct intel_ring_buffer *ring);
 void i915_gem_retire_work_handler(struct work_struct *work);
 void i915_gem_clflush_object(struct drm_gem_object *obj);
 int i915_gem_object_set_domain(struct drm_gem_object *obj,
@@ -937,9 +960,13 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
                     unsigned long end);
 int i915_gem_idle(struct drm_device *dev);
-uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
-                         uint32_t flush_domains);
-int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible);
+uint32_t i915_add_request(struct drm_device *dev,
+               struct drm_file *file_priv,
+               uint32_t flush_domains,
+               struct intel_ring_buffer *ring);
+int i915_do_wait_request(struct drm_device *dev,
+               uint32_t seqno, int interruptible,
+               struct intel_ring_buffer *ring);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
                                      int write);
@@ -1015,7 +1042,7 @@ extern void g4x_disable_fbc(struct drm_device *dev);
 extern void intel_disable_fbc(struct drm_device *dev);
 extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
 extern bool intel_fbc_enabled(struct drm_device *dev);
-
+extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
 extern void intel_detect_pch (struct drm_device *dev);
 extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
 
@@ -1026,7 +1053,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
  * has access to the ring.
  */
 #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do {                        \
-       if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
+       if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \
+                       == NULL)                                        \
                LOCK_TEST_WITH_RETURN(dev, file_priv);                  \
 } while (0)
 
@@ -1039,35 +1067,31 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
 #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg))
 #define I915_READ64(reg)       readq(dev_priv->regs + (reg))
 #define POSTING_READ(reg)      (void)I915_READ(reg)
+#define POSTING_READ16(reg)    (void)I915_READ16(reg)
 
 #define I915_VERBOSE 0
 
-#define RING_LOCALS    volatile unsigned int *ring_virt__;
-
-#define BEGIN_LP_RING(n) do {                                          \
-       int bytes__ = 4*(n);                                            \
-       if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n));        \
-       /* a wrap must occur between instructions so pad beforehand */  \
-       if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
-               i915_wrap_ring(dev);                                    \
-       if (unlikely (dev_priv->ring.space < bytes__))                  \
-               i915_wait_ring(dev, bytes__, __func__);                 \
-       ring_virt__ = (unsigned int *)                                  \
-               (dev_priv->ring.virtual_start + dev_priv->ring.tail);   \
-       dev_priv->ring.tail += bytes__;                                 \
-       dev_priv->ring.tail &= dev_priv->ring.Size - 1;                 \
-       dev_priv->ring.space -= bytes__;                                \
+#define BEGIN_LP_RING(n)  do { \
+       drm_i915_private_t *dev_priv = dev->dev_private;                \
+       if (I915_VERBOSE)                                               \
+               DRM_DEBUG("   BEGIN_LP_RING %x\n", (int)(n));           \
+       intel_ring_begin(dev, &dev_priv->render_ring, 4*(n));           \
 } while (0)
 
-#define OUT_RING(n) do {                                               \
-       if (I915_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));      \
-       *ring_virt__++ = (n);                                           \
+
+#define OUT_RING(x) do {                                               \
+       drm_i915_private_t *dev_priv = dev->dev_private;                \
+       if (I915_VERBOSE)                                               \
+               DRM_DEBUG("   OUT_RING %x\n", (int)(x));                \
+       intel_ring_emit(dev, &dev_priv->render_ring, x);                \
 } while (0)
 
 #define ADVANCE_LP_RING() do {                                         \
+       drm_i915_private_t *dev_priv = dev->dev_private;                \
        if (I915_VERBOSE)                                               \
-               DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \
-       I915_WRITE(PRB0_TAIL, dev_priv->ring.tail);                     \
+               DRM_DEBUG("ADVANCE_LP_RING %x\n",                       \
+                               dev_priv->render_ring.tail);            \
+       intel_ring_advance(dev, &dev_priv->render_ring);                \
 } while(0)
 
 /**
@@ -1085,14 +1109,12 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
  *
  * The area from dword 0x20 to 0x3ff is available for driver usage.
  */
-#define READ_HWSP(dev_priv, reg)  (((volatile u32*)(dev_priv->hw_status_page))[reg])
+#define READ_HWSP(dev_priv, reg)  (((volatile u32 *)\
+                       (dev_priv->render_ring.status_page.page_addr))[reg])
 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX)
 #define I915_GEM_HWS_INDEX             0x20
 #define I915_BREADCRUMB_INDEX          0x21
 
-extern int i915_wrap_ring(struct drm_device * dev);
-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
-
 #define INTEL_INFO(dev)        (((struct drm_i915_private *) (dev)->dev_private)->info)
 
 #define IS_I830(dev)           ((dev)->pci_device == 0x3577)
@@ -1138,6 +1160,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
                         (dev)->pci_device == 0x2A42 ||         \
                         (dev)->pci_device == 0x2E42)
 
+#define HAS_BSD(dev)            (IS_IRONLAKE(dev) || IS_G4X(dev))
 #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
 
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
index 112699f71fa4f5f0afdb4b2d03b4960243350d48..9ded3dae6c87105cdd7acaa65d5548aeb90dfee3 100644 (file)
@@ -35,8 +35,6 @@
 #include <linux/swap.h>
 #include <linux/pci.h>
 
-#define I915_GEM_GPU_DOMAINS   (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
-
 static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -169,7 +167,7 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
                obj_priv->tiling_mode != I915_TILING_NONE;
 }
 
-static inline int
+static inline void
 slow_shmem_copy(struct page *dst_page,
                int dst_offset,
                struct page *src_page,
@@ -178,25 +176,16 @@ slow_shmem_copy(struct page *dst_page,
 {
        char *dst_vaddr, *src_vaddr;
 
-       dst_vaddr = kmap_atomic(dst_page, KM_USER0);
-       if (dst_vaddr == NULL)
-               return -ENOMEM;
-
-       src_vaddr = kmap_atomic(src_page, KM_USER1);
-       if (src_vaddr == NULL) {
-               kunmap_atomic(dst_vaddr, KM_USER0);
-               return -ENOMEM;
-       }
+       dst_vaddr = kmap(dst_page);
+       src_vaddr = kmap(src_page);
 
        memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
 
-       kunmap_atomic(src_vaddr, KM_USER1);
-       kunmap_atomic(dst_vaddr, KM_USER0);
-
-       return 0;
+       kunmap(src_page);
+       kunmap(dst_page);
 }
 
-static inline int
+static inline void
 slow_shmem_bit17_copy(struct page *gpu_page,
                      int gpu_offset,
                      struct page *cpu_page,
@@ -216,15 +205,8 @@ slow_shmem_bit17_copy(struct page *gpu_page,
                                               cpu_page, cpu_offset, length);
        }
 
-       gpu_vaddr = kmap_atomic(gpu_page, KM_USER0);
-       if (gpu_vaddr == NULL)
-               return -ENOMEM;
-
-       cpu_vaddr = kmap_atomic(cpu_page, KM_USER1);
-       if (cpu_vaddr == NULL) {
-               kunmap_atomic(gpu_vaddr, KM_USER0);
-               return -ENOMEM;
-       }
+       gpu_vaddr = kmap(gpu_page);
+       cpu_vaddr = kmap(cpu_page);
 
        /* Copy the data, XORing A6 with A17 (1). The user already knows he's
         * XORing with the other bits (A9 for Y, A9 and A10 for X)
@@ -248,10 +230,8 @@ slow_shmem_bit17_copy(struct page *gpu_page,
                length -= this_length;
        }
 
-       kunmap_atomic(cpu_vaddr, KM_USER1);
-       kunmap_atomic(gpu_vaddr, KM_USER0);
-
-       return 0;
+       kunmap(cpu_page);
+       kunmap(gpu_page);
 }
 
 /**
@@ -427,21 +407,19 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
                        page_length = PAGE_SIZE - data_page_offset;
 
                if (do_bit17_swizzling) {
-                       ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
-                                                   shmem_page_offset,
-                                                   user_pages[data_page_index],
-                                                   data_page_offset,
-                                                   page_length,
-                                                   1);
-               } else {
-                       ret = slow_shmem_copy(user_pages[data_page_index],
-                                             data_page_offset,
-                                             obj_priv->pages[shmem_page_index],
+                       slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
                                              shmem_page_offset,
-                                             page_length);
+                                             user_pages[data_page_index],
+                                             data_page_offset,
+                                             page_length,
+                                             1);
+               } else {
+                       slow_shmem_copy(user_pages[data_page_index],
+                                       data_page_offset,
+                                       obj_priv->pages[shmem_page_index],
+                                       shmem_page_offset,
+                                       page_length);
                }
-               if (ret)
-                       goto fail_put_pages;
 
                remain -= page_length;
                data_ptr += page_length;
@@ -531,25 +509,24 @@ fast_user_write(struct io_mapping *mapping,
  * page faults
  */
 
-static inline int
+static inline void
 slow_kernel_write(struct io_mapping *mapping,
                  loff_t gtt_base, int gtt_offset,
                  struct page *user_page, int user_offset,
                  int length)
 {
-       char *src_vaddr, *dst_vaddr;
-       unsigned long unwritten;
+       char __iomem *dst_vaddr;
+       char *src_vaddr;
 
-       dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base);
-       src_vaddr = kmap_atomic(user_page, KM_USER1);
-       unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset,
-                                                     src_vaddr + user_offset,
-                                                     length);
-       kunmap_atomic(src_vaddr, KM_USER1);
-       io_mapping_unmap_atomic(dst_vaddr);
-       if (unwritten)
-               return -EFAULT;
-       return 0;
+       dst_vaddr = io_mapping_map_wc(mapping, gtt_base);
+       src_vaddr = kmap(user_page);
+
+       memcpy_toio(dst_vaddr + gtt_offset,
+                   src_vaddr + user_offset,
+                   length);
+
+       kunmap(user_page);
+       io_mapping_unmap(dst_vaddr);
 }
 
 static inline int
@@ -722,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                if ((data_page_offset + page_length) > PAGE_SIZE)
                        page_length = PAGE_SIZE - data_page_offset;
 
-               ret = slow_kernel_write(dev_priv->mm.gtt_mapping,
-                                       gtt_page_base, gtt_page_offset,
-                                       user_pages[data_page_index],
-                                       data_page_offset,
-                                       page_length);
-
-               /* If we get a fault while copying data, then (presumably) our
-                * source page isn't available.  Return the error and we'll
-                * retry in the slow path.
-                */
-               if (ret)
-                       goto out_unpin_object;
+               slow_kernel_write(dev_priv->mm.gtt_mapping,
+                                 gtt_page_base, gtt_page_offset,
+                                 user_pages[data_page_index],
+                                 data_page_offset,
+                                 page_length);
 
                remain -= page_length;
                offset += page_length;
@@ -902,21 +872,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                        page_length = PAGE_SIZE - data_page_offset;
 
                if (do_bit17_swizzling) {
-                       ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
-                                                   shmem_page_offset,
-                                                   user_pages[data_page_index],
-                                                   data_page_offset,
-                                                   page_length,
-                                                   0);
-               } else {
-                       ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
+                       slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
                                              shmem_page_offset,
                                              user_pages[data_page_index],
                                              data_page_offset,
-                                             page_length);
+                                             page_length,
+                                             0);
+               } else {
+                       slow_shmem_copy(obj_priv->pages[shmem_page_index],
+                                       shmem_page_offset,
+                                       user_pages[data_page_index],
+                                       data_page_offset,
+                                       page_length);
                }
-               if (ret)
-                       goto fail_put_pages;
 
                remain -= page_length;
                data_ptr += page_length;
@@ -973,7 +941,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        if (obj_priv->phys_obj)
                ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
        else if (obj_priv->tiling_mode == I915_TILING_NONE &&
-                dev->gtt_total != 0) {
+                dev->gtt_total != 0 &&
+                obj->write_domain != I915_GEM_DOMAIN_CPU) {
                ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv);
                if (ret == -EFAULT) {
                        ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
@@ -1484,11 +1453,14 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
 }
 
 static void
-i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
+i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno,
+                              struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+       BUG_ON(ring == NULL);
+       obj_priv->ring = ring;
 
        /* Add a reference if we're newly entering the active list. */
        if (!obj_priv->active) {
@@ -1497,8 +1469,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
        }
        /* Move from whatever list we were on to the tail of execution. */
        spin_lock(&dev_priv->mm.active_list_lock);
-       list_move_tail(&obj_priv->list,
-                      &dev_priv->mm.active_list);
+       list_move_tail(&obj_priv->list, &ring->active_list);
        spin_unlock(&dev_priv->mm.active_list_lock);
        obj_priv->last_rendering_seqno = seqno;
 }
@@ -1551,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
        BUG_ON(!list_empty(&obj_priv->gpu_write_list));
 
        obj_priv->last_rendering_seqno = 0;
+       obj_priv->ring = NULL;
        if (obj_priv->active) {
                obj_priv->active = 0;
                drm_gem_object_unreference(obj);
@@ -1560,7 +1532,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
 
 static void
 i915_gem_process_flushing_list(struct drm_device *dev,
-                              uint32_t flush_domains, uint32_t seqno)
+                              uint32_t flush_domains, uint32_t seqno,
+                              struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj_priv, *next;
@@ -1571,12 +1544,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
                struct drm_gem_object *obj = &obj_priv->base;
 
                if ((obj->write_domain & flush_domains) ==
-                   obj->write_domain) {
+                   obj->write_domain &&
+                   obj_priv->ring->ring_flag == ring->ring_flag) {
                        uint32_t old_write_domain = obj->write_domain;
 
                        obj->write_domain = 0;
                        list_del_init(&obj_priv->gpu_write_list);
-                       i915_gem_object_move_to_active(obj, seqno);
+                       i915_gem_object_move_to_active(obj, seqno, ring);
 
                        /* update the fence lru list */
                        if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
@@ -1593,31 +1567,15 @@ i915_gem_process_flushing_list(struct drm_device *dev,
        }
 }
 
-#define PIPE_CONTROL_FLUSH(addr)                                       \
-       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |          \
-                PIPE_CONTROL_DEPTH_STALL);                             \
-       OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);                       \
-       OUT_RING(0);                                                    \
-       OUT_RING(0);                                                    \
-
-/**
- * Creates a new sequence number, emitting a write of it to the status page
- * plus an interrupt, which will trigger i915_user_interrupt_handler.
- *
- * Must be called with struct_lock held.
- *
- * Returned sequence numbers are nonzero on success.
- */
 uint32_t
 i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
-                uint32_t flush_domains)
+                uint32_t flush_domains, struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_file_private *i915_file_priv = NULL;
        struct drm_i915_gem_request *request;
        uint32_t seqno;
        int was_empty;
-       RING_LOCALS;
 
        if (file_priv != NULL)
                i915_file_priv = file_priv->driver_priv;
@@ -1626,62 +1584,14 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
        if (request == NULL)
                return 0;
 
-       /* Grab the seqno we're going to make this request be, and bump the
-        * next (skipping 0 so it can be the reserved no-seqno value).
-        */
-       seqno = dev_priv->mm.next_gem_seqno;
-       dev_priv->mm.next_gem_seqno++;
-       if (dev_priv->mm.next_gem_seqno == 0)
-               dev_priv->mm.next_gem_seqno++;
-
-       if (HAS_PIPE_CONTROL(dev)) {
-               u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
-
-               /*
-                * Workaround qword write incoherence by flushing the
-                * PIPE_NOTIFY buffers out to memory before requesting
-                * an interrupt.
-                */
-               BEGIN_LP_RING(32);
-               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
-               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               OUT_RING(seqno);
-               OUT_RING(0);
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128; /* write to separate cachelines */
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
-                        PIPE_CONTROL_NOTIFY);
-               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               OUT_RING(seqno);
-               OUT_RING(0);
-               ADVANCE_LP_RING();
-       } else {
-               BEGIN_LP_RING(4);
-               OUT_RING(MI_STORE_DWORD_INDEX);
-               OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-               OUT_RING(seqno);
-
-               OUT_RING(MI_USER_INTERRUPT);
-               ADVANCE_LP_RING();
-       }
-
-       DRM_DEBUG_DRIVER("%d\n", seqno);
+       seqno = ring->add_request(dev, ring, file_priv, flush_domains);
 
        request->seqno = seqno;
+       request->ring = ring;
        request->emitted_jiffies = jiffies;
-       was_empty = list_empty(&dev_priv->mm.request_list);
-       list_add_tail(&request->list, &dev_priv->mm.request_list);
+       was_empty = list_empty(&ring->request_list);
+       list_add_tail(&request->list, &ring->request_list);
+
        if (i915_file_priv) {
                list_add_tail(&request->client_list,
                              &i915_file_priv->mm.request_list);
@@ -1693,7 +1603,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
         * domain we're flushing with our flush.
         */
        if (flush_domains != 0) 
-               i915_gem_process_flushing_list(dev, flush_domains, seqno);
+               i915_gem_process_flushing_list(dev, flush_domains, seqno, ring);
 
        if (!dev_priv->mm.suspended) {
                mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
@@ -1710,20 +1620,16 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
  * before signalling the CPU
  */
 static uint32_t
-i915_retire_commands(struct drm_device *dev)
+i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
        uint32_t flush_domains = 0;
-       RING_LOCALS;
 
        /* The sampler always gets flushed on i965 (sigh) */
        if (IS_I965G(dev))
                flush_domains |= I915_GEM_DOMAIN_SAMPLER;
-       BEGIN_LP_RING(2);
-       OUT_RING(cmd);
-       OUT_RING(0); /* noop */
-       ADVANCE_LP_RING();
+
+       ring->flush(dev, ring,
+                       I915_GEM_DOMAIN_COMMAND, flush_domains);
        return flush_domains;
 }
 
@@ -1743,11 +1649,11 @@ i915_gem_retire_request(struct drm_device *dev,
         * by the ringbuffer to the flushing/inactive lists as appropriate.
         */
        spin_lock(&dev_priv->mm.active_list_lock);
-       while (!list_empty(&dev_priv->mm.active_list)) {
+       while (!list_empty(&request->ring->active_list)) {
                struct drm_gem_object *obj;
                struct drm_i915_gem_object *obj_priv;
 
-               obj_priv = list_first_entry(&dev_priv->mm.active_list,
+               obj_priv = list_first_entry(&request->ring->active_list,
                                            struct drm_i915_gem_object,
                                            list);
                obj = &obj_priv->base;
@@ -1794,35 +1700,33 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
 }
 
 uint32_t
-i915_get_gem_seqno(struct drm_device *dev)
+i915_get_gem_seqno(struct drm_device *dev,
+                  struct intel_ring_buffer *ring)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
-
-       if (HAS_PIPE_CONTROL(dev))
-               return ((volatile u32 *)(dev_priv->seqno_page))[0];
-       else
-               return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+       return ring->get_gem_seqno(dev, ring);
 }
 
 /**
  * This function clears the request list as sequence numbers are passed.
  */
 void
-i915_gem_retire_requests(struct drm_device *dev)
+i915_gem_retire_requests(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        uint32_t seqno;
 
-       if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list))
+       if (!ring->status_page.page_addr
+                       || list_empty(&ring->request_list))
                return;
 
-       seqno = i915_get_gem_seqno(dev);
+       seqno = i915_get_gem_seqno(dev, ring);
 
-       while (!list_empty(&dev_priv->mm.request_list)) {
+       while (!list_empty(&ring->request_list)) {
                struct drm_i915_gem_request *request;
                uint32_t retiring_seqno;
 
-               request = list_first_entry(&dev_priv->mm.request_list,
+               request = list_first_entry(&ring->request_list,
                                           struct drm_i915_gem_request,
                                           list);
                retiring_seqno = request->seqno;
@@ -1840,7 +1744,8 @@ i915_gem_retire_requests(struct drm_device *dev)
 
        if (unlikely (dev_priv->trace_irq_seqno &&
                      i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) {
-               i915_user_irq_put(dev);
+
+               ring->user_irq_put(dev, ring);
                dev_priv->trace_irq_seqno = 0;
        }
 }
@@ -1856,15 +1761,22 @@ i915_gem_retire_work_handler(struct work_struct *work)
        dev = dev_priv->dev;
 
        mutex_lock(&dev->struct_mutex);
-       i915_gem_retire_requests(dev);
+       i915_gem_retire_requests(dev, &dev_priv->render_ring);
+
+       if (HAS_BSD(dev))
+               i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
+
        if (!dev_priv->mm.suspended &&
-           !list_empty(&dev_priv->mm.request_list))
+               (!list_empty(&dev_priv->render_ring.request_list) ||
+                       (HAS_BSD(dev) &&
+                        !list_empty(&dev_priv->bsd_ring.request_list))))
                queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
        mutex_unlock(&dev->struct_mutex);
 }
 
 int
-i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
+i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
+               int interruptible, struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 ier;
@@ -1875,7 +1787,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
        if (atomic_read(&dev_priv->mm.wedged))
                return -EIO;
 
-       if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
+       if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) {
                if (HAS_PCH_SPLIT(dev))
                        ier = I915_READ(DEIER) | I915_READ(GTIER);
                else
@@ -1889,19 +1801,21 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
 
                trace_i915_gem_request_wait_begin(dev, seqno);
 
-               dev_priv->mm.waiting_gem_seqno = seqno;
-               i915_user_irq_get(dev);
+               ring->waiting_gem_seqno = seqno;
+               ring->user_irq_get(dev, ring);
                if (interruptible)
-                       ret = wait_event_interruptible(dev_priv->irq_queue,
-                               i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
-                               atomic_read(&dev_priv->mm.wedged));
+                       ret = wait_event_interruptible(ring->irq_queue,
+                               i915_seqno_passed(
+                                       ring->get_gem_seqno(dev, ring), seqno)
+                               || atomic_read(&dev_priv->mm.wedged));
                else
-                       wait_event(dev_priv->irq_queue,
-                               i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
-                               atomic_read(&dev_priv->mm.wedged));
+                       wait_event(ring->irq_queue,
+                               i915_seqno_passed(
+                                       ring->get_gem_seqno(dev, ring), seqno)
+                               || atomic_read(&dev_priv->mm.wedged));
 
-               i915_user_irq_put(dev);
-               dev_priv->mm.waiting_gem_seqno = 0;
+               ring->user_irq_put(dev, ring);
+               ring->waiting_gem_seqno = 0;
 
                trace_i915_gem_request_wait_end(dev, seqno);
        }
@@ -1910,7 +1824,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
 
        if (ret && ret != -ERESTARTSYS)
                DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
-                         __func__, ret, seqno, i915_get_gem_seqno(dev));
+                         __func__, ret, seqno, ring->get_gem_seqno(dev, ring));
 
        /* Directly dispatch request retiring.  While we have the work queue
         * to handle this, the waiter on a request often wants an associated
@@ -1918,7 +1832,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
         * a separate wait queue to handle that.
         */
        if (ret == 0)
-               i915_gem_retire_requests(dev);
+               i915_gem_retire_requests(dev, ring);
 
        return ret;
 }
@@ -1928,9 +1842,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
  * request and object lists appropriately for that event.
  */
 static int
-i915_wait_request(struct drm_device *dev, uint32_t seqno)
+i915_wait_request(struct drm_device *dev, uint32_t seqno,
+               struct intel_ring_buffer *ring)
 {
-       return i915_do_wait_request(dev, seqno, 1);
+       return i915_do_wait_request(dev, seqno, 1, ring);
 }
 
 static void
@@ -1939,71 +1854,29 @@ i915_gem_flush(struct drm_device *dev,
               uint32_t flush_domains)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       uint32_t cmd;
-       RING_LOCALS;
-
-#if WATCH_EXEC
-       DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
-                 invalidate_domains, flush_domains);
-#endif
-       trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno,
-                                    invalidate_domains, flush_domains);
-
        if (flush_domains & I915_GEM_DOMAIN_CPU)
                drm_agp_chipset_flush(dev);
+       dev_priv->render_ring.flush(dev, &dev_priv->render_ring,
+                       invalidate_domains,
+                       flush_domains);
+
+       if (HAS_BSD(dev))
+               dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring,
+                               invalidate_domains,
+                               flush_domains);
+}
 
-       if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
-               /*
-                * read/write caches:
-                *
-                * I915_GEM_DOMAIN_RENDER is always invalidated, but is
-                * only flushed if MI_NO_WRITE_FLUSH is unset.  On 965, it is
-                * also flushed at 2d versus 3d pipeline switches.
-                *
-                * read-only caches:
-                *
-                * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
-                * MI_READ_FLUSH is set, and is always flushed on 965.
-                *
-                * I915_GEM_DOMAIN_COMMAND may not exist?
-                *
-                * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
-                * invalidated when MI_EXE_FLUSH is set.
-                *
-                * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
-                * invalidated with every MI_FLUSH.
-                *
-                * TLBs:
-                *
-                * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
-                * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
-                * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
-                * are flushed at any MI_FLUSH.
-                */
-
-               cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
-               if ((invalidate_domains|flush_domains) &
-                   I915_GEM_DOMAIN_RENDER)
-                       cmd &= ~MI_NO_WRITE_FLUSH;
-               if (!IS_I965G(dev)) {
-                       /*
-                        * On the 965, the sampler cache always gets flushed
-                        * and this bit is reserved.
-                        */
-                       if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
-                               cmd |= MI_READ_FLUSH;
-               }
-               if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
-                       cmd |= MI_EXE_FLUSH;
-
-#if WATCH_EXEC
-               DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
-#endif
-               BEGIN_LP_RING(2);
-               OUT_RING(cmd);
-               OUT_RING(MI_NOOP);
-               ADVANCE_LP_RING();
-       }
+static void
+i915_gem_flush_ring(struct drm_device *dev,
+              uint32_t invalidate_domains,
+              uint32_t flush_domains,
+              struct intel_ring_buffer *ring)
+{
+       if (flush_domains & I915_GEM_DOMAIN_CPU)
+               drm_agp_chipset_flush(dev);
+       ring->flush(dev, ring,
+                       invalidate_domains,
+                       flush_domains);
 }
 
 /**
@@ -2030,7 +1903,8 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)
                DRM_INFO("%s: object %p wait for seqno %08x\n",
                          __func__, obj, obj_priv->last_rendering_seqno);
 #endif
-               ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
+               ret = i915_wait_request(dev,
+                               obj_priv->last_rendering_seqno, obj_priv->ring);
                if (ret != 0)
                        return ret;
        }
@@ -2146,11 +2020,14 @@ i915_gpu_idle(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        bool lists_empty;
-       uint32_t seqno;
+       uint32_t seqno1, seqno2;
+       int ret;
 
        spin_lock(&dev_priv->mm.active_list_lock);
-       lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
-                     list_empty(&dev_priv->mm.active_list);
+       lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
+                      list_empty(&dev_priv->render_ring.active_list) &&
+                      (!HAS_BSD(dev) ||
+                       list_empty(&dev_priv->bsd_ring.active_list)));
        spin_unlock(&dev_priv->mm.active_list_lock);
 
        if (lists_empty)
@@ -2158,11 +2035,25 @@ i915_gpu_idle(struct drm_device *dev)
 
        /* Flush everything onto the inactive list. */
        i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
-       seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
-       if (seqno == 0)
+       seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS,
+                       &dev_priv->render_ring);
+       if (seqno1 == 0)
                return -ENOMEM;
+       ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring);
+
+       if (HAS_BSD(dev)) {
+               seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS,
+                               &dev_priv->bsd_ring);
+               if (seqno2 == 0)
+                       return -ENOMEM;
+
+               ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring);
+               if (ret)
+                       return ret;
+       }
+
 
-       return i915_wait_request(dev, seqno);
+       return ret;
 }
 
 static int
@@ -2175,7 +2066,9 @@ i915_gem_evict_everything(struct drm_device *dev)
        spin_lock(&dev_priv->mm.active_list_lock);
        lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
                       list_empty(&dev_priv->mm.flushing_list) &&
-                      list_empty(&dev_priv->mm.active_list));
+                      list_empty(&dev_priv->render_ring.active_list) &&
+                      (!HAS_BSD(dev)
+                       || list_empty(&dev_priv->bsd_ring.active_list)));
        spin_unlock(&dev_priv->mm.active_list_lock);
 
        if (lists_empty)
@@ -2195,7 +2088,9 @@ i915_gem_evict_everything(struct drm_device *dev)
        spin_lock(&dev_priv->mm.active_list_lock);
        lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
                       list_empty(&dev_priv->mm.flushing_list) &&
-                      list_empty(&dev_priv->mm.active_list));
+                      list_empty(&dev_priv->render_ring.active_list) &&
+                      (!HAS_BSD(dev)
+                       || list_empty(&dev_priv->bsd_ring.active_list)));
        spin_unlock(&dev_priv->mm.active_list_lock);
        BUG_ON(!lists_empty);
 
@@ -2209,8 +2104,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
        struct drm_gem_object *obj;
        int ret;
 
+       struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
+       struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
        for (;;) {
-               i915_gem_retire_requests(dev);
+               i915_gem_retire_requests(dev, render_ring);
+
+               if (HAS_BSD(dev))
+                       i915_gem_retire_requests(dev, bsd_ring);
 
                /* If there's an inactive buffer available now, grab it
                 * and be done.
@@ -2234,14 +2134,30 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
                 * things, wait for the next to finish and hopefully leave us
                 * a buffer to evict.
                 */
-               if (!list_empty(&dev_priv->mm.request_list)) {
+               if (!list_empty(&render_ring->request_list)) {
+                       struct drm_i915_gem_request *request;
+
+                       request = list_first_entry(&render_ring->request_list,
+                                                  struct drm_i915_gem_request,
+                                                  list);
+
+                       ret = i915_wait_request(dev,
+                                       request->seqno, request->ring);
+                       if (ret)
+                               return ret;
+
+                       continue;
+               }
+
+               if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) {
                        struct drm_i915_gem_request *request;
 
-                       request = list_first_entry(&dev_priv->mm.request_list,
+                       request = list_first_entry(&bsd_ring->request_list,
                                                   struct drm_i915_gem_request,
                                                   list);
 
-                       ret = i915_wait_request(dev, request->seqno);
+                       ret = i915_wait_request(dev,
+                                       request->seqno, request->ring);
                        if (ret)
                                return ret;
 
@@ -2268,10 +2184,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
                        if (obj != NULL) {
                                uint32_t seqno;
 
-                               i915_gem_flush(dev,
+                               i915_gem_flush_ring(dev,
+                                              obj->write_domain,
                                               obj->write_domain,
-                                              obj->write_domain);
-                               seqno = i915_add_request(dev, NULL, obj->write_domain);
+                                              obj_priv->ring);
+                               seqno = i915_add_request(dev, NULL,
+                                               obj->write_domain,
+                                               obj_priv->ring);
                                if (seqno == 0)
                                        return -ENOMEM;
                                continue;
@@ -2299,6 +2218,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
        struct inode *inode;
        struct page *page;
 
+       BUG_ON(obj_priv->pages_refcount
+                       == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT);
+
        if (obj_priv->pages_refcount++ != 0)
                return 0;
 
@@ -2697,6 +2619,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
                return -EINVAL;
        }
 
+       /* If the object is bigger than the entire aperture, reject it early
+        * before evicting everything in a vain attempt to find space.
+        */
+       if (obj->size > dev->gtt_total) {
+               DRM_ERROR("Attempting to bind an object larger than the aperture\n");
+               return -E2BIG;
+       }
+
  search_free:
        free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
                                        obj->size, alignment, 0);
@@ -2807,6 +2737,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        uint32_t old_write_domain;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
                return;
@@ -2814,7 +2745,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
        /* Queue the GPU write cache flushing we need. */
        old_write_domain = obj->write_domain;
        i915_gem_flush(dev, 0, obj->write_domain);
-       (void) i915_add_request(dev, NULL, obj->write_domain);
+       (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring);
        BUG_ON(obj->write_domain);
 
        trace_i915_gem_object_change_domain(obj,
@@ -2954,23 +2885,24 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
                DRM_INFO("%s: object %p wait for seqno %08x\n",
                          __func__, obj, obj_priv->last_rendering_seqno);
 #endif
-               ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0);
+               ret = i915_do_wait_request(dev,
+                               obj_priv->last_rendering_seqno,
+                               0,
+                               obj_priv->ring);
                if (ret != 0)
                        return ret;
        }
 
+       i915_gem_object_flush_cpu_write_domain(obj);
+
        old_write_domain = obj->write_domain;
        old_read_domains = obj->read_domains;
 
-       obj->read_domains &= I915_GEM_DOMAIN_GTT;
-
-       i915_gem_object_flush_cpu_write_domain(obj);
-
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
         */
        BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
-       obj->read_domains |= I915_GEM_DOMAIN_GTT;
+       obj->read_domains = I915_GEM_DOMAIN_GTT;
        obj->write_domain = I915_GEM_DOMAIN_GTT;
        obj_priv->dirty = 1;
 
@@ -3354,9 +3286,13 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                     obj_priv->tiling_mode != I915_TILING_NONE;
 
        /* Check fence reg constraints and rebind if necessary */
-       if (need_fence && !i915_gem_object_fence_offset_ok(obj,
-           obj_priv->tiling_mode))
-               i915_gem_object_unbind(obj);
+       if (need_fence &&
+           !i915_gem_object_fence_offset_ok(obj,
+                                            obj_priv->tiling_mode)) {
+               ret = i915_gem_object_unbind(obj);
+               if (ret)
+                       return ret;
+       }
 
        /* Choose the GTT offset for our buffer and put it there. */
        ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
@@ -3370,9 +3306,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
        if (need_fence) {
                ret = i915_gem_object_get_fence_reg(obj);
                if (ret != 0) {
-                       if (ret != -EBUSY && ret != -ERESTARTSYS)
-                               DRM_ERROR("Failure to install fence: %d\n",
-                                         ret);
                        i915_gem_object_unpin(obj);
                        return ret;
                }
@@ -3545,62 +3478,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
        return 0;
 }
 
-/** Dispatch a batchbuffer to the ring
- */
-static int
-i915_dispatch_gem_execbuffer(struct drm_device *dev,
-                             struct drm_i915_gem_execbuffer2 *exec,
-                             struct drm_clip_rect *cliprects,
-                             uint64_t exec_offset)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       int nbox = exec->num_cliprects;
-       int i = 0, count;
-       uint32_t exec_start, exec_len;
-       RING_LOCALS;
-
-       exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
-       exec_len = (uint32_t) exec->batch_len;
-
-       trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
-
-       count = nbox ? nbox : 1;
-
-       for (i = 0; i < count; i++) {
-               if (i < nbox) {
-                       int ret = i915_emit_box(dev, cliprects, i,
-                                               exec->DR1, exec->DR4);
-                       if (ret)
-                               return ret;
-               }
-
-               if (IS_I830(dev) || IS_845G(dev)) {
-                       BEGIN_LP_RING(4);
-                       OUT_RING(MI_BATCH_BUFFER);
-                       OUT_RING(exec_start | MI_BATCH_NON_SECURE);
-                       OUT_RING(exec_start + exec_len - 4);
-                       OUT_RING(0);
-                       ADVANCE_LP_RING();
-               } else {
-                       BEGIN_LP_RING(2);
-                       if (IS_I965G(dev)) {
-                               OUT_RING(MI_BATCH_BUFFER_START |
-                                        (2 << 6) |
-                                        MI_BATCH_NON_SECURE_I965);
-                               OUT_RING(exec_start);
-                       } else {
-                               OUT_RING(MI_BATCH_BUFFER_START |
-                                        (2 << 6));
-                               OUT_RING(exec_start | MI_BATCH_NON_SECURE);
-                       }
-                       ADVANCE_LP_RING();
-               }
-       }
-
-       /* XXX breadcrumb */
-       return 0;
-}
-
 /* Throttle our rendering by waiting until the ring has completed our requests
  * emitted over 20 msec ago.
  *
@@ -3629,7 +3506,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
                if (time_after_eq(request->emitted_jiffies, recent_enough))
                        break;
 
-               ret = i915_wait_request(dev, request->seqno);
+               ret = i915_wait_request(dev, request->seqno, request->ring);
                if (ret != 0)
                        break;
        }
@@ -3786,10 +3663,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        uint32_t seqno, flush_domains, reloc_index;
        int pin_tries, flips;
 
+       struct intel_ring_buffer *ring = NULL;
+
 #if WATCH_EXEC
        DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
                  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
 #endif
+       if (args->flags & I915_EXEC_BSD) {
+               if (!HAS_BSD(dev)) {
+                       DRM_ERROR("execbuf with wrong flag\n");
+                       return -EINVAL;
+               }
+               ring = &dev_priv->bsd_ring;
+       } else {
+               ring = &dev_priv->render_ring;
+       }
+
 
        if (args->buffer_count < 1) {
                DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
@@ -3902,11 +3791,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                if (ret != -ENOSPC || pin_tries >= 1) {
                        if (ret != -ERESTARTSYS) {
                                unsigned long long total_size = 0;
-                               for (i = 0; i < args->buffer_count; i++)
+                               int num_fences = 0;
+                               for (i = 0; i < args->buffer_count; i++) {
+                                       obj_priv = object_list[i]->driver_private;
+
                                        total_size += object_list[i]->size;
-                               DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n",
+                                       num_fences +=
+                                               exec_list[i].flags & EXEC_OBJECT_NEEDS_FENCE &&
+                                               obj_priv->tiling_mode != I915_TILING_NONE;
+                               }
+                               DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes, %d fences: %d\n",
                                          pinned+1, args->buffer_count,
-                                         total_size, ret);
+                                         total_size, num_fences,
+                                         ret);
                                DRM_ERROR("%d objects [%d pinned], "
                                          "%d object bytes [%d pinned], "
                                          "%d/%d gtt bytes\n",
@@ -3976,9 +3873,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                i915_gem_flush(dev,
                               dev->invalidate_domains,
                               dev->flush_domains);
-               if (dev->flush_domains & I915_GEM_GPU_DOMAINS)
+               if (dev->flush_domains & I915_GEM_GPU_DOMAINS) {
                        (void)i915_add_request(dev, file_priv,
-                                              dev->flush_domains);
+                                       dev->flush_domains,
+                                       &dev_priv->render_ring);
+
+                       if (HAS_BSD(dev))
+                               (void)i915_add_request(dev, file_priv,
+                                               dev->flush_domains,
+                                               &dev_priv->bsd_ring);
+               }
        }
 
        for (i = 0; i < args->buffer_count; i++) {
@@ -4015,7 +3919,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 #endif
 
        /* Exec the batchbuffer */
-       ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
+       ret = ring->dispatch_gem_execbuffer(dev, ring, args,
+                       cliprects, exec_offset);
        if (ret) {
                DRM_ERROR("dispatch failed %d\n", ret);
                goto err;
@@ -4025,7 +3930,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
         * Ensure that the commands in the batch buffer are
         * finished before the interrupt fires
         */
-       flush_domains = i915_retire_commands(dev);
+       flush_domains = i915_retire_commands(dev, ring);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
 
@@ -4036,12 +3941,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
         * *some* interrupts representing completion of buffers that we can
         * wait on when trying to clear up gtt space).
         */
-       seqno = i915_add_request(dev, file_priv, flush_domains);
+       seqno = i915_add_request(dev, file_priv, flush_domains, ring);
        BUG_ON(seqno == 0);
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
+               obj_priv = to_intel_bo(obj);
 
-               i915_gem_object_move_to_active(obj, seqno);
+               i915_gem_object_move_to_active(obj, seqno, ring);
 #if WATCH_LRU
                DRM_INFO("%s: move to exec list %p\n", __func__, obj);
 #endif
@@ -4153,7 +4059,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
        exec2.DR4 = args->DR4;
        exec2.num_cliprects = args->num_cliprects;
        exec2.cliprects_ptr = args->cliprects_ptr;
-       exec2.flags = 0;
+       exec2.flags = I915_EXEC_RENDER;
 
        ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list);
        if (!ret) {
@@ -4239,7 +4145,20 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
+       BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
+
        i915_verify_inactive(dev, __FILE__, __LINE__);
+
+       if (obj_priv->gtt_space != NULL) {
+               if (alignment == 0)
+                       alignment = i915_gem_get_gtt_alignment(obj);
+               if (obj_priv->gtt_offset & (alignment - 1)) {
+                       ret = i915_gem_object_unbind(obj);
+                       if (ret)
+                               return ret;
+               }
+       }
+
        if (obj_priv->gtt_space == NULL) {
                ret = i915_gem_object_bind_to_gtt(obj, alignment);
                if (ret)
@@ -4392,6 +4311,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_busy *args = data;
        struct drm_gem_object *obj;
        struct drm_i915_gem_object *obj_priv;
+       drm_i915_private_t *dev_priv = dev->dev_private;
 
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL) {
@@ -4406,7 +4326,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
         * actually unmasked, and our working set ends up being larger than
         * required.
         */
-       i915_gem_retire_requests(dev);
+       i915_gem_retire_requests(dev, &dev_priv->render_ring);
+
+       if (HAS_BSD(dev))
+               i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
 
        obj_priv = to_intel_bo(obj);
        /* Don't count being on the flushing list against the object being
@@ -4573,7 +4496,10 @@ i915_gem_idle(struct drm_device *dev)
 
        mutex_lock(&dev->struct_mutex);
 
-       if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) {
+       if (dev_priv->mm.suspended ||
+                       (dev_priv->render_ring.gem_object == NULL) ||
+                       (HAS_BSD(dev) &&
+                        dev_priv->bsd_ring.gem_object == NULL)) {
                mutex_unlock(&dev->struct_mutex);
                return 0;
        }
@@ -4654,71 +4580,6 @@ err:
        return ret;
 }
 
-static int
-i915_gem_init_hws(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_gem_object *obj;
-       struct drm_i915_gem_object *obj_priv;
-       int ret;
-
-       /* If we need a physical address for the status page, it's already
-        * initialized at driver load time.
-        */
-       if (!I915_NEED_GFX_HWS(dev))
-               return 0;
-
-       obj = i915_gem_alloc_object(dev, 4096);
-       if (obj == NULL) {
-               DRM_ERROR("Failed to allocate status page\n");
-               ret = -ENOMEM;
-               goto err;
-       }
-       obj_priv = to_intel_bo(obj);
-       obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
-
-       ret = i915_gem_object_pin(obj, 4096);
-       if (ret != 0) {
-               drm_gem_object_unreference(obj);
-               goto err_unref;
-       }
-
-       dev_priv->status_gfx_addr = obj_priv->gtt_offset;
-
-       dev_priv->hw_status_page = kmap(obj_priv->pages[0]);
-       if (dev_priv->hw_status_page == NULL) {
-               DRM_ERROR("Failed to map status page.\n");
-               memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
-               ret = -EINVAL;
-               goto err_unpin;
-       }
-
-       if (HAS_PIPE_CONTROL(dev)) {
-               ret = i915_gem_init_pipe_control(dev);
-               if (ret)
-                       goto err_unpin;
-       }
-
-       dev_priv->hws_obj = obj;
-       memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
-       if (IS_GEN6(dev)) {
-               I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr);
-               I915_READ(HWS_PGA_GEN6); /* posting read */
-       } else {
-               I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
-               I915_READ(HWS_PGA); /* posting read */
-       }
-       DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
-
-       return 0;
-
-err_unpin:
-       i915_gem_object_unpin(obj);
-err_unref:
-       drm_gem_object_unreference(obj);
-err:
-       return 0;
-}
 
 static void
 i915_gem_cleanup_pipe_control(struct drm_device *dev)
@@ -4737,146 +4598,46 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev)
        dev_priv->seqno_page = NULL;
 }
 
-static void
-i915_gem_cleanup_hws(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_gem_object *obj;
-       struct drm_i915_gem_object *obj_priv;
-
-       if (dev_priv->hws_obj == NULL)
-               return;
-
-       obj = dev_priv->hws_obj;
-       obj_priv = to_intel_bo(obj);
-
-       kunmap(obj_priv->pages[0]);
-       i915_gem_object_unpin(obj);
-       drm_gem_object_unreference(obj);
-       dev_priv->hws_obj = NULL;
-
-       memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
-       dev_priv->hw_status_page = NULL;
-
-       if (HAS_PIPE_CONTROL(dev))
-               i915_gem_cleanup_pipe_control(dev);
-
-       /* Write high address into HWS_PGA when disabling. */
-       I915_WRITE(HWS_PGA, 0x1ffff000);
-}
-
 int
 i915_gem_init_ringbuffer(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_gem_object *obj;
-       struct drm_i915_gem_object *obj_priv;
-       drm_i915_ring_buffer_t *ring = &dev_priv->ring;
        int ret;
-       u32 head;
-
-       ret = i915_gem_init_hws(dev);
-       if (ret != 0)
-               return ret;
 
-       obj = i915_gem_alloc_object(dev, 128 * 1024);
-       if (obj == NULL) {
-               DRM_ERROR("Failed to allocate ringbuffer\n");
-               i915_gem_cleanup_hws(dev);
-               return -ENOMEM;
-       }
-       obj_priv = to_intel_bo(obj);
+       dev_priv->render_ring = render_ring;
 
-       ret = i915_gem_object_pin(obj, 4096);
-       if (ret != 0) {
-               drm_gem_object_unreference(obj);
-               i915_gem_cleanup_hws(dev);
-               return ret;
+       if (!I915_NEED_GFX_HWS(dev)) {
+               dev_priv->render_ring.status_page.page_addr
+                       = dev_priv->status_page_dmah->vaddr;
+               memset(dev_priv->render_ring.status_page.page_addr,
+                               0, PAGE_SIZE);
        }
 
-       /* Set up the kernel mapping for the ring. */
-       ring->Size = obj->size;
-
-       ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
-       ring->map.size = obj->size;
-       ring->map.type = 0;
-       ring->map.flags = 0;
-       ring->map.mtrr = 0;
-
-       drm_core_ioremap_wc(&ring->map, dev);
-       if (ring->map.handle == NULL) {
-               DRM_ERROR("Failed to map ringbuffer.\n");
-               memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(obj);
-               i915_gem_cleanup_hws(dev);
-               return -EINVAL;
-       }
-       ring->ring_obj = obj;
-       ring->virtual_start = ring->map.handle;
-
-       /* Stop the ring if it's running. */
-       I915_WRITE(PRB0_CTL, 0);
-       I915_WRITE(PRB0_TAIL, 0);
-       I915_WRITE(PRB0_HEAD, 0);
-
-       /* Initialize the ring. */
-       I915_WRITE(PRB0_START, obj_priv->gtt_offset);
-       head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-
-       /* G45 ring initialization fails to reset head to zero */
-       if (head != 0) {
-               DRM_ERROR("Ring head not reset to zero "
-                         "ctl %08x head %08x tail %08x start %08x\n",
-                         I915_READ(PRB0_CTL),
-                         I915_READ(PRB0_HEAD),
-                         I915_READ(PRB0_TAIL),
-                         I915_READ(PRB0_START));
-               I915_WRITE(PRB0_HEAD, 0);
-
-               DRM_ERROR("Ring head forced to zero "
-                         "ctl %08x head %08x tail %08x start %08x\n",
-                         I915_READ(PRB0_CTL),
-                         I915_READ(PRB0_HEAD),
-                         I915_READ(PRB0_TAIL),
-                         I915_READ(PRB0_START));
-       }
-
-       I915_WRITE(PRB0_CTL,
-                  ((obj->size - 4096) & RING_NR_PAGES) |
-                  RING_NO_REPORT |
-                  RING_VALID);
-
-       head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-
-       /* If the head is still not zero, the ring is dead */
-       if (head != 0) {
-               DRM_ERROR("Ring initialization failed "
-                         "ctl %08x head %08x tail %08x start %08x\n",
-                         I915_READ(PRB0_CTL),
-                         I915_READ(PRB0_HEAD),
-                         I915_READ(PRB0_TAIL),
-                         I915_READ(PRB0_START));
-               return -EIO;
+       if (HAS_PIPE_CONTROL(dev)) {
+               ret = i915_gem_init_pipe_control(dev);
+               if (ret)
+                       return ret;
        }
 
-       /* Update our cache of the ring state */
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               i915_kernel_lost_context(dev);
-       else {
-               ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-               ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
-               ring->space = ring->head - (ring->tail + 8);
-               if (ring->space < 0)
-                       ring->space += ring->Size;
-       }
+       ret = intel_init_ring_buffer(dev, &dev_priv->render_ring);
+       if (ret)
+               goto cleanup_pipe_control;
 
-       if (IS_I9XX(dev) && !IS_GEN3(dev)) {
-               I915_WRITE(MI_MODE,
-                          (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+       if (HAS_BSD(dev)) {
+               dev_priv->bsd_ring = bsd_ring;
+               ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring);
+               if (ret)
+                       goto cleanup_render_ring;
        }
 
        return 0;
+
+cleanup_render_ring:
+       intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+cleanup_pipe_control:
+       if (HAS_PIPE_CONTROL(dev))
+               i915_gem_cleanup_pipe_control(dev);
+       return ret;
 }
 
 void
@@ -4884,17 +4645,11 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       if (dev_priv->ring.ring_obj == NULL)
-               return;
-
-       drm_core_ioremapfree(&dev_priv->ring.map, dev);
-
-       i915_gem_object_unpin(dev_priv->ring.ring_obj);
-       drm_gem_object_unreference(dev_priv->ring.ring_obj);
-       dev_priv->ring.ring_obj = NULL;
-       memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
-
-       i915_gem_cleanup_hws(dev);
+       intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+       if (HAS_BSD(dev))
+               intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
+       if (HAS_PIPE_CONTROL(dev))
+               i915_gem_cleanup_pipe_control(dev);
 }
 
 int
@@ -4922,12 +4677,14 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
        }
 
        spin_lock(&dev_priv->mm.active_list_lock);
-       BUG_ON(!list_empty(&dev_priv->mm.active_list));
+       BUG_ON(!list_empty(&dev_priv->render_ring.active_list));
+       BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list));
        spin_unlock(&dev_priv->mm.active_list_lock);
 
        BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
        BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
-       BUG_ON(!list_empty(&dev_priv->mm.request_list));
+       BUG_ON(!list_empty(&dev_priv->render_ring.request_list));
+       BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list));
        mutex_unlock(&dev->struct_mutex);
 
        drm_irq_install(dev);
@@ -4966,18 +4723,20 @@ i915_gem_load(struct drm_device *dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
 
        spin_lock_init(&dev_priv->mm.active_list_lock);
-       INIT_LIST_HEAD(&dev_priv->mm.active_list);
        INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
        INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
        INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
-       INIT_LIST_HEAD(&dev_priv->mm.request_list);
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+       INIT_LIST_HEAD(&dev_priv->render_ring.active_list);
+       INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
+       if (HAS_BSD(dev)) {
+               INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list);
+               INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list);
+       }
        for (i = 0; i < 16; i++)
                INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
                          i915_gem_retire_work_handler);
-       dev_priv->mm.next_gem_seqno = 1;
-
        spin_lock(&shrink_list_lock);
        list_add(&dev_priv->mm.shrink_list, &shrink_list);
        spin_unlock(&shrink_list_lock);
@@ -5209,7 +4968,9 @@ i915_gpu_is_active(struct drm_device *dev)
 
        spin_lock(&dev_priv->mm.active_list_lock);
        lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
-                     list_empty(&dev_priv->mm.active_list);
+                     list_empty(&dev_priv->render_ring.active_list);
+       if (HAS_BSD(dev))
+               lists_empty &= list_empty(&dev_priv->bsd_ring.active_list);
        spin_unlock(&dev_priv->mm.active_list_lock);
 
        return !lists_empty;
@@ -5254,8 +5015,10 @@ rescan:
                        continue;
 
                spin_unlock(&shrink_list_lock);
+               i915_gem_retire_requests(dev, &dev_priv->render_ring);
 
-               i915_gem_retire_requests(dev);
+               if (HAS_BSD(dev))
+                       i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
 
                list_for_each_entry_safe(obj_priv, next_obj,
                                         &dev_priv->mm.inactive_list,
index 8c3f0802686dbbbba9bc38692681368095db662a..2479be001e405c821345750d5b384ec41c79759c 100644 (file)
@@ -53,7 +53,7 @@
         I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
 
 /** Interrupts that we mask and unmask at runtime. */
-#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
+#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT)
 
 #define I915_PIPE_VBLANK_STATUS        (PIPE_START_VBLANK_INTERRUPT_STATUS |\
                                 PIPE_VBLANK_INTERRUPT_STATUS)
@@ -74,7 +74,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
        }
 }
 
-static inline void
+void
 ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
        if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
@@ -115,7 +115,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
        }
 }
 
-static inline void
+void
 i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
        if ((dev_priv->irq_mask_reg & mask) != mask) {
@@ -278,10 +278,9 @@ static void i915_handle_rps_change(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 busy_up, busy_down, max_avg, min_avg;
-       u16 rgvswctl;
        u8 new_delay = dev_priv->cur_delay;
 
-       I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG);
+       I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG);
        busy_up = I915_READ(RCPREVBSYTUPAVG);
        busy_down = I915_READ(RCPREVBSYTDNAVG);
        max_avg = I915_READ(RCBMAXAVG);
@@ -300,27 +299,8 @@ static void i915_handle_rps_change(struct drm_device *dev)
                        new_delay = dev_priv->min_delay;
        }
 
-       DRM_DEBUG("rps change requested: %d -> %d\n",
-                 dev_priv->cur_delay, new_delay);
-
-       rgvswctl = I915_READ(MEMSWCTL);
-       if (rgvswctl & MEMCTL_CMD_STS) {
-               DRM_ERROR("gpu busy, RCS change rejected\n");
-               return; /* still busy with another command */
-       }
-
-       /* Program the new state */
-       rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
-               (new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
-       I915_WRITE(MEMSWCTL, rgvswctl);
-       POSTING_READ(MEMSWCTL);
-
-       rgvswctl |= MEMCTL_CMD_STS;
-       I915_WRITE(MEMSWCTL, rgvswctl);
-
-       dev_priv->cur_delay = new_delay;
-
-       DRM_DEBUG("rps changed\n");
+       if (ironlake_set_drps(dev, new_delay))
+               dev_priv->cur_delay = new_delay;
 
        return;
 }
@@ -331,6 +311,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
        int ret = IRQ_NONE;
        u32 de_iir, gt_iir, de_ier, pch_iir;
        struct drm_i915_master_private *master_priv;
+       struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
 
        /* disable master interrupt before clearing iir  */
        de_ier = I915_READ(DEIER);
@@ -354,13 +335,16 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
        }
 
        if (gt_iir & GT_PIPE_NOTIFY) {
-               u32 seqno = i915_get_gem_seqno(dev);
-               dev_priv->mm.irq_gem_seqno = seqno;
+               u32 seqno = render_ring->get_gem_seqno(dev, render_ring);
+               render_ring->irq_gem_seqno = seqno;
                trace_i915_gem_request_complete(dev, seqno);
-               DRM_WAKEUP(&dev_priv->irq_queue);
+               DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
                dev_priv->hangcheck_count = 0;
                mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
        }
+       if (gt_iir & GT_BSD_USER_INTERRUPT)
+               DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
+
 
        if (de_iir & DE_GSE)
                ironlake_opregion_gse_intr(dev);
@@ -388,7 +372,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
        }
 
        if (de_iir & DE_PCU_EVENT) {
-               I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS));
+               I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
                i915_handle_rps_change(dev);
        }
 
@@ -536,17 +520,18 @@ i915_ringbuffer_last_batch(struct drm_device *dev)
         */
        bbaddr = 0;
        head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-       ring = (u32 *)(dev_priv->ring.virtual_start + head);
+       ring = (u32 *)(dev_priv->render_ring.virtual_start + head);
 
-       while (--ring >= (u32 *)dev_priv->ring.virtual_start) {
+       while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) {
                bbaddr = i915_get_bbaddr(dev, ring);
                if (bbaddr)
                        break;
        }
 
        if (bbaddr == 0) {
-               ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size);
-               while (--ring >= (u32 *)dev_priv->ring.virtual_start) {
+               ring = (u32 *)(dev_priv->render_ring.virtual_start
+                               + dev_priv->render_ring.size);
+               while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) {
                        bbaddr = i915_get_bbaddr(dev, ring);
                        if (bbaddr)
                                break;
@@ -587,7 +572,7 @@ static void i915_capture_error_state(struct drm_device *dev)
                return;
        }
 
-       error->seqno = i915_get_gem_seqno(dev);
+       error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring);
        error->eir = I915_READ(EIR);
        error->pgtbl_er = I915_READ(PGTBL_ER);
        error->pipeastat = I915_READ(PIPEASTAT);
@@ -615,7 +600,9 @@ static void i915_capture_error_state(struct drm_device *dev)
        batchbuffer[0] = NULL;
        batchbuffer[1] = NULL;
        count = 0;
-       list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+       list_for_each_entry(obj_priv,
+                       &dev_priv->render_ring.active_list, list) {
+
                struct drm_gem_object *obj = &obj_priv->base;
 
                if (batchbuffer[0] == NULL &&
@@ -639,7 +626,8 @@ static void i915_capture_error_state(struct drm_device *dev)
        error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]);
 
        /* Record the ringbuffer */
-       error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj);
+       error->ringbuffer = i915_error_object_create(dev,
+                       dev_priv->render_ring.gem_object);
 
        /* Record buffers on the active list. */
        error->active_bo = NULL;
@@ -651,7 +639,8 @@ static void i915_capture_error_state(struct drm_device *dev)
 
        if (error->active_bo) {
                int i = 0;
-               list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+               list_for_each_entry(obj_priv,
+                               &dev_priv->render_ring.active_list, list) {
                        struct drm_gem_object *obj = &obj_priv->base;
 
                        error->active_bo[i].size = obj->size;
@@ -703,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev)
                i915_error_state_free(dev, error);
 }
 
-/**
- * i915_handle_error - handle an error interrupt
- * @dev: drm device
- *
- * Do some basic checking of regsiter state at error interrupt time and
- * dump it to the syslog.  Also call i915_capture_error_state() to make
- * sure we get a record and make it available in debugfs.  Fire a uevent
- * so userspace knows something bad happened (should trigger collection
- * of a ring dump etc.).
- */
-static void i915_handle_error(struct drm_device *dev, bool wedged)
+static void i915_report_and_clear_eir(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 eir = I915_READ(EIR);
-       u32 pipea_stats = I915_READ(PIPEASTAT);
-       u32 pipeb_stats = I915_READ(PIPEBSTAT);
 
-       i915_capture_error_state(dev);
+       if (!eir)
+               return;
 
        printk(KERN_ERR "render error detected, EIR: 0x%08x\n",
               eir);
@@ -766,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
        }
 
        if (eir & I915_ERROR_MEMORY_REFRESH) {
+               u32 pipea_stats = I915_READ(PIPEASTAT);
+               u32 pipeb_stats = I915_READ(PIPEBSTAT);
+
                printk(KERN_ERR "memory refresh error\n");
                printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
                       pipea_stats);
@@ -822,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
                I915_WRITE(EMR, I915_READ(EMR) | eir);
                I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
        }
+}
+
+/**
+ * i915_handle_error - handle an error interrupt
+ * @dev: drm device
+ *
+ * Do some basic checking of regsiter state at error interrupt time and
+ * dump it to the syslog.  Also call i915_capture_error_state() to make
+ * sure we get a record and make it available in debugfs.  Fire a uevent
+ * so userspace knows something bad happened (should trigger collection
+ * of a ring dump etc.).
+ */
+static void i915_handle_error(struct drm_device *dev, bool wedged)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       i915_capture_error_state(dev);
+       i915_report_and_clear_eir(dev);
 
        if (wedged) {
                atomic_set(&dev_priv->mm.wedged, 1);
@@ -829,7 +828,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
                /*
                 * Wakeup waiting processes so they don't hang
                 */
-               DRM_WAKEUP(&dev_priv->irq_queue);
+               DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
        }
 
        queue_work(dev_priv->wq, &dev_priv->error_work);
@@ -848,6 +847,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
        unsigned long irqflags;
        int irq_received;
        int ret = IRQ_NONE;
+       struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
 
        atomic_inc(&dev_priv->irq_received);
 
@@ -928,14 +928,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                }
 
                if (iir & I915_USER_INTERRUPT) {
-                       u32 seqno = i915_get_gem_seqno(dev);
-                       dev_priv->mm.irq_gem_seqno = seqno;
+                       u32 seqno =
+                               render_ring->get_gem_seqno(dev, render_ring);
+                       render_ring->irq_gem_seqno = seqno;
                        trace_i915_gem_request_complete(dev, seqno);
-                       DRM_WAKEUP(&dev_priv->irq_queue);
+                       DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
                        dev_priv->hangcheck_count = 0;
                        mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
                }
 
+               if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT))
+                       DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
+
                if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
                        intel_prepare_page_flip(dev, 0);
 
@@ -984,7 +988,6 @@ static int i915_emit_irq(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
-       RING_LOCALS;
 
        i915_kernel_lost_context(dev);
 
@@ -1006,43 +1009,13 @@ static int i915_emit_irq(struct drm_device * dev)
        return dev_priv->counter;
 }
 
-void i915_user_irq_get(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-       if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
-               if (HAS_PCH_SPLIT(dev))
-                       ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
-               else
-                       i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
-       }
-       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
-}
-
-void i915_user_irq_put(struct drm_device *dev)
-{
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-       BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
-       if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
-               if (HAS_PCH_SPLIT(dev))
-                       ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
-               else
-                       i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
-       }
-       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
-}
-
 void i915_trace_irq_get(struct drm_device *dev, u32 seqno)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
 
        if (dev_priv->trace_irq_seqno == 0)
-               i915_user_irq_get(dev);
+               render_ring->user_irq_get(dev, render_ring);
 
        dev_priv->trace_irq_seqno = seqno;
 }
@@ -1052,6 +1025,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
        int ret = 0;
+       struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
 
        DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
                  READ_BREADCRUMB(dev_priv));
@@ -1065,10 +1039,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
        if (master_priv->sarea_priv)
                master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
 
-       i915_user_irq_get(dev);
-       DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
+       render_ring->user_irq_get(dev, render_ring);
+       DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ,
                    READ_BREADCRUMB(dev_priv) >= irq_nr);
-       i915_user_irq_put(dev);
+       render_ring->user_irq_put(dev, render_ring);
 
        if (ret == -EBUSY) {
                DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
@@ -1087,7 +1061,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
        drm_i915_irq_emit_t *emit = data;
        int result;
 
-       if (!dev_priv || !dev_priv->ring.virtual_start) {
+       if (!dev_priv || !dev_priv->render_ring.virtual_start) {
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
@@ -1233,9 +1207,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
        return -EINVAL;
 }
 
-struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) {
+struct drm_i915_gem_request *
+i915_get_tail_request(struct drm_device *dev)
+{
        drm_i915_private_t *dev_priv = dev->dev_private;
-       return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list);
+       return list_entry(dev_priv->render_ring.request_list.prev,
+                       struct drm_i915_gem_request, list);
 }
 
 /**
@@ -1260,8 +1237,10 @@ void i915_hangcheck_elapsed(unsigned long data)
                acthd = I915_READ(ACTHD_I965);
 
        /* If all work is done then ACTHD clearly hasn't advanced. */
-       if (list_empty(&dev_priv->mm.request_list) ||
-                      i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) {
+       if (list_empty(&dev_priv->render_ring.request_list) ||
+               i915_seqno_passed(i915_get_gem_seqno(dev,
+                               &dev_priv->render_ring),
+                       i915_get_tail_request(dev)->seqno)) {
                dev_priv->hangcheck_count = 0;
                return;
        }
@@ -1314,7 +1293,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
        /* enable kind of interrupts always enabled */
        u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
                           DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
-       u32 render_mask = GT_PIPE_NOTIFY;
+       u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT;
        u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
                           SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
@@ -1328,7 +1307,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
        (void) I915_READ(DEIER);
 
        /* user interrupt should be enabled, but masked initial */
-       dev_priv->gt_irq_mask_reg = 0xffffffff;
+       dev_priv->gt_irq_mask_reg = ~render_mask;
        dev_priv->gt_irq_enable_reg = render_mask;
 
        I915_WRITE(GTIIR, I915_READ(GTIIR));
@@ -1391,7 +1370,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
        u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
        u32 error_mask;
 
-       DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+       DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue);
+
+       if (HAS_BSD(dev))
+               DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue);
 
        dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
index f3e39cc46f0dd0c4e9dba3c130a05ce1dc5986cf..64b0a3afd92bcd8cdb11c71ba455edbad156396e 100644 (file)
 #define   I915_DEBUG_INTERRUPT                         (1<<2)
 #define   I915_USER_INTERRUPT                          (1<<1)
 #define   I915_ASLE_INTERRUPT                          (1<<0)
+#define   I915_BSD_USER_INTERRUPT                      (1<<25)
 #define EIR            0x020b0
 #define EMR            0x020b4
 #define ESR            0x020b8
 #define BB_ADDR                0x02140 /* 8 bytes */
 #define GFX_FLSH_CNTL  0x02170 /* 915+ only */
 
+/* GEN6 interrupt control */
+#define GEN6_RENDER_HWSTAM     0x2098
+#define GEN6_RENDER_IMR                0x20a8
+#define   GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT         (1 << 8)
+#define   GEN6_RENDER_PPGTT_PAGE_FAULT                 (1 << 7)
+#define   GEN6_RENDER TIMEOUT_COUNTER_EXPIRED          (1 << 6)
+#define   GEN6_RENDER_L3_PARITY_ERROR                  (1 << 5)
+#define   GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT    (1 << 4)
+#define   GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR      (1 << 3)
+#define   GEN6_RENDER_SYNC_STATUS                      (1 << 2)
+#define   GEN6_RENDER_DEBUG_INTERRUPT                  (1 << 1)
+#define   GEN6_RENDER_USER_INTERRUPT                   (1 << 0)
+
+#define GEN6_BLITTER_HWSTAM    0x22098
+#define GEN6_BLITTER_IMR       0x220a8
+#define   GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT    (1 << 26)
+#define   GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR     (1 << 25)
+#define   GEN6_BLITTER_SYNC_STATUS                     (1 << 24)
+#define   GEN6_BLITTER_USER_INTERRUPT                  (1 << 22)
+/*
+ * BSD (bit stream decoder instruction and interrupt control register defines
+ * (G4X and Ironlake only)
+ */
+
+#define BSD_RING_TAIL          0x04030
+#define BSD_RING_HEAD          0x04034
+#define BSD_RING_START         0x04038
+#define BSD_RING_CTL           0x0403c
+#define BSD_RING_ACTHD         0x04074
+#define BSD_HWS_PGA            0x04080
 
 /*
  * Framebuffer compression (915+ only)
 #define DCC_CHANNEL_XOR_DISABLE                                (1 << 10)
 #define DCC_CHANNEL_XOR_BIT_17                         (1 << 9)
 
+/** Pineview MCH register contains DDR3 setting */
+#define CSHRDDR3CTL            0x101a8
+#define CSHRDDR3CTL_DDR3       (1 << 2)
+
 /** 965 MCH register controlling DRAM channel configuration */
 #define C0DRB3                 0x10206
 #define C1DRB3                 0x10606
 #define CLKCFG_MEM_800                                 (3 << 4)
 #define CLKCFG_MEM_MASK                                        (7 << 4)
 
+#define TR1                    0x11006
+#define TSFS                   0x11020
+#define   TSFS_SLOPE_MASK      0x0000ff00
+#define   TSFS_SLOPE_SHIFT     8
+#define   TSFS_INTR_MASK       0x000000ff
+
 #define CRSTANDVID             0x11100
 #define PXVFREQ_BASE           0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */
 #define   PXVFREQ_PX_MASK      0x7f000000
 #define   MEMSTAT_SRC_CTL_STDBY 3
 #define RCPREVBSYTUPAVG                0x113b8
 #define RCPREVBSYTDNAVG                0x113bc
+#define SDEW                   0x1124c
+#define CSIEW0                 0x11250
+#define CSIEW1                 0x11254
+#define CSIEW2                 0x11258
+#define PEW                    0x1125c
+#define DEW                    0x11270
+#define MCHAFE                 0x112c0
+#define CSIEC                  0x112e0
+#define DMIEC                  0x112e4
+#define DDREC                  0x112e8
+#define PEG0EC                 0x112ec
+#define PEG1EC                 0x112f0
+#define GFXEC                  0x112f4
+#define RPPREVBSYTUPAVG                0x113b8
+#define RPPREVBSYTDNAVG                0x113bc
+#define ECR                    0x11600
+#define   ECR_GPFE             (1<<31)
+#define   ECR_IMONE            (1<<30)
+#define   ECR_CAP_MASK         0x0000001f /* Event range, 0-31 */
+#define OGW0                   0x11608
+#define OGW1                   0x1160c
+#define EG0                    0x11610
+#define EG1                    0x11614
+#define EG2                    0x11618
+#define EG3                    0x1161c
+#define EG4                    0x11620
+#define EG5                    0x11624
+#define EG6                    0x11628
+#define EG7                    0x1162c
+#define PXW                    0x11664
+#define PXWL                   0x11680
+#define LCFUSE02               0x116c0
+#define   LCFUSE_HIV_MASK      0x000000ff
+#define CSIPLL0                        0x12c10
+#define DDRMPLL1               0X12c20
 #define PEG_BAND_GAP_DATA      0x14d68
 
 /*
 #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV       (0 << 2)
 #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV       (1 << 2)
 #define CRT_HOTPLUG_MASK                       (0x3fc) /* Bits 9-2 */
-#define CRT_FORCE_HOTPLUG_MASK                 0xfffffe1f
 
 #define PORT_HOTPLUG_STAT      0x61114
 #define   HDMIB_HOTPLUG_INT_STATUS             (1 << 29)
 #define GT_PIPE_NOTIFY         (1 << 4)
 #define GT_SYNC_STATUS          (1 << 2)
 #define GT_USER_INTERRUPT       (1 << 0)
+#define GT_BSD_USER_INTERRUPT   (1 << 5)
+
 
 #define GTISR   0x44010
 #define GTIMR   0x44014
 #define  SDVO_ENCODING          (0)
 #define  TMDS_ENCODING          (2 << 10)
 #define  NULL_PACKET_VSYNC_ENABLE       (1 << 9)
+/* CPT */
+#define  HDMI_MODE_SELECT      (1 << 9)
+#define  DVI_MODE_SELECT       (0)
 #define  SDVOB_BORDER_ENABLE    (1 << 7)
 #define  AUDIO_ENABLE           (1 << 6)
 #define  VSYNC_ACTIVE_HIGH      (1 << 4)
index 9e4c45f68d6edd2af9812cef1c5fc89453e52f55..fab21760dd57857cef544f205c44766d08a923ff 100644 (file)
@@ -53,23 +53,6 @@ TRACE_EVENT(i915_gem_object_bind,
                      __entry->obj, __entry->gtt_offset)
 );
 
-TRACE_EVENT(i915_gem_object_clflush,
-
-           TP_PROTO(struct drm_gem_object *obj),
-
-           TP_ARGS(obj),
-
-           TP_STRUCT__entry(
-                            __field(struct drm_gem_object *, obj)
-                            ),
-
-           TP_fast_assign(
-                          __entry->obj = obj;
-                          ),
-
-           TP_printk("obj=%p", __entry->obj)
-);
-
 TRACE_EVENT(i915_gem_object_change_domain,
 
            TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain),
@@ -132,6 +115,13 @@ DECLARE_EVENT_CLASS(i915_gem_object,
            TP_printk("obj=%p", __entry->obj)
 );
 
+DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush,
+
+           TP_PROTO(struct drm_gem_object *obj),
+
+           TP_ARGS(obj)
+);
+
 DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind,
 
            TP_PROTO(struct drm_gem_object *obj),
index 4c748d8f73d63a4da25f8ea10a981f7fc8860c2e..96f75d7f663319c77ed5f77d279c8cc4794591d2 100644 (file)
@@ -95,6 +95,16 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
        panel_fixed_mode->clock = dvo_timing->clock * 10;
        panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
 
+       if (dvo_timing->hsync_positive)
+               panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+       else
+               panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
+
+       if (dvo_timing->vsync_positive)
+               panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+       else
+               panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
+
        /* Some VBTs have bogus h/vtotal values */
        if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
                panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
index e16ac5a28c3cb178550f4f1763ea81fdd25d801e..22ff38455731ae00b5b5446d5472391935d6c5bf 100644 (file)
@@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 hotplug_en;
+       u32 hotplug_en, orig, stat;
+       bool ret = false;
        int i, tries = 0;
 
        if (HAS_PCH_SPLIT(dev))
@@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
                tries = 2;
        else
                tries = 1;
-       hotplug_en = I915_READ(PORT_HOTPLUG_EN);
-       hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
+       hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN);
+       hotplug_en &= CRT_HOTPLUG_MASK;
        hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
 
        if (IS_G4X(dev))
@@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
                } while (time_after(timeout, jiffies));
        }
 
-       if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
-           CRT_HOTPLUG_MONITOR_NONE)
-               return true;
+       stat = I915_READ(PORT_HOTPLUG_STAT);
+       if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
+               ret = true;
+
+       /* clear the interrupt we just generated, if any */
+       I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
 
-       return false;
+       /* and put the bits back */
+       I915_WRITE(PORT_HOTPLUG_EN, orig);
+
+       return ret;
 }
 
 static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
@@ -569,7 +576,7 @@ void intel_crt_init(struct drm_device *dev)
                                   (1 << INTEL_ANALOG_CLONE_BIT) |
                                   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
-       connector->interlace_allowed = 0;
+       connector->interlace_allowed = 1;
        connector->doublescan_allowed = 0;
 
        drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
index f469a84cacfd92951ce866257699176ef37a21e5..88a1ab7c05ce819165032c328f694d5024f2830d 100644 (file)
@@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 void i8xx_disable_fbc(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned long timeout = jiffies + msecs_to_jiffies(1);
        u32 fbc_ctl;
 
        if (!I915_HAS_FBC(dev))
                return;
 
+       if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN))
+               return; /* Already off, just return */
+
        /* Disable compression */
        fbc_ctl = I915_READ(FBC_CONTROL);
        fbc_ctl &= ~FBC_CTL_EN;
        I915_WRITE(FBC_CONTROL, fbc_ctl);
 
        /* Wait for compressing bit to clear */
-       while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING)
-               ; /* nothing */
+       while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) {
+               if (time_after(jiffies, timeout)) {
+                       DRM_DEBUG_DRIVER("FBC idle timed out\n");
+                       break;
+               }
+               ; /* do nothing */
+       }
 
        intel_wait_for_vblank(dev);
 
@@ -1239,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc,
        return;
 
 out_disable:
-       DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
        /* Multiple disables should be harmless */
-       if (intel_fbc_enabled(dev))
+       if (intel_fbc_enabled(dev)) {
+               DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
                intel_disable_fbc(dev);
+       }
 }
 
 static int
@@ -1386,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
        Start = obj_priv->gtt_offset;
        Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
-       DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+       DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
+                     Start, Offset, x, y, crtc->fb->pitch);
        I915_WRITE(dspstride, crtc->fb->pitch);
        if (IS_I965G(dev)) {
                I915_WRITE(dspbase, Offset);
@@ -2345,6 +2356,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
                if (mode->clock * 3 > 27000 * 4)
                        return MODE_CLOCK_HIGH;
        }
+
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
        return true;
 }
 
@@ -2629,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
 
 struct cxsr_latency {
        int is_desktop;
+       int is_ddr3;
        unsigned long fsb_freq;
        unsigned long mem_freq;
        unsigned long display_sr;
@@ -2638,33 +2652,45 @@ struct cxsr_latency {
 };
 
 static struct cxsr_latency cxsr_latency_table[] = {
-       {1, 800, 400, 3382, 33382, 3983, 33983},    /* DDR2-400 SC */
-       {1, 800, 667, 3354, 33354, 3807, 33807},    /* DDR2-667 SC */
-       {1, 800, 800, 3347, 33347, 3763, 33763},    /* DDR2-800 SC */
-
-       {1, 667, 400, 3400, 33400, 4021, 34021},    /* DDR2-400 SC */
-       {1, 667, 667, 3372, 33372, 3845, 33845},    /* DDR2-667 SC */
-       {1, 667, 800, 3386, 33386, 3822, 33822},    /* DDR2-800 SC */
-
-       {1, 400, 400, 3472, 33472, 4173, 34173},    /* DDR2-400 SC */
-       {1, 400, 667, 3443, 33443, 3996, 33996},    /* DDR2-667 SC */
-       {1, 400, 800, 3430, 33430, 3946, 33946},    /* DDR2-800 SC */
-
-       {0, 800, 400, 3438, 33438, 4065, 34065},    /* DDR2-400 SC */
-       {0, 800, 667, 3410, 33410, 3889, 33889},    /* DDR2-667 SC */
-       {0, 800, 800, 3403, 33403, 3845, 33845},    /* DDR2-800 SC */
-
-       {0, 667, 400, 3456, 33456, 4103, 34106},    /* DDR2-400 SC */
-       {0, 667, 667, 3428, 33428, 3927, 33927},    /* DDR2-667 SC */
-       {0, 667, 800, 3443, 33443, 3905, 33905},    /* DDR2-800 SC */
-
-       {0, 400, 400, 3528, 33528, 4255, 34255},    /* DDR2-400 SC */
-       {0, 400, 667, 3500, 33500, 4079, 34079},    /* DDR2-667 SC */
-       {0, 400, 800, 3487, 33487, 4029, 34029},    /* DDR2-800 SC */
+       {1, 0, 800, 400, 3382, 33382, 3983, 33983},    /* DDR2-400 SC */
+       {1, 0, 800, 667, 3354, 33354, 3807, 33807},    /* DDR2-667 SC */
+       {1, 0, 800, 800, 3347, 33347, 3763, 33763},    /* DDR2-800 SC */
+       {1, 1, 800, 667, 6420, 36420, 6873, 36873},    /* DDR3-667 SC */
+       {1, 1, 800, 800, 5902, 35902, 6318, 36318},    /* DDR3-800 SC */
+
+       {1, 0, 667, 400, 3400, 33400, 4021, 34021},    /* DDR2-400 SC */
+       {1, 0, 667, 667, 3372, 33372, 3845, 33845},    /* DDR2-667 SC */
+       {1, 0, 667, 800, 3386, 33386, 3822, 33822},    /* DDR2-800 SC */
+       {1, 1, 667, 667, 6438, 36438, 6911, 36911},    /* DDR3-667 SC */
+       {1, 1, 667, 800, 5941, 35941, 6377, 36377},    /* DDR3-800 SC */
+
+       {1, 0, 400, 400, 3472, 33472, 4173, 34173},    /* DDR2-400 SC */
+       {1, 0, 400, 667, 3443, 33443, 3996, 33996},    /* DDR2-667 SC */
+       {1, 0, 400, 800, 3430, 33430, 3946, 33946},    /* DDR2-800 SC */
+       {1, 1, 400, 667, 6509, 36509, 7062, 37062},    /* DDR3-667 SC */
+       {1, 1, 400, 800, 5985, 35985, 6501, 36501},    /* DDR3-800 SC */
+
+       {0, 0, 800, 400, 3438, 33438, 4065, 34065},    /* DDR2-400 SC */
+       {0, 0, 800, 667, 3410, 33410, 3889, 33889},    /* DDR2-667 SC */
+       {0, 0, 800, 800, 3403, 33403, 3845, 33845},    /* DDR2-800 SC */
+       {0, 1, 800, 667, 6476, 36476, 6955, 36955},    /* DDR3-667 SC */
+       {0, 1, 800, 800, 5958, 35958, 6400, 36400},    /* DDR3-800 SC */
+
+       {0, 0, 667, 400, 3456, 33456, 4103, 34106},    /* DDR2-400 SC */
+       {0, 0, 667, 667, 3428, 33428, 3927, 33927},    /* DDR2-667 SC */
+       {0, 0, 667, 800, 3443, 33443, 3905, 33905},    /* DDR2-800 SC */
+       {0, 1, 667, 667, 6494, 36494, 6993, 36993},    /* DDR3-667 SC */
+       {0, 1, 667, 800, 5998, 35998, 6460, 36460},    /* DDR3-800 SC */
+
+       {0, 0, 400, 400, 3528, 33528, 4255, 34255},    /* DDR2-400 SC */
+       {0, 0, 400, 667, 3500, 33500, 4079, 34079},    /* DDR2-667 SC */
+       {0, 0, 400, 800, 3487, 33487, 4029, 34029},    /* DDR2-800 SC */
+       {0, 1, 400, 667, 6566, 36566, 7145, 37145},    /* DDR3-667 SC */
+       {0, 1, 400, 800, 6042, 36042, 6584, 36584},    /* DDR3-800 SC */
 };
 
-static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
-                                                  int mem)
+static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, 
+                                                  int fsb, int mem)
 {
        int i;
        struct cxsr_latency *latency;
@@ -2675,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
        for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
                latency = &cxsr_latency_table[i];
                if (is_desktop == latency->is_desktop &&
+                   is_ddr3 == latency->is_ddr3 &&
                    fsb == latency->fsb_freq && mem == latency->mem_freq)
                        return latency;
        }
@@ -2789,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
        struct cxsr_latency *latency;
        int sr_clock;
 
-       latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq,
-                                        dev_priv->mem_freq);
+       latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, 
+                                        dev_priv->fsb_freq, dev_priv->mem_freq);
        if (!latency) {
                DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
                pineview_disable_cxsr(dev);
@@ -3772,6 +3799,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                }
        }
 
+       if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+               pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+               /* the chip adds 2 halflines automatically */
+               adjusted_mode->crtc_vdisplay -= 1;
+               adjusted_mode->crtc_vtotal -= 1;
+               adjusted_mode->crtc_vblank_start -= 1;
+               adjusted_mode->crtc_vblank_end -= 1;
+               adjusted_mode->crtc_vsync_end -= 1;
+               adjusted_mode->crtc_vsync_start -= 1;
+       } else
+               pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
+
        I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
                   ((adjusted_mode->crtc_htotal - 1) << 16));
        I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
@@ -4436,6 +4475,8 @@ static void intel_idle_update(struct work_struct *work)
 
        mutex_lock(&dev->struct_mutex);
 
+       i915_update_gfx_val(dev_priv);
+
        if (IS_I945G(dev) || IS_I945GM(dev)) {
                DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
                I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
@@ -4564,12 +4605,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
        spin_lock_irqsave(&dev->event_lock, flags);
        work = intel_crtc->unpin_work;
        if (work == NULL || !work->pending) {
-               if (work && !work->pending) {
-                       obj_priv = to_intel_bo(work->pending_flip_obj);
-                       DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
-                                        obj_priv,
-                                        atomic_read(&obj_priv->pending_flip));
-               }
                spin_unlock_irqrestore(&dev->event_lock, flags);
                return;
        }
@@ -4629,14 +4664,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        unsigned long flags;
        int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
        int ret, pipesrc;
-       RING_LOCALS;
 
        work = kzalloc(sizeof *work, GFP_KERNEL);
        if (work == NULL)
                return -ENOMEM;
 
-       mutex_lock(&dev->struct_mutex);
-
        work->event = event;
        work->dev = crtc->dev;
        intel_fb = to_intel_framebuffer(crtc->fb);
@@ -4646,10 +4678,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        /* We borrow the event spin lock for protecting unpin_work */
        spin_lock_irqsave(&dev->event_lock, flags);
        if (intel_crtc->unpin_work) {
-               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
                spin_unlock_irqrestore(&dev->event_lock, flags);
                kfree(work);
-               mutex_unlock(&dev->struct_mutex);
+
+               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
                return -EBUSY;
        }
        intel_crtc->unpin_work = work;
@@ -4658,13 +4690,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_fb = to_intel_framebuffer(fb);
        obj = intel_fb->obj;
 
+       mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
        if (ret != 0) {
-               DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                         to_intel_bo(obj));
-               kfree(work);
-               intel_crtc->unpin_work = NULL;
                mutex_unlock(&dev->struct_mutex);
+
+               spin_lock_irqsave(&dev->event_lock, flags);
+               intel_crtc->unpin_work = NULL;
+               spin_unlock_irqrestore(&dev->event_lock, flags);
+
+               kfree(work);
+
+               DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
+                                to_intel_bo(obj));
                return ret;
        }
 
@@ -5023,10 +5061,32 @@ err_unref:
        return NULL;
 }
 
+bool ironlake_set_drps(struct drm_device *dev, u8 val)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u16 rgvswctl;
+
+       rgvswctl = I915_READ16(MEMSWCTL);
+       if (rgvswctl & MEMCTL_CMD_STS) {
+               DRM_DEBUG("gpu busy, RCS change rejected\n");
+               return false; /* still busy with another command */
+       }
+
+       rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
+               (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
+       I915_WRITE16(MEMSWCTL, rgvswctl);
+       POSTING_READ16(MEMSWCTL);
+
+       rgvswctl |= MEMCTL_CMD_STS;
+       I915_WRITE16(MEMSWCTL, rgvswctl);
+
+       return true;
+}
+
 void ironlake_enable_drps(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl;
+       u32 rgvmodectl = I915_READ(MEMMODECTL);
        u8 fmax, fmin, fstart, vstart;
        int i = 0;
 
@@ -5045,13 +5105,21 @@ void ironlake_enable_drps(struct drm_device *dev)
        fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
        fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
                MEMMODE_FSTART_SHIFT;
+       fstart = fmax;
+
        vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
                PXVFREQ_PX_SHIFT;
 
-       dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */
+       dev_priv->fmax = fstart; /* IPS callback will increase this */
+       dev_priv->fstart = fstart;
+
+       dev_priv->max_delay = fmax;
        dev_priv->min_delay = fmin;
        dev_priv->cur_delay = fstart;
 
+       DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin,
+                        fstart);
+
        I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
 
        /*
@@ -5073,20 +5141,19 @@ void ironlake_enable_drps(struct drm_device *dev)
        }
        msleep(1);
 
-       rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
-               (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
-       I915_WRITE(MEMSWCTL, rgvswctl);
-       POSTING_READ(MEMSWCTL);
+       ironlake_set_drps(dev, fstart);
 
-       rgvswctl |= MEMCTL_CMD_STS;
-       I915_WRITE(MEMSWCTL, rgvswctl);
+       dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
+               I915_READ(0x112e0);
+       dev_priv->last_time1 = jiffies_to_msecs(jiffies);
+       dev_priv->last_count2 = I915_READ(0x112f4);
+       getrawmonotonic(&dev_priv->last_time2);
 }
 
 void ironlake_disable_drps(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 rgvswctl;
-       u8 fstart;
+       u16 rgvswctl = I915_READ16(MEMSWCTL);
 
        /* Ack interrupts, disable EFC interrupt */
        I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN);
@@ -5096,11 +5163,7 @@ void ironlake_disable_drps(struct drm_device *dev)
        I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT);
 
        /* Go back to the starting frequency */
-       fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >>
-               MEMMODE_FSTART_SHIFT;
-       rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
-               (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
-       I915_WRITE(MEMSWCTL, rgvswctl);
+       ironlake_set_drps(dev, dev_priv->fstart);
        msleep(1);
        rgvswctl |= MEMCTL_CMD_STS;
        I915_WRITE(MEMSWCTL, rgvswctl);
@@ -5108,6 +5171,92 @@ void ironlake_disable_drps(struct drm_device *dev)
 
 }
 
+static unsigned long intel_pxfreq(u32 vidfreq)
+{
+       unsigned long freq;
+       int div = (vidfreq & 0x3f0000) >> 16;
+       int post = (vidfreq & 0x3000) >> 12;
+       int pre = (vidfreq & 0x7);
+
+       if (!pre)
+               return 0;
+
+       freq = ((div * 133333) / ((1<<post) * pre));
+
+       return freq;
+}
+
+void intel_init_emon(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 lcfuse;
+       u8 pxw[16];
+       int i;
+
+       /* Disable to program */
+       I915_WRITE(ECR, 0);
+       POSTING_READ(ECR);
+
+       /* Program energy weights for various events */
+       I915_WRITE(SDEW, 0x15040d00);
+       I915_WRITE(CSIEW0, 0x007f0000);
+       I915_WRITE(CSIEW1, 0x1e220004);
+       I915_WRITE(CSIEW2, 0x04000004);
+
+       for (i = 0; i < 5; i++)
+               I915_WRITE(PEW + (i * 4), 0);
+       for (i = 0; i < 3; i++)
+               I915_WRITE(DEW + (i * 4), 0);
+
+       /* Program P-state weights to account for frequency power adjustment */
+       for (i = 0; i < 16; i++) {
+               u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4));
+               unsigned long freq = intel_pxfreq(pxvidfreq);
+               unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
+                       PXVFREQ_PX_SHIFT;
+               unsigned long val;
+
+               val = vid * vid;
+               val *= (freq / 1000);
+               val *= 255;
+               val /= (127*127*900);
+               if (val > 0xff)
+                       DRM_ERROR("bad pxval: %ld\n", val);
+               pxw[i] = val;
+       }
+       /* Render standby states get 0 weight */
+       pxw[14] = 0;
+       pxw[15] = 0;
+
+       for (i = 0; i < 4; i++) {
+               u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
+                       (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
+               I915_WRITE(PXW + (i * 4), val);
+       }
+
+       /* Adjust magic regs to magic values (more experimental results) */
+       I915_WRITE(OGW0, 0);
+       I915_WRITE(OGW1, 0);
+       I915_WRITE(EG0, 0x00007f00);
+       I915_WRITE(EG1, 0x0000000e);
+       I915_WRITE(EG2, 0x000e0000);
+       I915_WRITE(EG3, 0x68000300);
+       I915_WRITE(EG4, 0x42000000);
+       I915_WRITE(EG5, 0x00140031);
+       I915_WRITE(EG6, 0);
+       I915_WRITE(EG7, 0);
+
+       for (i = 0; i < 8; i++)
+               I915_WRITE(PXWL + (i * 4), 0);
+
+       /* Enable PMON + select events */
+       I915_WRITE(ECR, 0x80000019);
+
+       lcfuse = I915_READ(LCFUSE02);
+
+       dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
+}
+
 void intel_init_clock_gating(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5277,11 +5426,13 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.update_wm = NULL;
        } else if (IS_PINEVIEW(dev)) {
                if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+                                           dev_priv->is_ddr3,
                                            dev_priv->fsb_freq,
                                            dev_priv->mem_freq)) {
                        DRM_INFO("failed to find known CxSR latency "
-                                "(found fsb freq %d, mem freq %d), "
+                                "(found ddr%s fsb freq %d, mem freq %d), "
                                 "disabling CxSR\n",
+                                (dev_priv->is_ddr3 == 1) ? "3": "2",
                                 dev_priv->fsb_freq, dev_priv->mem_freq);
                        /* Disable CxSR and never update its watermark again */
                        pineview_disable_cxsr(dev);
@@ -5354,8 +5505,10 @@ void intel_modeset_init(struct drm_device *dev)
 
        intel_init_clock_gating(dev);
 
-       if (IS_IRONLAKE_M(dev))
+       if (IS_IRONLAKE_M(dev)) {
                ironlake_enable_drps(dev);
+               intel_init_emon(dev);
+       }
 
        INIT_WORK(&dev_priv->idle_work, intel_idle_update);
        setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
index 6b1c9a27c27a236aada13d0ddf257f7a8330047c..49b54f05d3cfcb767b28c0caecc8523ea6deabed 100644 (file)
@@ -576,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                struct intel_encoder *intel_encoder;
                struct intel_dp_priv *dp_priv;
 
-               if (!encoder || encoder->crtc != crtc)
+               if (encoder->crtc != crtc)
                        continue;
 
                intel_encoder = enc_to_intel_encoder(encoder);
@@ -675,10 +675,9 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        dp_priv->link_configuration[1] = dp_priv->lane_count;
 
        /*
-        * Check for DPCD version > 1.1,
-        * enable enahanced frame stuff in that case
+        * Check for DPCD version > 1.1 and enhanced framing support
         */
-       if (dp_priv->dpcd[0] >= 0x11) {
+       if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
                dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
                dp_priv->DP |= DP_ENHANCED_FRAMING;
        }
@@ -1208,6 +1207,8 @@ ironlake_dp_detect(struct drm_connector *connector)
                if (dp_priv->dpcd[0] != 0)
                        status = connector_status_connected;
        }
+       DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0],
+                     dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]);
        return status;
 }
 
@@ -1352,7 +1353,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
        struct intel_encoder *intel_encoder = NULL;
 
        list_for_each_entry(encoder, &mode_config->encoder_list, head) {
-               if (!encoder || encoder->crtc != crtc)
+               if (encoder->crtc != crtc)
                        continue;
 
                intel_encoder = enc_to_intel_encoder(encoder);
index 6f53cf7fbc506a4fe5fac3d7b726001f083bd37b..f8c76e64bb77e4a189e450b606ecb3684fbcb017 100644 (file)
@@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
        }
 
        /* Flush everything out, we'll be doing GTT only from now on */
-       i915_gem_object_set_to_gtt_domain(fbo, 1);
+       ret = i915_gem_object_set_to_gtt_domain(fbo, 1);
+       if (ret) {
+               DRM_ERROR("failed to bind fb: %d.\n", ret);
+               goto out_unpin;
+       }
 
        info = framebuffer_alloc(0, device);
        if (!info) {
index 65727f0a79a3440202e5f315762431d975b5a9cf..83bd764b000e51cff80ac0a79a14b8cc5f05fcb4 100644 (file)
@@ -59,8 +59,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
                SDVO_VSYNC_ACTIVE_HIGH |
                SDVO_HSYNC_ACTIVE_HIGH;
 
-       if (hdmi_priv->has_hdmi_sink)
+       if (hdmi_priv->has_hdmi_sink) {
                sdvox |= SDVO_AUDIO_ENABLE;
+               if (HAS_PCH_CPT(dev))
+                       sdvox |= HDMI_MODE_SELECT;
+       }
 
        if (intel_crtc->pipe == 1) {
                if (HAS_PCH_CPT(dev))
index b0e17b06eb6ea08c2c67e57e8b62fe6989cd4e2d..d7ad5139d17cefa543ae30652757b81ff48b407b 100644 (file)
@@ -211,9 +211,8 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
 static int intel_overlay_on(struct intel_overlay *overlay)
 {
        struct drm_device *dev = overlay->dev;
-        drm_i915_private_t *dev_priv = dev->dev_private;
        int ret;
-       RING_LOCALS;
+       drm_i915_private_t *dev_priv = dev->dev_private;
 
        BUG_ON(overlay->active);
 
@@ -227,11 +226,13 @@ static int intel_overlay_on(struct intel_overlay *overlay)
        OUT_RING(MI_NOOP);
        ADVANCE_LP_RING();
 
-       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+       overlay->last_flip_req =
+               i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
        if (overlay->last_flip_req == 0)
                return -ENOMEM;
 
-       ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+       ret = i915_do_wait_request(dev,
+                       overlay->last_flip_req, 1, &dev_priv->render_ring);
        if (ret != 0)
                return ret;
 
@@ -248,7 +249,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
         drm_i915_private_t *dev_priv = dev->dev_private;
        u32 flip_addr = overlay->flip_addr;
        u32 tmp;
-       RING_LOCALS;
 
        BUG_ON(!overlay->active);
 
@@ -265,7 +265,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
        OUT_RING(flip_addr);
         ADVANCE_LP_RING();
 
-       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+       overlay->last_flip_req =
+               i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
 }
 
 static int intel_overlay_wait_flip(struct intel_overlay *overlay)
@@ -274,10 +275,10 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
         drm_i915_private_t *dev_priv = dev->dev_private;
        int ret;
        u32 tmp;
-       RING_LOCALS;
 
        if (overlay->last_flip_req != 0) {
-               ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+               ret = i915_do_wait_request(dev, overlay->last_flip_req,
+                               1, &dev_priv->render_ring);
                if (ret == 0) {
                        overlay->last_flip_req = 0;
 
@@ -296,11 +297,13 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
         OUT_RING(MI_NOOP);
         ADVANCE_LP_RING();
 
-       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+       overlay->last_flip_req =
+               i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
        if (overlay->last_flip_req == 0)
                return -ENOMEM;
 
-       ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+       ret = i915_do_wait_request(dev, overlay->last_flip_req,
+                       1, &dev_priv->render_ring);
        if (ret != 0)
                return ret;
 
@@ -314,9 +317,8 @@ static int intel_overlay_off(struct intel_overlay *overlay)
 {
        u32 flip_addr = overlay->flip_addr;
        struct drm_device *dev = overlay->dev;
-        drm_i915_private_t *dev_priv = dev->dev_private;
+       drm_i915_private_t *dev_priv = dev->dev_private;
        int ret;
-       RING_LOCALS;
 
        BUG_ON(!overlay->active);
 
@@ -336,11 +338,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
         OUT_RING(MI_NOOP);
         ADVANCE_LP_RING();
 
-       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+       overlay->last_flip_req =
+               i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
        if (overlay->last_flip_req == 0)
                return -ENOMEM;
 
-       ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+       ret = i915_do_wait_request(dev, overlay->last_flip_req,
+                       1, &dev_priv->render_ring);
        if (ret != 0)
                return ret;
 
@@ -354,11 +358,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
         OUT_RING(MI_NOOP);
        ADVANCE_LP_RING();
 
-       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+       overlay->last_flip_req =
+               i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
        if (overlay->last_flip_req == 0)
                return -ENOMEM;
 
-       ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+       ret = i915_do_wait_request(dev, overlay->last_flip_req,
+                       1, &dev_priv->render_ring);
        if (ret != 0)
                return ret;
 
@@ -390,22 +396,23 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
                                         int interruptible)
 {
        struct drm_device *dev = overlay->dev;
-        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_gem_object *obj;
+       drm_i915_private_t *dev_priv = dev->dev_private;
        u32 flip_addr;
        int ret;
-       RING_LOCALS;
 
        if (overlay->hw_wedged == HW_WEDGED)
                return -EIO;
 
        if (overlay->last_flip_req == 0) {
-               overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+               overlay->last_flip_req =
+                       i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
                if (overlay->last_flip_req == 0)
                        return -ENOMEM;
        }
 
-       ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible);
+       ret = i915_do_wait_request(dev, overlay->last_flip_req,
+                       interruptible, &dev_priv->render_ring);
        if (ret != 0)
                return ret;
 
@@ -429,12 +436,13 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
                        OUT_RING(MI_NOOP);
                        ADVANCE_LP_RING();
 
-                       overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+                       overlay->last_flip_req = i915_add_request(dev, NULL,
+                                       0, &dev_priv->render_ring);
                        if (overlay->last_flip_req == 0)
                                return -ENOMEM;
 
                        ret = i915_do_wait_request(dev, overlay->last_flip_req,
-                                       interruptible);
+                                       interruptible, &dev_priv->render_ring);
                        if (ret != 0)
                                return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
new file mode 100644 (file)
index 0000000..cea4f1a
--- /dev/null
@@ -0,0 +1,849 @@
+/*
+ * Copyright Â© 2008-2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Zou Nan hai <nanhai.zou@intel.com>
+ *    Xiang Hai hao<haihao.xiang@intel.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drv.h"
+#include "i915_drm.h"
+#include "i915_trace.h"
+
+static void
+render_ring_flush(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               u32     invalidate_domains,
+               u32     flush_domains)
+{
+#if WATCH_EXEC
+       DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
+                 invalidate_domains, flush_domains);
+#endif
+       u32 cmd;
+       trace_i915_gem_request_flush(dev, ring->next_seqno,
+                                    invalidate_domains, flush_domains);
+
+       if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
+               /*
+                * read/write caches:
+                *
+                * I915_GEM_DOMAIN_RENDER is always invalidated, but is
+                * only flushed if MI_NO_WRITE_FLUSH is unset.  On 965, it is
+                * also flushed at 2d versus 3d pipeline switches.
+                *
+                * read-only caches:
+                *
+                * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
+                * MI_READ_FLUSH is set, and is always flushed on 965.
+                *
+                * I915_GEM_DOMAIN_COMMAND may not exist?
+                *
+                * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
+                * invalidated when MI_EXE_FLUSH is set.
+                *
+                * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
+                * invalidated with every MI_FLUSH.
+                *
+                * TLBs:
+                *
+                * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
+                * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
+                * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
+                * are flushed at any MI_FLUSH.
+                */
+
+               cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
+               if ((invalidate_domains|flush_domains) &
+                   I915_GEM_DOMAIN_RENDER)
+                       cmd &= ~MI_NO_WRITE_FLUSH;
+               if (!IS_I965G(dev)) {
+                       /*
+                        * On the 965, the sampler cache always gets flushed
+                        * and this bit is reserved.
+                        */
+                       if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
+                               cmd |= MI_READ_FLUSH;
+               }
+               if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
+                       cmd |= MI_EXE_FLUSH;
+
+#if WATCH_EXEC
+               DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
+#endif
+               intel_ring_begin(dev, ring, 8);
+               intel_ring_emit(dev, ring, cmd);
+               intel_ring_emit(dev, ring, MI_NOOP);
+               intel_ring_advance(dev, ring);
+       }
+}
+
+static unsigned int render_ring_get_head(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       return I915_READ(PRB0_HEAD) & HEAD_ADDR;
+}
+
+static unsigned int render_ring_get_tail(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       return I915_READ(PRB0_TAIL) & TAIL_ADDR;
+}
+
+static unsigned int render_ring_get_active_head(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
+
+       return I915_READ(acthd_reg);
+}
+
+static void render_ring_advance_ring(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       I915_WRITE(PRB0_TAIL, ring->tail);
+}
+
+static int init_ring_common(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       u32 head;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_gem_object *obj_priv;
+       obj_priv = to_intel_bo(ring->gem_object);
+
+       /* Stop the ring if it's running. */
+       I915_WRITE(ring->regs.ctl, 0);
+       I915_WRITE(ring->regs.head, 0);
+       I915_WRITE(ring->regs.tail, 0);
+
+       /* Initialize the ring. */
+       I915_WRITE(ring->regs.start, obj_priv->gtt_offset);
+       head = ring->get_head(dev, ring);
+
+       /* G45 ring initialization fails to reset head to zero */
+       if (head != 0) {
+               DRM_ERROR("%s head not reset to zero "
+                               "ctl %08x head %08x tail %08x start %08x\n",
+                               ring->name,
+                               I915_READ(ring->regs.ctl),
+                               I915_READ(ring->regs.head),
+                               I915_READ(ring->regs.tail),
+                               I915_READ(ring->regs.start));
+
+               I915_WRITE(ring->regs.head, 0);
+
+               DRM_ERROR("%s head forced to zero "
+                               "ctl %08x head %08x tail %08x start %08x\n",
+                               ring->name,
+                               I915_READ(ring->regs.ctl),
+                               I915_READ(ring->regs.head),
+                               I915_READ(ring->regs.tail),
+                               I915_READ(ring->regs.start));
+       }
+
+       I915_WRITE(ring->regs.ctl,
+                       ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
+                       | RING_NO_REPORT | RING_VALID);
+
+       head = I915_READ(ring->regs.head) & HEAD_ADDR;
+       /* If the head is still not zero, the ring is dead */
+       if (head != 0) {
+               DRM_ERROR("%s initialization failed "
+                               "ctl %08x head %08x tail %08x start %08x\n",
+                               ring->name,
+                               I915_READ(ring->regs.ctl),
+                               I915_READ(ring->regs.head),
+                               I915_READ(ring->regs.tail),
+                               I915_READ(ring->regs.start));
+               return -EIO;
+       }
+
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               i915_kernel_lost_context(dev);
+       else {
+               ring->head = ring->get_head(dev, ring);
+               ring->tail = ring->get_tail(dev, ring);
+               ring->space = ring->head - (ring->tail + 8);
+               if (ring->space < 0)
+                       ring->space += ring->size;
+       }
+       return 0;
+}
+
+static int init_render_ring(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       int ret = init_ring_common(dev, ring);
+       if (IS_I9XX(dev) && !IS_GEN3(dev)) {
+               I915_WRITE(MI_MODE,
+                               (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+       }
+       return ret;
+}
+
+#define PIPE_CONTROL_FLUSH(addr)                                       \
+do {                                                                   \
+       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |          \
+                PIPE_CONTROL_DEPTH_STALL | 2);                         \
+       OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);                       \
+       OUT_RING(0);                                                    \
+       OUT_RING(0);                                                    \
+} while (0)
+
+/**
+ * Creates a new sequence number, emitting a write of it to the status page
+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
+ *
+ * Must be called with struct_lock held.
+ *
+ * Returned sequence numbers are nonzero on success.
+ */
+static u32
+render_ring_add_request(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               struct drm_file *file_priv,
+               u32 flush_domains)
+{
+       u32 seqno;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       seqno = intel_ring_get_seqno(dev, ring);
+
+       if (IS_GEN6(dev)) {
+               BEGIN_LP_RING(6);
+               OUT_RING(GFX_OP_PIPE_CONTROL | 3);
+               OUT_RING(PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
+                        PIPE_CONTROL_NOTIFY);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       } else if (HAS_PIPE_CONTROL(dev)) {
+               u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
+
+               /*
+                * Workaround qword write incoherence by flushing the
+                * PIPE_NOTIFY buffers out to memory before requesting
+                * an interrupt.
+                */
+               BEGIN_LP_RING(32);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128; /* write to separate cachelines */
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                        PIPE_CONTROL_NOTIFY);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       } else {
+               BEGIN_LP_RING(4);
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(seqno);
+
+               OUT_RING(MI_USER_INTERRUPT);
+               ADVANCE_LP_RING();
+       }
+       return seqno;
+}
+
+static u32
+render_ring_get_gem_seqno(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       if (HAS_PIPE_CONTROL(dev))
+               return ((volatile u32 *)(dev_priv->seqno_page))[0];
+       else
+               return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
+}
+
+static void
+render_ring_get_user_irq(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
+
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+       if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) {
+               if (HAS_PCH_SPLIT(dev))
+                       ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
+               else
+                       i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
+       }
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
+}
+
+static void
+render_ring_put_user_irq(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
+
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+       BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0);
+       if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) {
+               if (HAS_PCH_SPLIT(dev))
+                       ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
+               else
+                       i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
+       }
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
+}
+
+static void render_setup_status_page(struct drm_device *dev,
+       struct  intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       if (IS_GEN6(dev)) {
+               I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr);
+               I915_READ(HWS_PGA_GEN6); /* posting read */
+       } else {
+               I915_WRITE(HWS_PGA, ring->status_page.gfx_addr);
+               I915_READ(HWS_PGA); /* posting read */
+       }
+
+}
+
+void
+bsd_ring_flush(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               u32     invalidate_domains,
+               u32     flush_domains)
+{
+       intel_ring_begin(dev, ring, 8);
+       intel_ring_emit(dev, ring, MI_FLUSH);
+       intel_ring_emit(dev, ring, MI_NOOP);
+       intel_ring_advance(dev, ring);
+}
+
+static inline unsigned int bsd_ring_get_head(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       return I915_READ(BSD_RING_HEAD) & HEAD_ADDR;
+}
+
+static inline unsigned int bsd_ring_get_tail(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       return I915_READ(BSD_RING_TAIL) & TAIL_ADDR;
+}
+
+static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       return I915_READ(BSD_RING_ACTHD);
+}
+
+static inline void bsd_ring_advance_ring(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       I915_WRITE(BSD_RING_TAIL, ring->tail);
+}
+
+static int init_bsd_ring(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       return init_ring_common(dev, ring);
+}
+
+static u32
+bsd_ring_add_request(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               struct drm_file *file_priv,
+               u32 flush_domains)
+{
+       u32 seqno;
+       seqno = intel_ring_get_seqno(dev, ring);
+       intel_ring_begin(dev, ring, 4);
+       intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
+       intel_ring_emit(dev, ring,
+                       I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+       intel_ring_emit(dev, ring, seqno);
+       intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
+       intel_ring_advance(dev, ring);
+
+       DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
+
+       return seqno;
+}
+
+static void bsd_setup_status_page(struct drm_device *dev,
+               struct  intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr);
+       I915_READ(BSD_HWS_PGA);
+}
+
+static void
+bsd_ring_get_user_irq(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       /* do nothing */
+}
+static void
+bsd_ring_put_user_irq(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       /* do nothing */
+}
+
+static u32
+bsd_ring_get_gem_seqno(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
+}
+
+static int
+bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               struct drm_i915_gem_execbuffer2 *exec,
+               struct drm_clip_rect *cliprects,
+               uint64_t exec_offset)
+{
+       uint32_t exec_start;
+       exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
+       intel_ring_begin(dev, ring, 2);
+       intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START |
+                       (2 << 6) | MI_BATCH_NON_SECURE_I965);
+       intel_ring_emit(dev, ring, exec_start);
+       intel_ring_advance(dev, ring);
+       return 0;
+}
+
+
+static int
+render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               struct drm_i915_gem_execbuffer2 *exec,
+               struct drm_clip_rect *cliprects,
+               uint64_t exec_offset)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       int nbox = exec->num_cliprects;
+       int i = 0, count;
+       uint32_t exec_start, exec_len;
+       exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
+       exec_len = (uint32_t) exec->batch_len;
+
+       trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
+
+       count = nbox ? nbox : 1;
+
+       for (i = 0; i < count; i++) {
+               if (i < nbox) {
+                       int ret = i915_emit_box(dev, cliprects, i,
+                                               exec->DR1, exec->DR4);
+                       if (ret)
+                               return ret;
+               }
+
+               if (IS_I830(dev) || IS_845G(dev)) {
+                       intel_ring_begin(dev, ring, 4);
+                       intel_ring_emit(dev, ring, MI_BATCH_BUFFER);
+                       intel_ring_emit(dev, ring,
+                                       exec_start | MI_BATCH_NON_SECURE);
+                       intel_ring_emit(dev, ring, exec_start + exec_len - 4);
+                       intel_ring_emit(dev, ring, 0);
+               } else {
+                       intel_ring_begin(dev, ring, 4);
+                       if (IS_I965G(dev)) {
+                               intel_ring_emit(dev, ring,
+                                               MI_BATCH_BUFFER_START | (2 << 6)
+                                               | MI_BATCH_NON_SECURE_I965);
+                               intel_ring_emit(dev, ring, exec_start);
+                       } else {
+                               intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START
+                                               | (2 << 6));
+                               intel_ring_emit(dev, ring, exec_start |
+                                               MI_BATCH_NON_SECURE);
+                       }
+               }
+               intel_ring_advance(dev, ring);
+       }
+
+       /* XXX breadcrumb */
+       return 0;
+}
+
+static void cleanup_status_page(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+
+       obj = ring->status_page.obj;
+       if (obj == NULL)
+               return;
+       obj_priv = to_intel_bo(obj);
+
+       kunmap(obj_priv->pages[0]);
+       i915_gem_object_unpin(obj);
+       drm_gem_object_unreference(obj);
+       ring->status_page.obj = NULL;
+
+       memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+}
+
+static int init_status_page(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+       int ret;
+
+       obj = i915_gem_alloc_object(dev, 4096);
+       if (obj == NULL) {
+               DRM_ERROR("Failed to allocate status page\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+       obj_priv = to_intel_bo(obj);
+       obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
+
+       ret = i915_gem_object_pin(obj, 4096);
+       if (ret != 0) {
+               goto err_unref;
+       }
+
+       ring->status_page.gfx_addr = obj_priv->gtt_offset;
+       ring->status_page.page_addr = kmap(obj_priv->pages[0]);
+       if (ring->status_page.page_addr == NULL) {
+               memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+               goto err_unpin;
+       }
+       ring->status_page.obj = obj;
+       memset(ring->status_page.page_addr, 0, PAGE_SIZE);
+
+       ring->setup_status_page(dev, ring);
+       DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
+                       ring->name, ring->status_page.gfx_addr);
+
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+err:
+       return ret;
+}
+
+
+int intel_init_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       int ret;
+       struct drm_i915_gem_object *obj_priv;
+       struct drm_gem_object *obj;
+       ring->dev = dev;
+
+       if (I915_NEED_GFX_HWS(dev)) {
+               ret = init_status_page(dev, ring);
+               if (ret)
+                       return ret;
+       }
+
+       obj = i915_gem_alloc_object(dev, ring->size);
+       if (obj == NULL) {
+               DRM_ERROR("Failed to allocate ringbuffer\n");
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       ring->gem_object = obj;
+
+       ret = i915_gem_object_pin(obj, ring->alignment);
+       if (ret != 0) {
+               drm_gem_object_unreference(obj);
+               goto cleanup;
+       }
+
+       obj_priv = to_intel_bo(obj);
+       ring->map.size = ring->size;
+       ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
+       ring->map.type = 0;
+       ring->map.flags = 0;
+       ring->map.mtrr = 0;
+
+       drm_core_ioremap_wc(&ring->map, dev);
+       if (ring->map.handle == NULL) {
+               DRM_ERROR("Failed to map ringbuffer.\n");
+               i915_gem_object_unpin(obj);
+               drm_gem_object_unreference(obj);
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       ring->virtual_start = ring->map.handle;
+       ret = ring->init(dev, ring);
+       if (ret != 0) {
+               intel_cleanup_ring_buffer(dev, ring);
+               return ret;
+       }
+
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               i915_kernel_lost_context(dev);
+       else {
+               ring->head = ring->get_head(dev, ring);
+               ring->tail = ring->get_tail(dev, ring);
+               ring->space = ring->head - (ring->tail + 8);
+               if (ring->space < 0)
+                       ring->space += ring->size;
+       }
+       INIT_LIST_HEAD(&ring->active_list);
+       INIT_LIST_HEAD(&ring->request_list);
+       return ret;
+cleanup:
+       cleanup_status_page(dev, ring);
+       return ret;
+}
+
+void intel_cleanup_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       if (ring->gem_object == NULL)
+               return;
+
+       drm_core_ioremapfree(&ring->map, dev);
+
+       i915_gem_object_unpin(ring->gem_object);
+       drm_gem_object_unreference(ring->gem_object);
+       ring->gem_object = NULL;
+       cleanup_status_page(dev, ring);
+}
+
+int intel_wrap_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       unsigned int *virt;
+       int rem;
+       rem = ring->size - ring->tail;
+
+       if (ring->space < rem) {
+               int ret = intel_wait_ring_buffer(dev, ring, rem);
+               if (ret)
+                       return ret;
+       }
+
+       virt = (unsigned int *)(ring->virtual_start + ring->tail);
+       rem /= 4;
+       while (rem--)
+               *virt++ = MI_NOOP;
+
+       ring->tail = 0;
+
+       return 0;
+}
+
+int intel_wait_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring, int n)
+{
+       unsigned long end;
+
+       trace_i915_ring_wait_begin (dev);
+       end = jiffies + 3 * HZ;
+       do {
+               ring->head = ring->get_head(dev, ring);
+               ring->space = ring->head - (ring->tail + 8);
+               if (ring->space < 0)
+                       ring->space += ring->size;
+               if (ring->space >= n) {
+                       trace_i915_ring_wait_end (dev);
+                       return 0;
+               }
+
+               if (dev->primary->master) {
+                       struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+                       if (master_priv->sarea_priv)
+                               master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+               }
+
+               yield();
+       } while (!time_after(jiffies, end));
+       trace_i915_ring_wait_end (dev);
+       return -EBUSY;
+}
+
+void intel_ring_begin(struct drm_device *dev,
+               struct intel_ring_buffer *ring, int n)
+{
+       if (unlikely(ring->tail + n > ring->size))
+               intel_wrap_ring_buffer(dev, ring);
+       if (unlikely(ring->space < n))
+               intel_wait_ring_buffer(dev, ring, n);
+}
+
+void intel_ring_emit(struct drm_device *dev,
+               struct intel_ring_buffer *ring, unsigned int data)
+{
+       unsigned int *virt = ring->virtual_start + ring->tail;
+       *virt = data;
+       ring->tail += 4;
+       ring->tail &= ring->size - 1;
+       ring->space -= 4;
+}
+
+void intel_ring_advance(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       ring->advance_ring(dev, ring);
+}
+
+void intel_fill_struct(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               void *data,
+               unsigned int len)
+{
+       unsigned int *virt = ring->virtual_start + ring->tail;
+       BUG_ON((len&~(4-1)) != 0);
+       intel_ring_begin(dev, ring, len);
+       memcpy(virt, data, len);
+       ring->tail += len;
+       ring->tail &= ring->size - 1;
+       ring->space -= len;
+       intel_ring_advance(dev, ring);
+}
+
+u32 intel_ring_get_seqno(struct drm_device *dev,
+               struct intel_ring_buffer *ring)
+{
+       u32 seqno;
+       seqno = ring->next_seqno;
+
+       /* reserve 0 for non-seqno */
+       if (++ring->next_seqno == 0)
+               ring->next_seqno = 1;
+       return seqno;
+}
+
+struct intel_ring_buffer render_ring = {
+       .name                   = "render ring",
+       .regs                   = {
+               .ctl = PRB0_CTL,
+               .head = PRB0_HEAD,
+               .tail = PRB0_TAIL,
+               .start = PRB0_START
+       },
+       .ring_flag              = I915_EXEC_RENDER,
+       .size                   = 32 * PAGE_SIZE,
+       .alignment              = PAGE_SIZE,
+       .virtual_start          = NULL,
+       .dev                    = NULL,
+       .gem_object             = NULL,
+       .head                   = 0,
+       .tail                   = 0,
+       .space                  = 0,
+       .next_seqno             = 1,
+       .user_irq_refcount      = 0,
+       .irq_gem_seqno          = 0,
+       .waiting_gem_seqno      = 0,
+       .setup_status_page      = render_setup_status_page,
+       .init                   = init_render_ring,
+       .get_head               = render_ring_get_head,
+       .get_tail               = render_ring_get_tail,
+       .get_active_head        = render_ring_get_active_head,
+       .advance_ring           = render_ring_advance_ring,
+       .flush                  = render_ring_flush,
+       .add_request            = render_ring_add_request,
+       .get_gem_seqno          = render_ring_get_gem_seqno,
+       .user_irq_get           = render_ring_get_user_irq,
+       .user_irq_put           = render_ring_put_user_irq,
+       .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer,
+       .status_page            = {NULL, 0, NULL},
+       .map                    = {0,}
+};
+
+/* ring buffer for bit-stream decoder */
+
+struct intel_ring_buffer bsd_ring = {
+       .name                   = "bsd ring",
+       .regs                   = {
+               .ctl = BSD_RING_CTL,
+               .head = BSD_RING_HEAD,
+               .tail = BSD_RING_TAIL,
+               .start = BSD_RING_START
+       },
+       .ring_flag              = I915_EXEC_BSD,
+       .size                   = 32 * PAGE_SIZE,
+       .alignment              = PAGE_SIZE,
+       .virtual_start          = NULL,
+       .dev                    = NULL,
+       .gem_object             = NULL,
+       .head                   = 0,
+       .tail                   = 0,
+       .space                  = 0,
+       .next_seqno             = 1,
+       .user_irq_refcount      = 0,
+       .irq_gem_seqno          = 0,
+       .waiting_gem_seqno      = 0,
+       .setup_status_page      = bsd_setup_status_page,
+       .init                   = init_bsd_ring,
+       .get_head               = bsd_ring_get_head,
+       .get_tail               = bsd_ring_get_tail,
+       .get_active_head        = bsd_ring_get_active_head,
+       .advance_ring           = bsd_ring_advance_ring,
+       .flush                  = bsd_ring_flush,
+       .add_request            = bsd_ring_add_request,
+       .get_gem_seqno          = bsd_ring_get_gem_seqno,
+       .user_irq_get           = bsd_ring_get_user_irq,
+       .user_irq_put           = bsd_ring_put_user_irq,
+       .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer,
+       .status_page            = {NULL, 0, NULL},
+       .map                    = {0,}
+};
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
new file mode 100644 (file)
index 0000000..d5568d3
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef _INTEL_RINGBUFFER_H_
+#define _INTEL_RINGBUFFER_H_
+
+struct  intel_hw_status_page {
+       void            *page_addr;
+       unsigned int    gfx_addr;
+       struct          drm_gem_object *obj;
+};
+
+struct drm_i915_gem_execbuffer2;
+struct  intel_ring_buffer {
+       const char      *name;
+       struct          ring_regs {
+                       u32 ctl;
+                       u32 head;
+                       u32 tail;
+                       u32 start;
+       } regs;
+       unsigned int    ring_flag;
+       unsigned long   size;
+       unsigned int    alignment;
+       void            *virtual_start;
+       struct          drm_device *dev;
+       struct          drm_gem_object *gem_object;
+
+       unsigned int    head;
+       unsigned int    tail;
+       unsigned int    space;
+       u32             next_seqno;
+       struct intel_hw_status_page status_page;
+
+       u32             irq_gem_seqno;          /* last seq seem at irq time */
+       u32             waiting_gem_seqno;
+       int             user_irq_refcount;
+       void            (*user_irq_get)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       void            (*user_irq_put)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       void            (*setup_status_page)(struct drm_device *dev,
+                       struct  intel_ring_buffer *ring);
+
+       int             (*init)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+
+       unsigned int    (*get_head)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       unsigned int    (*get_tail)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       unsigned int    (*get_active_head)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       void            (*advance_ring)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       void            (*flush)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring,
+                       u32     invalidate_domains,
+                       u32     flush_domains);
+       u32             (*add_request)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring,
+                       struct drm_file *file_priv,
+                       u32 flush_domains);
+       u32             (*get_gem_seqno)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring);
+       int             (*dispatch_gem_execbuffer)(struct drm_device *dev,
+                       struct intel_ring_buffer *ring,
+                       struct drm_i915_gem_execbuffer2 *exec,
+                       struct drm_clip_rect *cliprects,
+                       uint64_t exec_offset);
+
+       /**
+        * List of objects currently involved in rendering from the
+        * ringbuffer.
+        *
+        * Includes buffers having the contents of their GPU caches
+        * flushed, not necessarily primitives.  last_rendering_seqno
+        * represents when the rendering involved will be completed.
+        *
+        * A reference is held on the buffer while on this list.
+        */
+       struct list_head active_list;
+
+       /**
+        * List of breadcrumbs associated with GPU requests currently
+        * outstanding.
+        */
+       struct list_head request_list;
+
+       wait_queue_head_t irq_queue;
+       drm_local_map_t map;
+};
+
+static inline u32
+intel_read_status_page(struct intel_ring_buffer *ring,
+               int reg)
+{
+       u32 *regs = ring->status_page.page_addr;
+       return regs[reg];
+}
+
+int intel_init_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
+void intel_cleanup_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
+int intel_wait_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring, int n);
+int intel_wrap_ring_buffer(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
+void intel_ring_begin(struct drm_device *dev,
+               struct intel_ring_buffer *ring, int n);
+void intel_ring_emit(struct drm_device *dev,
+               struct intel_ring_buffer *ring, u32 data);
+void intel_fill_struct(struct drm_device *dev,
+               struct intel_ring_buffer *ring,
+               void *data,
+               unsigned int len);
+void intel_ring_advance(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
+
+u32 intel_ring_get_seqno(struct drm_device *dev,
+               struct intel_ring_buffer *ring);
+
+extern struct intel_ring_buffer render_ring;
+extern struct intel_ring_buffer bsd_ring;
+
+#endif /* _INTEL_RINGBUFFER_H_ */
index aba72c489a2f07941fc69d88516fb2a52f086363..76993ac16cc1b1b84ca4c4ff102458ae47f76c80 100644 (file)
@@ -1479,7 +1479,7 @@ intel_find_analog_connector(struct drm_device *dev)
                intel_encoder = enc_to_intel_encoder(encoder);
                if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
                        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-                               if (connector && encoder == intel_attached_encoder(connector))
+                               if (encoder == intel_attached_encoder(connector))
                                        return connector;
                        }
                }
index e13f6af0037ac4dc805a821d785bf5ef541d9c07..d4bcca8a5133b2a4565b8f7d794b4d558da5557e 100644 (file)
@@ -34,7 +34,7 @@
 static struct nouveau_dsm_priv {
        bool dsm_detected;
        acpi_handle dhandle;
-       acpi_handle dsm_handle;
+       acpi_handle rom_handle;
 } nouveau_dsm_priv;
 
 static const char nouveau_dsm_muid[] = {
@@ -107,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
 static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
 {
        if (id == VGA_SWITCHEROO_IGD)
-               return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA);
+               return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
        else
-               return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED);
+               return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED);
 }
 
 static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
@@ -118,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
        if (id == VGA_SWITCHEROO_IGD)
                return 0;
 
-       return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state);
+       return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
 }
 
 static int nouveau_dsm_init(void)
@@ -151,18 +151,18 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev)
        dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
        if (!dhandle)
                return false;
+
        status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle);
        if (ACPI_FAILURE(status)) {
                return false;
        }
 
-       ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED,
-                        NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
+       ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
+                         NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
        if (ret < 0)
                return false;
 
        nouveau_dsm_priv.dhandle = dhandle;
-       nouveau_dsm_priv.dsm_handle = nvidia_handle;
        return true;
 }
 
@@ -173,6 +173,7 @@ static bool nouveau_dsm_detect(void)
        struct pci_dev *pdev = NULL;
        int has_dsm = 0;
        int vga_count = 0;
+
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
                vga_count++;
 
@@ -180,7 +181,7 @@ static bool nouveau_dsm_detect(void)
        }
 
        if (vga_count == 2 && has_dsm) {
-               acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer);
+               acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
                printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
                       acpi_method_name);
                nouveau_dsm_priv.dsm_detected = true;
@@ -204,3 +205,57 @@ void nouveau_unregister_dsm_handler(void)
 {
        vga_switcheroo_unregister_handler();
 }
+
+/* retrieve the ROM in 4k blocks */
+static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
+                           int offset, int len)
+{
+       acpi_status status;
+       union acpi_object rom_arg_elements[2], *obj;
+       struct acpi_object_list rom_arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+       rom_arg.count = 2;
+       rom_arg.pointer = &rom_arg_elements[0];
+
+       rom_arg_elements[0].type = ACPI_TYPE_INTEGER;
+       rom_arg_elements[0].integer.value = offset;
+
+       rom_arg_elements[1].type = ACPI_TYPE_INTEGER;
+       rom_arg_elements[1].integer.value = len;
+
+       status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer);
+       if (ACPI_FAILURE(status)) {
+               printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status));
+               return -ENODEV;
+       }
+       obj = (union acpi_object *)buffer.pointer;
+       memcpy(bios+offset, obj->buffer.pointer, len);
+       kfree(buffer.pointer);
+       return len;
+}
+
+bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
+{
+       acpi_status status;
+       acpi_handle dhandle, rom_handle;
+
+       if (!nouveau_dsm_priv.dsm_detected)
+               return false;
+
+       dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+       if (!dhandle)
+               return false;
+
+       status = acpi_get_handle(dhandle, "_ROM", &rom_handle);
+       if (ACPI_FAILURE(status))
+               return false;
+
+       nouveau_dsm_priv.rom_handle = rom_handle;
+       return true;
+}
+
+int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
+{
+       return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
+}
index e7e69ccce5c9985ba77b7e7790582f984c8efdb9..9ba2deaadcc7d38b833ff63fc99f4b76cc144ac1 100644 (file)
@@ -178,6 +178,25 @@ out:
        pci_disable_rom(dev->pdev);
 }
 
+static void load_vbios_acpi(struct drm_device *dev, uint8_t *data)
+{
+       int i;
+       int ret;
+       int size = 64 * 1024;
+
+       if (!nouveau_acpi_rom_supported(dev->pdev))
+               return;
+
+       for (i = 0; i < (size / ROM_BIOS_PAGE); i++) {
+               ret = nouveau_acpi_get_bios_chunk(data,
+                                                 (i * ROM_BIOS_PAGE),
+                                                 ROM_BIOS_PAGE);
+               if (ret <= 0)
+                       break;
+       }
+       return;
+}
+
 struct methods {
        const char desc[8];
        void (*loadbios)(struct drm_device *, uint8_t *);
@@ -191,6 +210,7 @@ static struct methods nv04_methods[] = {
 };
 
 static struct methods nv50_methods[] = {
+       { "ACPI", load_vbios_acpi, true },
        { "PRAMIN", load_vbios_pramin, true },
        { "PROM", load_vbios_prom, false },
        { "PCIROM", load_vbios_pci, true },
@@ -2807,7 +2827,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
 
                BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
 
-               nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
+               BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
+                       offset, gpio->tag, gpio->state_default);
+               if (bios->execute)
+                       nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
 
                /* The NVIDIA binary driver doesn't appear to actually do
                 * any of this, my VBIOS does however.
@@ -5533,12 +5556,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
        entry->bus = (conn >> 16) & 0xf;
        entry->location = (conn >> 20) & 0x3;
        entry->or = (conn >> 24) & 0xf;
-       /*
-        * Normal entries consist of a single bit, but dual link has the
-        * next most significant bit set too
-        */
-       entry->duallink_possible =
-                       ((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
 
        switch (entry->type) {
        case OUTPUT_ANALOG:
@@ -5622,6 +5639,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
                break;
        }
 
+       if (dcb->version < 0x40) {
+               /* Normal entries consist of a single bit, but dual link has
+                * the next most significant bit set too
+                */
+               entry->duallink_possible =
+                       ((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
+       } else {
+               entry->duallink_possible = (entry->sorconf.link == 3);
+       }
+
        /* unsure what DCB version introduces this, 3.0? */
        if (conf & 0x100000)
                entry->i2c_upper_default = true;
@@ -6205,6 +6232,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
                nouveau_i2c_fini(dev, entry);
 }
 
+static bool
+nouveau_bios_posted(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       bool was_locked;
+       unsigned htotal;
+
+       if (dev_priv->chipset >= NV_50) {
+               if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
+                   NVReadVgaCrtc(dev, 0, 0x1a) == 0)
+                       return false;
+               return true;
+       }
+
+       was_locked = NVLockVgaCrtcs(dev, false);
+       htotal  = NVReadVgaCrtc(dev, 0, 0x06);
+       htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
+       htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
+       htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
+       htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
+       NVLockVgaCrtcs(dev, was_locked);
+       return (htotal != 0);
+}
+
 int
 nouveau_bios_init(struct drm_device *dev)
 {
@@ -6239,11 +6290,9 @@ nouveau_bios_init(struct drm_device *dev)
        bios->execute = false;
 
        /* ... unless card isn't POSTed already */
-       if (dev_priv->card_type >= NV_10 &&
-           NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
-           NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
+       if (!nouveau_bios_posted(dev)) {
                NV_INFO(dev, "Adaptor not initialised\n");
-               if (dev_priv->card_type < NV_50) {
+               if (dev_priv->card_type < NV_40) {
                        NV_ERROR(dev, "Unable to POST this chipset\n");
                        return -ENODEV;
                }
index 266b0ff441af37b75ee555360bdcd68ce1cd881f..149ed224c3cb48c86c56e2f4b9bb18a599190d10 100644 (file)
@@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector,
 }
 
 static struct drm_display_mode *
-nouveau_connector_native_mode(struct nouveau_connector *connector)
+nouveau_connector_native_mode(struct drm_connector *connector)
 {
-       struct drm_device *dev = connector->base.dev;
+       struct drm_connector_helper_funcs *helper = connector->helper_private;
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct drm_device *dev = connector->dev;
        struct drm_display_mode *mode, *largest = NULL;
        int high_w = 0, high_h = 0, high_v = 0;
 
-       /* Use preferred mode if there is one.. */
-       list_for_each_entry(mode, &connector->base.probed_modes, head) {
+       list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
+               if (helper->mode_valid(connector, mode) != MODE_OK)
+                       continue;
+
+               /* Use preferred mode if there is one.. */
                if (mode->type & DRM_MODE_TYPE_PREFERRED) {
                        NV_DEBUG_KMS(dev, "native mode from preferred\n");
                        return drm_mode_duplicate(dev, mode);
                }
-       }
 
-       /* Otherwise, take the resolution with the largest width, then height,
-        * then vertical refresh
-        */
-       list_for_each_entry(mode, &connector->base.probed_modes, head) {
+               /* Otherwise, take the resolution with the largest width, then
+                * height, then vertical refresh
+                */
                if (mode->hdisplay < high_w)
                        continue;
 
@@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
         */
        if (!nv_connector->native_mode)
                nv_connector->native_mode =
-                       nouveau_connector_native_mode(nv_connector);
+                       nouveau_connector_native_mode(connector);
        if (ret == 0 && nv_connector->native_mode) {
                struct drm_display_mode *mode;
 
@@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
 
        switch (nv_encoder->dcb->type) {
        case OUTPUT_LVDS:
-               BUG_ON(!nv_connector->native_mode);
-               if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
-                   mode->vdisplay > nv_connector->native_mode->vdisplay)
+               if (nv_connector->native_mode &&
+                   (mode->hdisplay > nv_connector->native_mode->hdisplay ||
+                    mode->vdisplay > nv_connector->native_mode->vdisplay))
                        return MODE_PANEL;
 
                min_clock = 0;
@@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
                break;
        case OUTPUT_TMDS:
                if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
-                   (dev_priv->card_type < NV_50 &&
-                    !nv_encoder->dcb->duallink_possible))
+                   !nv_encoder->dcb->duallink_possible)
                        max_clock = 165000;
                else
                        max_clock = 330000;
@@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
        if (ret == 0)
                goto out;
        nv_connector->detected_encoder = nv_encoder;
-       nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
+       nv_connector->native_mode = nouveau_connector_native_mode(connector);
        list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
                drm_mode_remove(connector, mode);
 
index 49fa7b2d257e8e739391720ffaf66e8eea86ee45..cb1ce2a0916257ecbbe8ea72949baa8a80b32c56 100644 (file)
@@ -40,6 +40,8 @@ struct nouveau_crtc {
        int sharpness;
        int last_dpms;
 
+       int cursor_saved_x, cursor_saved_y;
+
        struct {
                int cpp;
                bool blanked;
index c6079e36669d9f43893db8ad88623dbb70b6147c..273770432298b72ae5687505e156fe5b03e0e4e4 100644 (file)
@@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
                nouveau_bo_unpin(nouveau_fb->nvbo);
        }
 
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+               nouveau_bo_unmap(nv_crtc->cursor.nvbo);
+               nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+       }
+
        NV_INFO(dev, "Evicting buffers...\n");
        ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
 
@@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev)
                nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
        }
 
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+               int ret;
+
+               ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+               if (!ret)
+                       ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+               if (ret)
+                       NV_ERROR(dev, "Could not pin/map cursor.\n");
+       }
+
        if (dev_priv->card_type < NV_50) {
                nv04_display_restore(dev);
                NVLockVgaCrtcs(dev, false);
        } else
                nv50_display_init(dev);
 
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+               nv_crtc->cursor.set_offset(nv_crtc,
+                                       nv_crtc->cursor.nvbo->bo.offset -
+                                       dev_priv->vm_vram_base);
+
+               nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
+                       nv_crtc->cursor_saved_y);
+       }
+
        /* Force CLUT to get re-loaded during modeset */
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
index 5b134438effebcda05e2fbb8c4a74581f6148bcc..c697191064894345efbbf76bf3bfd1fc83188270 100644 (file)
@@ -851,12 +851,17 @@ extern int  nouveau_dma_init(struct nouveau_channel *);
 extern int  nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
 
 /* nouveau_acpi.c */
+#define ROM_BIOS_PAGE 4096
 #if defined(CONFIG_ACPI)
 void nouveau_register_dsm_handler(void);
 void nouveau_unregister_dsm_handler(void);
+int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
+bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
 #else
 static inline void nouveau_register_dsm_handler(void) {}
 static inline void nouveau_unregister_dsm_handler(void) {}
+static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
+static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
 #endif
 
 /* nouveau_backlight.c */
index 775a7017af6437da7c149dfda2a04d172704fdb2..c1fd42b0dad19cb18e34463548c8ff4b60093747 100644 (file)
@@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev)
                dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
                dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
                if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
-                       dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
+                       dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
+                       dev_priv->vram_sys_base <<= 12;
        }
 
        NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
index e632339c323e5bd03efe592f554875117322b7b1..147e59c4015148e4b645648346b2e959370d3dcf 100644 (file)
@@ -376,12 +376,15 @@ out_err:
 static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
                                         enum vga_switcheroo_state state)
 {
+       struct drm_device *dev = pci_get_drvdata(pdev);
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
                nouveau_pci_resume(pdev);
+               drm_kms_helper_poll_enable(dev);
        } else {
                printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
+               drm_kms_helper_poll_disable(dev);
                nouveau_pci_suspend(pdev, pmm);
        }
 }
@@ -913,6 +916,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
        case NOUVEAU_GETPARAM_VM_VRAM_BASE:
                getparam->value = dev_priv->vm_vram_base;
                break;
+       case NOUVEAU_GETPARAM_PTIMER_TIME:
+               getparam->value = dev_priv->engine.timer.read(dev);
+               break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
                 * address is the same. User is supposed to know the card
index 89a91b9d8b258d54e24c2b3725727824c7a18df0..aaf3de3bc816c5e0d9e1d34fcd4847fa2fa3e5db 100644 (file)
@@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
 static void
 nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
 {
+       nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
        NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
                      NV_PRAMDAC_CU_START_POS,
                      XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
index 753e723adb3afb9e0dc733d4ef416a4468b3aacc..03ad7ab14f0960e1729674cd637a15ff325ae169 100644 (file)
@@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
 {
        struct drm_device *dev = nv_crtc->base.dev;
 
+       nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
        nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
                ((y & 0xFFFF) << 16) | (x & 0xFFFF));
        /* Needed to make the cursor move. */
index b11eaf9c5c7cd0575eec63e20d7217b7c8fd49c1..812778db76ac185b5943a8257ae401ff82f27202 100644 (file)
@@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
 int
 nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_encoder *nv_encoder = NULL;
        struct drm_encoder *encoder;
        bool dum;
@@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
                int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
                uint32_t tmp;
 
-               if (dev_priv->chipset < 0x90 ||
-                   dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
-                       tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
-               else
-                       tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+               tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
 
                switch ((tmp & 0x00000f00) >> 8) {
                case 8:
index 3c91312dea9a00d8aa93b097d2d5d476487fb2d8..84b1f2729d430deaddcf6e4241a1886339c0123b 100644 (file)
@@ -33,6 +33,9 @@ $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
 $(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable
        $(call if_changed,mkregtable)
 
+$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable
+       $(call if_changed,mkregtable)
+
 $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
 
 $(obj)/r200.o: $(obj)/r200_reg_safe.h
@@ -47,6 +50,8 @@ $(obj)/rs600.o: $(obj)/rs600_reg_safe.h
 
 $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
 
+$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h
+
 radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
        radeon_irq.o r300_cmdbuf.o r600_cp.o
 # add KMS driver
@@ -60,7 +65,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
        rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
        r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
        r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
-       evergreen.o
+       evergreen.o evergreen_cs.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
index 8c8e4d3cbaa377773d9fc39b5035a928f93ddf55..0440c0939bdd00e4efc71f09b0b02de16b3788da 100644 (file)
@@ -41,7 +41,12 @@ void evergreen_fini(struct radeon_device *rdev);
 
 void evergreen_pm_misc(struct radeon_device *rdev)
 {
+       int requested_index = rdev->pm.requested_power_state_index;
+       struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
+       struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
 
+       if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
+               radeon_atom_set_voltage(rdev, voltage->voltage);
 }
 
 void evergreen_pm_prepare(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
new file mode 100644 (file)
index 0000000..64516b9
--- /dev/null
@@ -0,0 +1,1356 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#include "drmP.h"
+#include "radeon.h"
+#include "evergreend.h"
+#include "evergreen_reg_safe.h"
+
+static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
+                                         struct radeon_cs_reloc **cs_reloc);
+
+struct evergreen_cs_track {
+       u32                     group_size;
+       u32                     nbanks;
+       u32                     npipes;
+       /* value we track */
+       u32                     nsamples;
+       u32                     cb_color_base_last[12];
+       struct radeon_bo        *cb_color_bo[12];
+       u32                     cb_color_bo_offset[12];
+       struct radeon_bo        *cb_color_fmask_bo[8];
+       struct radeon_bo        *cb_color_cmask_bo[8];
+       u32                     cb_color_info[12];
+       u32                     cb_color_view[12];
+       u32                     cb_color_pitch_idx[12];
+       u32                     cb_color_slice_idx[12];
+       u32                     cb_color_dim_idx[12];
+       u32                     cb_color_dim[12];
+       u32                     cb_color_pitch[12];
+       u32                     cb_color_slice[12];
+       u32                     cb_color_cmask_slice[8];
+       u32                     cb_color_fmask_slice[8];
+       u32                     cb_target_mask;
+       u32                     cb_shader_mask;
+       u32                     vgt_strmout_config;
+       u32                     vgt_strmout_buffer_config;
+       u32                     db_depth_control;
+       u32                     db_depth_view;
+       u32                     db_depth_size;
+       u32                     db_depth_size_idx;
+       u32                     db_z_info;
+       u32                     db_z_idx;
+       u32                     db_z_read_offset;
+       u32                     db_z_write_offset;
+       struct radeon_bo        *db_z_read_bo;
+       struct radeon_bo        *db_z_write_bo;
+       u32                     db_s_info;
+       u32                     db_s_idx;
+       u32                     db_s_read_offset;
+       u32                     db_s_write_offset;
+       struct radeon_bo        *db_s_read_bo;
+       struct radeon_bo        *db_s_write_bo;
+};
+
+static void evergreen_cs_track_init(struct evergreen_cs_track *track)
+{
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               track->cb_color_fmask_bo[i] = NULL;
+               track->cb_color_cmask_bo[i] = NULL;
+               track->cb_color_cmask_slice[i] = 0;
+               track->cb_color_fmask_slice[i] = 0;
+       }
+
+       for (i = 0; i < 12; i++) {
+               track->cb_color_base_last[i] = 0;
+               track->cb_color_bo[i] = NULL;
+               track->cb_color_bo_offset[i] = 0xFFFFFFFF;
+               track->cb_color_info[i] = 0;
+               track->cb_color_view[i] = 0;
+               track->cb_color_pitch_idx[i] = 0;
+               track->cb_color_slice_idx[i] = 0;
+               track->cb_color_dim[i] = 0;
+               track->cb_color_pitch[i] = 0;
+               track->cb_color_slice[i] = 0;
+               track->cb_color_dim[i] = 0;
+       }
+       track->cb_target_mask = 0xFFFFFFFF;
+       track->cb_shader_mask = 0xFFFFFFFF;
+
+       track->db_depth_view = 0xFFFFC000;
+       track->db_depth_size = 0xFFFFFFFF;
+       track->db_depth_size_idx = 0;
+       track->db_depth_control = 0xFFFFFFFF;
+       track->db_z_info = 0xFFFFFFFF;
+       track->db_z_idx = 0xFFFFFFFF;
+       track->db_z_read_offset = 0xFFFFFFFF;
+       track->db_z_write_offset = 0xFFFFFFFF;
+       track->db_z_read_bo = NULL;
+       track->db_z_write_bo = NULL;
+       track->db_s_info = 0xFFFFFFFF;
+       track->db_s_idx = 0xFFFFFFFF;
+       track->db_s_read_offset = 0xFFFFFFFF;
+       track->db_s_write_offset = 0xFFFFFFFF;
+       track->db_s_read_bo = NULL;
+       track->db_s_write_bo = NULL;
+}
+
+static inline int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
+{
+       /* XXX fill in */
+       return 0;
+}
+
+static int evergreen_cs_track_check(struct radeon_cs_parser *p)
+{
+       struct evergreen_cs_track *track = p->track;
+
+       /* we don't support stream out buffer yet */
+       if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) {
+               dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
+               return -EINVAL;
+       }
+
+       /* XXX fill in */
+       return 0;
+}
+
+/**
+ * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet
+ * @parser:    parser structure holding parsing context.
+ * @pkt:       where to store packet informations
+ *
+ * Assume that chunk_ib_index is properly set. Will return -EINVAL
+ * if packet is bigger than remaining ib size. or if packets is unknown.
+ **/
+int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
+                             struct radeon_cs_packet *pkt,
+                             unsigned idx)
+{
+       struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
+       uint32_t header;
+
+       if (idx >= ib_chunk->length_dw) {
+               DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
+                         idx, ib_chunk->length_dw);
+               return -EINVAL;
+       }
+       header = radeon_get_ib_value(p, idx);
+       pkt->idx = idx;
+       pkt->type = CP_PACKET_GET_TYPE(header);
+       pkt->count = CP_PACKET_GET_COUNT(header);
+       pkt->one_reg_wr = 0;
+       switch (pkt->type) {
+       case PACKET_TYPE0:
+               pkt->reg = CP_PACKET0_GET_REG(header);
+               break;
+       case PACKET_TYPE3:
+               pkt->opcode = CP_PACKET3_GET_OPCODE(header);
+               break;
+       case PACKET_TYPE2:
+               pkt->count = -1;
+               break;
+       default:
+               DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
+               return -EINVAL;
+       }
+       if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
+               DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
+                         pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/**
+ * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3
+ * @parser:            parser structure holding parsing context.
+ * @data:              pointer to relocation data
+ * @offset_start:      starting offset
+ * @offset_mask:       offset mask (to align start offset on)
+ * @reloc:             reloc informations
+ *
+ * Check next packet is relocation packet3, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
+                                         struct radeon_cs_reloc **cs_reloc)
+{
+       struct radeon_cs_chunk *relocs_chunk;
+       struct radeon_cs_packet p3reloc;
+       unsigned idx;
+       int r;
+
+       if (p->chunk_relocs_idx == -1) {
+               DRM_ERROR("No relocation chunk !\n");
+               return -EINVAL;
+       }
+       *cs_reloc = NULL;
+       relocs_chunk = &p->chunks[p->chunk_relocs_idx];
+       r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
+       if (r) {
+               return r;
+       }
+       p->idx += p3reloc.count + 2;
+       if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+               DRM_ERROR("No packet3 for relocation for packet at %d.\n",
+                         p3reloc.idx);
+               return -EINVAL;
+       }
+       idx = radeon_get_ib_value(p, p3reloc.idx + 1);
+       if (idx >= relocs_chunk->length_dw) {
+               DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
+                         idx, relocs_chunk->length_dw);
+               return -EINVAL;
+       }
+       /* FIXME: we assume reloc size is 4 dwords */
+       *cs_reloc = p->relocs_ptr[(idx / 4)];
+       return 0;
+}
+
+/**
+ * evergreen_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
+ * @parser:            parser structure holding parsing context.
+ *
+ * Check next packet is relocation packet3, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+static inline int evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
+{
+       struct radeon_cs_packet p3reloc;
+       int r;
+
+       r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
+       if (r) {
+               return 0;
+       }
+       if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+               return 0;
+       }
+       return 1;
+}
+
+/**
+ * evergreen_cs_packet_next_vline() - parse userspace VLINE packet
+ * @parser:            parser structure holding parsing context.
+ *
+ * Userspace sends a special sequence for VLINE waits.
+ * PACKET0 - VLINE_START_END + value
+ * PACKET3 - WAIT_REG_MEM poll vline status reg
+ * RELOC (P3) - crtc_id in reloc.
+ *
+ * This function parses this and relocates the VLINE START END
+ * and WAIT_REG_MEM packets to the correct crtc.
+ * It also detects a switched off crtc and nulls out the
+ * wait in that case.
+ */
+static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p)
+{
+       struct drm_mode_object *obj;
+       struct drm_crtc *crtc;
+       struct radeon_crtc *radeon_crtc;
+       struct radeon_cs_packet p3reloc, wait_reg_mem;
+       int crtc_id;
+       int r;
+       uint32_t header, h_idx, reg, wait_reg_mem_info;
+       volatile uint32_t *ib;
+
+       ib = p->ib->ptr;
+
+       /* parse the WAIT_REG_MEM */
+       r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx);
+       if (r)
+               return r;
+
+       /* check its a WAIT_REG_MEM */
+       if (wait_reg_mem.type != PACKET_TYPE3 ||
+           wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
+               DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
+               r = -EINVAL;
+               return r;
+       }
+
+       wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
+       /* bit 4 is reg (0) or mem (1) */
+       if (wait_reg_mem_info & 0x10) {
+               DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
+               r = -EINVAL;
+               return r;
+       }
+       /* waiting for value to be equal */
+       if ((wait_reg_mem_info & 0x7) != 0x3) {
+               DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
+               r = -EINVAL;
+               return r;
+       }
+       if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) {
+               DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
+               r = -EINVAL;
+               return r;
+       }
+
+       if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) {
+               DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
+               r = -EINVAL;
+               return r;
+       }
+
+       /* jump over the NOP */
+       r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
+       if (r)
+               return r;
+
+       h_idx = p->idx - 2;
+       p->idx += wait_reg_mem.count + 2;
+       p->idx += p3reloc.count + 2;
+
+       header = radeon_get_ib_value(p, h_idx);
+       crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
+       reg = CP_PACKET0_GET_REG(header);
+       mutex_lock(&p->rdev->ddev->mode_config.mutex);
+       obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
+       if (!obj) {
+               DRM_ERROR("cannot find crtc %d\n", crtc_id);
+               r = -EINVAL;
+               goto out;
+       }
+       crtc = obj_to_crtc(obj);
+       radeon_crtc = to_radeon_crtc(crtc);
+       crtc_id = radeon_crtc->crtc_id;
+
+       if (!crtc->enabled) {
+               /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
+               ib[h_idx + 2] = PACKET2(0);
+               ib[h_idx + 3] = PACKET2(0);
+               ib[h_idx + 4] = PACKET2(0);
+               ib[h_idx + 5] = PACKET2(0);
+               ib[h_idx + 6] = PACKET2(0);
+               ib[h_idx + 7] = PACKET2(0);
+               ib[h_idx + 8] = PACKET2(0);
+       } else {
+               switch (reg) {
+               case EVERGREEN_VLINE_START_END:
+                       header &= ~R600_CP_PACKET0_REG_MASK;
+                       header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2;
+                       ib[h_idx] = header;
+                       ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2;
+                       break;
+               default:
+                       DRM_ERROR("unknown crtc reloc\n");
+                       r = -EINVAL;
+                       goto out;
+               }
+       }
+out:
+       mutex_unlock(&p->rdev->ddev->mode_config.mutex);
+       return r;
+}
+
+static int evergreen_packet0_check(struct radeon_cs_parser *p,
+                                  struct radeon_cs_packet *pkt,
+                                  unsigned idx, unsigned reg)
+{
+       int r;
+
+       switch (reg) {
+       case EVERGREEN_VLINE_START_END:
+               r = evergreen_cs_packet_parse_vline(p);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                       idx, reg);
+                       return r;
+               }
+               break;
+       default:
+               printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+                      reg, idx);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p,
+                                     struct radeon_cs_packet *pkt)
+{
+       unsigned reg, i;
+       unsigned idx;
+       int r;
+
+       idx = pkt->idx + 1;
+       reg = pkt->reg;
+       for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
+               r = evergreen_packet0_check(p, pkt, idx, reg);
+               if (r) {
+                       return r;
+               }
+       }
+       return 0;
+}
+
+/**
+ * evergreen_cs_check_reg() - check if register is authorized or not
+ * @parser: parser structure holding parsing context
+ * @reg: register we are testing
+ * @idx: index into the cs buffer
+ *
+ * This function will test against evergreen_reg_safe_bm and return 0
+ * if register is safe. If register is not flag as safe this function
+ * will test it against a list of register needind special handling.
+ */
+static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
+{
+       struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
+       struct radeon_cs_reloc *reloc;
+       u32 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
+       u32 m, i, tmp, *ib;
+       int r;
+
+       i = (reg >> 7);
+       if (i > last_reg) {
+               dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+               return -EINVAL;
+       }
+       m = 1 << ((reg >> 2) & 31);
+       if (!(evergreen_reg_safe_bm[i] & m))
+               return 0;
+       ib = p->ib->ptr;
+       switch (reg) {
+       /* force following reg to 0 in an attemp to disable out buffer
+        * which will need us to better understand how it works to perform
+        * security check on it (Jerome)
+        */
+       case SQ_ESGS_RING_SIZE:
+       case SQ_GSVS_RING_SIZE:
+       case SQ_ESTMP_RING_SIZE:
+       case SQ_GSTMP_RING_SIZE:
+       case SQ_HSTMP_RING_SIZE:
+       case SQ_LSTMP_RING_SIZE:
+       case SQ_PSTMP_RING_SIZE:
+       case SQ_VSTMP_RING_SIZE:
+       case SQ_ESGS_RING_ITEMSIZE:
+       case SQ_ESTMP_RING_ITEMSIZE:
+       case SQ_GSTMP_RING_ITEMSIZE:
+       case SQ_GSVS_RING_ITEMSIZE:
+       case SQ_GS_VERT_ITEMSIZE:
+       case SQ_GS_VERT_ITEMSIZE_1:
+       case SQ_GS_VERT_ITEMSIZE_2:
+       case SQ_GS_VERT_ITEMSIZE_3:
+       case SQ_GSVS_RING_OFFSET_1:
+       case SQ_GSVS_RING_OFFSET_2:
+       case SQ_GSVS_RING_OFFSET_3:
+       case SQ_HSTMP_RING_ITEMSIZE:
+       case SQ_LSTMP_RING_ITEMSIZE:
+       case SQ_PSTMP_RING_ITEMSIZE:
+       case SQ_VSTMP_RING_ITEMSIZE:
+       case VGT_TF_RING_SIZE:
+               /* get value to populate the IB don't remove */
+               tmp =radeon_get_ib_value(p, idx);
+               ib[idx] = 0;
+               break;
+       case DB_DEPTH_CONTROL:
+               track->db_depth_control = radeon_get_ib_value(p, idx);
+               break;
+       case DB_Z_INFO:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->db_z_info = radeon_get_ib_value(p, idx);
+               ib[idx] &= ~Z_ARRAY_MODE(0xf);
+               track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                       ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+               } else {
+                       ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               }
+               break;
+       case DB_STENCIL_INFO:
+               track->db_s_info = radeon_get_ib_value(p, idx);
+               break;
+       case DB_DEPTH_VIEW:
+               track->db_depth_view = radeon_get_ib_value(p, idx);
+               break;
+       case DB_DEPTH_SIZE:
+               track->db_depth_size = radeon_get_ib_value(p, idx);
+               track->db_depth_size_idx = idx;
+               break;
+       case DB_Z_READ_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->db_z_read_offset = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->db_z_read_bo = reloc->robj;
+               break;
+       case DB_Z_WRITE_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->db_z_write_offset = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->db_z_write_bo = reloc->robj;
+               break;
+       case DB_STENCIL_READ_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->db_s_read_offset = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->db_s_read_bo = reloc->robj;
+               break;
+       case DB_STENCIL_WRITE_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->db_s_write_offset = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->db_s_write_bo = reloc->robj;
+               break;
+       case VGT_STRMOUT_CONFIG:
+               track->vgt_strmout_config = radeon_get_ib_value(p, idx);
+               break;
+       case VGT_STRMOUT_BUFFER_CONFIG:
+               track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
+               break;
+       case CB_TARGET_MASK:
+               track->cb_target_mask = radeon_get_ib_value(p, idx);
+               break;
+       case CB_SHADER_MASK:
+               track->cb_shader_mask = radeon_get_ib_value(p, idx);
+               break;
+       case PA_SC_AA_CONFIG:
+               tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK;
+               track->nsamples = 1 << tmp;
+               break;
+       case CB_COLOR0_VIEW:
+       case CB_COLOR1_VIEW:
+       case CB_COLOR2_VIEW:
+       case CB_COLOR3_VIEW:
+       case CB_COLOR4_VIEW:
+       case CB_COLOR5_VIEW:
+       case CB_COLOR6_VIEW:
+       case CB_COLOR7_VIEW:
+               tmp = (reg - CB_COLOR0_VIEW) / 0x3c;
+               track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
+               break;
+       case CB_COLOR8_VIEW:
+       case CB_COLOR9_VIEW:
+       case CB_COLOR10_VIEW:
+       case CB_COLOR11_VIEW:
+               tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8;
+               track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
+               break;
+       case CB_COLOR0_INFO:
+       case CB_COLOR1_INFO:
+       case CB_COLOR2_INFO:
+       case CB_COLOR3_INFO:
+       case CB_COLOR4_INFO:
+       case CB_COLOR5_INFO:
+       case CB_COLOR6_INFO:
+       case CB_COLOR7_INFO:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               tmp = (reg - CB_COLOR0_INFO) / 0x3c;
+               track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               }
+               break;
+       case CB_COLOR8_INFO:
+       case CB_COLOR9_INFO:
+       case CB_COLOR10_INFO:
+       case CB_COLOR11_INFO:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
+               track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               }
+               break;
+       case CB_COLOR0_PITCH:
+       case CB_COLOR1_PITCH:
+       case CB_COLOR2_PITCH:
+       case CB_COLOR3_PITCH:
+       case CB_COLOR4_PITCH:
+       case CB_COLOR5_PITCH:
+       case CB_COLOR6_PITCH:
+       case CB_COLOR7_PITCH:
+               tmp = (reg - CB_COLOR0_PITCH) / 0x3c;
+               track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_pitch_idx[tmp] = idx;
+               break;
+       case CB_COLOR8_PITCH:
+       case CB_COLOR9_PITCH:
+       case CB_COLOR10_PITCH:
+       case CB_COLOR11_PITCH:
+               tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8;
+               track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_pitch_idx[tmp] = idx;
+               break;
+       case CB_COLOR0_SLICE:
+       case CB_COLOR1_SLICE:
+       case CB_COLOR2_SLICE:
+       case CB_COLOR3_SLICE:
+       case CB_COLOR4_SLICE:
+       case CB_COLOR5_SLICE:
+       case CB_COLOR6_SLICE:
+       case CB_COLOR7_SLICE:
+               tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
+               track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_slice_idx[tmp] = idx;
+               break;
+       case CB_COLOR8_SLICE:
+       case CB_COLOR9_SLICE:
+       case CB_COLOR10_SLICE:
+       case CB_COLOR11_SLICE:
+               tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
+               track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_slice_idx[tmp] = idx;
+               break;
+       case CB_COLOR0_ATTRIB:
+       case CB_COLOR1_ATTRIB:
+       case CB_COLOR2_ATTRIB:
+       case CB_COLOR3_ATTRIB:
+       case CB_COLOR4_ATTRIB:
+       case CB_COLOR5_ATTRIB:
+       case CB_COLOR6_ATTRIB:
+       case CB_COLOR7_ATTRIB:
+       case CB_COLOR8_ATTRIB:
+       case CB_COLOR9_ATTRIB:
+       case CB_COLOR10_ATTRIB:
+       case CB_COLOR11_ATTRIB:
+               break;
+       case CB_COLOR0_DIM:
+       case CB_COLOR1_DIM:
+       case CB_COLOR2_DIM:
+       case CB_COLOR3_DIM:
+       case CB_COLOR4_DIM:
+       case CB_COLOR5_DIM:
+       case CB_COLOR6_DIM:
+       case CB_COLOR7_DIM:
+               tmp = (reg - CB_COLOR0_DIM) / 0x3c;
+               track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_dim_idx[tmp] = idx;
+               break;
+       case CB_COLOR8_DIM:
+       case CB_COLOR9_DIM:
+       case CB_COLOR10_DIM:
+       case CB_COLOR11_DIM:
+               tmp = ((reg - CB_COLOR8_DIM) / 0x1c) + 8;
+               track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
+               track->cb_color_dim_idx[tmp] = idx;
+               break;
+       case CB_COLOR0_FMASK:
+       case CB_COLOR1_FMASK:
+       case CB_COLOR2_FMASK:
+       case CB_COLOR3_FMASK:
+       case CB_COLOR4_FMASK:
+       case CB_COLOR5_FMASK:
+       case CB_COLOR6_FMASK:
+       case CB_COLOR7_FMASK:
+               tmp = (reg - CB_COLOR0_FMASK) / 0x3c;
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->cb_color_fmask_bo[tmp] = reloc->robj;
+               break;
+       case CB_COLOR0_CMASK:
+       case CB_COLOR1_CMASK:
+       case CB_COLOR2_CMASK:
+       case CB_COLOR3_CMASK:
+       case CB_COLOR4_CMASK:
+       case CB_COLOR5_CMASK:
+       case CB_COLOR6_CMASK:
+       case CB_COLOR7_CMASK:
+               tmp = (reg - CB_COLOR0_CMASK) / 0x3c;
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->cb_color_cmask_bo[tmp] = reloc->robj;
+               break;
+       case CB_COLOR0_FMASK_SLICE:
+       case CB_COLOR1_FMASK_SLICE:
+       case CB_COLOR2_FMASK_SLICE:
+       case CB_COLOR3_FMASK_SLICE:
+       case CB_COLOR4_FMASK_SLICE:
+       case CB_COLOR5_FMASK_SLICE:
+       case CB_COLOR6_FMASK_SLICE:
+       case CB_COLOR7_FMASK_SLICE:
+               tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c;
+               track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx);
+               break;
+       case CB_COLOR0_CMASK_SLICE:
+       case CB_COLOR1_CMASK_SLICE:
+       case CB_COLOR2_CMASK_SLICE:
+       case CB_COLOR3_CMASK_SLICE:
+       case CB_COLOR4_CMASK_SLICE:
+       case CB_COLOR5_CMASK_SLICE:
+       case CB_COLOR6_CMASK_SLICE:
+       case CB_COLOR7_CMASK_SLICE:
+               tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c;
+               track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx);
+               break;
+       case CB_COLOR0_BASE:
+       case CB_COLOR1_BASE:
+       case CB_COLOR2_BASE:
+       case CB_COLOR3_BASE:
+       case CB_COLOR4_BASE:
+       case CB_COLOR5_BASE:
+       case CB_COLOR6_BASE:
+       case CB_COLOR7_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               tmp = (reg - CB_COLOR0_BASE) / 0x3c;
+               track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->cb_color_base_last[tmp] = ib[idx];
+               track->cb_color_bo[tmp] = reloc->robj;
+               break;
+       case CB_COLOR8_BASE:
+       case CB_COLOR9_BASE:
+       case CB_COLOR10_BASE:
+       case CB_COLOR11_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8;
+               track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->cb_color_base_last[tmp] = ib[idx];
+               track->cb_color_bo[tmp] = reloc->robj;
+               break;
+       case CB_IMMED0_BASE:
+       case CB_IMMED1_BASE:
+       case CB_IMMED2_BASE:
+       case CB_IMMED3_BASE:
+       case CB_IMMED4_BASE:
+       case CB_IMMED5_BASE:
+       case CB_IMMED6_BASE:
+       case CB_IMMED7_BASE:
+       case CB_IMMED8_BASE:
+       case CB_IMMED9_BASE:
+       case CB_IMMED10_BASE:
+       case CB_IMMED11_BASE:
+       case DB_HTILE_DATA_BASE:
+       case SQ_PGM_START_FS:
+       case SQ_PGM_START_ES:
+       case SQ_PGM_START_VS:
+       case SQ_PGM_START_GS:
+       case SQ_PGM_START_PS:
+       case SQ_PGM_START_HS:
+       case SQ_PGM_START_LS:
+       case GDS_ADDR_BASE:
+       case SQ_CONST_MEM_BASE:
+       case SQ_ALU_CONST_CACHE_GS_0:
+       case SQ_ALU_CONST_CACHE_GS_1:
+       case SQ_ALU_CONST_CACHE_GS_2:
+       case SQ_ALU_CONST_CACHE_GS_3:
+       case SQ_ALU_CONST_CACHE_GS_4:
+       case SQ_ALU_CONST_CACHE_GS_5:
+       case SQ_ALU_CONST_CACHE_GS_6:
+       case SQ_ALU_CONST_CACHE_GS_7:
+       case SQ_ALU_CONST_CACHE_GS_8:
+       case SQ_ALU_CONST_CACHE_GS_9:
+       case SQ_ALU_CONST_CACHE_GS_10:
+       case SQ_ALU_CONST_CACHE_GS_11:
+       case SQ_ALU_CONST_CACHE_GS_12:
+       case SQ_ALU_CONST_CACHE_GS_13:
+       case SQ_ALU_CONST_CACHE_GS_14:
+       case SQ_ALU_CONST_CACHE_GS_15:
+       case SQ_ALU_CONST_CACHE_PS_0:
+       case SQ_ALU_CONST_CACHE_PS_1:
+       case SQ_ALU_CONST_CACHE_PS_2:
+       case SQ_ALU_CONST_CACHE_PS_3:
+       case SQ_ALU_CONST_CACHE_PS_4:
+       case SQ_ALU_CONST_CACHE_PS_5:
+       case SQ_ALU_CONST_CACHE_PS_6:
+       case SQ_ALU_CONST_CACHE_PS_7:
+       case SQ_ALU_CONST_CACHE_PS_8:
+       case SQ_ALU_CONST_CACHE_PS_9:
+       case SQ_ALU_CONST_CACHE_PS_10:
+       case SQ_ALU_CONST_CACHE_PS_11:
+       case SQ_ALU_CONST_CACHE_PS_12:
+       case SQ_ALU_CONST_CACHE_PS_13:
+       case SQ_ALU_CONST_CACHE_PS_14:
+       case SQ_ALU_CONST_CACHE_PS_15:
+       case SQ_ALU_CONST_CACHE_VS_0:
+       case SQ_ALU_CONST_CACHE_VS_1:
+       case SQ_ALU_CONST_CACHE_VS_2:
+       case SQ_ALU_CONST_CACHE_VS_3:
+       case SQ_ALU_CONST_CACHE_VS_4:
+       case SQ_ALU_CONST_CACHE_VS_5:
+       case SQ_ALU_CONST_CACHE_VS_6:
+       case SQ_ALU_CONST_CACHE_VS_7:
+       case SQ_ALU_CONST_CACHE_VS_8:
+       case SQ_ALU_CONST_CACHE_VS_9:
+       case SQ_ALU_CONST_CACHE_VS_10:
+       case SQ_ALU_CONST_CACHE_VS_11:
+       case SQ_ALU_CONST_CACHE_VS_12:
+       case SQ_ALU_CONST_CACHE_VS_13:
+       case SQ_ALU_CONST_CACHE_VS_14:
+       case SQ_ALU_CONST_CACHE_VS_15:
+       case SQ_ALU_CONST_CACHE_HS_0:
+       case SQ_ALU_CONST_CACHE_HS_1:
+       case SQ_ALU_CONST_CACHE_HS_2:
+       case SQ_ALU_CONST_CACHE_HS_3:
+       case SQ_ALU_CONST_CACHE_HS_4:
+       case SQ_ALU_CONST_CACHE_HS_5:
+       case SQ_ALU_CONST_CACHE_HS_6:
+       case SQ_ALU_CONST_CACHE_HS_7:
+       case SQ_ALU_CONST_CACHE_HS_8:
+       case SQ_ALU_CONST_CACHE_HS_9:
+       case SQ_ALU_CONST_CACHE_HS_10:
+       case SQ_ALU_CONST_CACHE_HS_11:
+       case SQ_ALU_CONST_CACHE_HS_12:
+       case SQ_ALU_CONST_CACHE_HS_13:
+       case SQ_ALU_CONST_CACHE_HS_14:
+       case SQ_ALU_CONST_CACHE_HS_15:
+       case SQ_ALU_CONST_CACHE_LS_0:
+       case SQ_ALU_CONST_CACHE_LS_1:
+       case SQ_ALU_CONST_CACHE_LS_2:
+       case SQ_ALU_CONST_CACHE_LS_3:
+       case SQ_ALU_CONST_CACHE_LS_4:
+       case SQ_ALU_CONST_CACHE_LS_5:
+       case SQ_ALU_CONST_CACHE_LS_6:
+       case SQ_ALU_CONST_CACHE_LS_7:
+       case SQ_ALU_CONST_CACHE_LS_8:
+       case SQ_ALU_CONST_CACHE_LS_9:
+       case SQ_ALU_CONST_CACHE_LS_10:
+       case SQ_ALU_CONST_CACHE_LS_11:
+       case SQ_ALU_CONST_CACHE_LS_12:
+       case SQ_ALU_CONST_CACHE_LS_13:
+       case SQ_ALU_CONST_CACHE_LS_14:
+       case SQ_ALU_CONST_CACHE_LS_15:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               break;
+       default:
+               dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/**
+ * evergreen_check_texture_resource() - check if register is authorized or not
+ * @p: parser structure holding parsing context
+ * @idx: index into the cs buffer
+ * @texture: texture's bo structure
+ * @mipmap: mipmap's bo structure
+ *
+ * This function will check that the resource has valid field and that
+ * the texture and mipmap bo object are big enough to cover this resource.
+ */
+static inline int evergreen_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
+                                                  struct radeon_bo *texture,
+                                                  struct radeon_bo *mipmap)
+{
+       /* XXX fill in */
+       return 0;
+}
+
+static int evergreen_packet3_check(struct radeon_cs_parser *p,
+                                  struct radeon_cs_packet *pkt)
+{
+       struct radeon_cs_reloc *reloc;
+       struct evergreen_cs_track *track;
+       volatile u32 *ib;
+       unsigned idx;
+       unsigned i;
+       unsigned start_reg, end_reg, reg;
+       int r;
+       u32 idx_value;
+
+       track = (struct evergreen_cs_track *)p->track;
+       ib = p->ib->ptr;
+       idx = pkt->idx + 1;
+       idx_value = radeon_get_ib_value(p, idx);
+
+       switch (pkt->opcode) {
+       case PACKET3_CONTEXT_CONTROL:
+               if (pkt->count != 1) {
+                       DRM_ERROR("bad CONTEXT_CONTROL\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_INDEX_TYPE:
+       case PACKET3_NUM_INSTANCES:
+       case PACKET3_CLEAR_STATE:
+               if (pkt->count) {
+                       DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_INDEX_BASE:
+               if (pkt->count != 1) {
+                       DRM_ERROR("bad INDEX_BASE\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad INDEX_BASE\n");
+                       return -EINVAL;
+               }
+               ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+               ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX:
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad DRAW_INDEX\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad DRAW_INDEX\n");
+                       return -EINVAL;
+               }
+               ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+               ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_2:
+               if (pkt->count != 4) {
+                       DRM_ERROR("bad DRAW_INDEX_2\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad DRAW_INDEX_2\n");
+                       return -EINVAL;
+               }
+               ib[idx+1] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+               ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_AUTO:
+               if (pkt->count != 1) {
+                       DRM_ERROR("bad DRAW_INDEX_AUTO\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_MULTI_AUTO:
+               if (pkt->count != 2) {
+                       DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_IMMD:
+               if (pkt->count < 2) {
+                       DRM_ERROR("bad DRAW_INDEX_IMMD\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_OFFSET:
+               if (pkt->count != 2) {
+                       DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_DRAW_INDEX_OFFSET_2:
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_track_check(p);
+               if (r) {
+                       dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+                       return r;
+               }
+               break;
+       case PACKET3_WAIT_REG_MEM:
+               if (pkt->count != 5) {
+                       DRM_ERROR("bad WAIT_REG_MEM\n");
+                       return -EINVAL;
+               }
+               /* bit 4 is reg (0) or mem (1) */
+               if (idx_value & 0x10) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("bad WAIT_REG_MEM\n");
+                               return -EINVAL;
+                       }
+                       ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+                       ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               }
+               break;
+       case PACKET3_SURFACE_SYNC:
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad SURFACE_SYNC\n");
+                       return -EINVAL;
+               }
+               /* 0xffffffff/0x0 is flush all cache flag */
+               if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
+                   radeon_get_ib_value(p, idx + 2) != 0) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("bad SURFACE_SYNC\n");
+                               return -EINVAL;
+                       }
+                       ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               }
+               break;
+       case PACKET3_EVENT_WRITE:
+               if (pkt->count != 2 && pkt->count != 0) {
+                       DRM_ERROR("bad EVENT_WRITE\n");
+                       return -EINVAL;
+               }
+               if (pkt->count) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("bad EVENT_WRITE\n");
+                               return -EINVAL;
+                       }
+                       ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+                       ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               }
+               break;
+       case PACKET3_EVENT_WRITE_EOP:
+               if (pkt->count != 4) {
+                       DRM_ERROR("bad EVENT_WRITE_EOP\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad EVENT_WRITE_EOP\n");
+                       return -EINVAL;
+               }
+               ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+               ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               break;
+       case PACKET3_EVENT_WRITE_EOS:
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad EVENT_WRITE_EOS\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad EVENT_WRITE_EOS\n");
+                       return -EINVAL;
+               }
+               ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+               ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+               break;
+       case PACKET3_SET_CONFIG_REG:
+               start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
+                   (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
+                   (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
+                       DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
+                       return -EINVAL;
+               }
+               for (i = 0; i < pkt->count; i++) {
+                       reg = start_reg + (4 * i);
+                       r = evergreen_cs_check_reg(p, reg, idx+1+i);
+                       if (r)
+                               return r;
+               }
+               break;
+       case PACKET3_SET_CONTEXT_REG:
+               start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_CONTEXT_REG_START) ||
+                   (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
+                   (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
+                       DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
+                       return -EINVAL;
+               }
+               for (i = 0; i < pkt->count; i++) {
+                       reg = start_reg + (4 * i);
+                       r = evergreen_cs_check_reg(p, reg, idx+1+i);
+                       if (r)
+                               return r;
+               }
+               break;
+       case PACKET3_SET_RESOURCE:
+               if (pkt->count % 8) {
+                       DRM_ERROR("bad SET_RESOURCE\n");
+                       return -EINVAL;
+               }
+               start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_RESOURCE_START) ||
+                   (start_reg >= PACKET3_SET_RESOURCE_END) ||
+                   (end_reg >= PACKET3_SET_RESOURCE_END)) {
+                       DRM_ERROR("bad SET_RESOURCE\n");
+                       return -EINVAL;
+               }
+               for (i = 0; i < (pkt->count / 8); i++) {
+                       struct radeon_bo *texture, *mipmap;
+                       u32 size, offset;
+
+                       switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
+                       case SQ_TEX_VTX_VALID_TEXTURE:
+                               /* tex base */
+                               r = evergreen_cs_packet_next_reloc(p, &reloc);
+                               if (r) {
+                                       DRM_ERROR("bad SET_RESOURCE (tex)\n");
+                                       return -EINVAL;
+                               }
+                               ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               texture = reloc->robj;
+                               /* tex mip base */
+                               r = evergreen_cs_packet_next_reloc(p, &reloc);
+                               if (r) {
+                                       DRM_ERROR("bad SET_RESOURCE (tex)\n");
+                                       return -EINVAL;
+                               }
+                               ib[idx+1+(i*8)+4] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+                               mipmap = reloc->robj;
+                               r = evergreen_check_texture_resource(p,  idx+1+(i*8),
+                                               texture, mipmap);
+                               if (r)
+                                       return r;
+                               break;
+                       case SQ_TEX_VTX_VALID_BUFFER:
+                               /* vtx base */
+                               r = evergreen_cs_packet_next_reloc(p, &reloc);
+                               if (r) {
+                                       DRM_ERROR("bad SET_RESOURCE (vtx)\n");
+                                       return -EINVAL;
+                               }
+                               offset = radeon_get_ib_value(p, idx+1+(i*8)+0);
+                               size = radeon_get_ib_value(p, idx+1+(i*8)+1);
+                               if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
+                                       /* force size to size of the buffer */
+                                       dev_warn(p->dev, "vbo resource seems too big for the bo\n");
+                                       ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj);
+                               }
+                               ib[idx+1+(i*8)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
+                               ib[idx+1+(i*8)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+                               break;
+                       case SQ_TEX_VTX_INVALID_TEXTURE:
+                       case SQ_TEX_VTX_INVALID_BUFFER:
+                       default:
+                               DRM_ERROR("bad SET_RESOURCE\n");
+                               return -EINVAL;
+                       }
+               }
+               break;
+       case PACKET3_SET_ALU_CONST:
+               /* XXX fix me ALU const buffers only */
+               break;
+       case PACKET3_SET_BOOL_CONST:
+               start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_BOOL_CONST_START) ||
+                   (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
+                   (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
+                       DRM_ERROR("bad SET_BOOL_CONST\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_SET_LOOP_CONST:
+               start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_LOOP_CONST_START) ||
+                   (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
+                   (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
+                       DRM_ERROR("bad SET_LOOP_CONST\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_SET_CTL_CONST:
+               start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_CTL_CONST_START) ||
+                   (start_reg >= PACKET3_SET_CTL_CONST_END) ||
+                   (end_reg >= PACKET3_SET_CTL_CONST_END)) {
+                       DRM_ERROR("bad SET_CTL_CONST\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_SET_SAMPLER:
+               if (pkt->count % 3) {
+                       DRM_ERROR("bad SET_SAMPLER\n");
+                       return -EINVAL;
+               }
+               start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START;
+               end_reg = 4 * pkt->count + start_reg - 4;
+               if ((start_reg < PACKET3_SET_SAMPLER_START) ||
+                   (start_reg >= PACKET3_SET_SAMPLER_END) ||
+                   (end_reg >= PACKET3_SET_SAMPLER_END)) {
+                       DRM_ERROR("bad SET_SAMPLER\n");
+                       return -EINVAL;
+               }
+               break;
+       case PACKET3_NOP:
+               break;
+       default:
+               DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int evergreen_cs_parse(struct radeon_cs_parser *p)
+{
+       struct radeon_cs_packet pkt;
+       struct evergreen_cs_track *track;
+       int r;
+
+       if (p->track == NULL) {
+               /* initialize tracker, we are in kms */
+               track = kzalloc(sizeof(*track), GFP_KERNEL);
+               if (track == NULL)
+                       return -ENOMEM;
+               evergreen_cs_track_init(track);
+               track->npipes = p->rdev->config.evergreen.tiling_npipes;
+               track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
+               track->group_size = p->rdev->config.evergreen.tiling_group_size;
+               p->track = track;
+       }
+       do {
+               r = evergreen_cs_packet_parse(p, &pkt, p->idx);
+               if (r) {
+                       kfree(p->track);
+                       p->track = NULL;
+                       return r;
+               }
+               p->idx += pkt.count + 2;
+               switch (pkt.type) {
+               case PACKET_TYPE0:
+                       r = evergreen_cs_parse_packet0(p, &pkt);
+                       break;
+               case PACKET_TYPE2:
+                       break;
+               case PACKET_TYPE3:
+                       r = evergreen_packet3_check(p, &pkt);
+                       break;
+               default:
+                       DRM_ERROR("Unknown packet type %d !\n", pkt.type);
+                       kfree(p->track);
+                       p->track = NULL;
+                       return -EINVAL;
+               }
+               if (r) {
+                       kfree(p->track);
+                       p->track = NULL;
+                       return r;
+               }
+       } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+#if 0
+       for (r = 0; r < p->ib->length_dw; r++) {
+               printk(KERN_INFO "%05d  0x%08X\n", r, p->ib->ptr[r]);
+               mdelay(1);
+       }
+#endif
+       kfree(p->track);
+       p->track = NULL;
+       return 0;
+}
+
index af86af836f13dcb446d78418c65f3c6c69a2660f..e028c1cd9d9b7732d8eeaf1c8773df35e13c93fa 100644 (file)
 #define EVERGREEN_DATA_FORMAT                           0x6b00
 #       define EVERGREEN_INTERLEAVE_EN                  (1 << 0)
 #define EVERGREEN_DESKTOP_HEIGHT                        0x6b04
+#define EVERGREEN_VLINE_START_END                       0x6b08
+#define EVERGREEN_VLINE_STATUS                          0x6bb8
+#       define EVERGREEN_VLINE_STAT                     (1 << 12)
 
 #define EVERGREEN_VIEWPORT_START                        0x6d70
 #define EVERGREEN_VIEWPORT_SIZE                         0x6d74
index 93e9e17ad54ad4a1717738489cad54caaf47bb17..79683f6b4452907854d2a6fa9639bf04132a785c 100644 (file)
 #define                CLIP_VTX_REORDER_ENA                            (1 << 0)
 #define                NUM_CLIP_SEQ(x)                                 ((x) << 1)
 #define PA_SC_AA_CONFIG                                        0x28C04
+#define         MSAA_NUM_SAMPLES_SHIFT                  0
+#define         MSAA_NUM_SAMPLES_MASK                   0x3
 #define PA_SC_CLIPRECT_RULE                            0x2820C
 #define        PA_SC_EDGERULE                                  0x28230
 #define        PA_SC_FIFO_SIZE                                 0x8BCC
 #       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
 #       define DC_HPDx_EN                                 (1 << 28)
 
+/*
+ * PM4
+ */
+#define        PACKET_TYPE0    0
+#define        PACKET_TYPE1    1
+#define        PACKET_TYPE2    2
+#define        PACKET_TYPE3    3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+#define PACKET0(reg, n)        ((PACKET_TYPE0 << 30) |                         \
+                        (((reg) >> 2) & 0xFFFF) |                      \
+                        ((n) & 0x3FFF) << 16)
+#define CP_PACKET2                     0x80000000
+#define                PACKET2_PAD_SHIFT               0
+#define                PACKET2_PAD_MASK                (0x3fffffff << 0)
+
+#define PACKET2(v)     (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) |                         \
+                        (((op) & 0xFF) << 8) |                         \
+                        ((n) & 0x3FFF) << 16)
+
+/* Packet 3 types */
+#define        PACKET3_NOP                                     0x10
+#define        PACKET3_SET_BASE                                0x11
+#define        PACKET3_CLEAR_STATE                             0x12
+#define        PACKET3_INDIRECT_BUFFER_SIZE                    0x13
+#define        PACKET3_DISPATCH_DIRECT                         0x15
+#define        PACKET3_DISPATCH_INDIRECT                       0x16
+#define        PACKET3_INDIRECT_BUFFER_END                     0x17
+#define        PACKET3_SET_PREDICATION                         0x20
+#define        PACKET3_REG_RMW                                 0x21
+#define        PACKET3_COND_EXEC                               0x22
+#define        PACKET3_PRED_EXEC                               0x23
+#define        PACKET3_DRAW_INDIRECT                           0x24
+#define        PACKET3_DRAW_INDEX_INDIRECT                     0x25
+#define        PACKET3_INDEX_BASE                              0x26
+#define        PACKET3_DRAW_INDEX_2                            0x27
+#define        PACKET3_CONTEXT_CONTROL                         0x28
+#define        PACKET3_DRAW_INDEX_OFFSET                       0x29
+#define        PACKET3_INDEX_TYPE                              0x2A
+#define        PACKET3_DRAW_INDEX                              0x2B
+#define        PACKET3_DRAW_INDEX_AUTO                         0x2D
+#define        PACKET3_DRAW_INDEX_IMMD                         0x2E
+#define        PACKET3_NUM_INSTANCES                           0x2F
+#define        PACKET3_DRAW_INDEX_MULTI_AUTO                   0x30
+#define        PACKET3_STRMOUT_BUFFER_UPDATE                   0x34
+#define        PACKET3_DRAW_INDEX_OFFSET_2                     0x35
+#define        PACKET3_DRAW_INDEX_MULTI_ELEMENT                0x36
+#define        PACKET3_MEM_SEMAPHORE                           0x39
+#define        PACKET3_MPEG_INDEX                              0x3A
+#define        PACKET3_WAIT_REG_MEM                            0x3C
+#define        PACKET3_MEM_WRITE                               0x3D
+#define        PACKET3_INDIRECT_BUFFER                         0x32
+#define        PACKET3_SURFACE_SYNC                            0x43
+#              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
+#              define PACKET3_CB1_DEST_BASE_ENA    (1 << 7)
+#              define PACKET3_CB2_DEST_BASE_ENA    (1 << 8)
+#              define PACKET3_CB3_DEST_BASE_ENA    (1 << 9)
+#              define PACKET3_CB4_DEST_BASE_ENA    (1 << 10)
+#              define PACKET3_CB5_DEST_BASE_ENA    (1 << 11)
+#              define PACKET3_CB6_DEST_BASE_ENA    (1 << 12)
+#              define PACKET3_CB7_DEST_BASE_ENA    (1 << 13)
+#              define PACKET3_DB_DEST_BASE_ENA     (1 << 14)
+#              define PACKET3_CB8_DEST_BASE_ENA    (1 << 15)
+#              define PACKET3_CB9_DEST_BASE_ENA    (1 << 16)
+#              define PACKET3_CB10_DEST_BASE_ENA   (1 << 17)
+#              define PACKET3_CB11_DEST_BASE_ENA   (1 << 17)
+#              define PACKET3_FULL_CACHE_ENA       (1 << 20)
+#              define PACKET3_TC_ACTION_ENA        (1 << 23)
+#              define PACKET3_VC_ACTION_ENA        (1 << 24)
+#              define PACKET3_CB_ACTION_ENA        (1 << 25)
+#              define PACKET3_DB_ACTION_ENA        (1 << 26)
+#              define PACKET3_SH_ACTION_ENA        (1 << 27)
+#              define PACKET3_SMX_ACTION_ENA       (1 << 28)
+#define        PACKET3_ME_INITIALIZE                           0x44
+#define                PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
+#define        PACKET3_COND_WRITE                              0x45
+#define        PACKET3_EVENT_WRITE                             0x46
+#define        PACKET3_EVENT_WRITE_EOP                         0x47
+#define        PACKET3_EVENT_WRITE_EOS                         0x48
+#define        PACKET3_PREAMBLE_CNTL                           0x4A
+#define        PACKET3_RB_OFFSET                               0x4B
+#define        PACKET3_ALU_PS_CONST_BUFFER_COPY                0x4C
+#define        PACKET3_ALU_VS_CONST_BUFFER_COPY                0x4D
+#define        PACKET3_ALU_PS_CONST_UPDATE                     0x4E
+#define        PACKET3_ALU_VS_CONST_UPDATE                     0x4F
+#define        PACKET3_ONE_REG_WRITE                           0x57
+#define        PACKET3_SET_CONFIG_REG                          0x68
+#define                PACKET3_SET_CONFIG_REG_START                    0x00008000
+#define                PACKET3_SET_CONFIG_REG_END                      0x0000ac00
+#define        PACKET3_SET_CONTEXT_REG                         0x69
+#define                PACKET3_SET_CONTEXT_REG_START                   0x00028000
+#define                PACKET3_SET_CONTEXT_REG_END                     0x00029000
+#define        PACKET3_SET_ALU_CONST                           0x6A
+/* alu const buffers only; no reg file */
+#define        PACKET3_SET_BOOL_CONST                          0x6B
+#define                PACKET3_SET_BOOL_CONST_START                    0x0003a500
+#define                PACKET3_SET_BOOL_CONST_END                      0x0003a518
+#define        PACKET3_SET_LOOP_CONST                          0x6C
+#define                PACKET3_SET_LOOP_CONST_START                    0x0003a200
+#define                PACKET3_SET_LOOP_CONST_END                      0x0003a500
+#define        PACKET3_SET_RESOURCE                            0x6D
+#define                PACKET3_SET_RESOURCE_START                      0x00030000
+#define                PACKET3_SET_RESOURCE_END                        0x00038000
+#define        PACKET3_SET_SAMPLER                             0x6E
+#define                PACKET3_SET_SAMPLER_START                       0x0003c000
+#define                PACKET3_SET_SAMPLER_END                         0x0003c600
+#define        PACKET3_SET_CTL_CONST                           0x6F
+#define                PACKET3_SET_CTL_CONST_START                     0x0003cff0
+#define                PACKET3_SET_CTL_CONST_END                       0x0003ff0c
+#define        PACKET3_SET_RESOURCE_OFFSET                     0x70
+#define        PACKET3_SET_ALU_CONST_VS                        0x71
+#define        PACKET3_SET_ALU_CONST_DI                        0x72
+#define        PACKET3_SET_CONTEXT_REG_INDIRECT                0x73
+#define        PACKET3_SET_RESOURCE_INDIRECT                   0x74
+#define        PACKET3_SET_APPEND_CNT                          0x75
+
+#define        SQ_RESOURCE_CONSTANT_WORD7_0                            0x3001c
+#define                S__SQ_CONSTANT_TYPE(x)                  (((x) & 3) << 30)
+#define                G__SQ_CONSTANT_TYPE(x)                  (((x) >> 30) & 3)
+#define                        SQ_TEX_VTX_INVALID_TEXTURE                      0x0
+#define                        SQ_TEX_VTX_INVALID_BUFFER                       0x1
+#define                        SQ_TEX_VTX_VALID_TEXTURE                        0x2
+#define                        SQ_TEX_VTX_VALID_BUFFER                         0x3
+
+#define SQ_CONST_MEM_BASE                              0x8df8
+
+#define SQ_ESGS_RING_SIZE                              0x8c44
+#define SQ_GSVS_RING_SIZE                              0x8c4c
+#define SQ_ESTMP_RING_SIZE                             0x8c54
+#define SQ_GSTMP_RING_SIZE                             0x8c5c
+#define SQ_VSTMP_RING_SIZE                             0x8c64
+#define SQ_PSTMP_RING_SIZE                             0x8c6c
+#define SQ_LSTMP_RING_SIZE                             0x8e14
+#define SQ_HSTMP_RING_SIZE                             0x8e1c
+#define VGT_TF_RING_SIZE                               0x8988
+
+#define SQ_ESGS_RING_ITEMSIZE                          0x28900
+#define SQ_GSVS_RING_ITEMSIZE                          0x28904
+#define SQ_ESTMP_RING_ITEMSIZE                         0x28908
+#define SQ_GSTMP_RING_ITEMSIZE                         0x2890c
+#define SQ_VSTMP_RING_ITEMSIZE                         0x28910
+#define SQ_PSTMP_RING_ITEMSIZE                         0x28914
+#define SQ_LSTMP_RING_ITEMSIZE                         0x28830
+#define SQ_HSTMP_RING_ITEMSIZE                         0x28834
+
+#define SQ_GS_VERT_ITEMSIZE                            0x2891c
+#define SQ_GS_VERT_ITEMSIZE_1                          0x28920
+#define SQ_GS_VERT_ITEMSIZE_2                          0x28924
+#define SQ_GS_VERT_ITEMSIZE_3                          0x28928
+#define SQ_GSVS_RING_OFFSET_1                          0x2892c
+#define SQ_GSVS_RING_OFFSET_2                          0x28930
+#define SQ_GSVS_RING_OFFSET_3                          0x28934
+
+#define SQ_ALU_CONST_CACHE_PS_0                                0x28940
+#define SQ_ALU_CONST_CACHE_PS_1                                0x28944
+#define SQ_ALU_CONST_CACHE_PS_2                                0x28948
+#define SQ_ALU_CONST_CACHE_PS_3                                0x2894c
+#define SQ_ALU_CONST_CACHE_PS_4                                0x28950
+#define SQ_ALU_CONST_CACHE_PS_5                                0x28954
+#define SQ_ALU_CONST_CACHE_PS_6                                0x28958
+#define SQ_ALU_CONST_CACHE_PS_7                                0x2895c
+#define SQ_ALU_CONST_CACHE_PS_8                                0x28960
+#define SQ_ALU_CONST_CACHE_PS_9                                0x28964
+#define SQ_ALU_CONST_CACHE_PS_10                       0x28968
+#define SQ_ALU_CONST_CACHE_PS_11                       0x2896c
+#define SQ_ALU_CONST_CACHE_PS_12                       0x28970
+#define SQ_ALU_CONST_CACHE_PS_13                       0x28974
+#define SQ_ALU_CONST_CACHE_PS_14                       0x28978
+#define SQ_ALU_CONST_CACHE_PS_15                       0x2897c
+#define SQ_ALU_CONST_CACHE_VS_0                                0x28980
+#define SQ_ALU_CONST_CACHE_VS_1                                0x28984
+#define SQ_ALU_CONST_CACHE_VS_2                                0x28988
+#define SQ_ALU_CONST_CACHE_VS_3                                0x2898c
+#define SQ_ALU_CONST_CACHE_VS_4                                0x28990
+#define SQ_ALU_CONST_CACHE_VS_5                                0x28994
+#define SQ_ALU_CONST_CACHE_VS_6                                0x28998
+#define SQ_ALU_CONST_CACHE_VS_7                                0x2899c
+#define SQ_ALU_CONST_CACHE_VS_8                                0x289a0
+#define SQ_ALU_CONST_CACHE_VS_9                                0x289a4
+#define SQ_ALU_CONST_CACHE_VS_10                       0x289a8
+#define SQ_ALU_CONST_CACHE_VS_11                       0x289ac
+#define SQ_ALU_CONST_CACHE_VS_12                       0x289b0
+#define SQ_ALU_CONST_CACHE_VS_13                       0x289b4
+#define SQ_ALU_CONST_CACHE_VS_14                       0x289b8
+#define SQ_ALU_CONST_CACHE_VS_15                       0x289bc
+#define SQ_ALU_CONST_CACHE_GS_0                                0x289c0
+#define SQ_ALU_CONST_CACHE_GS_1                                0x289c4
+#define SQ_ALU_CONST_CACHE_GS_2                                0x289c8
+#define SQ_ALU_CONST_CACHE_GS_3                                0x289cc
+#define SQ_ALU_CONST_CACHE_GS_4                                0x289d0
+#define SQ_ALU_CONST_CACHE_GS_5                                0x289d4
+#define SQ_ALU_CONST_CACHE_GS_6                                0x289d8
+#define SQ_ALU_CONST_CACHE_GS_7                                0x289dc
+#define SQ_ALU_CONST_CACHE_GS_8                                0x289e0
+#define SQ_ALU_CONST_CACHE_GS_9                                0x289e4
+#define SQ_ALU_CONST_CACHE_GS_10                       0x289e8
+#define SQ_ALU_CONST_CACHE_GS_11                       0x289ec
+#define SQ_ALU_CONST_CACHE_GS_12                       0x289f0
+#define SQ_ALU_CONST_CACHE_GS_13                       0x289f4
+#define SQ_ALU_CONST_CACHE_GS_14                       0x289f8
+#define SQ_ALU_CONST_CACHE_GS_15                       0x289fc
+#define SQ_ALU_CONST_CACHE_HS_0                                0x28f00
+#define SQ_ALU_CONST_CACHE_HS_1                                0x28f04
+#define SQ_ALU_CONST_CACHE_HS_2                                0x28f08
+#define SQ_ALU_CONST_CACHE_HS_3                                0x28f0c
+#define SQ_ALU_CONST_CACHE_HS_4                                0x28f10
+#define SQ_ALU_CONST_CACHE_HS_5                                0x28f14
+#define SQ_ALU_CONST_CACHE_HS_6                                0x28f18
+#define SQ_ALU_CONST_CACHE_HS_7                                0x28f1c
+#define SQ_ALU_CONST_CACHE_HS_8                                0x28f20
+#define SQ_ALU_CONST_CACHE_HS_9                                0x28f24
+#define SQ_ALU_CONST_CACHE_HS_10                       0x28f28
+#define SQ_ALU_CONST_CACHE_HS_11                       0x28f2c
+#define SQ_ALU_CONST_CACHE_HS_12                       0x28f30
+#define SQ_ALU_CONST_CACHE_HS_13                       0x28f34
+#define SQ_ALU_CONST_CACHE_HS_14                       0x28f38
+#define SQ_ALU_CONST_CACHE_HS_15                       0x28f3c
+#define SQ_ALU_CONST_CACHE_LS_0                                0x28f40
+#define SQ_ALU_CONST_CACHE_LS_1                                0x28f44
+#define SQ_ALU_CONST_CACHE_LS_2                                0x28f48
+#define SQ_ALU_CONST_CACHE_LS_3                                0x28f4c
+#define SQ_ALU_CONST_CACHE_LS_4                                0x28f50
+#define SQ_ALU_CONST_CACHE_LS_5                                0x28f54
+#define SQ_ALU_CONST_CACHE_LS_6                                0x28f58
+#define SQ_ALU_CONST_CACHE_LS_7                                0x28f5c
+#define SQ_ALU_CONST_CACHE_LS_8                                0x28f60
+#define SQ_ALU_CONST_CACHE_LS_9                                0x28f64
+#define SQ_ALU_CONST_CACHE_LS_10                       0x28f68
+#define SQ_ALU_CONST_CACHE_LS_11                       0x28f6c
+#define SQ_ALU_CONST_CACHE_LS_12                       0x28f70
+#define SQ_ALU_CONST_CACHE_LS_13                       0x28f74
+#define SQ_ALU_CONST_CACHE_LS_14                       0x28f78
+#define SQ_ALU_CONST_CACHE_LS_15                       0x28f7c
+
+#define DB_DEPTH_CONTROL                               0x28800
+#define DB_DEPTH_VIEW                                  0x28008
+#define DB_HTILE_DATA_BASE                             0x28014
+#define DB_Z_INFO                                      0x28040
+#       define Z_ARRAY_MODE(x)                          ((x) << 4)
+#define DB_STENCIL_INFO                                        0x28044
+#define DB_Z_READ_BASE                                 0x28048
+#define DB_STENCIL_READ_BASE                           0x2804c
+#define DB_Z_WRITE_BASE                                        0x28050
+#define DB_STENCIL_WRITE_BASE                          0x28054
+#define DB_DEPTH_SIZE                                  0x28058
+
+#define SQ_PGM_START_PS                                        0x28840
+#define SQ_PGM_START_VS                                        0x2885c
+#define SQ_PGM_START_GS                                        0x28874
+#define SQ_PGM_START_ES                                        0x2888c
+#define SQ_PGM_START_FS                                        0x288a4
+#define SQ_PGM_START_HS                                        0x288b8
+#define SQ_PGM_START_LS                                        0x288d0
+
+#define VGT_STRMOUT_CONFIG                             0x28b94
+#define VGT_STRMOUT_BUFFER_CONFIG                      0x28b98
+
+#define CB_TARGET_MASK                                 0x28238
+#define CB_SHADER_MASK                                 0x2823c
+
+#define GDS_ADDR_BASE                                  0x28720
+
+#define        CB_IMMED0_BASE                                  0x28b9c
+#define        CB_IMMED1_BASE                                  0x28ba0
+#define        CB_IMMED2_BASE                                  0x28ba4
+#define        CB_IMMED3_BASE                                  0x28ba8
+#define        CB_IMMED4_BASE                                  0x28bac
+#define        CB_IMMED5_BASE                                  0x28bb0
+#define        CB_IMMED6_BASE                                  0x28bb4
+#define        CB_IMMED7_BASE                                  0x28bb8
+#define        CB_IMMED8_BASE                                  0x28bbc
+#define        CB_IMMED9_BASE                                  0x28bc0
+#define        CB_IMMED10_BASE                                 0x28bc4
+#define        CB_IMMED11_BASE                                 0x28bc8
+
+/* all 12 CB blocks have these regs */
+#define        CB_COLOR0_BASE                                  0x28c60
+#define        CB_COLOR0_PITCH                                 0x28c64
+#define        CB_COLOR0_SLICE                                 0x28c68
+#define        CB_COLOR0_VIEW                                  0x28c6c
+#define        CB_COLOR0_INFO                                  0x28c70
+#       define CB_ARRAY_MODE(x)                         ((x) << 8)
+#       define ARRAY_LINEAR_GENERAL                     0
+#       define ARRAY_LINEAR_ALIGNED                     1
+#       define ARRAY_1D_TILED_THIN1                     2
+#       define ARRAY_2D_TILED_THIN1                     4
+#define        CB_COLOR0_ATTRIB                                0x28c74
+#define        CB_COLOR0_DIM                                   0x28c78
+/* only CB0-7 blocks have these regs */
+#define        CB_COLOR0_CMASK                                 0x28c7c
+#define        CB_COLOR0_CMASK_SLICE                           0x28c80
+#define        CB_COLOR0_FMASK                                 0x28c84
+#define        CB_COLOR0_FMASK_SLICE                           0x28c88
+#define        CB_COLOR0_CLEAR_WORD0                           0x28c8c
+#define        CB_COLOR0_CLEAR_WORD1                           0x28c90
+#define        CB_COLOR0_CLEAR_WORD2                           0x28c94
+#define        CB_COLOR0_CLEAR_WORD3                           0x28c98
+
+#define        CB_COLOR1_BASE                                  0x28c9c
+#define        CB_COLOR2_BASE                                  0x28cd8
+#define        CB_COLOR3_BASE                                  0x28d14
+#define        CB_COLOR4_BASE                                  0x28d50
+#define        CB_COLOR5_BASE                                  0x28d8c
+#define        CB_COLOR6_BASE                                  0x28dc8
+#define        CB_COLOR7_BASE                                  0x28e04
+#define        CB_COLOR8_BASE                                  0x28e40
+#define        CB_COLOR9_BASE                                  0x28e5c
+#define        CB_COLOR10_BASE                                 0x28e78
+#define        CB_COLOR11_BASE                                 0x28e94
+
+#define        CB_COLOR1_PITCH                                 0x28ca0
+#define        CB_COLOR2_PITCH                                 0x28cdc
+#define        CB_COLOR3_PITCH                                 0x28d18
+#define        CB_COLOR4_PITCH                                 0x28d54
+#define        CB_COLOR5_PITCH                                 0x28d90
+#define        CB_COLOR6_PITCH                                 0x28dcc
+#define        CB_COLOR7_PITCH                                 0x28e08
+#define        CB_COLOR8_PITCH                                 0x28e44
+#define        CB_COLOR9_PITCH                                 0x28e60
+#define        CB_COLOR10_PITCH                                0x28e7c
+#define        CB_COLOR11_PITCH                                0x28e98
+
+#define        CB_COLOR1_SLICE                                 0x28ca4
+#define        CB_COLOR2_SLICE                                 0x28ce0
+#define        CB_COLOR3_SLICE                                 0x28d1c
+#define        CB_COLOR4_SLICE                                 0x28d58
+#define        CB_COLOR5_SLICE                                 0x28d94
+#define        CB_COLOR6_SLICE                                 0x28dd0
+#define        CB_COLOR7_SLICE                                 0x28e0c
+#define        CB_COLOR8_SLICE                                 0x28e48
+#define        CB_COLOR9_SLICE                                 0x28e64
+#define        CB_COLOR10_SLICE                                0x28e80
+#define        CB_COLOR11_SLICE                                0x28e9c
+
+#define        CB_COLOR1_VIEW                                  0x28ca8
+#define        CB_COLOR2_VIEW                                  0x28ce4
+#define        CB_COLOR3_VIEW                                  0x28d20
+#define        CB_COLOR4_VIEW                                  0x28d5c
+#define        CB_COLOR5_VIEW                                  0x28d98
+#define        CB_COLOR6_VIEW                                  0x28dd4
+#define        CB_COLOR7_VIEW                                  0x28e10
+#define        CB_COLOR8_VIEW                                  0x28e4c
+#define        CB_COLOR9_VIEW                                  0x28e68
+#define        CB_COLOR10_VIEW                                 0x28e84
+#define        CB_COLOR11_VIEW                                 0x28ea0
+
+#define        CB_COLOR1_INFO                                  0x28cac
+#define        CB_COLOR2_INFO                                  0x28ce8
+#define        CB_COLOR3_INFO                                  0x28d24
+#define        CB_COLOR4_INFO                                  0x28d60
+#define        CB_COLOR5_INFO                                  0x28d9c
+#define        CB_COLOR6_INFO                                  0x28dd8
+#define        CB_COLOR7_INFO                                  0x28e14
+#define        CB_COLOR8_INFO                                  0x28e50
+#define        CB_COLOR9_INFO                                  0x28e6c
+#define        CB_COLOR10_INFO                                 0x28e88
+#define        CB_COLOR11_INFO                                 0x28ea4
+
+#define        CB_COLOR1_ATTRIB                                0x28cb0
+#define        CB_COLOR2_ATTRIB                                0x28cec
+#define        CB_COLOR3_ATTRIB                                0x28d28
+#define        CB_COLOR4_ATTRIB                                0x28d64
+#define        CB_COLOR5_ATTRIB                                0x28da0
+#define        CB_COLOR6_ATTRIB                                0x28ddc
+#define        CB_COLOR7_ATTRIB                                0x28e18
+#define        CB_COLOR8_ATTRIB                                0x28e54
+#define        CB_COLOR9_ATTRIB                                0x28e70
+#define        CB_COLOR10_ATTRIB                               0x28e8c
+#define        CB_COLOR11_ATTRIB                               0x28ea8
+
+#define        CB_COLOR1_DIM                                   0x28cb4
+#define        CB_COLOR2_DIM                                   0x28cf0
+#define        CB_COLOR3_DIM                                   0x28d2c
+#define        CB_COLOR4_DIM                                   0x28d68
+#define        CB_COLOR5_DIM                                   0x28da4
+#define        CB_COLOR6_DIM                                   0x28de0
+#define        CB_COLOR7_DIM                                   0x28e1c
+#define        CB_COLOR8_DIM                                   0x28e58
+#define        CB_COLOR9_DIM                                   0x28e74
+#define        CB_COLOR10_DIM                                  0x28e90
+#define        CB_COLOR11_DIM                                  0x28eac
+
+#define        CB_COLOR1_CMASK                                 0x28cb8
+#define        CB_COLOR2_CMASK                                 0x28cf4
+#define        CB_COLOR3_CMASK                                 0x28d30
+#define        CB_COLOR4_CMASK                                 0x28d6c
+#define        CB_COLOR5_CMASK                                 0x28da8
+#define        CB_COLOR6_CMASK                                 0x28de4
+#define        CB_COLOR7_CMASK                                 0x28e20
+
+#define        CB_COLOR1_CMASK_SLICE                           0x28cbc
+#define        CB_COLOR2_CMASK_SLICE                           0x28cf8
+#define        CB_COLOR3_CMASK_SLICE                           0x28d34
+#define        CB_COLOR4_CMASK_SLICE                           0x28d70
+#define        CB_COLOR5_CMASK_SLICE                           0x28dac
+#define        CB_COLOR6_CMASK_SLICE                           0x28de8
+#define        CB_COLOR7_CMASK_SLICE                           0x28e24
+
+#define        CB_COLOR1_FMASK                                 0x28cc0
+#define        CB_COLOR2_FMASK                                 0x28cfc
+#define        CB_COLOR3_FMASK                                 0x28d38
+#define        CB_COLOR4_FMASK                                 0x28d74
+#define        CB_COLOR5_FMASK                                 0x28db0
+#define        CB_COLOR6_FMASK                                 0x28dec
+#define        CB_COLOR7_FMASK                                 0x28e28
+
+#define        CB_COLOR1_FMASK_SLICE                           0x28cc4
+#define        CB_COLOR2_FMASK_SLICE                           0x28d00
+#define        CB_COLOR3_FMASK_SLICE                           0x28d3c
+#define        CB_COLOR4_FMASK_SLICE                           0x28d78
+#define        CB_COLOR5_FMASK_SLICE                           0x28db4
+#define        CB_COLOR6_FMASK_SLICE                           0x28df0
+#define        CB_COLOR7_FMASK_SLICE                           0x28e2c
+
+#define        CB_COLOR1_CLEAR_WORD0                           0x28cc8
+#define        CB_COLOR2_CLEAR_WORD0                           0x28d04
+#define        CB_COLOR3_CLEAR_WORD0                           0x28d40
+#define        CB_COLOR4_CLEAR_WORD0                           0x28d7c
+#define        CB_COLOR5_CLEAR_WORD0                           0x28db8
+#define        CB_COLOR6_CLEAR_WORD0                           0x28df4
+#define        CB_COLOR7_CLEAR_WORD0                           0x28e30
+
+#define        CB_COLOR1_CLEAR_WORD1                           0x28ccc
+#define        CB_COLOR2_CLEAR_WORD1                           0x28d08
+#define        CB_COLOR3_CLEAR_WORD1                           0x28d44
+#define        CB_COLOR4_CLEAR_WORD1                           0x28d80
+#define        CB_COLOR5_CLEAR_WORD1                           0x28dbc
+#define        CB_COLOR6_CLEAR_WORD1                           0x28df8
+#define        CB_COLOR7_CLEAR_WORD1                           0x28e34
+
+#define        CB_COLOR1_CLEAR_WORD2                           0x28cd0
+#define        CB_COLOR2_CLEAR_WORD2                           0x28d0c
+#define        CB_COLOR3_CLEAR_WORD2                           0x28d48
+#define        CB_COLOR4_CLEAR_WORD2                           0x28d84
+#define        CB_COLOR5_CLEAR_WORD2                           0x28dc0
+#define        CB_COLOR6_CLEAR_WORD2                           0x28dfc
+#define        CB_COLOR7_CLEAR_WORD2                           0x28e38
+
+#define        CB_COLOR1_CLEAR_WORD3                           0x28cd4
+#define        CB_COLOR2_CLEAR_WORD3                           0x28d10
+#define        CB_COLOR3_CLEAR_WORD3                           0x28d4c
+#define        CB_COLOR4_CLEAR_WORD3                           0x28d88
+#define        CB_COLOR5_CLEAR_WORD3                           0x28dc4
+#define        CB_COLOR6_CLEAR_WORD3                           0x28e00
+#define        CB_COLOR7_CLEAR_WORD3                           0x28e3c
+
+#define SQ_TEX_RESOURCE_WORD0_0                         0x30000
+#define SQ_TEX_RESOURCE_WORD1_0                         0x30004
+#       define TEX_ARRAY_MODE(x)                        ((x) << 28)
+#define SQ_TEX_RESOURCE_WORD2_0                         0x30008
+#define SQ_TEX_RESOURCE_WORD3_0                         0x3000C
+#define SQ_TEX_RESOURCE_WORD4_0                         0x30010
+#define SQ_TEX_RESOURCE_WORD5_0                         0x30014
+#define SQ_TEX_RESOURCE_WORD6_0                         0x30018
+#define SQ_TEX_RESOURCE_WORD7_0                         0x3001c
+
+
 #endif
index 44e96a2ae25aa2be1640d491a68570aa1257bae9..e14f59748e65212f628ed7b1a5ed427fa89f7aec 100644 (file)
@@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
 
 void r600_pm_misc(struct radeon_device *rdev)
 {
+       int requested_index = rdev->pm.requested_power_state_index;
+       struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
+       struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
+
+       if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
+               radeon_atom_set_voltage(rdev, voltage->voltage);
 
 }
 
index 669feb689bfcdc6df0f8536493c4defc5bd0e42a..5f96fe871b3fdeb13c89c2e8438958c06651ab60 100644 (file)
@@ -176,6 +176,7 @@ void radeon_pm_suspend(struct radeon_device *rdev);
 void radeon_pm_resume(struct radeon_device *rdev);
 void radeon_combios_get_power_modes(struct radeon_device *rdev);
 void radeon_atombios_get_power_modes(struct radeon_device *rdev);
+void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
 
 /*
  * Fences.
index e57df08d4aeb9a36eb2f721ddde0f282e7365998..87f7e2cc52d4ef81be592d50891769740d9bf4e8 100644 (file)
@@ -724,8 +724,8 @@ static struct radeon_asic evergreen_asic = {
        .irq_set = &evergreen_irq_set,
        .irq_process = &evergreen_irq_process,
        .get_vblank_counter = &evergreen_get_vblank_counter,
-       .fence_ring_emit = NULL,
-       .cs_parse = NULL,
+       .fence_ring_emit = &r600_fence_ring_emit,
+       .cs_parse = &evergreen_cs_parse,
        .copy_blit = NULL,
        .copy_dma = NULL,
        .copy = NULL,
index 5c40a3dfaca2e936679c7610468521b5c7c93b90..c0bbaa64157a466efb81990431903dc8fbe2dc33 100644 (file)
@@ -314,6 +314,7 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev,
 u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc);
 int evergreen_irq_set(struct radeon_device *rdev);
 int evergreen_irq_process(struct radeon_device *rdev);
+extern int evergreen_cs_parse(struct radeon_cs_parser *p);
 extern void evergreen_pm_misc(struct radeon_device *rdev);
 extern void evergreen_pm_prepare(struct radeon_device *rdev);
 extern void evergreen_pm_finish(struct radeon_device *rdev);
index 24ea683f7cf53ec5bd2a2958a0a86d95a5185624..4305cd55d0acf6976c54f17e93e860031e74abfe 100644 (file)
@@ -1538,7 +1538,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                        rdev->pm.power_state[state_index].pcie_lanes =
                                                power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
                                        misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
-                                       if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+                                       if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
+                                           (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.type =
                                                        VOLTAGE_GPIO;
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1605,7 +1606,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                                power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
                                        misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
                                        misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
-                                       if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+                                       if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
+                                           (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.type =
                                                        VOLTAGE_GPIO;
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1679,7 +1681,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                                power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
                                        misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
                                        misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
-                                       if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+                                       if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||
+                                           (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.type =
                                                        VOLTAGE_GPIO;
                                                rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
@@ -1755,9 +1758,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                rdev->pm.power_state[state_index].misc2 = 0;
                        }
                } else {
+                       int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
+                       uint8_t fw_frev, fw_crev;
+                       uint16_t fw_data_offset, vddc = 0;
+                       union firmware_info *firmware_info;
+                       ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController;
+
+                       if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL,
+                                                  &fw_frev, &fw_crev, &fw_data_offset)) {
+                               firmware_info =
+                                       (union firmware_info *)(mode_info->atom_context->bios +
+                                                               fw_data_offset);
+                               vddc = firmware_info->info_14.usBootUpVDDCVoltage;
+                       }
+
                        /* add the i2c bus for thermal/fan chip */
                        /* no support for internal controller yet */
-                       ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController;
                        if (controller->ucType > 0) {
                                if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
                                    (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) ||
@@ -1904,6 +1920,16 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                                rdev->pm.default_power_state_index = state_index;
                                                rdev->pm.power_state[state_index].default_clock_mode =
                                                        &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
+                                               /* patch the table values with the default slck/mclk from firmware info */
+                                               for (j = 0; j < mode_index; j++) {
+                                                       rdev->pm.power_state[state_index].clock_info[j].mclk =
+                                                               rdev->clock.default_mclk;
+                                                       rdev->pm.power_state[state_index].clock_info[j].sclk =
+                                                               rdev->clock.default_sclk;
+                                                       if (vddc)
+                                                               rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
+                                                                       vddc;
+                                               }
                                        }
                                        state_index++;
                                }
@@ -1998,6 +2024,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev,
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+union set_voltage {
+       struct _SET_VOLTAGE_PS_ALLOCATION alloc;
+       struct _SET_VOLTAGE_PARAMETERS v1;
+       struct _SET_VOLTAGE_PARAMETERS_V2 v2;
+};
+
+void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level)
+{
+       union set_voltage args;
+       int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
+       u8 frev, crev, volt_index = level;
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (crev) {
+       case 1:
+               args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
+               args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
+               args.v1.ucVoltageIndex = volt_index;
+               break;
+       case 2:
+               args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
+               args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
+               args.v2.usVoltageLevel = cpu_to_le16(level);
+               break;
+       default:
+               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+               return;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+
+
 void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 {
        struct radeon_device *rdev = dev->dev_private;
index 7b5e10d3e9c9223556f3319aba979d5cecc19c15..102c744eaf5a14a7ee093c96db24bc2d40c6072d 100644 (file)
@@ -2454,7 +2454,12 @@ default_mode:
        rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
        rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
        rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
-       rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+       if ((state_index > 0) &&
+           (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO))
+               rdev->pm.power_state[state_index].clock_info[0].voltage =
+                       rdev->pm.power_state[0].clock_info[0].voltage;
+       else
+               rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
        rdev->pm.power_state[state_index].pcie_lanes = 16;
        rdev->pm.power_state[state_index].flags = 0;
        rdev->pm.default_power_state_index = state_index;
index fdc3fdf78acb3b45dc025ae6598942d032b99bf8..f10faed21567f85feef0d1f097b219002d68b978 100644 (file)
@@ -546,8 +546,10 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
                /* don't suspend or resume card normally */
                rdev->powered_down = false;
                radeon_resume_kms(dev);
+               drm_kms_helper_poll_enable(dev);
        } else {
                printk(KERN_INFO "radeon: switched off\n");
+               drm_kms_helper_poll_disable(dev);
                radeon_suspend_kms(dev, pmm);
                /* don't suspend or resume card normally */
                rdev->powered_down = true;
@@ -711,6 +713,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 {
        struct radeon_device *rdev;
        struct drm_crtc *crtc;
+       struct drm_connector *connector;
        int r;
 
        if (dev == NULL || dev->dev_private == NULL) {
@@ -723,6 +726,12 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 
        if (rdev->powered_down)
                return 0;
+
+       /* turn off display hw */
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+       }
+
        /* unpin the front buffers */
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
index a8d162c6f82966e83b482e41187af4a37e2b4957..02281269a88153d4d04b9054233bf7c8320b8e51 100644 (file)
@@ -151,6 +151,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev)
 static void radeon_set_power_state(struct radeon_device *rdev)
 {
        u32 sclk, mclk;
+       bool misc_after = false;
 
        if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
            (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
@@ -167,55 +168,47 @@ static void radeon_set_power_state(struct radeon_device *rdev)
                if (mclk > rdev->clock.default_mclk)
                        mclk = rdev->clock.default_mclk;
 
-               /* voltage, pcie lanes, etc.*/
-               radeon_pm_misc(rdev);
+               /* upvolt before raising clocks, downvolt after lowering clocks */
+               if (sclk < rdev->pm.current_sclk)
+                       misc_after = true;
 
-               if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
-                       radeon_sync_with_vblank(rdev);
+               radeon_sync_with_vblank(rdev);
 
+               if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
                        if (!radeon_pm_in_vbl(rdev))
                                return;
+               }
 
-                       radeon_pm_prepare(rdev);
-                       /* set engine clock */
-                       if (sclk != rdev->pm.current_sclk) {
-                               radeon_pm_debug_check_in_vbl(rdev, false);
-                               radeon_set_engine_clock(rdev, sclk);
-                               radeon_pm_debug_check_in_vbl(rdev, true);
-                               rdev->pm.current_sclk = sclk;
-                               DRM_DEBUG("Setting: e: %d\n", sclk);
-                       }
+               radeon_pm_prepare(rdev);
 
-                       /* set memory clock */
-                       if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
-                               radeon_pm_debug_check_in_vbl(rdev, false);
-                               radeon_set_memory_clock(rdev, mclk);
-                               radeon_pm_debug_check_in_vbl(rdev, true);
-                               rdev->pm.current_mclk = mclk;
-                               DRM_DEBUG("Setting: m: %d\n", mclk);
-                       }
-                       radeon_pm_finish(rdev);
-               } else {
-                       /* set engine clock */
-                       if (sclk != rdev->pm.current_sclk) {
-                               radeon_sync_with_vblank(rdev);
-                               radeon_pm_prepare(rdev);
-                               radeon_set_engine_clock(rdev, sclk);
-                               radeon_pm_finish(rdev);
-                               rdev->pm.current_sclk = sclk;
-                               DRM_DEBUG("Setting: e: %d\n", sclk);
-                       }
-                       /* set memory clock */
-                       if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
-                               radeon_sync_with_vblank(rdev);
-                               radeon_pm_prepare(rdev);
-                               radeon_set_memory_clock(rdev, mclk);
-                               radeon_pm_finish(rdev);
-                               rdev->pm.current_mclk = mclk;
-                               DRM_DEBUG("Setting: m: %d\n", mclk);
-                       }
+               if (!misc_after)
+                       /* voltage, pcie lanes, etc.*/
+                       radeon_pm_misc(rdev);
+
+               /* set engine clock */
+               if (sclk != rdev->pm.current_sclk) {
+                       radeon_pm_debug_check_in_vbl(rdev, false);
+                       radeon_set_engine_clock(rdev, sclk);
+                       radeon_pm_debug_check_in_vbl(rdev, true);
+                       rdev->pm.current_sclk = sclk;
+                       DRM_DEBUG("Setting: e: %d\n", sclk);
+               }
+
+               /* set memory clock */
+               if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
+                       radeon_pm_debug_check_in_vbl(rdev, false);
+                       radeon_set_memory_clock(rdev, mclk);
+                       radeon_pm_debug_check_in_vbl(rdev, true);
+                       rdev->pm.current_mclk = mclk;
+                       DRM_DEBUG("Setting: m: %d\n", mclk);
                }
 
+               if (misc_after)
+                       /* voltage, pcie lanes, etc.*/
+                       radeon_pm_misc(rdev);
+
+               radeon_pm_finish(rdev);
+
                rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
                rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
        } else
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
new file mode 100644 (file)
index 0000000..b5c757f
--- /dev/null
@@ -0,0 +1,611 @@
+evergreen 0x9400
+0x00008040 WAIT_UNTIL
+0x00008044 WAIT_UNTIL_POLL_CNTL
+0x00008048 WAIT_UNTIL_POLL_MASK
+0x0000804c WAIT_UNTIL_POLL_REFDATA
+0x000088B0 VGT_VTX_VECT_EJECT_REG
+0x000088C4 VGT_CACHE_INVALIDATION
+0x000088D4 VGT_GS_VERTEX_REUSE
+0x00008958 VGT_PRIMITIVE_TYPE
+0x0000895C VGT_INDEX_TYPE
+0x00008970 VGT_NUM_INDICES
+0x00008974 VGT_NUM_INSTANCES
+0x00008990 VGT_COMPUTE_DIM_X
+0x00008994 VGT_COMPUTE_DIM_Y
+0x00008998 VGT_COMPUTE_DIM_Z
+0x0000899C VGT_COMPUTE_START_X
+0x000089A0 VGT_COMPUTE_START_Y
+0x000089A4 VGT_COMPUTE_START_Z
+0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE
+0x00008A14 PA_CL_ENHANCE
+0x00008A60 PA_SC_LINE_STIPPLE_VALUE
+0x00008B10 PA_SC_LINE_STIPPLE_STATE
+0x00008BF0 PA_SC_ENHANCE
+0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
+0x00008C00 SQ_CONFIG
+0x00008C04 SQ_GPR_RESOURCE_MGMT_1
+0x00008C08 SQ_GPR_RESOURCE_MGMT_2
+0x00008C0C SQ_GPR_RESOURCE_MGMT_3
+0x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1
+0x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2
+0x00008C18 SQ_THREAD_RESOURCE_MGMT
+0x00008C1C SQ_THREAD_RESOURCE_MGMT_2
+0x00008C20 SQ_STACK_RESOURCE_MGMT_1
+0x00008C24 SQ_STACK_RESOURCE_MGMT_2
+0x00008C28 SQ_STACK_RESOURCE_MGMT_3
+0x00008DF8 SQ_CONST_MEM_BASE
+0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS
+0x00009100 SPI_CONFIG_CNTL
+0x0000913C SPI_CONFIG_CNTL_1
+0x00009700 VC_CNTL
+0x00009714 VC_ENHANCE
+0x00009830 DB_DEBUG
+0x00009834 DB_DEBUG2
+0x00009838 DB_DEBUG3
+0x0000983C DB_DEBUG4
+0x00009854 DB_WATERMARKS
+0x0000A400 TD_PS_BORDER_COLOR_INDEX
+0x0000A404 TD_PS_BORDER_COLOR_RED
+0x0000A408 TD_PS_BORDER_COLOR_GREEN
+0x0000A40C TD_PS_BORDER_COLOR_BLUE
+0x0000A410 TD_PS_BORDER_COLOR_ALPHA
+0x0000A414 TD_VS_BORDER_COLOR_INDEX
+0x0000A418 TD_VS_BORDER_COLOR_RED
+0x0000A41C TD_VS_BORDER_COLOR_GREEN
+0x0000A420 TD_VS_BORDER_COLOR_BLUE
+0x0000A424 TD_VS_BORDER_COLOR_ALPHA
+0x0000A428 TD_GS_BORDER_COLOR_INDEX
+0x0000A42C TD_GS_BORDER_COLOR_RED
+0x0000A430 TD_GS_BORDER_COLOR_GREEN
+0x0000A434 TD_GS_BORDER_COLOR_BLUE
+0x0000A438 TD_GS_BORDER_COLOR_ALPHA
+0x0000A43C TD_HS_BORDER_COLOR_INDEX
+0x0000A440 TD_HS_BORDER_COLOR_RED
+0x0000A444 TD_HS_BORDER_COLOR_GREEN
+0x0000A448 TD_HS_BORDER_COLOR_BLUE
+0x0000A44C TD_HS_BORDER_COLOR_ALPHA
+0x0000A450 TD_LS_BORDER_COLOR_INDEX
+0x0000A454 TD_LS_BORDER_COLOR_RED
+0x0000A458 TD_LS_BORDER_COLOR_GREEN
+0x0000A45C TD_LS_BORDER_COLOR_BLUE
+0x0000A460 TD_LS_BORDER_COLOR_ALPHA
+0x0000A464 TD_CS_BORDER_COLOR_INDEX
+0x0000A468 TD_CS_BORDER_COLOR_RED
+0x0000A46C TD_CS_BORDER_COLOR_GREEN
+0x0000A470 TD_CS_BORDER_COLOR_BLUE
+0x0000A474 TD_CS_BORDER_COLOR_ALPHA
+0x00028000 DB_RENDER_CONTROL
+0x00028004 DB_COUNT_CONTROL
+0x0002800C DB_RENDER_OVERRIDE
+0x00028010 DB_RENDER_OVERRIDE2
+0x00028028 DB_STENCIL_CLEAR
+0x0002802C DB_DEPTH_CLEAR
+0x00028034 PA_SC_SCREEN_SCISSOR_BR
+0x00028030 PA_SC_SCREEN_SCISSOR_TL
+0x0002805C DB_DEPTH_SLICE
+0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
+0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
+0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
+0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3
+0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4
+0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5
+0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6
+0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7
+0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8
+0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9
+0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10
+0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11
+0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12
+0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13
+0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14
+0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15
+0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0
+0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1
+0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2
+0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3
+0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4
+0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5
+0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6
+0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7
+0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8
+0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9
+0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10
+0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11
+0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12
+0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13
+0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14
+0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15
+0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0
+0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1
+0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2
+0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3
+0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4
+0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5
+0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6
+0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7
+0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8
+0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9
+0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10
+0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11
+0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12
+0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13
+0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14
+0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15
+0x00028200 PA_SC_WINDOW_OFFSET
+0x00028204 PA_SC_WINDOW_SCISSOR_TL
+0x00028208 PA_SC_WINDOW_SCISSOR_BR
+0x0002820C PA_SC_CLIPRECT_RULE
+0x00028210 PA_SC_CLIPRECT_0_TL
+0x00028214 PA_SC_CLIPRECT_0_BR
+0x00028218 PA_SC_CLIPRECT_1_TL
+0x0002821C PA_SC_CLIPRECT_1_BR
+0x00028220 PA_SC_CLIPRECT_2_TL
+0x00028224 PA_SC_CLIPRECT_2_BR
+0x00028228 PA_SC_CLIPRECT_3_TL
+0x0002822C PA_SC_CLIPRECT_3_BR
+0x00028230 PA_SC_EDGERULE
+0x00028234 PA_SU_HARDWARE_SCREEN_OFFSET
+0x00028240 PA_SC_GENERIC_SCISSOR_TL
+0x00028244 PA_SC_GENERIC_SCISSOR_BR
+0x00028250 PA_SC_VPORT_SCISSOR_0_TL
+0x00028254 PA_SC_VPORT_SCISSOR_0_BR
+0x00028258 PA_SC_VPORT_SCISSOR_1_TL
+0x0002825C PA_SC_VPORT_SCISSOR_1_BR
+0x00028260 PA_SC_VPORT_SCISSOR_2_TL
+0x00028264 PA_SC_VPORT_SCISSOR_2_BR
+0x00028268 PA_SC_VPORT_SCISSOR_3_TL
+0x0002826C PA_SC_VPORT_SCISSOR_3_BR
+0x00028270 PA_SC_VPORT_SCISSOR_4_TL
+0x00028274 PA_SC_VPORT_SCISSOR_4_BR
+0x00028278 PA_SC_VPORT_SCISSOR_5_TL
+0x0002827C PA_SC_VPORT_SCISSOR_5_BR
+0x00028280 PA_SC_VPORT_SCISSOR_6_TL
+0x00028284 PA_SC_VPORT_SCISSOR_6_BR
+0x00028288 PA_SC_VPORT_SCISSOR_7_TL
+0x0002828C PA_SC_VPORT_SCISSOR_7_BR
+0x00028290 PA_SC_VPORT_SCISSOR_8_TL
+0x00028294 PA_SC_VPORT_SCISSOR_8_BR
+0x00028298 PA_SC_VPORT_SCISSOR_9_TL
+0x0002829C PA_SC_VPORT_SCISSOR_9_BR
+0x000282A0 PA_SC_VPORT_SCISSOR_10_TL
+0x000282A4 PA_SC_VPORT_SCISSOR_10_BR
+0x000282A8 PA_SC_VPORT_SCISSOR_11_TL
+0x000282AC PA_SC_VPORT_SCISSOR_11_BR
+0x000282B0 PA_SC_VPORT_SCISSOR_12_TL
+0x000282B4 PA_SC_VPORT_SCISSOR_12_BR
+0x000282B8 PA_SC_VPORT_SCISSOR_13_TL
+0x000282BC PA_SC_VPORT_SCISSOR_13_BR
+0x000282C0 PA_SC_VPORT_SCISSOR_14_TL
+0x000282C4 PA_SC_VPORT_SCISSOR_14_BR
+0x000282C8 PA_SC_VPORT_SCISSOR_15_TL
+0x000282CC PA_SC_VPORT_SCISSOR_15_BR
+0x000282D0 PA_SC_VPORT_ZMIN_0
+0x000282D4 PA_SC_VPORT_ZMAX_0
+0x000282D8 PA_SC_VPORT_ZMIN_1
+0x000282DC PA_SC_VPORT_ZMAX_1
+0x000282E0 PA_SC_VPORT_ZMIN_2
+0x000282E4 PA_SC_VPORT_ZMAX_2
+0x000282E8 PA_SC_VPORT_ZMIN_3
+0x000282EC PA_SC_VPORT_ZMAX_3
+0x000282F0 PA_SC_VPORT_ZMIN_4
+0x000282F4 PA_SC_VPORT_ZMAX_4
+0x000282F8 PA_SC_VPORT_ZMIN_5
+0x000282FC PA_SC_VPORT_ZMAX_5
+0x00028300 PA_SC_VPORT_ZMIN_6
+0x00028304 PA_SC_VPORT_ZMAX_6
+0x00028308 PA_SC_VPORT_ZMIN_7
+0x0002830C PA_SC_VPORT_ZMAX_7
+0x00028310 PA_SC_VPORT_ZMIN_8
+0x00028314 PA_SC_VPORT_ZMAX_8
+0x00028318 PA_SC_VPORT_ZMIN_9
+0x0002831C PA_SC_VPORT_ZMAX_9
+0x00028320 PA_SC_VPORT_ZMIN_10
+0x00028324 PA_SC_VPORT_ZMAX_10
+0x00028328 PA_SC_VPORT_ZMIN_11
+0x0002832C PA_SC_VPORT_ZMAX_11
+0x00028330 PA_SC_VPORT_ZMIN_12
+0x00028334 PA_SC_VPORT_ZMAX_12
+0x00028338 PA_SC_VPORT_ZMIN_13
+0x0002833C PA_SC_VPORT_ZMAX_13
+0x00028340 PA_SC_VPORT_ZMIN_14
+0x00028344 PA_SC_VPORT_ZMAX_14
+0x00028348 PA_SC_VPORT_ZMIN_15
+0x0002834C PA_SC_VPORT_ZMAX_15
+0x00028350 SX_MISC
+0x00028380 SQ_VTX_SEMANTIC_0
+0x00028384 SQ_VTX_SEMANTIC_1
+0x00028388 SQ_VTX_SEMANTIC_2
+0x0002838C SQ_VTX_SEMANTIC_3
+0x00028390 SQ_VTX_SEMANTIC_4
+0x00028394 SQ_VTX_SEMANTIC_5
+0x00028398 SQ_VTX_SEMANTIC_6
+0x0002839C SQ_VTX_SEMANTIC_7
+0x000283A0 SQ_VTX_SEMANTIC_8
+0x000283A4 SQ_VTX_SEMANTIC_9
+0x000283A8 SQ_VTX_SEMANTIC_10
+0x000283AC SQ_VTX_SEMANTIC_11
+0x000283B0 SQ_VTX_SEMANTIC_12
+0x000283B4 SQ_VTX_SEMANTIC_13
+0x000283B8 SQ_VTX_SEMANTIC_14
+0x000283BC SQ_VTX_SEMANTIC_15
+0x000283C0 SQ_VTX_SEMANTIC_16
+0x000283C4 SQ_VTX_SEMANTIC_17
+0x000283C8 SQ_VTX_SEMANTIC_18
+0x000283CC SQ_VTX_SEMANTIC_19
+0x000283D0 SQ_VTX_SEMANTIC_20
+0x000283D4 SQ_VTX_SEMANTIC_21
+0x000283D8 SQ_VTX_SEMANTIC_22
+0x000283DC SQ_VTX_SEMANTIC_23
+0x000283E0 SQ_VTX_SEMANTIC_24
+0x000283E4 SQ_VTX_SEMANTIC_25
+0x000283E8 SQ_VTX_SEMANTIC_26
+0x000283EC SQ_VTX_SEMANTIC_27
+0x000283F0 SQ_VTX_SEMANTIC_28
+0x000283F4 SQ_VTX_SEMANTIC_29
+0x000283F8 SQ_VTX_SEMANTIC_30
+0x000283FC SQ_VTX_SEMANTIC_31
+0x00028400 VGT_MAX_VTX_INDX
+0x00028404 VGT_MIN_VTX_INDX
+0x00028408 VGT_INDX_OFFSET
+0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX
+0x00028410 SX_ALPHA_TEST_CONTROL
+0x00028414 CB_BLEND_RED
+0x00028418 CB_BLEND_GREEN
+0x0002841C CB_BLEND_BLUE
+0x00028420 CB_BLEND_ALPHA
+0x00028430 DB_STENCILREFMASK
+0x00028434 DB_STENCILREFMASK_BF
+0x00028438 SX_ALPHA_REF
+0x0002843C PA_CL_VPORT_XSCALE_0
+0x00028440 PA_CL_VPORT_XOFFSET_0
+0x00028444 PA_CL_VPORT_YSCALE_0
+0x00028448 PA_CL_VPORT_YOFFSET_0
+0x0002844C PA_CL_VPORT_ZSCALE_0
+0x00028450 PA_CL_VPORT_ZOFFSET_0
+0x00028454 PA_CL_VPORT_XSCALE_1
+0x00028458 PA_CL_VPORT_XOFFSET_1
+0x0002845C PA_CL_VPORT_YSCALE_1
+0x00028460 PA_CL_VPORT_YOFFSET_1
+0x00028464 PA_CL_VPORT_ZSCALE_1
+0x00028468 PA_CL_VPORT_ZOFFSET_1
+0x0002846C PA_CL_VPORT_XSCALE_2
+0x00028470 PA_CL_VPORT_XOFFSET_2
+0x00028474 PA_CL_VPORT_YSCALE_2
+0x00028478 PA_CL_VPORT_YOFFSET_2
+0x0002847C PA_CL_VPORT_ZSCALE_2
+0x00028480 PA_CL_VPORT_ZOFFSET_2
+0x00028484 PA_CL_VPORT_XSCALE_3
+0x00028488 PA_CL_VPORT_XOFFSET_3
+0x0002848C PA_CL_VPORT_YSCALE_3
+0x00028490 PA_CL_VPORT_YOFFSET_3
+0x00028494 PA_CL_VPORT_ZSCALE_3
+0x00028498 PA_CL_VPORT_ZOFFSET_3
+0x0002849C PA_CL_VPORT_XSCALE_4
+0x000284A0 PA_CL_VPORT_XOFFSET_4
+0x000284A4 PA_CL_VPORT_YSCALE_4
+0x000284A8 PA_CL_VPORT_YOFFSET_4
+0x000284AC PA_CL_VPORT_ZSCALE_4
+0x000284B0 PA_CL_VPORT_ZOFFSET_4
+0x000284B4 PA_CL_VPORT_XSCALE_5
+0x000284B8 PA_CL_VPORT_XOFFSET_5
+0x000284BC PA_CL_VPORT_YSCALE_5
+0x000284C0 PA_CL_VPORT_YOFFSET_5
+0x000284C4 PA_CL_VPORT_ZSCALE_5
+0x000284C8 PA_CL_VPORT_ZOFFSET_5
+0x000284CC PA_CL_VPORT_XSCALE_6
+0x000284D0 PA_CL_VPORT_XOFFSET_6
+0x000284D4 PA_CL_VPORT_YSCALE_6
+0x000284D8 PA_CL_VPORT_YOFFSET_6
+0x000284DC PA_CL_VPORT_ZSCALE_6
+0x000284E0 PA_CL_VPORT_ZOFFSET_6
+0x000284E4 PA_CL_VPORT_XSCALE_7
+0x000284E8 PA_CL_VPORT_XOFFSET_7
+0x000284EC PA_CL_VPORT_YSCALE_7
+0x000284F0 PA_CL_VPORT_YOFFSET_7
+0x000284F4 PA_CL_VPORT_ZSCALE_7
+0x000284F8 PA_CL_VPORT_ZOFFSET_7
+0x000284FC PA_CL_VPORT_XSCALE_8
+0x00028500 PA_CL_VPORT_XOFFSET_8
+0x00028504 PA_CL_VPORT_YSCALE_8
+0x00028508 PA_CL_VPORT_YOFFSET_8
+0x0002850C PA_CL_VPORT_ZSCALE_8
+0x00028510 PA_CL_VPORT_ZOFFSET_8
+0x00028514 PA_CL_VPORT_XSCALE_9
+0x00028518 PA_CL_VPORT_XOFFSET_9
+0x0002851C PA_CL_VPORT_YSCALE_9
+0x00028520 PA_CL_VPORT_YOFFSET_9
+0x00028524 PA_CL_VPORT_ZSCALE_9
+0x00028528 PA_CL_VPORT_ZOFFSET_9
+0x0002852C PA_CL_VPORT_XSCALE_10
+0x00028530 PA_CL_VPORT_XOFFSET_10
+0x00028534 PA_CL_VPORT_YSCALE_10
+0x00028538 PA_CL_VPORT_YOFFSET_10
+0x0002853C PA_CL_VPORT_ZSCALE_10
+0x00028540 PA_CL_VPORT_ZOFFSET_10
+0x00028544 PA_CL_VPORT_XSCALE_11
+0x00028548 PA_CL_VPORT_XOFFSET_11
+0x0002854C PA_CL_VPORT_YSCALE_11
+0x00028550 PA_CL_VPORT_YOFFSET_11
+0x00028554 PA_CL_VPORT_ZSCALE_11
+0x00028558 PA_CL_VPORT_ZOFFSET_11
+0x0002855C PA_CL_VPORT_XSCALE_12
+0x00028560 PA_CL_VPORT_XOFFSET_12
+0x00028564 PA_CL_VPORT_YSCALE_12
+0x00028568 PA_CL_VPORT_YOFFSET_12
+0x0002856C PA_CL_VPORT_ZSCALE_12
+0x00028570 PA_CL_VPORT_ZOFFSET_12
+0x00028574 PA_CL_VPORT_XSCALE_13
+0x00028578 PA_CL_VPORT_XOFFSET_13
+0x0002857C PA_CL_VPORT_YSCALE_13
+0x00028580 PA_CL_VPORT_YOFFSET_13
+0x00028584 PA_CL_VPORT_ZSCALE_13
+0x00028588 PA_CL_VPORT_ZOFFSET_13
+0x0002858C PA_CL_VPORT_XSCALE_14
+0x00028590 PA_CL_VPORT_XOFFSET_14
+0x00028594 PA_CL_VPORT_YSCALE_14
+0x00028598 PA_CL_VPORT_YOFFSET_14
+0x0002859C PA_CL_VPORT_ZSCALE_14
+0x000285A0 PA_CL_VPORT_ZOFFSET_14
+0x000285A4 PA_CL_VPORT_XSCALE_15
+0x000285A8 PA_CL_VPORT_XOFFSET_15
+0x000285AC PA_CL_VPORT_YSCALE_15
+0x000285B0 PA_CL_VPORT_YOFFSET_15
+0x000285B4 PA_CL_VPORT_ZSCALE_15
+0x000285B8 PA_CL_VPORT_ZOFFSET_15
+0x000285BC PA_CL_UCP_0_X
+0x000285C0 PA_CL_UCP_0_Y
+0x000285C4 PA_CL_UCP_0_Z
+0x000285C8 PA_CL_UCP_0_W
+0x000285CC PA_CL_UCP_1_X
+0x000285D0 PA_CL_UCP_1_Y
+0x000285D4 PA_CL_UCP_1_Z
+0x000285D8 PA_CL_UCP_1_W
+0x000285DC PA_CL_UCP_2_X
+0x000285E0 PA_CL_UCP_2_Y
+0x000285E4 PA_CL_UCP_2_Z
+0x000285E8 PA_CL_UCP_2_W
+0x000285EC PA_CL_UCP_3_X
+0x000285F0 PA_CL_UCP_3_Y
+0x000285F4 PA_CL_UCP_3_Z
+0x000285F8 PA_CL_UCP_3_W
+0x000285FC PA_CL_UCP_4_X
+0x00028600 PA_CL_UCP_4_Y
+0x00028604 PA_CL_UCP_4_Z
+0x00028608 PA_CL_UCP_4_W
+0x0002860C PA_CL_UCP_5_X
+0x00028610 PA_CL_UCP_5_Y
+0x00028614 PA_CL_UCP_5_Z
+0x00028618 PA_CL_UCP_5_W
+0x0002861C SPI_VS_OUT_ID_0
+0x00028620 SPI_VS_OUT_ID_1
+0x00028624 SPI_VS_OUT_ID_2
+0x00028628 SPI_VS_OUT_ID_3
+0x0002862C SPI_VS_OUT_ID_4
+0x00028630 SPI_VS_OUT_ID_5
+0x00028634 SPI_VS_OUT_ID_6
+0x00028638 SPI_VS_OUT_ID_7
+0x0002863C SPI_VS_OUT_ID_8
+0x00028640 SPI_VS_OUT_ID_9
+0x00028644 SPI_PS_INPUT_CNTL_0
+0x00028648 SPI_PS_INPUT_CNTL_1
+0x0002864C SPI_PS_INPUT_CNTL_2
+0x00028650 SPI_PS_INPUT_CNTL_3
+0x00028654 SPI_PS_INPUT_CNTL_4
+0x00028658 SPI_PS_INPUT_CNTL_5
+0x0002865C SPI_PS_INPUT_CNTL_6
+0x00028660 SPI_PS_INPUT_CNTL_7
+0x00028664 SPI_PS_INPUT_CNTL_8
+0x00028668 SPI_PS_INPUT_CNTL_9
+0x0002866C SPI_PS_INPUT_CNTL_10
+0x00028670 SPI_PS_INPUT_CNTL_11
+0x00028674 SPI_PS_INPUT_CNTL_12
+0x00028678 SPI_PS_INPUT_CNTL_13
+0x0002867C SPI_PS_INPUT_CNTL_14
+0x00028680 SPI_PS_INPUT_CNTL_15
+0x00028684 SPI_PS_INPUT_CNTL_16
+0x00028688 SPI_PS_INPUT_CNTL_17
+0x0002868C SPI_PS_INPUT_CNTL_18
+0x00028690 SPI_PS_INPUT_CNTL_19
+0x00028694 SPI_PS_INPUT_CNTL_20
+0x00028698 SPI_PS_INPUT_CNTL_21
+0x0002869C SPI_PS_INPUT_CNTL_22
+0x000286A0 SPI_PS_INPUT_CNTL_23
+0x000286A4 SPI_PS_INPUT_CNTL_24
+0x000286A8 SPI_PS_INPUT_CNTL_25
+0x000286AC SPI_PS_INPUT_CNTL_26
+0x000286B0 SPI_PS_INPUT_CNTL_27
+0x000286B4 SPI_PS_INPUT_CNTL_28
+0x000286B8 SPI_PS_INPUT_CNTL_29
+0x000286BC SPI_PS_INPUT_CNTL_30
+0x000286C0 SPI_PS_INPUT_CNTL_31
+0x000286C4 SPI_VS_OUT_CONFIG
+0x000286C8 SPI_THREAD_GROUPING
+0x000286CC SPI_PS_IN_CONTROL_0
+0x000286D0 SPI_PS_IN_CONTROL_1
+0x000286D4 SPI_INTERP_CONTROL_0
+0x000286D8 SPI_INPUT_Z
+0x000286DC SPI_FOG_CNTL
+0x000286E0 SPI_BARYC_CNTL
+0x000286E4 SPI_PS_IN_CONTROL_2
+0x000286E8 SPI_COMPUTE_INPUT_CNTL
+0x000286EC SPI_COMPUTE_NUM_THREAD_X
+0x000286F0 SPI_COMPUTE_NUM_THREAD_Y
+0x000286F4 SPI_COMPUTE_NUM_THREAD_Z
+0x000286F8 GDS_ADDR_SIZE
+0x00028780 CB_BLEND0_CONTROL
+0x00028784 CB_BLEND1_CONTROL
+0x00028788 CB_BLEND2_CONTROL
+0x0002878C CB_BLEND3_CONTROL
+0x00028790 CB_BLEND4_CONTROL
+0x00028794 CB_BLEND5_CONTROL
+0x00028798 CB_BLEND6_CONTROL
+0x0002879C CB_BLEND7_CONTROL
+0x000287CC CS_COPY_STATE
+0x000287D0 GFX_COPY_STATE
+0x000287D4 PA_CL_POINT_X_RAD
+0x000287D8 PA_CL_POINT_Y_RAD
+0x000287DC PA_CL_POINT_SIZE
+0x000287E0 PA_CL_POINT_CULL_RAD
+0x00028808 CB_COLOR_CONTROL
+0x0002880C DB_SHADER_CONTROL
+0x00028810 PA_CL_CLIP_CNTL
+0x00028814 PA_SU_SC_MODE_CNTL
+0x00028818 PA_CL_VTE_CNTL
+0x0002881C PA_CL_VS_OUT_CNTL
+0x00028820 PA_CL_NANINF_CNTL
+0x00028824 PA_SU_LINE_STIPPLE_CNTL
+0x00028828 PA_SU_LINE_STIPPLE_SCALE
+0x0002882C PA_SU_PRIM_FILTER_CNTL
+0x00028838 SQ_DYN_GPR_RESOURCE_LIMIT_1
+0x00028844 SQ_PGM_RESOURCES_PS
+0x00028848 SQ_PGM_RESOURCES_2_PS
+0x0002884C SQ_PGM_EXPORTS_PS
+0x0002885C SQ_PGM_RESOURCES_VS
+0x00028860 SQ_PGM_RESOURCES_2_VS
+0x00028878 SQ_PGM_RESOURCES_GS
+0x0002887C SQ_PGM_RESOURCES_2_GS
+0x00028890 SQ_PGM_RESOURCES_ES
+0x00028894 SQ_PGM_RESOURCES_2_ES
+0x000288A8 SQ_PGM_RESOURCES_FS
+0x000288BC SQ_PGM_RESOURCES_HS
+0x000288C0 SQ_PGM_RESOURCES_2_HS
+0x000288D0 SQ_PGM_RESOURCES_LS
+0x000288D4 SQ_PGM_RESOURCES_2_LS
+0x000288E8 SQ_LDS_ALLOC
+0x000288EC SQ_LDS_ALLOC_PS
+0x000288F0 SQ_VTX_SEMANTIC_CLEAR
+0x00028A00 PA_SU_POINT_SIZE
+0x00028A04 PA_SU_POINT_MINMAX
+0x00028A08 PA_SU_LINE_CNTL
+0x00028A0C PA_SC_LINE_STIPPLE
+0x00028A10 VGT_OUTPUT_PATH_CNTL
+0x00028A14 VGT_HOS_CNTL
+0x00028A18 VGT_HOS_MAX_TESS_LEVEL
+0x00028A1C VGT_HOS_MIN_TESS_LEVEL
+0x00028A20 VGT_HOS_REUSE_DEPTH
+0x00028A24 VGT_GROUP_PRIM_TYPE
+0x00028A28 VGT_GROUP_FIRST_DECR
+0x00028A2C VGT_GROUP_DECR
+0x00028A30 VGT_GROUP_VECT_0_CNTL
+0x00028A34 VGT_GROUP_VECT_1_CNTL
+0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL
+0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL
+0x00028A40 VGT_GS_MODE
+0x00028A48 PA_SC_MODE_CNTL_0
+0x00028A4C PA_SC_MODE_CNTL_1
+0x00028A50 VGT_ENHANCE
+0x00028A54 VGT_GS_PER_ES
+0x00028A58 VGT_ES_PER_GS
+0x00028A5C VGT_GS_PER_VS
+0x00028A6C VGT_GS_OUT_PRIM_TYPE
+0x00028A84 VGT_PRIMITIVEID_EN
+0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN
+0x00028AA0 VGT_INSTANCE_STEP_RATE_0
+0x00028AA4 VGT_INSTANCE_STEP_RATE_1
+0x00028AB4 VGT_REUSE_OFF
+0x00028AB8 VGT_VTX_CNT_EN
+0x00028ABC DB_HTILE_SURFACE
+0x00028AC0 DB_SRESULTS_COMPARE_STATE0
+0x00028AC4 DB_SRESULTS_COMPARE_STATE1
+0x00028AC8 DB_PRELOAD_CONTROL
+0x00028B38 VGT_GS_MAX_VERT_OUT
+0x00028B54 VGT_SHADER_STAGES_EN
+0x00028B58 VGT_LS_HS_CONFIG
+0x00028B5C VGT_LS_SIZE
+0x00028B60 VGT_HS_SIZE
+0x00028B64 VGT_LS_HS_ALLOC
+0x00028B68 VGT_HS_PATCH_CONST
+0x00028B6C VGT_TF_PARAM
+0x00028B70 DB_ALPHA_TO_MASK
+0x00028B74 VGT_DISPATCH_INITIATOR
+0x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL
+0x00028B7C PA_SU_POLY_OFFSET_CLAMP
+0x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE
+0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET
+0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE
+0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET
+0x00028B74 VGT_GS_INSTANCE_CNT
+0x00028C00 PA_SC_LINE_CNTL
+0x00028C08 PA_SU_VTX_CNTL
+0x00028C0C PA_CL_GB_VERT_CLIP_ADJ
+0x00028C10 PA_CL_GB_VERT_DISC_ADJ
+0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
+0x00028C18 PA_CL_GB_HORZ_DISC_ADJ
+0x00028C1C PA_SC_AA_SAMPLE_LOCS_0
+0x00028C20 PA_SC_AA_SAMPLE_LOCS_1
+0x00028C24 PA_SC_AA_SAMPLE_LOCS_2
+0x00028C28 PA_SC_AA_SAMPLE_LOCS_3
+0x00028C2C PA_SC_AA_SAMPLE_LOCS_4
+0x00028C30 PA_SC_AA_SAMPLE_LOCS_5
+0x00028C34 PA_SC_AA_SAMPLE_LOCS_6
+0x00028C38 PA_SC_AA_SAMPLE_LOCS_7
+0x00028C3C PA_SC_AA_MASK
+0x00028C8C CB_COLOR0_CLEAR_WORD0
+0x00028C90 CB_COLOR0_CLEAR_WORD1
+0x00028C94 CB_COLOR0_CLEAR_WORD2
+0x00028C98 CB_COLOR0_CLEAR_WORD3
+0x00028CC8 CB_COLOR1_CLEAR_WORD0
+0x00028CCC CB_COLOR1_CLEAR_WORD1
+0x00028CD0 CB_COLOR1_CLEAR_WORD2
+0x00028CD4 CB_COLOR1_CLEAR_WORD3
+0x00028D04 CB_COLOR2_CLEAR_WORD0
+0x00028D08 CB_COLOR2_CLEAR_WORD1
+0x00028D0C CB_COLOR2_CLEAR_WORD2
+0x00028D10 CB_COLOR2_CLEAR_WORD3
+0x00028D40 CB_COLOR3_CLEAR_WORD0
+0x00028D44 CB_COLOR3_CLEAR_WORD1
+0x00028D48 CB_COLOR3_CLEAR_WORD2
+0x00028D4C CB_COLOR3_CLEAR_WORD3
+0x00028D7C CB_COLOR4_CLEAR_WORD0
+0x00028D80 CB_COLOR4_CLEAR_WORD1
+0x00028D84 CB_COLOR4_CLEAR_WORD2
+0x00028D88 CB_COLOR4_CLEAR_WORD3
+0x00028DB8 CB_COLOR5_CLEAR_WORD0
+0x00028DBC CB_COLOR5_CLEAR_WORD1
+0x00028DC0 CB_COLOR5_CLEAR_WORD2
+0x00028DC4 CB_COLOR5_CLEAR_WORD3
+0x00028DF4 CB_COLOR6_CLEAR_WORD0
+0x00028DF8 CB_COLOR6_CLEAR_WORD1
+0x00028DFC CB_COLOR6_CLEAR_WORD2
+0x00028E00 CB_COLOR6_CLEAR_WORD3
+0x00028E30 CB_COLOR7_CLEAR_WORD0
+0x00028E34 CB_COLOR7_CLEAR_WORD1
+0x00028E38 CB_COLOR7_CLEAR_WORD2
+0x00028E3C CB_COLOR7_CLEAR_WORD3
+0x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0
+0x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1
+0x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2
+0x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3
+0x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4
+0x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5
+0x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6
+0x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7
+0x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8
+0x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9
+0x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10
+0x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11
+0x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12
+0x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13
+0x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14
+0x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15
+0x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0
+0x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1
+0x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2
+0x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3
+0x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4
+0x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5
+0x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6
+0x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7
+0x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8
+0x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9
+0x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10
+0x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11
+0x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12
+0x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13
+0x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14
+0x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15
+0x0003CFF0 SQ_VTX_BASE_VTX_LOC
+0x0003CFF4 SQ_VTX_START_INST_LOC
+0x0003FF00 SQ_TEX_SAMPLER_CLEAR
+0x0003FF04 SQ_TEX_RESOURCE_CLEAR
+0x0003FF08 SQ_LOOP_BOOL_CLEAR
index 79887cac5b54ce19da66e1d5ba3e55df8df07527..7bb4c3e52f3b055ceafc27471e516477e4a3fa5b 100644 (file)
@@ -74,7 +74,8 @@ void rs600_pm_misc(struct radeon_device *rdev)
                        if (voltage->delay)
                                udelay(voltage->delay);
                }
-       }
+       } else if (voltage->type == VOLTAGE_VDDC)
+               radeon_atom_set_voltage(rdev, voltage->vddc_id);
 
        dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH);
        dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
index 253f24aec031e48e1cf2bd99d8595a50275b1f0d..33952da65340503ad3e07bbb428bf4487b027737 100644 (file)
@@ -44,7 +44,12 @@ void rv770_fini(struct radeon_device *rdev);
 
 void rv770_pm_misc(struct radeon_device *rdev)
 {
+       int requested_index = rdev->pm.requested_power_state_index;
+       struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
+       struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
 
+       if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
+               radeon_atom_set_voltage(rdev, voltage->voltage);
 }
 
 /*
index 0d9a42c2394f79983344cd8bd21d99204a288109..ef910694bd634807631dd0958831bfa8c44421df 100644 (file)
@@ -77,7 +77,7 @@ struct ttm_page_pool {
 /**
  * Limits for the pool. They are handled without locks because only place where
  * they may change is in sysfs store. They won't have immediate effect anyway
- * so forcing serialiazation to access them is pointless.
+ * so forcing serialization to access them is pointless.
  */
 
 struct ttm_pool_opts {
@@ -165,16 +165,18 @@ static ssize_t ttm_pool_store(struct kobject *kobj,
                m->options.small = val;
        else if (attr == &ttm_page_pool_alloc_size) {
                if (val > NUM_PAGES_TO_ALLOC*8) {
-                       printk(KERN_ERR "[ttm] Setting allocation size to %lu "
-                                       "is not allowed. Recomended size is "
-                                       "%lu\n",
-                                       NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
-                                       NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+                       printk(KERN_ERR TTM_PFX
+                              "Setting allocation size to %lu "
+                              "is not allowed. Recommended size is "
+                              "%lu\n",
+                              NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7),
+                              NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
                        return size;
                } else if (val > NUM_PAGES_TO_ALLOC) {
-                       printk(KERN_WARNING "[ttm] Setting allocation size to "
-                                       "larger than %lu is not recomended.\n",
-                                       NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
+                       printk(KERN_WARNING TTM_PFX
+                              "Setting allocation size to "
+                              "larger than %lu is not recommended.\n",
+                              NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10));
                }
                m->options.alloc_size = val;
        }
@@ -277,7 +279,7 @@ static void ttm_pages_put(struct page *pages[], unsigned npages)
 {
        unsigned i;
        if (set_pages_array_wb(pages, npages))
-               printk(KERN_ERR "[ttm] Failed to set %d pages to wb!\n",
+               printk(KERN_ERR TTM_PFX "Failed to set %d pages to wb!\n",
                                npages);
        for (i = 0; i < npages; ++i)
                __free_page(pages[i]);
@@ -313,7 +315,8 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
        pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
                        GFP_KERNEL);
        if (!pages_to_free) {
-               printk(KERN_ERR "Failed to allocate memory for pool free operation.\n");
+               printk(KERN_ERR TTM_PFX
+                      "Failed to allocate memory for pool free operation.\n");
                return 0;
        }
 
@@ -390,7 +393,7 @@ static int ttm_pool_get_num_unused_pages(void)
 }
 
 /**
- * Calback for mm to request pool to reduce number of page held.
+ * Callback for mm to request pool to reduce number of page held.
  */
 static int ttm_pool_mm_shrink(int shrink_pages, gfp_t gfp_mask)
 {
@@ -433,14 +436,16 @@ static int ttm_set_pages_caching(struct page **pages,
        case tt_uncached:
                r = set_pages_array_uc(pages, cpages);
                if (r)
-                       printk(KERN_ERR "[ttm] Failed to set %d pages to uc!\n",
-                                       cpages);
+                       printk(KERN_ERR TTM_PFX
+                              "Failed to set %d pages to uc!\n",
+                              cpages);
                break;
        case tt_wc:
                r = set_pages_array_wc(pages, cpages);
                if (r)
-                       printk(KERN_ERR "[ttm] Failed to set %d pages to wc!\n",
-                                       cpages);
+                       printk(KERN_ERR TTM_PFX
+                              "Failed to set %d pages to wc!\n",
+                              cpages);
                break;
        default:
                break;
@@ -458,7 +463,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages,
                struct page **failed_pages, unsigned cpages)
 {
        unsigned i;
-       /* Failed pages has to be reed */
+       /* Failed pages have to be freed */
        for (i = 0; i < cpages; ++i) {
                list_del(&failed_pages[i]->lru);
                __free_page(failed_pages[i]);
@@ -485,7 +490,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
        caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL);
 
        if (!caching_array) {
-               printk(KERN_ERR "[ttm] unable to allocate table for new pages.");
+               printk(KERN_ERR TTM_PFX
+                      "Unable to allocate table for new pages.");
                return -ENOMEM;
        }
 
@@ -493,12 +499,13 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
                p = alloc_page(gfp_flags);
 
                if (!p) {
-                       printk(KERN_ERR "[ttm] unable to get page %u\n", i);
+                       printk(KERN_ERR TTM_PFX "Unable to get page %u.\n", i);
 
                        /* store already allocated pages in the pool after
                         * setting the caching state */
                        if (cpages) {
-                               r = ttm_set_pages_caching(caching_array, cstate, cpages);
+                               r = ttm_set_pages_caching(caching_array,
+                                                         cstate, cpages);
                                if (r)
                                        ttm_handle_caching_state_failure(pages,
                                                ttm_flags, cstate,
@@ -590,7 +597,8 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
                        ++pool->nrefills;
                        pool->npages += alloc_size;
                } else {
-                       printk(KERN_ERR "[ttm] Failed to fill pool (%p).", pool);
+                       printk(KERN_ERR TTM_PFX
+                              "Failed to fill pool (%p).", pool);
                        /* If we have any pages left put them to the pool. */
                        list_for_each_entry(p, &pool->list, lru) {
                                ++cpages;
@@ -671,13 +679,14 @@ int ttm_get_pages(struct list_head *pages, int flags,
                if (flags & TTM_PAGE_FLAG_DMA32)
                        gfp_flags |= GFP_DMA32;
                else
-                       gfp_flags |= __GFP_HIGHMEM;
+                       gfp_flags |= GFP_HIGHUSER;
 
                for (r = 0; r < count; ++r) {
                        p = alloc_page(gfp_flags);
                        if (!p) {
 
-                               printk(KERN_ERR "[ttm] unable to allocate page.");
+                               printk(KERN_ERR TTM_PFX
+                                      "Unable to allocate page.");
                                return -ENOMEM;
                        }
 
@@ -709,8 +718,9 @@ int ttm_get_pages(struct list_head *pages, int flags,
                if (r) {
                        /* If there is any pages in the list put them back to
                         * the pool. */
-                       printk(KERN_ERR "[ttm] Failed to allocate extra pages "
-                                       "for large request.");
+                       printk(KERN_ERR TTM_PFX
+                              "Failed to allocate extra pages "
+                              "for large request.");
                        ttm_put_pages(pages, 0, flags, cstate);
                        return r;
                }
@@ -778,7 +788,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
        if (atomic_add_return(1, &_manager.page_alloc_inited) > 1)
                return 0;
 
-       printk(KERN_INFO "[ttm] Initializing pool allocator.\n");
+       printk(KERN_INFO TTM_PFX "Initializing pool allocator.\n");
 
        ttm_page_pool_init_locked(&_manager.wc_pool, GFP_HIGHUSER, "wc");
 
@@ -813,7 +823,7 @@ void ttm_page_alloc_fini()
        if (atomic_sub_return(1, &_manager.page_alloc_inited) > 0)
                return;
 
-       printk(KERN_INFO "[ttm] Finilizing pool allocator.\n");
+       printk(KERN_INFO TTM_PFX "Finalizing pool allocator.\n");
        ttm_pool_mm_shrink_fini(&_manager);
 
        for (i = 0; i < NUM_POOLS; ++i)
index 1a3cb6816d1cc1a72a58b75a1c4c952e6607c7d3..4505e17df3f557e21beb14581e72f3356985e345 100644 (file)
@@ -4,6 +4,6 @@ ccflags-y := -Iinclude/drm
 vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
            vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \
            vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
-           vmwgfx_overlay.o
+           vmwgfx_overlay.o vmwgfx_fence.o
 
 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
index 0c9c0811f42dd03b9c92d0ea154e249b8ed3b397..b793c8c9acb3162049fabe03b7cf43cfab1939fb 100644 (file)
@@ -88,6 +88,9 @@
 #define DRM_IOCTL_VMW_FENCE_WAIT                               \
        DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT,         \
                 struct drm_vmw_fence_wait_arg)
+#define DRM_IOCTL_VMW_UPDATE_LAYOUT                            \
+       DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT,      \
+                struct drm_vmw_update_layout_arg)
 
 
 /**
@@ -135,7 +138,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = {
        VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
                      DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED),
        VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
-                     DRM_AUTH | DRM_UNLOCKED)
+                     DRM_AUTH | DRM_UNLOCKED),
+       VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl,
+                     DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED)
 };
 
 static struct pci_device_id vmw_pci_id_list[] = {
@@ -318,6 +323,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
                goto out_err3;
        }
 
+       /* Need mmio memory to check for fifo pitchlock cap. */
+       if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
+           !(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) &&
+           !vmw_fifo_have_pitchlock(dev_priv)) {
+               ret = -ENOSYS;
+               DRM_ERROR("Hardware has no pitchlock\n");
+               goto out_err4;
+       }
+
        dev_priv->tdev = ttm_object_device_init
            (dev_priv->mem_global_ref.object, 12);
 
@@ -399,8 +413,6 @@ static int vmw_driver_unload(struct drm_device *dev)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
 
-       DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n");
-
        unregister_pm_notifier(&dev_priv->pm_nb);
 
        vmw_fb_close(dev_priv);
@@ -546,7 +558,6 @@ static int vmw_master_create(struct drm_device *dev,
 {
        struct vmw_master *vmaster;
 
-       DRM_INFO("Master create.\n");
        vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
        if (unlikely(vmaster == NULL))
                return -ENOMEM;
@@ -563,7 +574,6 @@ static void vmw_master_destroy(struct drm_device *dev,
 {
        struct vmw_master *vmaster = vmw_master(master);
 
-       DRM_INFO("Master destroy.\n");
        master->driver_priv = NULL;
        kfree(vmaster);
 }
@@ -579,8 +589,6 @@ static int vmw_master_set(struct drm_device *dev,
        struct vmw_master *vmaster = vmw_master(file_priv->master);
        int ret = 0;
 
-       DRM_INFO("Master set.\n");
-
        if (active) {
                BUG_ON(active != &dev_priv->fbdev_master);
                ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
@@ -622,8 +630,6 @@ static void vmw_master_drop(struct drm_device *dev,
        struct vmw_master *vmaster = vmw_master(file_priv->master);
        int ret;
 
-       DRM_INFO("Master drop.\n");
-
        /**
         * Make sure the master doesn't disappear while we have
         * it locked.
index 356dc935ec133f974c2c95e2be5d1146cd07c9a9..eaad520953393f5f5da3601627e0ec141c4c4a1f 100644 (file)
 
 #define VMWGFX_DRIVER_DATE "20100209"
 #define VMWGFX_DRIVER_MAJOR 1
-#define VMWGFX_DRIVER_MINOR 0
+#define VMWGFX_DRIVER_MINOR 2
 #define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
 #define VMWGFX_MAX_RELOCATIONS 2048
 #define VMWGFX_MAX_GMRS 2048
+#define VMWGFX_MAX_DISPLAYS 16
 
 struct vmw_fpriv {
        struct drm_master *locked_master;
@@ -102,6 +103,13 @@ struct vmw_surface {
        struct vmw_cursor_snooper snooper;
 };
 
+struct vmw_fence_queue {
+       struct list_head head;
+       struct timespec lag;
+       struct timespec lag_time;
+       spinlock_t lock;
+};
+
 struct vmw_fifo_state {
        unsigned long reserved_size;
        __le32 *dynamic_buffer;
@@ -115,6 +123,7 @@ struct vmw_fifo_state {
        uint32_t capabilities;
        struct mutex fifo_mutex;
        struct rw_semaphore rwsem;
+       struct vmw_fence_queue fence_queue;
 };
 
 struct vmw_relocation {
@@ -144,6 +153,14 @@ struct vmw_master {
        struct ttm_lock lock;
 };
 
+struct vmw_vga_topology_state {
+       uint32_t width;
+       uint32_t height;
+       uint32_t primary;
+       uint32_t pos_x;
+       uint32_t pos_y;
+};
+
 struct vmw_private {
        struct ttm_bo_device bdev;
        struct ttm_bo_global_ref bo_global_ref;
@@ -171,14 +188,19 @@ struct vmw_private {
         * VGA registers.
         */
 
+       struct vmw_vga_topology_state vga_save[VMWGFX_MAX_DISPLAYS];
        uint32_t vga_width;
        uint32_t vga_height;
        uint32_t vga_depth;
        uint32_t vga_bpp;
        uint32_t vga_pseudo;
        uint32_t vga_red_mask;
-       uint32_t vga_blue_mask;
        uint32_t vga_green_mask;
+       uint32_t vga_blue_mask;
+       uint32_t vga_bpl;
+       uint32_t vga_pitchlock;
+
+       uint32_t num_displays;
 
        /*
         * Framebuffer info.
@@ -393,6 +415,7 @@ extern int vmw_fifo_send_fence(struct vmw_private *dev_priv,
 extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
 extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
 extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
+extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv);
 
 /**
  * TTM glue - vmwgfx_ttm_glue.c
@@ -441,6 +464,23 @@ extern int vmw_fallback_wait(struct vmw_private *dev_priv,
                             uint32_t sequence,
                             bool interruptible,
                             unsigned long timeout);
+extern void vmw_update_sequence(struct vmw_private *dev_priv,
+                               struct vmw_fifo_state *fifo_state);
+
+
+/**
+ * Rudimentary fence objects currently used only for throttling -
+ * vmwgfx_fence.c
+ */
+
+extern void vmw_fence_queue_init(struct vmw_fence_queue *queue);
+extern void vmw_fence_queue_takedown(struct vmw_fence_queue *queue);
+extern int vmw_fence_push(struct vmw_fence_queue *queue,
+                         uint32_t sequence);
+extern int vmw_fence_pull(struct vmw_fence_queue *queue,
+                         uint32_t signaled_sequence);
+extern int vmw_wait_lag(struct vmw_private *dev_priv,
+                       struct vmw_fence_queue *queue, uint32_t us);
 
 /**
  * Kernel framebuffer - vmwgfx_fb.c
@@ -466,6 +506,11 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
                          struct ttm_object_file *tfile,
                          struct ttm_buffer_object *bo,
                          SVGA3dCmdHeader *header);
+void vmw_kms_write_svga(struct vmw_private *vmw_priv,
+                       unsigned width, unsigned height, unsigned pitch,
+                       unsigned bbp, unsigned depth);
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
 
 /**
  * Overlay control - vmwgfx_overlay.c
index dbd36b8910cf5cc65f22879c61017f8a0de83dc3..bdd67cf83315f590165fbf6b40437454d4e29186 100644 (file)
@@ -669,6 +669,15 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
                goto out_err;
 
        vmw_apply_relocations(sw_context);
+
+       if (arg->throttle_us) {
+               ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.fence_queue,
+                                  arg->throttle_us);
+
+               if (unlikely(ret != 0))
+                       goto out_err;
+       }
+
        vmw_fifo_commit(dev_priv, arg->command_size);
 
        ret = vmw_fifo_send_fence(dev_priv, &sequence);
index 7421aaad8d094e17da75b3b5308d3f491a63e9fa..b0866f04ec7613133a6e4ebc7ab3546906af8258 100644 (file)
@@ -132,16 +132,14 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var,
                return -EINVAL;
        }
 
-       /* without multimon its hard to resize */
-       if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) &&
-           (var->xres != par->max_width ||
-            var->yres != par->max_height)) {
-               DRM_ERROR("Tried to resize, but we don't have multimon\n");
+       if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
+           (var->xoffset != 0 || var->yoffset != 0)) {
+               DRM_ERROR("Can not handle panning without display topology\n");
                return -EINVAL;
        }
 
-       if (var->xres > par->max_width ||
-           var->yres > par->max_height) {
+       if ((var->xoffset + var->xres) > par->max_width ||
+           (var->yoffset + var->yres) > par->max_height) {
                DRM_ERROR("Requested geom can not fit in framebuffer\n");
                return -EINVAL;
        }
@@ -154,27 +152,11 @@ static int vmw_fb_set_par(struct fb_info *info)
        struct vmw_fb_par *par = info->par;
        struct vmw_private *vmw_priv = par->vmw_priv;
 
-       if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
-               vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
-
-               vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
-               vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width);
-               vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height);
-               vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp);
-               vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth);
-               vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
-               vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
-               vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
-
+       vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
+                          info->fix.line_length,
+                          par->bpp, par->depth);
+       if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) {
                /* TODO check if pitch and offset changes */
-
                vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
@@ -183,13 +165,13 @@ static int vmw_fb_set_par(struct fb_info *info)
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
-       } else {
-               vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres);
-               vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres);
-
-               /* TODO check if pitch and offset changes */
        }
 
+       /* This is really helpful since if this fails the user
+        * can probably not see anything on the screen.
+        */
+       WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0);
+
        return 0;
 }
 
@@ -416,48 +398,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
        unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size;
        int ret;
 
+       /* XXX These shouldn't be hardcoded. */
        initial_width = 800;
        initial_height = 600;
 
        fb_bbp = 32;
        fb_depth = 24;
 
-       if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
-               fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
-               fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
-       } else {
-               fb_width = min(vmw_priv->fb_max_width, initial_width);
-               fb_height = min(vmw_priv->fb_max_height, initial_height);
-       }
+       /* XXX As shouldn't these be as well. */
+       fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
+       fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
 
        initial_width = min(fb_width, initial_width);
        initial_height = min(fb_height, initial_height);
 
-       vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width);
-       vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height);
-       vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp);
-       vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth);
-       vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
-       vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
-       vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
-
-       fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE);
+       fb_pitch = fb_width * fb_bbp / 8;
+       fb_size = fb_pitch * fb_height;
        fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET);
-       fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE);
-
-       DRM_DEBUG("width  %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH));
-       DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT));
-       DRM_DEBUG("width  %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH));
-       DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT));
-       DRM_DEBUG("bpp    %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL));
-       DRM_DEBUG("depth  %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH));
-       DRM_DEBUG("bpl    %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE));
-       DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK));
-       DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK));
-       DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK));
-       DRM_DEBUG("fb_offset 0x%08x\n", fb_offset);
-       DRM_DEBUG("fb_pitch  %u\n", fb_pitch);
-       DRM_DEBUG("fb_size   %u kiB\n", fb_size / 1024);
 
        info = framebuffer_alloc(sizeof(*par), device);
        if (!info)
@@ -659,6 +616,10 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
                goto err_unlock;
 
        ret = ttm_bo_validate(bo, &ne_placement, false, false, false);
+
+       /* Could probably bug on */
+       WARN_ON(bo->offset != 0);
+
        ttm_bo_unreserve(bo);
 err_unlock:
        ttm_write_unlock(&vmw_priv->active_master->lock);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
new file mode 100644 (file)
index 0000000..61eacc1
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2010 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "vmwgfx_drv.h"
+
+struct vmw_fence {
+       struct list_head head;
+       uint32_t sequence;
+       struct timespec submitted;
+};
+
+void vmw_fence_queue_init(struct vmw_fence_queue *queue)
+{
+       INIT_LIST_HEAD(&queue->head);
+       queue->lag = ns_to_timespec(0);
+       getrawmonotonic(&queue->lag_time);
+       spin_lock_init(&queue->lock);
+}
+
+void vmw_fence_queue_takedown(struct vmw_fence_queue *queue)
+{
+       struct vmw_fence *fence, *next;
+
+       spin_lock(&queue->lock);
+       list_for_each_entry_safe(fence, next, &queue->head, head) {
+               kfree(fence);
+       }
+       spin_unlock(&queue->lock);
+}
+
+int vmw_fence_push(struct vmw_fence_queue *queue,
+                  uint32_t sequence)
+{
+       struct vmw_fence *fence = kmalloc(sizeof(*fence), GFP_KERNEL);
+
+       if (unlikely(!fence))
+               return -ENOMEM;
+
+       fence->sequence = sequence;
+       getrawmonotonic(&fence->submitted);
+       spin_lock(&queue->lock);
+       list_add_tail(&fence->head, &queue->head);
+       spin_unlock(&queue->lock);
+
+       return 0;
+}
+
+int vmw_fence_pull(struct vmw_fence_queue *queue,
+                  uint32_t signaled_sequence)
+{
+       struct vmw_fence *fence, *next;
+       struct timespec now;
+       bool updated = false;
+
+       spin_lock(&queue->lock);
+       getrawmonotonic(&now);
+
+       if (list_empty(&queue->head)) {
+               queue->lag = ns_to_timespec(0);
+               queue->lag_time = now;
+               updated = true;
+               goto out_unlock;
+       }
+
+       list_for_each_entry_safe(fence, next, &queue->head, head) {
+               if (signaled_sequence - fence->sequence > (1 << 30))
+                       continue;
+
+               queue->lag = timespec_sub(now, fence->submitted);
+               queue->lag_time = now;
+               updated = true;
+               list_del(&fence->head);
+               kfree(fence);
+       }
+
+out_unlock:
+       spin_unlock(&queue->lock);
+
+       return (updated) ? 0 : -EBUSY;
+}
+
+static struct timespec vmw_timespec_add(struct timespec t1,
+                                       struct timespec t2)
+{
+       t1.tv_sec += t2.tv_sec;
+       t1.tv_nsec += t2.tv_nsec;
+       if (t1.tv_nsec >= 1000000000L) {
+               t1.tv_sec += 1;
+               t1.tv_nsec -= 1000000000L;
+       }
+
+       return t1;
+}
+
+static struct timespec vmw_fifo_lag(struct vmw_fence_queue *queue)
+{
+       struct timespec now;
+
+       spin_lock(&queue->lock);
+       getrawmonotonic(&now);
+       queue->lag = vmw_timespec_add(queue->lag,
+                                     timespec_sub(now, queue->lag_time));
+       queue->lag_time = now;
+       spin_unlock(&queue->lock);
+       return queue->lag;
+}
+
+
+static bool vmw_lag_lt(struct vmw_fence_queue *queue,
+                      uint32_t us)
+{
+       struct timespec lag, cond;
+
+       cond = ns_to_timespec((s64) us * 1000);
+       lag = vmw_fifo_lag(queue);
+       return (timespec_compare(&lag, &cond) < 1);
+}
+
+int vmw_wait_lag(struct vmw_private *dev_priv,
+                struct vmw_fence_queue *queue, uint32_t us)
+{
+       struct vmw_fence *fence;
+       uint32_t sequence;
+       int ret;
+
+       while (!vmw_lag_lt(queue, us)) {
+               spin_lock(&queue->lock);
+               if (list_empty(&queue->head))
+                       sequence = atomic_read(&dev_priv->fence_seq);
+               else {
+                       fence = list_first_entry(&queue->head,
+                                                struct vmw_fence, head);
+                       sequence = fence->sequence;
+               }
+               spin_unlock(&queue->lock);
+
+               ret = vmw_wait_fence(dev_priv, false, sequence, true,
+                                    3*HZ);
+
+               if (unlikely(ret != 0))
+                       return ret;
+
+               (void) vmw_fence_pull(queue, sequence);
+       }
+       return 0;
+}
+
+
index 39d43a01d846fd9e7bcd6a1206b06143f90a740d..e6a1eb7ea95498f00e65d123adeae79160af8fa8 100644 (file)
@@ -34,6 +34,9 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
        __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
        uint32_t fifo_min, hwversion;
 
+       if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
+               return false;
+
        fifo_min = ioread32(fifo_mem  + SVGA_FIFO_MIN);
        if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
                return false;
@@ -48,6 +51,21 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
        return true;
 }
 
+bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv)
+{
+       __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+       uint32_t caps;
+
+       if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
+               return false;
+
+       caps = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES);
+       if (caps & SVGA_FIFO_CAP_PITCHLOCK)
+               return true;
+
+       return false;
+}
+
 int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
 {
        __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
@@ -120,7 +138,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
 
        atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence);
        iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE);
-
+       vmw_fence_queue_init(&fifo->fence_queue);
        return vmw_fifo_send_fence(dev_priv, &dummy);
 out_err:
        vfree(fifo->static_buffer);
@@ -159,6 +177,7 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
                  dev_priv->enable_state);
 
        mutex_unlock(&dev_priv->hw_mutex);
+       vmw_fence_queue_takedown(&fifo->fence_queue);
 
        if (likely(fifo->last_buffer != NULL)) {
                vfree(fifo->last_buffer);
@@ -484,6 +503,8 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence)
        fifo_state->last_buffer_add = true;
        vmw_fifo_commit(dev_priv, bytes);
        fifo_state->last_buffer_add = false;
+       (void) vmw_fence_push(&fifo_state->fence_queue, *sequence);
+       vmw_update_sequence(dev_priv, fifo_state);
 
 out_err:
        return ret;
index 4d7cb539386000b50798960f8615d2fc2b25d2ba..e92298a6a383c1fe60c290002a33a3e39caa456f 100644 (file)
@@ -64,22 +64,33 @@ static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t sequence)
        return (busy == 0);
 }
 
+void vmw_update_sequence(struct vmw_private *dev_priv,
+                        struct vmw_fifo_state *fifo_state)
+{
+       __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+
+       uint32_t sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE);
+
+       if (dev_priv->last_read_sequence != sequence) {
+               dev_priv->last_read_sequence = sequence;
+               vmw_fence_pull(&fifo_state->fence_queue, sequence);
+       }
+}
 
 bool vmw_fence_signaled(struct vmw_private *dev_priv,
                        uint32_t sequence)
 {
-       __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
        struct vmw_fifo_state *fifo_state;
        bool ret;
 
        if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
                return true;
 
-       dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE);
+       fifo_state = &dev_priv->fifo;
+       vmw_update_sequence(dev_priv, fifo_state);
        if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
                return true;
 
-       fifo_state = &dev_priv->fifo;
        if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) &&
            vmw_fifo_idle(dev_priv, sequence))
                return true;
index bbc7c4c30bc7fc26d6c2244ba53ab70324af1593..f1d62611241586f73115a0a8cd60f853837308f6 100644 (file)
@@ -30,6 +30,8 @@
 /* Might need a hrtimer here? */
 #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
 
+static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb);
+static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb);
 
 void vmw_display_unit_cleanup(struct vmw_display_unit *du)
 {
@@ -326,6 +328,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
 struct vmw_framebuffer_surface {
        struct vmw_framebuffer base;
        struct vmw_surface *surface;
+       struct vmw_dma_buffer *buffer;
        struct delayed_work d_work;
        struct mutex work_lock;
        bool present_fs;
@@ -500,8 +503,8 @@ int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
        vfbs->base.base.depth = 24;
        vfbs->base.base.width = width;
        vfbs->base.base.height = height;
-       vfbs->base.pin = NULL;
-       vfbs->base.unpin = NULL;
+       vfbs->base.pin = &vmw_surface_dmabuf_pin;
+       vfbs->base.unpin = &vmw_surface_dmabuf_unpin;
        vfbs->surface = surface;
        mutex_init(&vfbs->work_lock);
        INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback);
@@ -589,6 +592,40 @@ static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
        .create_handle = vmw_framebuffer_create_handle,
 };
 
+static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb)
+{
+       struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
+       struct vmw_framebuffer_surface *vfbs =
+               vmw_framebuffer_to_vfbs(&vfb->base);
+       unsigned long size = vfbs->base.base.pitch * vfbs->base.base.height;
+       int ret;
+
+       vfbs->buffer = kzalloc(sizeof(*vfbs->buffer), GFP_KERNEL);
+       if (unlikely(vfbs->buffer == NULL))
+               return -ENOMEM;
+
+       vmw_overlay_pause_all(dev_priv);
+       ret = vmw_dmabuf_init(dev_priv, vfbs->buffer, size,
+                              &vmw_vram_ne_placement,
+                              false, &vmw_dmabuf_bo_free);
+       vmw_overlay_resume_all(dev_priv);
+
+       return ret;
+}
+
+static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb)
+{
+       struct ttm_buffer_object *bo;
+       struct vmw_framebuffer_surface *vfbs =
+               vmw_framebuffer_to_vfbs(&vfb->base);
+
+       bo = &vfbs->buffer->base;
+       ttm_bo_unref(&bo);
+       vfbs->buffer = NULL;
+
+       return 0;
+}
+
 static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
 {
        struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
@@ -596,33 +633,15 @@ static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
                vmw_framebuffer_to_vfbd(&vfb->base);
        int ret;
 
+
        vmw_overlay_pause_all(dev_priv);
 
        ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer);
 
-       if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
-               vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
-
-               vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
-               vmw_write(dev_priv, SVGA_REG_WIDTH, vfb->base.width);
-               vmw_write(dev_priv, SVGA_REG_HEIGHT, vfb->base.height);
-               vmw_write(dev_priv, SVGA_REG_BITS_PER_PIXEL, vfb->base.bits_per_pixel);
-               vmw_write(dev_priv, SVGA_REG_DEPTH, vfb->base.depth);
-               vmw_write(dev_priv, SVGA_REG_RED_MASK, 0x00ff0000);
-               vmw_write(dev_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
-               vmw_write(dev_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
-       } else
-               WARN_ON(true);
-
        vmw_overlay_resume_all(dev_priv);
 
+       WARN_ON(ret != 0);
+
        return 0;
 }
 
@@ -668,7 +687,7 @@ int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
 
        /* XXX get the first 3 from the surface info */
        vfbd->base.base.bits_per_pixel = 32;
-       vfbd->base.base.pitch = width * 32 / 4;
+       vfbd->base.base.pitch = width * vfbd->base.base.bits_per_pixel / 8;
        vfbd->base.base.depth = 24;
        vfbd->base.base.width = width;
        vfbd->base.base.height = height;
@@ -765,8 +784,9 @@ int vmw_kms_init(struct vmw_private *dev_priv)
        dev->mode_config.funcs = &vmw_kms_funcs;
        dev->mode_config.min_width = 1;
        dev->mode_config.min_height = 1;
-       dev->mode_config.max_width = dev_priv->fb_max_width;
-       dev->mode_config.max_height = dev_priv->fb_max_height;
+       /* assumed largest fb size */
+       dev->mode_config.max_width = 8192;
+       dev->mode_config.max_height = 8192;
 
        ret = vmw_kms_init_legacy_display_system(dev_priv);
 
@@ -826,49 +846,140 @@ out:
        return ret;
 }
 
+void vmw_kms_write_svga(struct vmw_private *vmw_priv,
+                       unsigned width, unsigned height, unsigned pitch,
+                       unsigned bbp, unsigned depth)
+{
+       if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
+               vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
+       else if (vmw_fifo_have_pitchlock(vmw_priv))
+               iowrite32(pitch, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
+       vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
+       vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
+       vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bbp);
+       vmw_write(vmw_priv, SVGA_REG_DEPTH, depth);
+       vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
+       vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
+       vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
+}
+
 int vmw_kms_save_vga(struct vmw_private *vmw_priv)
 {
-       /*
-        * setup a single multimon monitor with the size
-        * of 0x0, this stops the UI from resizing when we
-        * change the framebuffer size
-        */
-       if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
-               vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
-               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
-       }
+       struct vmw_vga_topology_state *save;
+       uint32_t i;
 
        vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
        vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
-       vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
        vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH);
+       vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
        vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR);
        vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK);
-       vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
        vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK);
+       vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
+       if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
+               vmw_priv->vga_pitchlock =
+                 vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
+       else if (vmw_fifo_have_pitchlock(vmw_priv))
+               vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt +
+                                                      SVGA_FIFO_PITCHLOCK);
+
+       if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
+               return 0;
 
+       vmw_priv->num_displays = vmw_read(vmw_priv,
+                                         SVGA_REG_NUM_GUEST_DISPLAYS);
+
+       for (i = 0; i < vmw_priv->num_displays; ++i) {
+               save = &vmw_priv->vga_save[i];
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
+               save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
+               save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
+               save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
+               save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
+               save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+       }
        return 0;
 }
 
 int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
 {
+       struct vmw_vga_topology_state *save;
+       uint32_t i;
+
        vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
        vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
-       vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
        vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth);
+       vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
        vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo);
        vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask);
        vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask);
        vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask);
+       if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
+               vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
+                         vmw_priv->vga_pitchlock);
+       else if (vmw_fifo_have_pitchlock(vmw_priv))
+               iowrite32(vmw_priv->vga_pitchlock,
+                         vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
+
+       if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
+               return 0;
 
-       /* TODO check for multimon */
-       vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0);
+       for (i = 0; i < vmw_priv->num_displays; ++i) {
+               save = &vmw_priv->vga_save[i];
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
+               vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+       }
 
        return 0;
 }
+
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv)
+{
+       struct vmw_private *dev_priv = vmw_priv(dev);
+       struct drm_vmw_update_layout_arg *arg =
+               (struct drm_vmw_update_layout_arg *)data;
+       struct vmw_master *vmaster = vmw_master(file_priv->master);
+       void __user *user_rects;
+       struct drm_vmw_rect *rects;
+       unsigned rects_size;
+       int ret;
+
+       ret = ttm_read_lock(&vmaster->lock, true);
+       if (unlikely(ret != 0))
+               return ret;
+
+       if (!arg->num_outputs) {
+               struct drm_vmw_rect def_rect = {0, 0, 800, 600};
+               vmw_kms_ldu_update_layout(dev_priv, 1, &def_rect);
+               goto out_unlock;
+       }
+
+       rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
+       rects = kzalloc(rects_size, GFP_KERNEL);
+       if (unlikely(!rects)) {
+               ret = -ENOMEM;
+               goto out_unlock;
+       }
+
+       user_rects = (void __user *)(unsigned long)arg->rects;
+       ret = copy_from_user(rects, user_rects, rects_size);
+       if (unlikely(ret != 0)) {
+               DRM_ERROR("Failed to get rects.\n");
+               goto out_free;
+       }
+
+       vmw_kms_ldu_update_layout(dev_priv, arg->num_outputs, rects);
+
+out_free:
+       kfree(rects);
+out_unlock:
+       ttm_read_unlock(&vmaster->lock);
+       return ret;
+}
index 8b95249f0531ab0767f9248daee39063874d024f..8a398a0339b6c82a2c86178eb8d7657f80212964 100644 (file)
@@ -94,9 +94,11 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
 int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
 
 /*
- * Legacy display unit functions - vmwgfx_ldu.h
+ * Legacy display unit functions - vmwgfx_ldu.c
  */
 int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv);
 int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv);
+int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
+                             struct drm_vmw_rect *rects);
 
 #endif
index 90891593bf6c2ea01cc23ab52d03452cb5d99c08..cfaf690a5b2f423d6f150800cfb2d655d272a0bc 100644 (file)
@@ -38,6 +38,7 @@ struct vmw_legacy_display {
        struct list_head active;
 
        unsigned num_active;
+       unsigned last_num_active;
 
        struct vmw_framebuffer *fb;
 };
@@ -48,9 +49,12 @@ struct vmw_legacy_display {
 struct vmw_legacy_display_unit {
        struct vmw_display_unit base;
 
-       struct list_head active;
+       unsigned pref_width;
+       unsigned pref_height;
+       bool pref_active;
+       struct drm_display_mode *pref_mode;
 
-       unsigned unit;
+       struct list_head active;
 };
 
 static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu)
@@ -88,23 +92,44 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
 {
        struct vmw_legacy_display *lds = dev_priv->ldu_priv;
        struct vmw_legacy_display_unit *entry;
-       struct drm_crtc *crtc;
+       struct drm_framebuffer *fb = NULL;
+       struct drm_crtc *crtc = NULL;
        int i = 0;
 
-       /* to stop the screen from changing size on resize */
-       vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0);
-       for (i = 0; i < lds->num_active; i++) {
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
-               vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+       /* If there is no display topology the host just assumes
+        * that the guest will set the same layout as the host.
+        */
+       if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) {
+               int w = 0, h = 0;
+               list_for_each_entry(entry, &lds->active, active) {
+                       crtc = &entry->base.crtc;
+                       w = max(w, crtc->x + crtc->mode.hdisplay);
+                       h = max(h, crtc->y + crtc->mode.vdisplay);
+                       i++;
+               }
+
+               if (crtc == NULL)
+                       return 0;
+               fb = entry->base.crtc.fb;
+
+               vmw_kms_write_svga(dev_priv, w, h, fb->pitch,
+                                  fb->bits_per_pixel, fb->depth);
+
+               return 0;
        }
 
-       /* Now set the mode */
-       vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active);
+       if (!list_empty(&lds->active)) {
+               entry = list_entry(lds->active.next, typeof(*entry), active);
+               fb = entry->base.crtc.fb;
+
+               vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitch,
+                                  fb->bits_per_pixel, fb->depth);
+       }
+
+       /* Make sure we always show something. */
+       vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS,
+                 lds->num_active ? lds->num_active : 1);
+
        i = 0;
        list_for_each_entry(entry, &lds->active, active) {
                crtc = &entry->base.crtc;
@@ -120,6 +145,10 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
                i++;
        }
 
+       BUG_ON(i != lds->num_active);
+
+       lds->last_num_active = lds->num_active;
+
        return 0;
 }
 
@@ -130,6 +159,7 @@ static int vmw_ldu_del_active(struct vmw_private *vmw_priv,
        if (list_empty(&ldu->active))
                return 0;
 
+       /* Must init otherwise list_empty(&ldu->active) will not work. */
        list_del_init(&ldu->active);
        if (--(ld->num_active) == 0) {
                BUG_ON(!ld->fb);
@@ -149,24 +179,29 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv,
        struct vmw_legacy_display_unit *entry;
        struct list_head *at;
 
+       BUG_ON(!ld->num_active && ld->fb);
+       if (vfb != ld->fb) {
+               if (ld->fb && ld->fb->unpin)
+                       ld->fb->unpin(ld->fb);
+               if (vfb->pin)
+                       vfb->pin(vfb);
+               ld->fb = vfb;
+       }
+
        if (!list_empty(&ldu->active))
                return 0;
 
        at = &ld->active;
        list_for_each_entry(entry, &ld->active, active) {
-               if (entry->unit > ldu->unit)
+               if (entry->base.unit > ldu->base.unit)
                        break;
 
                at = &entry->active;
        }
 
        list_add(&ldu->active, at);
-       if (ld->num_active++ == 0) {
-               BUG_ON(ld->fb);
-               if (vfb->pin)
-                       vfb->pin(vfb);
-               ld->fb = vfb;
-       }
+
+       ld->num_active++;
 
        return 0;
 }
@@ -208,6 +243,8 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
 
        /* ldu only supports one fb active at the time */
        if (dev_priv->ldu_priv->fb && vfb &&
+           !(dev_priv->ldu_priv->num_active == 1 &&
+             !list_empty(&ldu->active)) &&
            dev_priv->ldu_priv->fb != vfb) {
                DRM_ERROR("Multiple framebuffers not supported\n");
                return -EINVAL;
@@ -300,8 +337,7 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
 static enum drm_connector_status
        vmw_ldu_connector_detect(struct drm_connector *connector)
 {
-       /* XXX vmwctrl should control connection status */
-       if (vmw_connector_to_ldu(connector)->base.unit == 0)
+       if (vmw_connector_to_ldu(connector)->pref_active)
                return connector_status_connected;
        return connector_status_disconnected;
 }
@@ -312,10 +348,9 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = {
                   752, 800, 0, 480, 489, 492, 525, 0,
                   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
        /* 800x600@60Hz */
-       { DRM_MODE("800x600",
-                  DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-                  40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628,
-                  0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+       { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
+                  968, 1056, 0, 600, 601, 605, 628, 0,
+                  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
        /* 1024x768@60Hz */
        { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
                   1184, 1344, 0, 768, 771, 777, 806, 0,
@@ -387,10 +422,34 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = {
 static int vmw_ldu_connector_fill_modes(struct drm_connector *connector,
                                        uint32_t max_width, uint32_t max_height)
 {
+       struct vmw_legacy_display_unit *ldu = vmw_connector_to_ldu(connector);
        struct drm_device *dev = connector->dev;
        struct drm_display_mode *mode = NULL;
+       struct drm_display_mode prefmode = { DRM_MODE("preferred",
+               DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
+       };
        int i;
 
+       /* Add preferred mode */
+       {
+               mode = drm_mode_duplicate(dev, &prefmode);
+               if (!mode)
+                       return 0;
+               mode->hdisplay = ldu->pref_width;
+               mode->vdisplay = ldu->pref_height;
+               mode->vrefresh = drm_mode_vrefresh(mode);
+               drm_mode_probed_add(connector, mode);
+
+               if (ldu->pref_mode) {
+                       list_del_init(&ldu->pref_mode->head);
+                       drm_mode_destroy(dev, ldu->pref_mode);
+               }
+
+               ldu->pref_mode = mode;
+       }
+
        for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) {
                if (vmw_ldu_connector_builtin[i].hdisplay > max_width ||
                    vmw_ldu_connector_builtin[i].vdisplay > max_height)
@@ -443,18 +502,21 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
        if (!ldu)
                return -ENOMEM;
 
-       ldu->unit = unit;
+       ldu->base.unit = unit;
        crtc = &ldu->base.crtc;
        encoder = &ldu->base.encoder;
        connector = &ldu->base.connector;
 
+       INIT_LIST_HEAD(&ldu->active);
+
+       ldu->pref_active = (unit == 0);
+       ldu->pref_width = 800;
+       ldu->pref_height = 600;
+       ldu->pref_mode = NULL;
+
        drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
-       /* Initial status */
-       if (unit == 0)
-               connector->status = connector_status_connected;
-       else
-               connector->status = connector_status_disconnected;
+       connector->status = vmw_ldu_connector_detect(connector);
 
        drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
                         DRM_MODE_ENCODER_LVDS);
@@ -462,8 +524,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
        encoder->possible_crtcs = (1 << unit);
        encoder->possible_clones = 0;
 
-       INIT_LIST_HEAD(&ldu->active);
-
        drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs);
 
        drm_connector_attach_property(connector,
@@ -487,18 +547,22 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
 
        INIT_LIST_HEAD(&dev_priv->ldu_priv->active);
        dev_priv->ldu_priv->num_active = 0;
+       dev_priv->ldu_priv->last_num_active = 0;
        dev_priv->ldu_priv->fb = NULL;
 
        drm_mode_create_dirty_info_property(dev_priv->dev);
 
        vmw_ldu_init(dev_priv, 0);
-       vmw_ldu_init(dev_priv, 1);
-       vmw_ldu_init(dev_priv, 2);
-       vmw_ldu_init(dev_priv, 3);
-       vmw_ldu_init(dev_priv, 4);
-       vmw_ldu_init(dev_priv, 5);
-       vmw_ldu_init(dev_priv, 6);
-       vmw_ldu_init(dev_priv, 7);
+       /* for old hardware without multimon only enable one display */
+       if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
+               vmw_ldu_init(dev_priv, 1);
+               vmw_ldu_init(dev_priv, 2);
+               vmw_ldu_init(dev_priv, 3);
+               vmw_ldu_init(dev_priv, 4);
+               vmw_ldu_init(dev_priv, 5);
+               vmw_ldu_init(dev_priv, 6);
+               vmw_ldu_init(dev_priv, 7);
+       }
 
        return 0;
 }
@@ -514,3 +578,42 @@ int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
 
        return 0;
 }
+
+int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
+                             struct drm_vmw_rect *rects)
+{
+       struct drm_device *dev = dev_priv->dev;
+       struct vmw_legacy_display_unit *ldu;
+       struct drm_connector *con;
+       int i;
+
+       mutex_lock(&dev->mode_config.mutex);
+
+#if 0
+       DRM_INFO("%s: new layout ", __func__);
+       for (i = 0; i < (int)num; i++)
+               DRM_INFO("(%i, %i %ux%u) ", rects[i].x, rects[i].y,
+                        rects[i].w, rects[i].h);
+       DRM_INFO("\n");
+#else
+       (void)i;
+#endif
+
+       list_for_each_entry(con, &dev->mode_config.connector_list, head) {
+               ldu = vmw_connector_to_ldu(con);
+               if (num > ldu->base.unit) {
+                       ldu->pref_width = rects[ldu->base.unit].w;
+                       ldu->pref_height = rects[ldu->base.unit].h;
+                       ldu->pref_active = true;
+               } else {
+                       ldu->pref_width = 800;
+                       ldu->pref_height = 600;
+                       ldu->pref_active = false;
+               }
+               con->status = vmw_ldu_connector_detect(con);
+       }
+
+       mutex_unlock(&dev->mode_config.mutex);
+
+       return 0;
+}
index ad566c85b075da13305ecef856b254ff4dc30a6b..df2036ed18d5f2c920ba61f99b716998a6f25329 100644 (file)
@@ -358,6 +358,8 @@ static int vmw_overlay_update_stream(struct vmw_private *dev_priv,
        if (stream->buf != buf)
                stream->buf = vmw_dmabuf_reference(buf);
        stream->saved = *arg;
+       /* stream is no longer stopped/paused */
+       stream->paused = false;
 
        return 0;
 }
index 441e38c95a8535b863d924aea1c468872ba6d27a..b87569e96b163c04fb35790ef8c457999480e3f3 100644 (file)
@@ -1,12 +1,32 @@
 /*
- * vgaarb.c
+ * vgaarb.c: Implements the VGA arbitration. For details refer to
+ * Documentation/vgaarbiter.txt
+ *
  *
  * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
  * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
  * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
  *
- * Implements the VGA arbitration. For details refer to
- * Documentation/vgaarbiter.txt
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
+ *
  */
 
 #include <linux/module.h>
@@ -155,8 +175,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
            (vgadev->decodes & VGA_RSRC_LEGACY_MEM))
                rsrc |= VGA_RSRC_LEGACY_MEM;
 
-       pr_devel("%s: %d\n", __func__, rsrc);
-       pr_devel("%s: owns: %d\n", __func__, vgadev->owns);
+       pr_debug("%s: %d\n", __func__, rsrc);
+       pr_debug("%s: owns: %d\n", __func__, vgadev->owns);
 
        /* Check what resources we need to acquire */
        wants = rsrc & ~vgadev->owns;
@@ -268,7 +288,7 @@ static void __vga_put(struct vga_device *vgadev, unsigned int rsrc)
 {
        unsigned int old_locks = vgadev->locks;
 
-       pr_devel("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        /* Update our counters, and account for equivalent legacy resources
         * if we decode them
@@ -575,6 +595,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
                else
                        vga_decode_count--;
        }
+       pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count);
 }
 
 void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
@@ -831,7 +852,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                curr_pos += 5;
                remaining -= 5;
 
-               pr_devel("client 0x%p called 'lock'\n", priv);
+               pr_debug("client 0x%p called 'lock'\n", priv);
 
                if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
                        ret_val = -EPROTO;
@@ -867,7 +888,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                curr_pos += 7;
                remaining -= 7;
 
-               pr_devel("client 0x%p called 'unlock'\n", priv);
+               pr_debug("client 0x%p called 'unlock'\n", priv);
 
                if (strncmp(curr_pos, "all", 3) == 0)
                        io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
@@ -917,7 +938,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                curr_pos += 8;
                remaining -= 8;
 
-               pr_devel("client 0x%p called 'trylock'\n", priv);
+               pr_debug("client 0x%p called 'trylock'\n", priv);
 
                if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
                        ret_val = -EPROTO;
@@ -961,7 +982,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
 
                curr_pos += 7;
                remaining -= 7;
-               pr_devel("client 0x%p called 'target'\n", priv);
+               pr_debug("client 0x%p called 'target'\n", priv);
                /* if target is default */
                if (!strncmp(curr_pos, "default", 7))
                        pdev = pci_dev_get(vga_default_device());
@@ -971,11 +992,11 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                                ret_val = -EPROTO;
                                goto done;
                        }
-                       pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
+                       pr_debug("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
                                domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
                        pbus = pci_find_bus(domain, bus);
-                       pr_devel("vgaarb: pbus %p\n", pbus);
+                       pr_debug("vgaarb: pbus %p\n", pbus);
                        if (pbus == NULL) {
                                pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n",
                                        domain, bus);
@@ -983,7 +1004,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                                goto done;
                        }
                        pdev = pci_get_slot(pbus, devfn);
-                       pr_devel("vgaarb: pdev %p\n", pdev);
+                       pr_debug("vgaarb: pdev %p\n", pdev);
                        if (!pdev) {
                                pr_err("vgaarb: invalid PCI address %x:%x\n",
                                        bus, devfn);
@@ -993,7 +1014,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                }
 
                vgadev = vgadev_find(pdev);
-               pr_devel("vgaarb: vgadev %p\n", vgadev);
+               pr_debug("vgaarb: vgadev %p\n", vgadev);
                if (vgadev == NULL) {
                        pr_err("vgaarb: this pci device is not a vga device\n");
                        pci_dev_put(pdev);
@@ -1029,7 +1050,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
        } else if (strncmp(curr_pos, "decodes ", 8) == 0) {
                curr_pos += 8;
                remaining -= 8;
-               pr_devel("vgaarb: client 0x%p called 'decodes'\n", priv);
+               pr_debug("vgaarb: client 0x%p called 'decodes'\n", priv);
 
                if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
                        ret_val = -EPROTO;
@@ -1058,7 +1079,7 @@ static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait)
 {
        struct vga_arb_private *priv = file->private_data;
 
-       pr_devel("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        if (priv == NULL)
                return -ENODEV;
@@ -1071,7 +1092,7 @@ static int vga_arb_open(struct inode *inode, struct file *file)
        struct vga_arb_private *priv;
        unsigned long flags;
 
-       pr_devel("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL);
        if (priv == NULL)
@@ -1101,7 +1122,7 @@ static int vga_arb_release(struct inode *inode, struct file *file)
        unsigned long flags;
        int i;
 
-       pr_devel("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        if (priv == NULL)
                return -ENODEV;
@@ -1112,7 +1133,7 @@ static int vga_arb_release(struct inode *inode, struct file *file)
                uc = &priv->cards[i];
                if (uc->pdev == NULL)
                        continue;
-               pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n",
+               pr_debug("uc->io_cnt == %d, uc->mem_cnt == %d\n",
                         uc->io_cnt, uc->mem_cnt);
                while (uc->io_cnt--)
                        vga_put(uc->pdev, VGA_RSRC_LEGACY_IO);
@@ -1165,7 +1186,7 @@ static int pci_notify(struct notifier_block *nb, unsigned long action,
        struct pci_dev *pdev = to_pci_dev(dev);
        bool notify = false;
 
-       pr_devel("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        /* For now we're only intereted in devices added and removed. I didn't
         * test this thing here, so someone needs to double check for the
index 4086c7257f912f23608c261f1b29f68b3c04a602..f13c843a2964bbb07728c06363cda065937293bb 100644 (file)
@@ -316,7 +316,6 @@ static int __devinit adt7411_probe(struct i2c_client *client,
  exit_remove:
        sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
  exit_free:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return ret;
 }
@@ -327,7 +326,6 @@ static int __devexit adt7411_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return 0;
 }
index 0f388adc61876cc3f0481de786289d724b1977a6..3b973f30b1f6495a89029b4002816ee8ff299353 100644 (file)
@@ -1141,7 +1141,6 @@ exit_remove:
                                   &(asc7621_params[i].sda.dev_attr));
        }
 
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return err;
 }
@@ -1196,7 +1195,6 @@ static int asc7621_remove(struct i2c_client *client)
                                   &(asc7621_params[i].sda.dev_attr));
        }
 
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return 0;
 }
index bad2cf3ef4a448aa76a72033b527647c6434f9d3..0f58ecc5334d941cb4114a3681e2e5a44893280e 100644 (file)
@@ -662,7 +662,6 @@ exit_remove:
        sysfs_remove_group(&client->dev.kobj, &f75375_group);
 exit_free:
        kfree(data);
-       i2c_set_clientdata(client, NULL);
        return err;
 }
 
@@ -672,7 +671,6 @@ static int f75375_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &f75375_group);
        kfree(data);
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index 09ea12e0a55185b3e5d0699cf7922898752b70af..1f63d1a3af5ebc4aae1d31f18d505881273b8a65 100644 (file)
@@ -236,7 +236,6 @@ error_hwmon_device_register:
        sysfs_remove_group(&client->dev.kobj, &g760a_group);
 error_sysfs_create_group:
        kfree(data);
-       i2c_set_clientdata(client, NULL);
 
        return err;
 }
@@ -247,7 +246,6 @@ static int g760a_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &g760a_group);
        kfree(data);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 4d1b76bc81486b64dc6963d8ee415c2608c0fb82..29b9030d42c3111ecfdc49cc2a9cbf8aa4257cd6 100644 (file)
@@ -136,7 +136,6 @@ static int lm73_remove(struct i2c_client *client)
 
        hwmon_device_unregister(hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &lm73_group);
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index 56463428a419ce8f4222f5504b96f57cd44503fd..393f354f92a4c012c46ee96a8062f7b604697cdf 100644 (file)
@@ -192,7 +192,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &lm75_group);
 exit_free:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return status;
 }
@@ -204,7 +203,6 @@ static int lm75_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &lm75_group);
        lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return 0;
 }
index 8fc8eb8cba47400fd23614a392b135949aab8c76..94741d42112da02ca902b2e87beacbe96aab3cd3 100644 (file)
@@ -399,7 +399,6 @@ static int lm95241_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &lm95241_group);
 
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return 0;
 }
index 8013895a1fafc19918faca9b838be7b4dc58d581..93187c3cb5e7949a72b5599bb127fce61701ec49 100644 (file)
@@ -224,7 +224,6 @@ fail_remove_sysfs:
 fail_restore_config:
        tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig);
 fail_free:
-       i2c_set_clientdata(client, NULL);
        kfree(tmp102);
 
        return status;
@@ -247,7 +246,6 @@ static int __devexit tmp102_remove(struct i2c_client *client)
                                         config | TMP102_CONF_SD);
        }
 
-       i2c_set_clientdata(client, NULL);
        kfree(tmp102);
 
        return 0;
index 738c472ece273bf972b1206e9b164b88d046b0bc..6b4165c12092b388c365824c49c8c7d6a65c9a8c 100644 (file)
@@ -295,7 +295,6 @@ exit_remove:
        sysfs_remove_group(&client->dev.kobj, &tmp421_group);
 
 exit_free:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 
        return err;
@@ -308,7 +307,6 @@ static int tmp421_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &tmp421_group);
 
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 
        return 0;
index 32d4adee73db650fc5ba2b2cc42586b12b642cd3..c84b9b4e69609e70e55419a6faae4f8f1905a63c 100644 (file)
@@ -1197,7 +1197,6 @@ ERROR4:
        if (data->lm75[1])
                i2c_unregister_device(data->lm75[1]);
 ERROR3:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 ERROR1:
        return err;
@@ -1219,7 +1218,6 @@ w83781d_remove(struct i2c_client *client)
        if (data->lm75[1])
                i2c_unregister_device(data->lm75[1]);
 
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 
        return 0;
index 87ab0568bb0ed1e18b979b675a5d8db0303ef545..bceafbfa72683698769890bfb664dbe57ea3a010 100644 (file)
@@ -475,6 +475,26 @@ config I2C_PASEMI
        help
          Supports the PA Semi PWRficient on-chip SMBus interfaces.
 
+config I2C_PCA_PLATFORM
+       tristate "PCA9564/PCA9665 as platform device"
+       select I2C_ALGOPCA
+       default n
+       help
+         This driver supports a memory mapped Philips PCA9564/PCA9665
+         parallel bus to I2C bus controller.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pca-platform.
+
+config I2C_PMCMSP
+       tristate "PMC MSP I2C TWI Controller"
+       depends on PMC_MSP
+       help
+         This driver supports the PMC TWI controller on MSP devices.
+
+         This driver can also be built as module. If so, the module
+         will be called i2c-pmcmsp.
+
 config I2C_PNX
        tristate "I2C bus support for Philips PNX targets"
        depends on ARCH_PNX4008
@@ -711,26 +731,6 @@ config I2C_PCA_ISA
          delays when I2C/SMBus chip drivers are loaded (e.g. at boot
          time).  If unsure, say N.
 
-config I2C_PCA_PLATFORM
-       tristate "PCA9564/PCA9665 as platform device"
-       select I2C_ALGOPCA
-       default n
-       help
-         This driver supports a memory mapped Philips PCA9564/PCA9665
-         parallel bus to I2C bus controller.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-pca-platform.
-
-config I2C_PMCMSP
-       tristate "PMC MSP I2C TWI Controller"
-       depends on PMC_MSP
-       help
-         This driver supports the PMC TWI controller on MSP devices.
-
-         This driver can also be built as module. If so, the module
-         will be called i2c-pmcmsp.
-
 config I2C_SIBYTE
        tristate "SiByte SMBus interface"
        depends on SIBYTE_SB1xxx_SOC
index 097236f631e8d68e57a2ca87562912c995f280ca..936880bd1dc58404d4ed666919939729c7c99585 100644 (file)
@@ -27,7 +27,7 @@ obj-$(CONFIG_I2C_VIAPRO)      += i2c-viapro.o
 obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
 obj-$(CONFIG_I2C_POWERMAC)     += i2c-powermac.o
 
-# Embebbed system I2C/SMBus host controller drivers
+# Embedded system I2C/SMBus host controller drivers
 obj-$(CONFIG_I2C_AT91)         += i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)       += i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
@@ -46,6 +46,8 @@ obj-$(CONFIG_I2C_NOMADIK)     += i2c-nomadik.o
 obj-$(CONFIG_I2C_OCORES)       += i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)         += i2c-omap.o
 obj-$(CONFIG_I2C_PASEMI)       += i2c-pasemi.o
+obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
+obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
@@ -68,8 +70,6 @@ obj-$(CONFIG_I2C_TINY_USB)    += i2c-tiny-usb.o
 obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
-obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
-obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
 obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
 obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
 obj-$(CONFIG_SCx200_ACB)       += scx200_acb.o
index e0f833cca3f1193c24480c4efc446a7568a9a3af..1cca2631e5b3bc8331062617a68968006a9fd06e 100644 (file)
@@ -47,7 +47,6 @@ static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
 
 static struct device_type i2c_client_type;
-static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
 static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
 
 /* ------------------------------------------------------------------------- */
@@ -371,6 +370,59 @@ struct i2c_client *i2c_verify_client(struct device *dev)
 EXPORT_SYMBOL(i2c_verify_client);
 
 
+/* This is a permissive address validity check, I2C address map constraints
+ * are purposedly not enforced, except for the general call address. */
+static int i2c_check_client_addr_validity(const struct i2c_client *client)
+{
+       if (client->flags & I2C_CLIENT_TEN) {
+               /* 10-bit address, all values are valid */
+               if (client->addr > 0x3ff)
+                       return -EINVAL;
+       } else {
+               /* 7-bit address, reject the general call address */
+               if (client->addr == 0x00 || client->addr > 0x7f)
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+/* And this is a strict address validity check, used when probing. If a
+ * device uses a reserved address, then it shouldn't be probed. 7-bit
+ * addressing is assumed, 10-bit address devices are rare and should be
+ * explicitly enumerated. */
+static int i2c_check_addr_validity(unsigned short addr)
+{
+       /*
+        * Reserved addresses per I2C specification:
+        *  0x00       General call address / START byte
+        *  0x01       CBUS address
+        *  0x02       Reserved for different bus format
+        *  0x03       Reserved for future purposes
+        *  0x04-0x07  Hs-mode master code
+        *  0x78-0x7b  10-bit slave addressing
+        *  0x7c-0x7f  Reserved for future purposes
+        */
+       if (addr < 0x08 || addr > 0x77)
+               return -EINVAL;
+       return 0;
+}
+
+static int __i2c_check_addr_busy(struct device *dev, void *addrp)
+{
+       struct i2c_client       *client = i2c_verify_client(dev);
+       int                     addr = *(int *)addrp;
+
+       if (client && client->addr == addr)
+               return -EBUSY;
+       return 0;
+}
+
+static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
+{
+       return device_for_each_child(&adapter->dev, &addr,
+                                    __i2c_check_addr_busy);
+}
+
 /**
  * i2c_new_device - instantiate an i2c device
  * @adap: the adapter managing the device
@@ -410,8 +462,16 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
 
        strlcpy(client->name, info->type, sizeof(client->name));
 
+       /* Check for address validity */
+       status = i2c_check_client_addr_validity(client);
+       if (status) {
+               dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",
+                       client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
+               goto out_err_silent;
+       }
+
        /* Check for address business */
-       status = i2c_check_addr(adap, client->addr);
+       status = i2c_check_addr_busy(adap, client->addr);
        if (status)
                goto out_err;
 
@@ -436,6 +496,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
 out_err:
        dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
                "(%d)\n", client->name, client->addr, status);
+out_err_silent:
        kfree(client);
        return NULL;
 }
@@ -561,15 +622,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
        }
 
-       if (info.addr < 0x03 || info.addr > 0x77) {
-               dev_err(dev, "%s: Invalid I2C address 0x%hx\n", "new_device",
-                       info.addr);
-               return -EINVAL;
-       }
-
        client = i2c_new_device(adap, &info);
        if (!client)
-               return -EEXIST;
+               return -EINVAL;
 
        /* Keep track of the added device */
        i2c_lock_adapter(adap);
@@ -1024,21 +1079,6 @@ EXPORT_SYMBOL(i2c_del_driver);
 
 /* ------------------------------------------------------------------------- */
 
-static int __i2c_check_addr(struct device *dev, void *addrp)
-{
-       struct i2c_client       *client = i2c_verify_client(dev);
-       int                     addr = *(int *)addrp;
-
-       if (client && client->addr == addr)
-               return -EBUSY;
-       return 0;
-}
-
-static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
-{
-       return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
-}
-
 /**
  * i2c_use_client - increments the reference count of the i2c client structure
  * @client: the client being referenced
@@ -1277,6 +1317,41 @@ EXPORT_SYMBOL(i2c_master_recv);
  * ----------------------------------------------------
  */
 
+/*
+ * Legacy default probe function, mostly relevant for SMBus. The default
+ * probe method is a quick write, but it is known to corrupt the 24RF08
+ * EEPROMs due to a state machine bug, and could also irreversibly
+ * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f,
+ * we use a short byte read instead. Also, some bus drivers don't implement
+ * quick write, so we fallback to a byte read in that case too.
+ * On x86, there is another special case for FSC hardware monitoring chips,
+ * which want regular byte reads (address 0x73.) Fortunately, these are the
+ * only known chips using this I2C address on PC hardware.
+ * Returns 1 if probe succeeded, 0 if not.
+ */
+static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
+{
+       int err;
+       union i2c_smbus_data dummy;
+
+#ifdef CONFIG_X86
+       if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON)
+        && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))
+               err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
+                                    I2C_SMBUS_BYTE_DATA, &dummy);
+       else
+#endif
+       if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50
+        || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
+               err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
+                                    I2C_SMBUS_BYTE, &dummy);
+       else
+               err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
+                                    I2C_SMBUS_QUICK, NULL);
+
+       return err >= 0;
+}
+
 static int i2c_detect_address(struct i2c_client *temp_client,
                              struct i2c_driver *driver)
 {
@@ -1286,34 +1361,20 @@ static int i2c_detect_address(struct i2c_client *temp_client,
        int err;
 
        /* Make sure the address is valid */
-       if (addr < 0x03 || addr > 0x77) {
+       err = i2c_check_addr_validity(addr);
+       if (err) {
                dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
                         addr);
-               return -EINVAL;
+               return err;
        }
 
        /* Skip if already in use */
-       if (i2c_check_addr(adapter, addr))
+       if (i2c_check_addr_busy(adapter, addr))
                return 0;
 
        /* Make sure there is something at this address */
-       if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
-               /* Special probe for FSC hwmon chips */
-               union i2c_smbus_data dummy;
-
-               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
-                                  I2C_SMBUS_BYTE_DATA, &dummy) < 0)
-                       return 0;
-       } else {
-               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
-                                  I2C_SMBUS_QUICK, NULL) < 0)
-                       return 0;
-
-               /* Prevent 24RF08 corruption */
-               if ((addr & ~0x0f) == 0x50)
-                       i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
-                                      I2C_SMBUS_QUICK, NULL);
-       }
+       if (!i2c_default_probe(adapter, addr))
+               return 0;
 
        /* Finally call the custom detection function */
        memset(&info, 0, sizeof(struct i2c_board_info));
@@ -1407,42 +1468,22 @@ i2c_new_probed_device(struct i2c_adapter *adap,
 
        for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
                /* Check address validity */
-               if (addr_list[i] < 0x03 || addr_list[i] > 0x77) {
+               if (i2c_check_addr_validity(addr_list[i]) < 0) {
                        dev_warn(&adap->dev, "Invalid 7-bit address "
                                 "0x%02x\n", addr_list[i]);
                        continue;
                }
 
                /* Check address availability */
-               if (i2c_check_addr(adap, addr_list[i])) {
+               if (i2c_check_addr_busy(adap, addr_list[i])) {
                        dev_dbg(&adap->dev, "Address 0x%02x already in "
                                "use, not probing\n", addr_list[i]);
                        continue;
                }
 
-               /* Test address responsiveness
-                  The default probe method is a quick write, but it is known
-                  to corrupt the 24RF08 EEPROMs due to a state machine bug,
-                  and could also irreversibly write-protect some EEPROMs, so
-                  for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte
-                  read instead. Also, some bus drivers don't implement
-                  quick write, so we fallback to a byte read it that case
-                  too. */
-               if ((addr_list[i] & ~0x07) == 0x30
-                || (addr_list[i] & ~0x0f) == 0x50
-                || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
-                       union i2c_smbus_data data;
-
-                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
-                                          I2C_SMBUS_READ, 0,
-                                          I2C_SMBUS_BYTE, &data) >= 0)
-                               break;
-               } else {
-                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
-                                          I2C_SMBUS_WRITE, 0,
-                                          I2C_SMBUS_QUICK, NULL) >= 0)
-                               break;
-               }
+               /* Test address responsiveness */
+               if (i2c_default_probe(adap, addr_list[i]))
+                       break;
        }
 
        if (addr_list[i] == I2C_CLIENT_END) {
index a24e0bfe9201a87a7012b1f42791d925aaf5b76f..f61ccc1e5ea3ea7a350af1cc3ec7858bf0f5dbe8 100644 (file)
@@ -173,7 +173,6 @@ static int smbalert_remove(struct i2c_client *ara)
 
        cancel_work_sync(&alert->alert);
 
-       i2c_set_clientdata(ara, NULL);
        kfree(alert);
        return 0;
 }
index 183fa38760d85be4e520529c0747b6d88a614365..ebcf8e470a97b2685a1bf9b63b2e16c7a0b3b581 100644 (file)
@@ -1400,8 +1400,11 @@ static struct of_device_id pmac_ide_macio_match[] =
 
 static struct macio_driver pmac_ide_macio_driver = 
 {
-       .name           = "ide-pmac",
-       .match_table    = pmac_ide_macio_match,
+       .driver = {
+               .name           = "ide-pmac",
+               .owner          = THIS_MODULE,
+               .of_match_table = pmac_ide_macio_match,
+       },
        .probe          = pmac_ide_macio_attach,
        .suspend        = pmac_ide_macio_suspend,
        .resume         = pmac_ide_macio_resume,
index 4771ab172b59b22dda93eaa5437aba8019d7a208..744600eff222935b8af076ac8122c07f22a896e9 100644 (file)
@@ -287,7 +287,6 @@ static int __devexit adp5588_remove(struct i2c_client *client)
        free_irq(client->irq, kpad);
        cancel_delayed_work_sync(&kpad->work);
        input_unregister_device(kpad->input);
-       i2c_set_clientdata(client, NULL);
        kfree(kpad);
 
        return 0;
index bc696931fed7b127a87afb262f63aa26fc63ac9a..40b032f0e32cd47a12e33f300810da9a131941c0 100644 (file)
@@ -778,8 +778,6 @@ static int __devexit lm8323_remove(struct i2c_client *client)
        struct lm8323_chip *lm = i2c_get_clientdata(client);
        int i;
 
-       i2c_set_clientdata(client, NULL);
-
        disable_irq_wake(client->irq);
        free_irq(client->irq, lm);
        cancel_work_sync(&lm->work);
index 7fc8185e5c1bd8ab914cedb0f0d78e15e974ed89..9091ff5ea808b8829d7d9475f15f704532d10c5e 100644 (file)
@@ -265,7 +265,6 @@ static int __devexit max7359_remove(struct i2c_client *client)
 
        free_irq(client->irq, keypad);
        input_unregister_device(keypad->input_dev);
-       i2c_set_clientdata(client, NULL);
        kfree(keypad);
 
        return 0;
index 31f30087b591866c9e81af4401d0a3feeaae359e..fac695157e8afce221fb8dae22fa2d750d745963 100644 (file)
@@ -358,7 +358,6 @@ static int __devexit qt2160_remove(struct i2c_client *client)
        input_unregister_device(qt2160->input);
        kfree(qt2160);
 
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index 493c93f25e2abb96c0555d46d6ac9f20801d9098..00137bebcf974a8133ff3f4f4234bcace30cd084 100644 (file)
@@ -316,8 +316,6 @@ static int __devexit tca6416_keypad_remove(struct i2c_client *client)
        input_unregister_device(chip->input);
        kfree(chip);
 
-       i2c_set_clientdata(client, NULL);
-
        return 0;
 }
 
index e9adbe49f6a49fe0a01e74648747985cb517061d..2bef8fa56c948e0ba4305ea0f4f22450244f79d4 100644 (file)
@@ -97,7 +97,6 @@ static int __devexit ad714x_i2c_remove(struct i2c_client *client)
        struct ad714x_chip *chip = i2c_get_clientdata(client);
 
        ad714x_remove(chip);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 5c3ac4e0b055837976624cbd3ef1873cc81d82c6..0ac47d2898ec6d2baca97153f737f75878ffa950 100644 (file)
@@ -168,8 +168,6 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client)
        input_unregister_device(lp->idev);
        kfree(lp);
 
-       i2c_set_clientdata(client, NULL);
-
        return 0;
 }
 
index 8291e7399ffab3606d2563a8e7257e513b5179f6..0ae62f0bcb3216ca32c494e3a807a75a8f6753bd 100644 (file)
@@ -613,7 +613,6 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client)
                free_irq(client->irq, touch);
 
        input_unregister_device(touch->input);
-       i2c_set_clientdata(client, NULL);
        kfree(touch);
 
        return 0;
index 794d070c6900607752f2af1b7641f0cc98ef267f..4b32fb4704cd37b24f67c84db53de4ed431320c8 100644 (file)
@@ -812,10 +812,8 @@ static int __devinit ad7879_probe(struct i2c_client *client,
        ts->bus = client;
 
        error = ad7879_construct(client, ts);
-       if (error) {
-               i2c_set_clientdata(client, NULL);
+       if (error)
                kfree(ts);
-       }
 
        return error;
 }
@@ -825,7 +823,6 @@ static int __devexit ad7879_remove(struct i2c_client *client)
        struct ad7879 *ts = dev_get_drvdata(&client->dev);
 
        ad7879_destroy(client, ts);
-       i2c_set_clientdata(client, NULL);
        kfree(ts);
 
        return 0;
index 75f8b73010fa5aa30dd3758a7421697b16c03e46..7a3a916f84a857137332ba89a53373d9dfe136d7 100644 (file)
@@ -238,7 +238,6 @@ err2:
        input = NULL; /* so we dont try to free it below */
 err1:
        input_free_device(input);
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
 err0:
        return err;
@@ -256,7 +255,6 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
        enable_irq(priv->irq);
 
        input_unregister_device(priv->input);
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
 
        return 0;
index ce8ab0269f6fc755f6496e90a5a4cd4c8157b816..1fb0c2f06a4470657b1b05e5295b77b3c67d6236 100644 (file)
@@ -256,7 +256,6 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client)
        free_irq(client->irq, data);
        input_unregister_device(data->input_dev);
        kfree(data);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 769b479fcaa625fb4406096dd84746b89cc877e4..be23780e8a3e3b81be9df7b7cd0f8aab86d87e61 100644 (file)
@@ -347,8 +347,6 @@ static int __devexit tsc2007_remove(struct i2c_client *client)
        struct tsc2007  *ts = i2c_get_clientdata(client);
        struct tsc2007_platform_data *pdata = client->dev.platform_data;
 
-       i2c_set_clientdata(client, NULL);
-
        tsc2007_free_irq(ts);
 
        if (pdata->exit_platform_hw)
index b3b7e2879bac25873da4d2666567f2c52fae434f..8700474747e8cd0251bc54f99f80cb2a7b8eb8e1 100644 (file)
@@ -97,8 +97,10 @@ static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
                        hw->name, __func__, reg, val);
 
        spin_lock(&hw->ctrl_lock);
-       if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE)
+       if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
+               spin_unlock(&hw->ctrl_lock);
                return 1;
+       }
        buf = &hw->ctrl_buff[hw->ctrl_in_idx];
        buf->hfcs_reg = reg;
        buf->reg_val = val;
index 0a3553df065fcd38d884e939e040486760073de7..54ae71a907f937c8fcf3d443bf79d4a43a5499bd 100644 (file)
@@ -320,12 +320,12 @@ inittiger(struct tiger_hw *card)
                return -ENOMEM;
        }
        for (i = 0; i < 2; i++) {
-               card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_KERNEL);
+               card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC);
                if (!card->bc[i].hsbuf) {
                        pr_info("%s: no B%d send buffer\n", card->name, i + 1);
                        return -ENOMEM;
                }
-               card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_KERNEL);
+               card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC);
                if (!card->bc[i].hrbuf) {
                        pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
                        return -ENOMEM;
index 286b501a3573d3b7d0d4cec872fa7b40008c83d5..5dcdf9d69b3abae8d0370ccbe1a0d913c716e7d1 100644 (file)
@@ -742,7 +742,6 @@ failed_unregister_dev_file:
        for (i--; i >= 0; i--)
                device_remove_file(&led->client->dev, bd2802_attributes[i]);
 failed_free:
-       i2c_set_clientdata(client, NULL);
        kfree(led);
 
        return ret;
@@ -759,7 +758,6 @@ static int __exit bd2802_remove(struct i2c_client *client)
                bd2802_disable_adv_conf(led);
        for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
                device_remove_file(&led->client->dev, bd2802_attributes[i]);
-       i2c_set_clientdata(client, NULL);
        kfree(led);
 
        return 0;
index 932a58da76c4e97cba12a3c7b657b72dafa70e86..9010c054615e414fa5c236a8fe2cc4a700a00757 100644 (file)
@@ -432,7 +432,6 @@ static int __devexit lp3944_remove(struct i2c_client *client)
                }
 
        kfree(data);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 6682175fa9f7c4e3c5a91d99120c83b2003f6b9a..43d08756d823556b26f5c531d6837ff89818964b 100644 (file)
@@ -320,10 +320,8 @@ static int pca9532_probe(struct i2c_client *client,
        mutex_init(&data->update_lock);
 
        err = pca9532_configure(client, data, pca9532_pdata);
-       if (err) {
+       if (err)
                kfree(data);
-               i2c_set_clientdata(client, NULL);
-       }
 
        return err;
 }
@@ -351,7 +349,6 @@ static int pca9532_remove(struct i2c_client *client)
                }
 
        kfree(data);
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index 8ff50f234190a38129342d743a14c8c7c201ad6c..66aa3e8e786f545c4db0e6bd4318a173a792fc1e 100644 (file)
@@ -342,7 +342,6 @@ exit:
        }
 
        kfree(pca955x);
-       i2c_set_clientdata(client, NULL);
 
        return err;
 }
@@ -358,7 +357,6 @@ static int __devexit pca955x_remove(struct i2c_client *client)
        }
 
        kfree(pca955x);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 97147804a49cefc2e6b8864da44be7de13ca0832..b6e7ddc09d76573eb0b423747bb613ce16599a7d 100644 (file)
@@ -492,8 +492,8 @@ static void macio_pci_add_devices(struct macio_chip *chip)
        }
 
        /* Add media bay devices if any */
-       pnode = mbdev->ofdev.dev.of_node;
-       if (mbdev)
+       if (mbdev) {
+               pnode = mbdev->ofdev.dev.of_node;
                for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
                        if (macio_skip_device(np))
                                continue;
@@ -502,10 +502,11 @@ static void macio_pci_add_devices(struct macio_chip *chip)
                                                 mbdev,  root_res) == NULL)
                                of_node_put(np);
                }
+       }
 
        /* Add serial ports if any */
-       pnode = sdev->ofdev.dev.of_node;
        if (sdev) {
+               pnode = sdev->ofdev.dev.of_node;
                for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
                        if (macio_skip_device(np))
                                continue;
@@ -525,7 +526,6 @@ static void macio_pci_add_devices(struct macio_chip *chip)
 int macio_register_driver(struct macio_driver *drv)
 {
        /* initialize common driver fields */
-       drv->driver.name = drv->name;
        drv->driver.bus = &macio_bus_type;
 
        /* register with core */
index 288acce76b74ec36d8324d2284439c9592cbd3c7..2fd435bc542e0db14a8488cbe97dc9380768dc72 100644 (file)
@@ -728,8 +728,10 @@ static struct of_device_id media_bay_match[] =
 
 static struct macio_driver media_bay_driver =
 {
-       .name           = "media-bay",
-       .match_table    = media_bay_match,
+       .driver = {
+               .name           = "media-bay",
+               .of_match_table = media_bay_match,
+       },
        .probe          = media_bay_attach,
        .suspend        = media_bay_suspend,
        .resume         = media_bay_resume
index 12946c5f583f53526654b58a41138595f0f0afc9..53cce3a5da2336b97fd94e0bd55123be2968adbf 100644 (file)
@@ -584,9 +584,11 @@ static struct of_device_id rackmeter_match[] = {
 };
 
 static struct macio_driver rackmeter_driver = {
-       .name = "rackmeter",
-       .owner = THIS_MODULE,
-       .match_table = rackmeter_match,
+       .driver = {
+               .name = "rackmeter",
+               .owner = THIS_MODULE,
+               .of_match_table = rackmeter_match,
+       },
        .probe = rackmeter_probe,
        .remove = __devexit_p(rackmeter_remove),
        .shutdown = rackmeter_shutdown,
index 16d82f17ae82b3a2e0f5a5e37a0a73e18e51e7b5..c42eeb43042daa92d9f04e22b2205ce6d1d2a33d 100644 (file)
@@ -182,7 +182,6 @@ remove_thermostat(struct i2c_client *client)
 
        thermostat = NULL;
 
-       i2c_set_clientdata(client, NULL);
        kfree(th);
 
        return 0;
@@ -400,7 +399,6 @@ static int probe_thermostat(struct i2c_client *client,
        rc = read_reg(th, CONFIG_REG);
        if (rc < 0) {
                dev_err(&client->dev, "Thermostat failed to read config!\n");
-               i2c_set_clientdata(client, NULL);
                kfree(th);
                return -ENODEV;
        }
index d8257d35afde91c225b49bad6f0cc9885cf3fc69..647c6add2193e63d9bcec2be088ac2f28096a962 100644 (file)
@@ -107,10 +107,8 @@ static int wf_lm75_probe(struct i2c_client *client,
        i2c_set_clientdata(client, lm);
 
        rc = wf_register_sensor(&lm->sens);
-       if (rc) {
-               i2c_set_clientdata(client, NULL);
+       if (rc)
                kfree(lm);
-       }
 
        return rc;
 }
@@ -216,7 +214,6 @@ static int wf_lm75_remove(struct i2c_client *client)
        /* release sensor */
        wf_unregister_sensor(&lm->sens);
 
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index b486eb929fde725fb9e0271d4af46cdc241c2113..8204113268f471db6021ffa7915be03272a0c40c 100644 (file)
@@ -81,7 +81,6 @@ static int wf_max6690_probe(struct i2c_client *client,
 
        rc = wf_register_sensor(&max->sens);
        if (rc) {
-               i2c_set_clientdata(client, NULL);
                kfree(max);
        }
 
index e20330a28959bc539d0691337bf49438e2022efe..65a8ff3e1f8e8d4e1e73a7a7eda4bb9500fb9c82 100644 (file)
@@ -376,7 +376,6 @@ static int wf_sat_remove(struct i2c_client *client)
        /* XXX TODO */
 
        sat->i2c = NULL;
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index a5844d08d8b7917c19702d9f7879a1bc0244aba4..67a4ec8768a6145ecfd6fb1d44095bfb51f29fdc 100644 (file)
@@ -482,7 +482,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
        cancel_work_sync(&radio->radio_work);
        video_unregister_device(radio->videodev);
        kfree(radio);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index b62c0bd3f8ea013de803ceac7f3f25f1c7a9bb57..e3b9a8ab37f4e5c53f11c14d82a8855883f50036 100644 (file)
@@ -785,7 +785,6 @@ static int mt9m001_probe(struct i2c_client *client,
        ret = mt9m001_video_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(mt9m001);
        }
 
@@ -799,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client)
 
        icd->ops = NULL;
        mt9m001_video_remove(icd);
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(mt9m001);
 
index d35f536f9fc37fd6729211d9610adbfa2334c77e..e42162c50f0a3436ae74ee2249221b6ff75a1120 100644 (file)
@@ -1068,7 +1068,6 @@ static int mt9m111_probe(struct i2c_client *client,
        ret = mt9m111_video_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(mt9m111);
        }
 
@@ -1081,7 +1080,6 @@ static int mt9m111_remove(struct i2c_client *client)
        struct soc_camera_device *icd = client->dev.platform_data;
 
        icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(mt9m111);
 
index 78b4e091d2d5f527dd76db13a072bb339289fa84..9f5ff2547f1993bde3f594aa95bf4bb11d23c50d 100644 (file)
@@ -883,7 +883,6 @@ static int mt9t031_probe(struct i2c_client *client,
        if (ret) {
                if (icd)
                        icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(mt9t031);
        }
 
@@ -897,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client)
 
        if (icd)
                icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(mt9t031);
 
index 7438f8d775ba7fa09fb32f9ad2f0a8934606afb5..aa4fce95098f06a5e8dcb832cd56d7d15de972ba 100644 (file)
@@ -1119,7 +1119,6 @@ static int mt9t112_probe(struct i2c_client *client,
        ret = mt9t112_camera_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
        }
 
@@ -1132,7 +1131,6 @@ static int mt9t112_remove(struct i2c_client *client)
        struct soc_camera_device *icd = client->dev.platform_data;
 
        icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
        return 0;
 }
index e5bae4c9393b8b9e3d4a0c8acbcf770d627fe3bc..fb44ff006628834fb45b5d728589edfad34b99a8 100644 (file)
@@ -920,7 +920,6 @@ static int mt9v022_probe(struct i2c_client *client,
        ret = mt9v022_video_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(mt9v022);
        }
 
@@ -934,7 +933,6 @@ static int mt9v022_remove(struct i2c_client *client)
 
        icd->ops = NULL;
        mt9v022_video_remove(icd);
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(mt9v022);
 
index 7f8ece30c77ba790cb38c314783544a0de0e162d..c33acc94b7472c5c6fdaec46b26d1690fed541d7 100644 (file)
@@ -1159,7 +1159,6 @@ static int ov772x_probe(struct i2c_client *client,
        ret = ov772x_video_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
        }
 
@@ -1172,7 +1171,6 @@ static int ov772x_remove(struct i2c_client *client)
        struct soc_camera_device *icd = client->dev.platform_data;
 
        icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
        return 0;
 }
index 36599a65f54851759f47a5a412bd5fdc629b8e1f..035e9ecb0c7569ce0e65bde6607d1b6b529c10ff 100644 (file)
@@ -783,7 +783,6 @@ static int ov9640_probe(struct i2c_client *client,
 
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
        }
 
@@ -794,7 +793,6 @@ static int ov9640_remove(struct i2c_client *client)
 {
        struct ov9640_priv *priv = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
        return 0;
 }
index bbd9c11e2c5a721436230f6656f83806058ade54..2c3b58c99e1884fb8db7bc7546eb758b5aaea094 100644 (file)
@@ -1444,7 +1444,6 @@ static int rj54n1_probe(struct i2c_client *client,
        ret = rj54n1_video_probe(icd, client, rj54n1_priv);
        if (ret < 0) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(rj54n1);
                return ret;
        }
@@ -1461,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client)
        icd->ops = NULL;
        if (icl->free_bus)
                icl->free_bus(icl);
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(rj54n1);
 
index b90e9da3167dde4e38df0037832375e9aaa48e3f..54681a5358222df6a722451e92d9fd9e627d22f8 100644 (file)
@@ -850,7 +850,6 @@ static int tcm825x_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
        struct tcm825x_sensor *sensor = &tcm825x;
-       int rval;
 
        if (i2c_get_clientdata(client))
                return -EBUSY;
@@ -871,11 +870,7 @@ static int tcm825x_probe(struct i2c_client *client,
        sensor->pix.height = tcm825x_sizes[QVGA].height;
        sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565;
 
-       rval = v4l2_int_device_register(sensor->v4l2_int_device);
-       if (rval)
-               i2c_set_clientdata(client, NULL);
-
-       return rval;
+       return v4l2_int_device_register(sensor->v4l2_int_device);
 }
 
 static int tcm825x_remove(struct i2c_client *client)
@@ -886,7 +881,6 @@ static int tcm825x_remove(struct i2c_client *client)
                return -ENODEV; /* our client isn't attached */
 
        v4l2_int_device_unregister(sensor->v4l2_int_device);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 76be733eabfd4d3f7b4bc474219a6f0a9c8fb5ea..6eb3395def077754f30e7be7cdb5c1a60ea57b4c 100644 (file)
@@ -977,7 +977,6 @@ static int tw9910_probe(struct i2c_client *client,
        ret = tw9910_video_probe(icd, client);
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
        }
 
@@ -990,7 +989,6 @@ static int tw9910_remove(struct i2c_client *client)
        struct soc_camera_device *icd = client->dev.platform_data;
 
        icd->ops = NULL;
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
        return 0;
 }
index c933b64d1283645071301eb4571b45e7ede1909a..bc02e6b21608be1ee4a0fcf4e52e3e6e7f383982 100644 (file)
@@ -200,8 +200,6 @@ static int __devexit pm860x_remove(struct i2c_client *client)
 
        pm860x_device_exit(chip);
        i2c_unregister_device(chip->companion);
-       i2c_set_clientdata(chip->client, NULL);
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 53ebfee548fa3bfbc5311d34c98bfc5b166290b7..66379b413906a3ed5147370040ed7ccffd0b5068 100644 (file)
@@ -957,7 +957,6 @@ static int __init ab3100_probe(struct i2c_client *client,
        i2c_unregister_device(ab3100->testreg_client);
  exit_no_testreg_client:
  exit_no_detect:
-       i2c_set_clientdata(client, NULL);
        kfree(ab3100);
        return err;
 }
@@ -979,7 +978,6 @@ static int __exit ab3100_remove(struct i2c_client *client)
         * their notifiers so deactivate IRQ
         */
        free_irq(client->irq, ab3100);
-       i2c_set_clientdata(client, NULL);
        kfree(ab3100);
        return 0;
 }
index 1060f8e1c40a1cd0c280b2dbfcb3759fd932241e..f54ab62e7bc6b50a11558b470637889d8a5c6533 100644 (file)
@@ -1362,7 +1362,6 @@ static int __exit ab3550_remove(struct i2c_client *client)
         * their notifiers so deactivate IRQ
         */
        free_irq(client->irq, ab);
-       i2c_set_clientdata(client, NULL);
        kfree(ab);
        return 0;
 }
index 005532865654b0bbfa036bc873a37858220ffac1..3122139b430022d819b532ba90d4d7dbccf69c96 100644 (file)
@@ -302,7 +302,6 @@ out_free_irq:
                free_irq(chip->irq, chip);
 
 out_free_chip:
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
 
        return ret;
@@ -317,7 +316,6 @@ static int __devexit adp5520_remove(struct i2c_client *client)
 
        adp5520_remove_subdevs(chip);
        adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 3ad915d0589c0626234ffdbc357afbbe2ff37af3..c07aece900fbb93b9ec08b2aa99ee85e144093fe 100644 (file)
@@ -534,7 +534,6 @@ static int __devinit da903x_probe(struct i2c_client *client,
 out_free_irq:
        free_irq(client->irq, chip);
 out_free_chip:
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return ret;
 }
@@ -544,7 +543,6 @@ static int __devexit da903x_remove(struct i2c_client *client)
        struct da903x_chip *chip = i2c_get_clientdata(client);
 
        da903x_remove_subdevs(chip);
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index e73f3f5252a89cf138dac35254263ed58630f72c..0219115e00c73f84c925045afceb96d65ea83ea3 100644 (file)
@@ -173,7 +173,6 @@ static int __devexit max8925_remove(struct i2c_client *client)
        max8925_device_exit(chip);
        i2c_unregister_device(chip->adc);
        i2c_unregister_device(chip->rtc);
-       i2c_set_clientdata(chip->i2c, NULL);
        kfree(chip);
        return 0;
 }
index 721948be12c77a7ad622e3559abc2f3953c1365a..a3fb4bcb98897718400da09d23dfd95116b99f58 100644 (file)
@@ -1228,7 +1228,6 @@ fail2:
        free_irq(client->irq, menelaus);
        flush_scheduled_work();
 fail1:
-       i2c_set_clientdata(client, NULL);
        kfree(menelaus);
        return err;
 }
@@ -1238,7 +1237,6 @@ static int __exit menelaus_remove(struct i2c_client *client)
        struct menelaus_chip    *menelaus = i2c_get_clientdata(client);
 
        free_irq(client->irq, menelaus);
-       i2c_set_clientdata(client, NULL);
        kfree(menelaus);
        the_menelaus = NULL;
        return 0;
index 704736e6e9b9b2efea2c66f4cf3a6ee36183eaa4..23e58552728596d7be431583e27602792b7e65d3 100644 (file)
@@ -336,7 +336,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
        return 0;
 
 err_free:
-       i2c_set_clientdata(client, NULL);
        kfree(pcf);
 
        return ret;
@@ -357,7 +356,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
        for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
                platform_device_unregister(pcf->regulator_pdev[i]);
 
-       i2c_set_clientdata(client, NULL);
        kfree(pcf);
 
        return 0;
index 715f095dd7a6119b580e6eed2a6b425347ed88d4..e619e2a55997ebd0ed1ab6f27969da4497a78de9 100644 (file)
@@ -296,7 +296,6 @@ out_freeirq:
 out_removeirq:
        tc35892_irq_remove(tc35892);
 out_free:
-       i2c_set_clientdata(i2c, NULL);
        kfree(tc35892);
        return ret;
 }
@@ -310,7 +309,6 @@ static int __devexit tc35892_remove(struct i2c_client *client)
        free_irq(tc35892->i2c->irq, tc35892);
        tc35892_irq_remove(tc35892);
 
-       i2c_set_clientdata(client, NULL);
        kfree(tc35892);
 
        return 0;
index 9b22a77f70f5dac90aec0395d176d9ad06d4a71f..d0016b67d125ce40b8d9a810f1abb7ade2678756 100644 (file)
@@ -530,7 +530,6 @@ static int __exit tps65010_remove(struct i2c_client *client)
        cancel_delayed_work(&tps->work);
        flush_scheduled_work();
        debugfs_remove(tps->file);
-       i2c_set_clientdata(client, NULL);
        kfree(tps);
        the_tps = NULL;
        return 0;
index 7795af4b1fe15f7ee4690bd1a16eb17188ac492f..5fe5de166adb39bdafb2e7714ce046f58b6ccb3b 100644 (file)
@@ -80,7 +80,6 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
        return ret;
 
 err:
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8350);
        return ret;
 }
@@ -90,7 +89,6 @@ static int wm8350_i2c_remove(struct i2c_client *i2c)
        struct wm8350 *wm8350 = i2c_get_clientdata(i2c);
 
        wm8350_device_exit(wm8350);
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8350);
 
        return 0;
index e08aafa663dc4a1460bd901fd369fe9ec11a12b9..1bfef4846b07b0d98138c87509872937b2c29e6f 100644 (file)
@@ -415,7 +415,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
        return 0;
 
 struct_err:
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8400);
 err:
        return ret;
@@ -426,7 +425,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
        struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
 
        wm8400_release(wm8400);
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8400);
 
        return 0;
index f7ca3a42b49089fcf48c6927260057d908641762..559b0b3c16c379584be01a08db209e2437549a04 100644 (file)
@@ -643,7 +643,6 @@ static int __devexit at24_remove(struct i2c_client *client)
 
        kfree(at24->writebuf);
        kfree(at24);
-       i2c_set_clientdata(client, NULL);
        return 0;
 }
 
index eb476b7f8d113cdadd87f558994a1fe95061cf49..f4ce273e93fd5e5888adbc73c9e684bd5568849c 100644 (file)
@@ -234,7 +234,6 @@ static int __devexit pismo_remove(struct i2c_client *client)
        /* FIXME: set_vpp needs saner arguments */
        pismo_setvpp_remove_fix(pismo);
 
-       i2c_set_clientdata(client, NULL);
        kfree(pismo);
 
        return 0;
@@ -286,7 +285,6 @@ static int __devinit pismo_probe(struct i2c_client *client,
        return 0;
 
  exit_free:
-       i2c_set_clientdata(client, NULL);
        kfree(pismo);
        return ret;
 }
index 00aea6f7d1f1bc6bbf8bfae8080bce0b01c633e7..1312eda57ba6621c335fe592f7a7d963a5d05a5d 100644 (file)
@@ -232,7 +232,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
        if (!fun)
                return -ENOMEM;
 
-       ret = of_address_to_resource(ofdev->node, 0, &io_res);
+       ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res);
        if (ret) {
                dev_err(&ofdev->dev, "can't get IO base\n");
                goto err1;
@@ -244,7 +244,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
                goto err1;
        }
 
-       prop = of_get_property(ofdev->node, "fsl,upm-addr-offset", &size);
+       prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-offset",
+                              &size);
        if (!prop || size != sizeof(uint32_t)) {
                dev_err(&ofdev->dev, "can't get UPM address offset\n");
                ret = -EINVAL;
@@ -252,7 +253,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
        }
        fun->upm_addr_offset = *prop;
 
-       prop = of_get_property(ofdev->node, "fsl,upm-cmd-offset", &size);
+       prop = of_get_property(ofdev->dev.of_node, "fsl,upm-cmd-offset", &size);
        if (!prop || size != sizeof(uint32_t)) {
                dev_err(&ofdev->dev, "can't get UPM command offset\n");
                ret = -EINVAL;
@@ -260,7 +261,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
        }
        fun->upm_cmd_offset = *prop;
 
-       prop = of_get_property(ofdev->node,
+       prop = of_get_property(ofdev->dev.of_node,
                               "fsl,upm-addr-line-cs-offsets", &size);
        if (prop && (size / sizeof(uint32_t)) > 0) {
                fun->mchip_count = size / sizeof(uint32_t);
@@ -276,7 +277,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
 
        for (i = 0; i < fun->mchip_count; i++) {
                fun->rnb_gpio[i] = -1;
-               rnb_gpio = of_get_gpio(ofdev->node, i);
+               rnb_gpio = of_get_gpio(ofdev->dev.of_node, i);
                if (rnb_gpio >= 0) {
                        ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
                        if (ret) {
@@ -292,13 +293,13 @@ static int __devinit fun_probe(struct of_device *ofdev,
                }
        }
 
-       prop = of_get_property(ofdev->node, "chip-delay", NULL);
+       prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL);
        if (prop)
                fun->chip_delay = *prop;
        else
                fun->chip_delay = 50;
 
-       prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+       prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size);
        if (prop && size == sizeof(uint32_t))
                fun->wait_flags = *prop;
        else
@@ -315,7 +316,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
        fun->dev = &ofdev->dev;
        fun->last_ctrl = NAND_CLE;
 
-       ret = fun_chip_init(fun, ofdev->node, &io_res);
+       ret = fun_chip_init(fun, ofdev->dev.of_node, &io_res);
        if (ret)
                goto err2;
 
index 3d0867d829cb01a02976328aa2fd1fe858b3fcf1..0a130dcaa1292974b264199824ec602fe002b677 100644 (file)
@@ -650,7 +650,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
 static int __devinit mpc5121_nfc_probe(struct of_device *op,
                                        const struct of_device_id *match)
 {
-       struct device_node *rootnode, *dn = op->node;
+       struct device_node *rootnode, *dn = op->dev.of_node;
        struct device *dev = &op->dev;
        struct mpc5121_nfc_prv *prv;
        struct resource res;
@@ -889,12 +889,12 @@ static struct of_device_id mpc5121_nfc_match[] __devinitdata = {
 };
 
 static struct of_platform_driver mpc5121_nfc_driver = {
-       .match_table    = mpc5121_nfc_match,
        .probe          = mpc5121_nfc_probe,
        .remove         = __devexit_p(mpc5121_nfc_remove),
        .driver         = {
-               .name   = DRV_NAME,
-               .owner  = THIS_MODULE,
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = mpc5121_nfc_match,
        },
 };
 
index 884852dc7eb44b29d1788fb43db7c3f6846c6936..cc728b12de82d4446315f91c165a032aa15f1c4b 100644 (file)
@@ -183,7 +183,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev,
                return -ENOMEM;
        }
 
-       host->io_base = of_iomap(ofdev->node, 0);
+       host->io_base = of_iomap(ofdev->dev.of_node, 0);
        if (host->io_base == NULL) {
                printk(KERN_ERR "socrates_nand: ioremap failed\n");
                kfree(host);
@@ -244,7 +244,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev,
 #ifdef CONFIG_MTD_OF_PARTS
        if (num_partitions == 0) {
                num_partitions = of_mtd_parse_partitions(&ofdev->dev,
-                                                        ofdev->node,
+                                                        ofdev->dev.of_node,
                                                         &partitions);
                if (num_partitions < 0) {
                        res = num_partitions;
index 9d11dbf5e4da2d96d941a48c2af51d8bae9bdb57..b9ad799c719f1d5b541a33d93d095318e6c362fc 100644 (file)
@@ -1429,7 +1429,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        wrb = wrb_from_mccq(adapter);
        if (!wrb) {
                status = -EBUSY;
-               goto err;
+               goto err_unlock;
        }
        req = cmd->va;
        sge = nonembedded_sgl(wrb);
@@ -1457,7 +1457,10 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        else
                status = adapter->flash_status;
 
-err:
+       return status;
+
+err_unlock:
+       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
@@ -1497,7 +1500,7 @@ err:
        return status;
 }
 
-extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
+int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
                                struct be_dma_mem *nonemb_cmd)
 {
        struct be_mcc_wrb *wrb;
@@ -1590,7 +1593,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
                        OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req));
-       req->hdr.timeout = 4;
+       req->hdr.timeout = cpu_to_le32(4);
 
        req->pattern = cpu_to_le64(pattern);
        req->src_port = cpu_to_le32(port_num);
@@ -1662,7 +1665,7 @@ err:
        return status;
 }
 
-extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
+int be_cmd_get_seeprom_data(struct be_adapter *adapter,
                                struct be_dma_mem *nonemb_cmd)
 {
        struct be_mcc_wrb *wrb;
index 39250b2ca886e9c7216ffcc956870c1320f85d0e..959add2410bf1787f8dff73ff786582be105831e 100644 (file)
@@ -1654,8 +1654,11 @@ MODULE_DEVICE_TABLE (of, bmac_match);
 
 static struct macio_driver bmac_driver =
 {
-       .name           = "bmac",
-       .match_table    = bmac_match,
+       .driver = {
+               .name           = "bmac",
+               .owner          = THIS_MODULE,
+               .of_match_table = bmac_match,
+       },
        .probe          = bmac_probe,
        .remove         = bmac_remove,
 #ifdef CONFIG_PM
index 8af8442c694a69c2e4e5dea49ebcd7d13a4e92de..af753936e835840ac0127ea78f6421893887b37d 100644 (file)
@@ -73,7 +73,7 @@ static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
        else
                *mscan_clksrc = MSCAN_CLKSRC_XTAL;
 
-       freq = mpc5xxx_get_bus_frequency(ofdev->node);
+       freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
        if (!freq)
                return 0;
 
@@ -152,7 +152,7 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
        }
 
        /* Determine the MSCAN device index from the physical address */
-       pval = of_get_property(ofdev->node, "reg", &plen);
+       pval = of_get_property(ofdev->dev.of_node, "reg", &plen);
        BUG_ON(!pval || plen < sizeof(*pval));
        clockidx = (*pval & 0x80) ? 1 : 0;
        if (*pval & 0x2000)
@@ -168,11 +168,11 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
         */
        if (clock_name && !strcmp(clock_name, "ip")) {
                *mscan_clksrc = MSCAN_CLKSRC_IPS;
-               freq = mpc5xxx_get_bus_frequency(ofdev->node);
+               freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
        } else {
                *mscan_clksrc = MSCAN_CLKSRC_BUS;
 
-               pval = of_get_property(ofdev->node,
+               pval = of_get_property(ofdev->dev.of_node,
                                       "fsl,mscan-clock-divider", &plen);
                if (pval && plen == sizeof(*pval))
                        clockdiv = *pval;
@@ -251,7 +251,7 @@ static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
                                       const struct of_device_id *id)
 {
        struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data;
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct net_device *dev;
        struct mscan_priv *priv;
        void __iomem *base;
index 5d45084b287d13afa6d24dcfc02d18f56afb0ce1..48e91b6242ce99b8382aeb4d55ec17c3af682cc7 100644 (file)
@@ -504,17 +504,54 @@ static int get_regs_len(struct net_device *dev)
 }
 
 /* Some transmit errors cause the transmitter to shut
- * down.  We now issue a restart transmit.  Since the
- * errors close the BD and update the pointers, the restart
- * _should_ pick up without having to reset any of our
- * pointers either.  Also, To workaround 8260 device erratum
- * CPM37, we must disable and then re-enable the transmitter
- * following a Late Collision, Underrun, or Retry Limit error.
+ * down.  We now issue a restart transmit.
+ * Also, to workaround 8260 device erratum CPM37, we must
+ * disable and then re-enable the transmitterfollowing a
+ * Late Collision, Underrun, or Retry Limit error.
+ * In addition, tbptr may point beyond BDs beyond still marked
+ * as ready due to internal pipelining, so we need to look back
+ * through the BDs and adjust tbptr to point to the last BD
+ * marked as ready.  This may result in some buffers being
+ * retransmitted.
  */
 static void tx_restart(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
        fcc_t __iomem *fccp = fep->fcc.fccp;
+       const struct fs_platform_info *fpi = fep->fpi;
+       fcc_enet_t __iomem *ep = fep->fcc.ep;
+       cbd_t __iomem *curr_tbptr;
+       cbd_t __iomem *recheck_bd;
+       cbd_t __iomem *prev_bd;
+       cbd_t __iomem *last_tx_bd;
+
+       last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t));
+
+       /* get the current bd held in TBPTR  and scan back from this point */
+       recheck_bd = curr_tbptr = (cbd_t __iomem *)
+               ((R32(ep, fen_genfcc.fcc_tbptr) - fep->ring_mem_addr) +
+               fep->ring_base);
+
+       prev_bd = (recheck_bd == fep->tx_bd_base) ? last_tx_bd : recheck_bd - 1;
+
+       /* Move through the bds in reverse, look for the earliest buffer
+        * that is not ready.  Adjust TBPTR to the following buffer */
+       while ((CBDR_SC(prev_bd) & BD_ENET_TX_READY) != 0) {
+               /* Go back one buffer */
+               recheck_bd = prev_bd;
+
+               /* update the previous buffer */
+               prev_bd = (prev_bd == fep->tx_bd_base) ? last_tx_bd : prev_bd - 1;
+
+               /* We should never see all bds marked as ready, check anyway */
+               if (recheck_bd == curr_tbptr)
+                       break;
+       }
+       /* Now update the TBPTR and dirty flag to the current buffer */
+       W32(ep, fen_genfcc.fcc_tbptr,
+               (uint) (((void *)recheck_bd - fep->ring_base) +
+               fep->ring_mem_addr));
+       fep->dirty_tx = recheck_bd;
 
        C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
        udelay(10);
index 0f90685d3d19472e3bc0dc9b05ed5872a5fa9f63..3607340f3da7ce93a671a964366758780f7bc038 100644 (file)
@@ -169,7 +169,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 
        new_bus->name = "CPM2 Bitbanged MII",
 
-       ret = fs_mii_bitbang_init(new_bus, ofdev->node);
+       ret = fs_mii_bitbang_init(new_bus, ofdev->dev.of_node);
        if (ret)
                goto out_free_bus;
 
@@ -181,7 +181,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
        new_bus->parent = &ofdev->dev;
        dev_set_drvdata(&ofdev->dev, new_bus);
 
-       ret = of_mdiobus_register(new_bus, ofdev->node);
+       ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
        if (ret)
                goto out_free_irqs;
 
index f37a4c143ddddf985556018dc5e21288e23f3207..3a029d02c2b410405dd37c5e6b1b7e8e4ccb63c9 100644 (file)
@@ -1607,14 +1607,13 @@ static struct of_device_id greth_of_match[] = {
 MODULE_DEVICE_TABLE(of, greth_of_match);
 
 static struct of_platform_driver greth_of_driver = {
-       .name = "grlib-greth",
-       .match_table = greth_of_match,
+       .driver = {
+               .name = "grlib-greth",
+               .owner = THIS_MODULE,
+               .of_match_table = greth_of_match,
+       },
        .probe = greth_of_probe,
        .remove = __devexit_p(greth_of_remove),
-       .driver = {
-                  .owner = THIS_MODULE,
-                  .name = "grlib-greth",
-                  },
 };
 
 static int __init greth_init(void)
index c80ca64277b224934bc57e1b541c7cef7193a9ff..7805bbf1d53a6ceeaf02f8c68f4e3740e2c4939d 100644 (file)
@@ -4854,7 +4854,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)
  *
  * Return 0 if successful; otherwise an error code indicating failure.
  */
-static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct dev_priv *priv = netdev_priv(dev);
        struct dev_info *hw_priv = priv->adapter;
@@ -6863,6 +6863,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_tx_timeout         = netdev_tx_timeout,
        .ndo_change_mtu         = netdev_change_mtu,
        .ndo_set_mac_address    = netdev_set_mac_address,
+       .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_set_rx_mode        = netdev_set_rx_mode,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index b6855a6476f8eaa3480135d65096c05b870ed101..1c5221f79d6faf3fdc055e728c9498f28e9f5d8d 100644 (file)
@@ -997,8 +997,11 @@ MODULE_DEVICE_TABLE (of, mace_match);
 
 static struct macio_driver mace_driver =
 {
-       .name           = "mace",
-       .match_table    = mace_match,
+       .driver = {
+               .name           = "mace",
+               .owner          = THIS_MODULE,
+               .of_match_table = mace_match,
+       },
        .probe          = mace_probe,
        .remove         = mace_remove,
 };
index 78eb3190b9b1343bee9e1cd786090c395ebd0877..1edb7a61983c05660aaec2624e596159ab2cd5c9 100644 (file)
@@ -340,7 +340,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
 
        skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len);
 
-       err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 2, skb);
+       err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 2, skb, gfp);
        if (err < 0)
                dev_kfree_skb(skb);
 
@@ -385,8 +385,8 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
 
        /* chain first in list head */
        first->private = (unsigned long)list;
-       err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2,
-                                      first);
+       err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2,
+                                   first, gfp);
        if (err < 0)
                give_pages(vi, first);
 
@@ -404,7 +404,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
 
        sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE);
 
-       err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 1, page);
+       err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 1, page, gfp);
        if (err < 0)
                give_pages(vi, page);
 
index 82ab532a492335c803af5f1cd32f34eb527a334a..a93dc18a45c3fc9e0911197f7292948518741927 100644 (file)
@@ -739,17 +739,27 @@ err_out:
 static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
 {
        struct device *parent = aru->udev->dev.parent;
+       struct usb_device *udev;
+
+       /*
+        * Store a copy of the usb_device pointer locally.
+        * This is because device_release_driver initiates
+        * ar9170_usb_disconnect, which in turn frees our
+        * driver context (aru).
+        */
+       udev = aru->udev;
 
        complete(&aru->firmware_loading_complete);
 
        /* unbind anything failed */
        if (parent)
                device_lock(parent);
-       device_release_driver(&aru->udev->dev);
+
+       device_release_driver(&udev->dev);
        if (parent)
                device_unlock(parent);
 
-       usb_put_dev(aru->udev);
+       usb_put_dev(udev);
 }
 
 static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
index 3db19172b43b7a1aa165e68463fabaf71dd4d278..859aa4ab07698aafcd937b606cb7bafd7f4e05fe 100644 (file)
@@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
                int r;
 
                ath_print(common, ATH_DBG_FATAL,
-                         "Unable to stop TxDMA. Reset HAL!\n");
+                         "Failed to stop TX DMA. Resetting hardware!\n");
 
                spin_lock_bh(&sc->sc_resetlock);
                r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
@@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
        } else
                bf->bf_isnullfunc = false;
 
+       bf->bf_tx_aborted = false;
+
        return 0;
 }
 
@@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
        int nbad = 0;
        int isaggr = 0;
 
-       if (bf->bf_tx_aborted)
+       if (bf->bf_lastbf->bf_tx_aborted)
                return 0;
 
        isaggr = bf_isaggr(bf);
index a115bfa9513a8776f49139924e475a517884819c..7a377f5b76627540b6309f563bf6c974be503799 100644 (file)
@@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
        /* create the exported radio header */
 
        /* radiotap header */
-       radiotap_hdr.hdr.it_version = 0;
-       /* XXX must check this value for pad */
-       radiotap_hdr.hdr.it_pad = 0;
+       memset(&radiotap_hdr, 0, sizeof(radiotap_hdr));
+       /* XXX must check radiotap_hdr.hdr.it_pad for pad */
        radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
        radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
        radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
index 9bcee10c9308f861089843ccfe7c9b3009907e6d..4a0a0e5265c9bc068ee7116a240b5f8fa7560487 100644 (file)
@@ -239,8 +239,11 @@ static struct of_device_id airport_match[] =
 MODULE_DEVICE_TABLE(of, airport_match);
 
 static struct macio_driver airport_driver = {
-       .name           = DRIVER_NAME,
-       .match_table    = airport_match,
+       .driver = {
+               .name           = DRIVER_NAME,
+               .owner          = THIS_MODULE,
+               .of_match_table = airport_match,
+       },
        .probe          = airport_attach,
        .remove         = airport_detach,
        .suspend        = airport_suspend,
index 699161327d656feb56cb7c74d081e17e277a9394..0f8b84b7224cace0167ebe5b0065da28af08986c 100644 (file)
@@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
         */
        rt2x00_desc_read(txi, 0, &word);
        rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
-                          skb->len - TXINFO_DESC_SIZE);
+                          skb->len + TXWI_DESC_SIZE);
        rt2x00_set_field32(&word, TXINFO_W0_WIV,
                           !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
        rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
index 1a648b90b634890512ffb95560c1944d5d7a214a..25e5e30a18afdd6bafaae72e1c06314f42c9efb0 100644 (file)
@@ -1157,7 +1157,7 @@ static int __init m8xx_probe(struct of_device *ofdev,
        unsigned int i, m, hwirq;
        pcmconf8xx_t *pcmcia;
        int status;
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
 
        pcmcia_info("%s\n", version);
 
@@ -1301,7 +1301,7 @@ static struct of_platform_driver m8xx_pcmcia_driver = {
        .driver = {
                .name = driver_name,
                .owner = THIS_MODULE,
-               .match_table = m8xx_pcmcia_match,
+               .of_match_table = m8xx_pcmcia_match,
        },
        .probe = m8xx_probe,
        .remove = m8xx_remove,
index 576c3ed924356d5fc1f3915bce9670b498a636ca..40658e3385b45346ddc91132816e28ccfee4dd84 100644 (file)
@@ -524,7 +524,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
        for (i = 0; i < inlen; i++)
                ipc_data_writel(*in++, 4 * i);
 
-       ipc_command(cmd << 12 | sub);
+       ipc_command((cmd << 12) | sub | (inlen << 18));
        err = busy_loop();
 
        for (i = 0; i < outlen; i++)
index f3e22c9fe20a538581a70fc0d0134bf78a5a1b33..2f2f9a6f54fad6d75dc692fbee4d128b7ba642a4 100644 (file)
@@ -225,7 +225,6 @@ static int __devinit max17040_probe(struct i2c_client *client,
        ret = power_supply_register(&client->dev, &chip->battery);
        if (ret) {
                dev_err(&client->dev, "failed: power supply register\n");
-               i2c_set_clientdata(client, NULL);
                kfree(chip);
                return ret;
        }
@@ -245,7 +244,6 @@ static int __devexit max17040_remove(struct i2c_client *client)
 
        power_supply_unregister(&chip->battery);
        cancel_delayed_work(&chip->work);
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 671a7d1f1f0e33e5f9f0fd4e016b742a870da3a4..8ae3732eb24bcd28e414049b583d3644fa8ffd17 100644 (file)
@@ -519,8 +519,6 @@ static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
        struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
        int i;
 
-       i2c_set_clientdata(i2c, NULL);
-
        for (i = 0; i < lp3971->num_regulators; i++)
                regulator_unregister(lp3971->rdev[i]);
 
index b3c1afc16889434f47c9fd74e387da39bb255737..2b54d9d75f11e2893ead65a3624199fa13fb9b24 100644 (file)
@@ -244,7 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
        for (i = 0; i <= MAX1586_V6; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
-       i2c_set_clientdata(client, NULL);
        kfree(rdev);
 
        return 0;
index bfc4c5ffdc966f3ab03081259faf52adce239906..4520ace3f7e707f82ccbf0fb068df921dfc6c2df 100644 (file)
@@ -357,7 +357,6 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
        dev_info(info->dev, "Max8649 regulator device is detected.\n");
        return 0;
 out:
-       i2c_set_clientdata(client, NULL);
        kfree(info);
        return ret;
 }
@@ -369,7 +368,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
        if (info) {
                if (info->regulator)
                        regulator_unregister(info->regulator);
-               i2c_set_clientdata(client, NULL);
                kfree(info);
        }
 
index 3790b21879ff2f8d2c5b8000fe216f1f0770a436..d97220efae5ab4f1fde54cd909c724a3f5bf3523 100644 (file)
@@ -471,7 +471,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
        for (i = 0; i < MAX8660_V_END; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
-       i2c_set_clientdata(client, NULL);
        kfree(rdev);
 
        return 0;
index 8e2f2098b00562fd2e9608494569f28f9b85a83f..f50afc9f287a80f04513bcf670839fcf84ebc23b 100644 (file)
@@ -538,9 +538,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
        struct tps_pmic *tps = i2c_get_clientdata(client);
        int i;
 
-       /* clear the client data in i2c */
-       i2c_set_clientdata(client, NULL);
-
        for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
                regulator_unregister(tps->rdev[i]);
 
index 61945734ad003c379fde6424c708942b1afbbf8a..1f0007fd44314c5b65ffc39fde6df81cc568d492 100644 (file)
@@ -403,7 +403,6 @@ out_irq:
                free_irq(client->irq, client);
 
 out_free:
-       i2c_set_clientdata(client, NULL);
        kfree(ds1374);
        return ret;
 }
@@ -422,7 +421,6 @@ static int __devexit ds1374_remove(struct i2c_client *client)
        }
 
        rtc_device_unregister(ds1374->rtc);
-       i2c_set_clientdata(client, NULL);
        kfree(ds1374);
        return 0;
 }
index f0dbf9cb8f9c42f30e51b6db7dba823d887c6f61..db5d8c416d26a18e6fdb141c3bfa1d7c106e18d9 100644 (file)
@@ -279,7 +279,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
        if (!rtc)
                return -ENOMEM;
 
-       rtc->regs = of_iomap(op->node, 0);
+       rtc->regs = of_iomap(op->dev.of_node, 0);
        if (!rtc->regs) {
                dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
                err = -ENOSYS;
@@ -290,7 +290,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
 
        dev_set_drvdata(&op->dev, rtc);
 
-       rtc->irq = irq_of_parse_and_map(op->node, 1);
+       rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
        err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
                                                "mpc5121-rtc", &op->dev);
        if (err) {
@@ -299,7 +299,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op,
                goto out_dispose;
        }
 
-       rtc->irq_periodic = irq_of_parse_and_map(op->node, 0);
+       rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
        err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
                                IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
        if (err) {
@@ -365,9 +365,11 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = {
 };
 
 static struct of_platform_driver mpc5121_rtc_driver = {
-       .owner = THIS_MODULE,
-       .name = "mpc5121-rtc",
-       .match_table = mpc5121_rtc_match,
+       .driver = {
+               .name = "mpc5121-rtc",
+               .owner = THIS_MODULE,
+               .of_match_table = mpc5121_rtc_match,
+       },
        .probe = mpc5121_rtc_probe,
        .remove = __devexit_p(mpc5121_rtc_remove),
 };
index b65c82f792d9cd6f86614304db1f4c9d99077c6b..789f62f9b47d4b288ba8dffe30adeaf123c1fc84 100644 (file)
@@ -632,7 +632,6 @@ errout_reg:
        rtc_device_unregister(rx8025->rtc);
 
 errout_free:
-       i2c_set_clientdata(client, NULL);
        kfree(rx8025);
 
 errout:
@@ -656,7 +655,6 @@ static int __devexit rx8025_remove(struct i2c_client *client)
 
        rx8025_sysfs_unregister(&client->dev);
        rtc_device_unregister(rx8025->rtc);
-       i2c_set_clientdata(client, NULL);
        kfree(rx8025);
        return 0;
 }
index def4d396d0b096cef968a5572f2b5122d92eeb33..f789e002c9b013664a2588ea342b25a52acf8a1c 100644 (file)
@@ -275,7 +275,6 @@ exit_dummy:
                if (s35390a->client[i])
                        i2c_unregister_device(s35390a->client[i]);
        kfree(s35390a);
-       i2c_set_clientdata(client, NULL);
 
 exit:
        return err;
@@ -292,7 +291,6 @@ static int s35390a_remove(struct i2c_client *client)
 
        rtc_device_unregister(s35390a->rtc);
        kfree(s35390a);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 18735b39b3d39c8547e27b8037fbef033a0df76a..3ddb4dc62d5d5eed49ecc1a1228ddbdfbecd1f47 100644 (file)
@@ -542,8 +542,11 @@ MODULE_DEVICE_TABLE (of, mac53c94_match);
 
 static struct macio_driver mac53c94_driver = 
 {
-       .name           = "mac53c94",
-       .match_table    = mac53c94_match,
+       .driver = {
+               .name           = "mac53c94",
+               .owner          = THIS_MODULE,
+               .of_match_table = mac53c94_match,
+       },
        .probe          = mac53c94_probe,
        .remove         = mac53c94_remove,
 };
index a1c97e88068ae961ce3605ecfe1143f2c80af7b3..1f784fde25109b53ef86f2b79fd975ed5cc2bf38 100644 (file)
@@ -2036,8 +2036,11 @@ MODULE_DEVICE_TABLE (of, mesh_match);
 
 static struct macio_driver mesh_driver = 
 {
-       .name           = "mesh",
-       .match_table    = mesh_match,
+       .driver = {
+               .name           = "mesh",
+               .owner          = THIS_MODULE,
+               .of_match_table = mesh_match,
+       },
        .probe          = mesh_probe,
        .remove         = mesh_remove,
        .shutdown       = mesh_shutdown,
index cabbdc7ba5838bf62e1fa799a6ed2678eb650864..5b9cde79e4eaf5c3f686f7b056952e04b1eef027 100644 (file)
@@ -2005,8 +2005,11 @@ static struct of_device_id pmz_match[] =
 MODULE_DEVICE_TABLE (of, pmz_match);
 
 static struct macio_driver pmz_driver = {
-       .name           = "pmac_zilog",
-       .match_table    = pmz_match,
+       .driver = {
+               .name           = "pmac_zilog",
+               .owner          = THIS_MODULE,
+               .of_match_table = pmz_match,
+       },
        .probe          = pmz_attach,
        .remove         = pmz_detach,
        .suspend        = pmz_suspend,
index 28a126d2742bcf1fd89e1f753080341dfe4958a3..2534b1ec3eddc5b39485c8fa71fff21dcbef07d3 100644 (file)
@@ -512,29 +512,29 @@ static int __init mpc512x_psc_spi_of_probe(struct of_device *op,
        u64 regaddr64, size64;
        s16 id = -1;
 
-       regaddr_p = of_get_address(op->node, 0, &size64, NULL);
+       regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
        if (!regaddr_p) {
                dev_err(&op->dev, "Invalid PSC address\n");
                return -EINVAL;
        }
-       regaddr64 = of_translate_address(op->node, regaddr_p);
+       regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
 
        /* get PSC id (0..11, used by port_config) */
        if (op->dev.platform_data == NULL) {
                const u32 *psc_nump;
 
-               psc_nump = of_get_property(op->node, "cell-index", NULL);
+               psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL);
                if (!psc_nump || *psc_nump > 11) {
                        dev_err(&op->dev, "mpc512x_psc_spi: Device node %s "
                                "has invalid cell-index property\n",
-                               op->node->full_name);
+                               op->dev.of_node->full_name);
                        return -EINVAL;
                }
                id = *psc_nump;
        }
 
        return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
-                                       irq_of_parse_and_map(op->node, 0), id);
+                               irq_of_parse_and_map(op->dev.of_node, 0), id);
 }
 
 static int __exit mpc512x_psc_spi_of_remove(struct of_device *op)
@@ -550,12 +550,12 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = {
 MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);
 
 static struct of_platform_driver mpc512x_psc_spi_of_driver = {
-       .match_table = mpc512x_psc_spi_of_match,
        .probe = mpc512x_psc_spi_of_probe,
        .remove = __exit_p(mpc512x_psc_spi_of_remove),
        .driver = {
                .name = "mpc512x-psc-spi",
                .owner = THIS_MODULE,
+               .of_match_table = mpc512x_psc_spi_of_match,
        },
 };
 
index 19c0b3b34fce0160d7cb4d0b0c16f14d8143671d..d53466a249d9700bb9108478a5b08ffcf1955b6a 100644 (file)
@@ -397,7 +397,7 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op,
        struct spi_master *master;
        struct spi_bitbang *bbp;
        struct resource resource;
-       struct device_node *np = op->node;
+       struct device_node *np = op->dev.of_node;
        struct device *dev = &op->dev;
        struct device_node *opbnp;
        int ret;
index 989e2752cc36d8abb9613b6c77b50936be85184c..6dcda86be6ebdb83d579d27907ee1f153889000a 100644 (file)
@@ -625,9 +625,12 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
                ssb_printk(KERN_ERR PFX "No SPROM available!\n");
                return -ENODEV;
        }
-
-       bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
-               SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
+       if (bus->chipco.dev) {  /* can be unavailible! */
+               bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
+                       SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
+       } else {
+               bus->sprom_offset = SSB_SPROM_BASE1;
+       }
 
        buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
        if (!buf)
index 007bc3a03486b621034134f33a1c3029cb8e0b29..4f7cc8d13277ddb84126430923202f9fa7938ac7 100644 (file)
@@ -185,6 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus)
        /* this routine differs from specs as we do not access SPROM directly
           on PCMCIA */
        if (bus->bustype == SSB_BUSTYPE_PCI &&
+           bus->chipco.dev &&  /* can be unavailible! */
            bus->chipco.dev->id.revision >= 31)
                return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
 
index 1f020dad6234b475ea4edc76dd48d7e02278b341..3320359408a966b15d11809ddf9760b00e2a782a 100644 (file)
@@ -519,7 +519,6 @@ err_input_register_device_failed:
 err_input_dev_alloc_failed:
 err_detect_failed:
 err_power_failed:
-       i2c_set_clientdata(client, NULL);
        kfree(ts);
 err_alloc_data_failed:
 err_check_functionality_failed:
@@ -537,7 +536,6 @@ static int synaptics_ts_remove(struct i2c_client *client)
        else
                hrtimer_cancel(&ts->timer);
        input_unregister_device(ts->input_dev);
-       i2c_set_clientdata(client, NULL);
        kfree(ts);
        return 0;
 }
index bd925457f8b710ec8b44a86b7a32dddc22d0abfd..72f5c1f56d195f9c777ba09106b829f1814b9de0 100644 (file)
@@ -289,7 +289,6 @@ static int wis_saa7113_probe(struct i2c_client *client,
        if (write_regs(client, initial_registers) < 0) {
                printk(KERN_ERR
                        "wis-saa7113: error initializing SAA7113\n");
-               i2c_set_clientdata(client, NULL);
                kfree(dec);
                return -ENODEV;
        }
@@ -301,7 +300,6 @@ static int wis_saa7113_remove(struct i2c_client *client)
 {
        struct wis_saa7113 *dec = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(dec);
        return 0;
 }
index b2eb804c1954ceedd9fe7986e319c9425551babf..cd950b61cf70ee1c4d1d883f2949c5677c085368 100644 (file)
@@ -422,7 +422,6 @@ static int wis_saa7115_probe(struct i2c_client *client,
        if (write_regs(client, initial_registers) < 0) {
                printk(KERN_ERR
                        "wis-saa7115: error initializing SAA7115\n");
-               i2c_set_clientdata(client, NULL);
                kfree(dec);
                return -ENODEV;
        }
@@ -434,7 +433,6 @@ static int wis_saa7115_remove(struct i2c_client *client)
 {
        struct wis_saa7115 *dec = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(dec);
        return 0;
 }
index b1013291190f162f6668af96c8593c81b57cb7e9..981c9b311b8b9643befcd08440b1e598354cc5eb 100644 (file)
@@ -684,7 +684,6 @@ static int wis_sony_tuner_remove(struct i2c_client *client)
 {
        struct wis_sony_tuner *t = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(t);
        return 0;
 }
index 315268d130dd61311873a36bd3ae373ed75f3539..ee28a99dc3883620135726feba6034f54632c9ea 100644 (file)
@@ -323,7 +323,6 @@ static int wis_tw2804_remove(struct i2c_client *client)
 {
        struct wis_tw2804 *dec = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(dec);
        return 0;
 }
index 2afea09091b97e020fff05d4438b1b93156e64a7..80d47269b1c01f4054faeb8f2f4514f242e0dc29 100644 (file)
@@ -294,7 +294,6 @@ static int wis_tw9903_probe(struct i2c_client *client,
 
        if (write_regs(client, initial_registers) < 0) {
                printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
-               i2c_set_clientdata(client, NULL);
                kfree(dec);
                return -ENODEV;
        }
@@ -306,7 +305,6 @@ static int wis_tw9903_remove(struct i2c_client *client)
 {
        struct wis_tw9903 *dec = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(dec);
        return 0;
 }
index 20e267448d1fdffe25eedf5ef35c1b10c2746413..905f8560d31f94d0a4651d54ab8b8191ca69d1f4 100644 (file)
@@ -1011,7 +1011,6 @@ error_put_reg:
        if (!IS_ERR(st->reg))
                regulator_put(st->reg);
 error_free_st:
-       i2c_set_clientdata(client, NULL);
        kfree(st);
 
 error_ret:
@@ -1030,7 +1029,6 @@ static int max1363_remove(struct i2c_client *client)
                regulator_disable(st->reg);
                regulator_put(st->reg);
        }
-       i2c_set_clientdata(client, NULL);
        kfree(st);
 
        return 0;
index 43aaacff4e744bc6a1d18f182f5ac640ac2eabef..e4b0a5ef1c1f4913d39870c9ef363917ca552e83 100644 (file)
@@ -694,7 +694,6 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 fail2:
        iio_device_unregister(chip->indio_dev);
 fail1:
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return err;
 }
@@ -705,7 +704,6 @@ static int tsl2563_remove(struct i2c_client *client)
 
        iio_device_unregister(chip->indio_dev);
 
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 2928523268b53ac61470959ac6d6cd41519633d1..82506ca297d5f1632312f8d52b7f80b7aab49637 100644 (file)
@@ -2400,7 +2400,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);
 static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev)
 {
        struct qe_udc *udc;
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        unsigned int tmp_addr = 0;
        struct usb_device_para __iomem *usbpram;
        unsigned int i;
@@ -2525,7 +2525,7 @@ static void qe_udc_release(struct device *dev)
 static int __devinit qe_udc_probe(struct of_device *ofdev,
                        const struct of_device_id *match)
 {
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct qe_ep *ep;
        unsigned int ret = 0;
        unsigned int i;
index 013972bbde57d21bd16c737c1a1e455a1f90876a..4899f451add98f5727cd72710ea8f4751070d868 100644 (file)
@@ -151,7 +151,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
 static int __devinit
 ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dn = op->node;
+       struct device_node *dn = op->dev.of_node;
        struct usb_hcd *hcd;
        struct ehci_hcd *ehci;
        struct resource res;
index 51fcc0a2c94a9097aea33eff174b1b38969b263d..e45833ce975bd6cb60fb2d8b09db767d28987c14 100644 (file)
@@ -242,7 +242,7 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
        struct atyfb_par *par = (struct atyfb_par *) info->par;
-       u32 color = rect->color, dx = rect->dx, width = rect->width, rotation = 0;
+       u32 color, dx = rect->dx, width = rect->width, rotation = 0;
 
        if (par->asleep)
                return;
@@ -253,8 +253,11 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
                return;
        }
 
-       color |= (rect->color << 8);
-       color |= (rect->color << 16);
+       if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+           info->fix.visual == FB_VISUAL_DIRECTCOLOR)
+               color = ((u32 *)(info->pseudo_palette))[rect->color];
+       else
+               color = rect->color;
 
        if (info->var.bits_per_pixel == 24) {
                /* In 24 bpp, the engine is in 8 bpp - this requires that all */
index 921ca37398f39b63943f3484192140dc355087d6..3ec24609151e8ec322c48afcebae8dc9ce578b5d 100644 (file)
@@ -756,7 +756,6 @@ out:
 out1:
        backlight_device_unregister(bl);
 out2:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 
        return ret;
@@ -776,7 +775,6 @@ static int __devexit adp8860_remove(struct i2c_client *client)
                        &adp8860_bl_attr_group);
 
        backlight_device_unregister(data->bl);
-       i2c_set_clientdata(client, NULL);
        kfree(data);
 
        return 0;
index e03e60bbfd855f01301ab14d71b1fc9d94453bcc..2a04b382ec4834a03270db15701136f5f01694cf 100644 (file)
@@ -119,7 +119,6 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
 
 err_reg:
        data->bl = NULL;
-       i2c_set_clientdata(client, NULL);
 err_gpio_dir:
        gpio_free(TOSA_GPIO_BL_C20MA);
 err_gpio_bl:
@@ -133,7 +132,6 @@ static int __devexit tosa_bl_remove(struct i2c_client *client)
 
        backlight_device_unregister(data->bl);
        data->bl = NULL;
-       i2c_set_clientdata(client, NULL);
 
        gpio_free(TOSA_GPIO_BL_C20MA);
 
index 2c371c07f0daaff562b844184bfb742284b9cc53..09f1b9b462f4a8a4ce86a600aa55a4cbf1685622 100644 (file)
@@ -275,7 +275,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par,
 
 static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct bw2_par *par;
        int linebytes, err;
index d12e05b6e63f96ce0cd36ba1ddb810167953d280..e5dc2241194fed66606c1e694aa4c77ed3357c81 100644 (file)
@@ -465,7 +465,7 @@ static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
 
 static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct cg14_par *par;
        int is_8mb, linebytes, i, err;
index b98f93f7f6638f0a02a39250aaeaca54b595bbb3..558d73a948a0d836c73ea20c26440229738ba581 100644 (file)
@@ -349,7 +349,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par)
 static int __devinit cg3_probe(struct of_device *op,
                               const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct cg3_par *par;
        int linebytes, err;
index 3d7895316eaf37e79bb56f2413d748fcbdfca131..9e8bf7d5e249df2a3d0f3243181bab0b76b633a9 100644 (file)
@@ -550,7 +550,7 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info,
 static int __devinit leo_probe(struct of_device *op,
                               const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct leo_par *par;
        int linebytes, err;
index 0540de4f5cb48f062bedb6d9874964ab1423d62b..4e2b8cc3d46093299a2ae05178ead6db2e783640 100644 (file)
@@ -553,7 +553,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par)
 static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev,
                                               const struct of_device_id *id)
 {
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct device *dev = &ofdev->dev;
        struct mb862xxfb_par *par;
        struct fb_info *info;
index c85dd408a9b87369fffdce371fad0754f1100810..6552751e81aaa058a18af29ff8892d9abe1a54af 100644 (file)
@@ -251,7 +251,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
 
 static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct p9100_par *par;
        int linebytes, err;
index ef7a7bd8b503492fec8aa1f56ab678adfe2f06f0..cc039b33d2d8bd762a493bd650fceb1b0895a52f 100644 (file)
@@ -365,7 +365,7 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
 static int __devinit tcx_probe(struct of_device *op,
                               const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
+       struct device_node *dp = op->dev.of_node;
        struct fb_info *info;
        struct tcx_par *par;
        int linebytes, i, err;
index ca0f4c6cf5ab98217f1b444a94611b0098781041..1df284f9c2a1b3fcd9e667b49915e4dbc21f5de3 100644 (file)
@@ -273,7 +273,7 @@ static int __devinit gef_wdt_probe(struct of_device *dev,
                bus_clk = freq;
 
        /* Map devices registers into memory */
-       gef_wdt_regs = of_iomap(dev->node, 0);
+       gef_wdt_regs = of_iomap(dev->dev.of_node, 0);
        if (gef_wdt_regs == NULL)
                return -ENOMEM;
 
index 6622335773bbc53fd2f0c3aa90b986d6b2dca0ea..4cda64dd309c0367208358ef6eb41b73180969cc 100644 (file)
@@ -189,7 +189,7 @@ static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev,
                                       const struct of_device_id *match)
 {
        int ret;
-       struct device_node *np = ofdev->node;
+       struct device_node *np = ofdev->dev.of_node;
        struct mpc8xxx_wdt_type *wdt_type = match->data;
        u32 freq = fsl_get_sys_freq();
        bool enabled;
index eab33f1dbdf7013f451af491b882973ea017f718..7b547f53f65ee9267f19dd493a6ab7321310ed4c 100644 (file)
@@ -499,7 +499,7 @@ int xenbus_printf(struct xenbus_transaction t,
 #define PRINTF_BUFFER_SIZE 4096
        char *printf_buffer;
 
-       printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
+       printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_NOIO | __GFP_HIGH);
        if (printf_buffer == NULL)
                return -ENOMEM;
 
index f4909951667554b6e4263ebebedc6d2513599d48..9fdc7fe3a7bc127da02963e76c3628221c334ed0 100644 (file)
@@ -91,9 +91,10 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell,
 
                memcpy(&server->addr, addr, sizeof(struct in_addr));
                server->addr.s_addr = addr->s_addr;
+               _leave(" = %p{%d}", server, atomic_read(&server->usage));
+       } else {
+               _leave(" = NULL [nomem]");
        }
-
-       _leave(" = %p{%d}", server, atomic_read(&server->usage));
        return server;
 }
 
index 2c5f9a0e5d72bb0357c45d5524186c14b3284bca..63039ed9576f75c396ed0dae71bec1e4abf53058 100644 (file)
@@ -990,10 +990,9 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
 
                /* clear any space allocated but not loaded */
                if (phdr->p_filesz < phdr->p_memsz) {
-                       ret = clear_user((void *) (seg->addr + phdr->p_filesz),
-                                        phdr->p_memsz - phdr->p_filesz);
-                       if (ret)
-                               return ret;
+                       if (clear_user((void *) (seg->addr + phdr->p_filesz),
+                                      phdr->p_memsz - phdr->p_filesz))
+                               return -EFAULT;
                }
 
                if (mm) {
@@ -1027,7 +1026,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
        struct elf32_fdpic_loadseg *seg;
        struct elf32_phdr *phdr;
        unsigned long load_addr, delta_vaddr;
-       int loop, dvset, ret;
+       int loop, dvset;
 
        load_addr = params->load_addr;
        delta_vaddr = 0;
@@ -1127,9 +1126,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
                 * PT_LOAD */
                if (prot & PROT_WRITE && disp > 0) {
                        kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
-                       ret = clear_user((void __user *) maddr, disp);
-                       if (ret)
-                               return ret;
+                       if (clear_user((void __user *) maddr, disp))
+                               return -EFAULT;
                        maddr += disp;
                }
 
@@ -1164,19 +1162,17 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
                if (prot & PROT_WRITE && excess1 > 0) {
                        kdebug("clear[%d] ad=%lx sz=%lx",
                               loop, maddr + phdr->p_filesz, excess1);
-                       ret = clear_user((void __user *) maddr + phdr->p_filesz,
-                                        excess1);
-                       if (ret)
-                               return ret;
+                       if (clear_user((void __user *) maddr + phdr->p_filesz,
+                                      excess1))
+                               return -EFAULT;
                }
 
 #else
                if (excess > 0) {
                        kdebug("clear[%d] ad=%lx sz=%lx",
                               loop, maddr + phdr->p_filesz, excess);
-                       ret = clear_user((void *) maddr + phdr->p_filesz, excess);
-                       if (ret)
-                               return ret;
+                       if (clear_user((void *) maddr + phdr->p_filesz, excess))
+                               return -EFAULT;
                }
 #endif
 
index f1ff785b22924d8ccb736fd7794f8c424c2b32c0..75541af4b3db1395ecfab6fd318144b88b959fd8 100644 (file)
@@ -1952,6 +1952,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                        bytes_read -= PAGE_CACHE_SIZE;
                        continue;
                }
+               page_cache_release(page);
 
                target = kmap_atomic(page, KM_USER0);
 
index 47aefd376e54060341d15a31ab5cf96a2755a13e..723b889fd219f5eb6a6f360b807ac8e45881f00a 100644 (file)
@@ -710,30 +710,26 @@ static void fscache_write_op(struct fscache_operation *_op)
                goto superseded;
        }
 
-       if (page) {
-               radix_tree_tag_set(&cookie->stores, page->index,
-                                  FSCACHE_COOKIE_STORING_TAG);
-               radix_tree_tag_clear(&cookie->stores, page->index,
-                                    FSCACHE_COOKIE_PENDING_TAG);
-       }
+       radix_tree_tag_set(&cookie->stores, page->index,
+                          FSCACHE_COOKIE_STORING_TAG);
+       radix_tree_tag_clear(&cookie->stores, page->index,
+                            FSCACHE_COOKIE_PENDING_TAG);
 
        spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
 
-       if (page) {
-               fscache_set_op_state(&op->op, "Store");
-               fscache_stat(&fscache_n_store_pages);
-               fscache_stat(&fscache_n_cop_write_page);
-               ret = object->cache->ops->write_page(op, page);
-               fscache_stat_d(&fscache_n_cop_write_page);
-               fscache_set_op_state(&op->op, "EndWrite");
-               fscache_end_page_write(object, page);
-               if (ret < 0) {
-                       fscache_set_op_state(&op->op, "Abort");
-                       fscache_abort_object(object);
-               } else {
-                       fscache_enqueue_operation(&op->op);
-               }
+       fscache_set_op_state(&op->op, "Store");
+       fscache_stat(&fscache_n_store_pages);
+       fscache_stat(&fscache_n_cop_write_page);
+       ret = object->cache->ops->write_page(op, page);
+       fscache_stat_d(&fscache_n_cop_write_page);
+       fscache_set_op_state(&op->op, "EndWrite");
+       fscache_end_page_write(object, page);
+       if (ret < 0) {
+               fscache_set_op_state(&op->op, "Abort");
+               fscache_abort_object(object);
+       } else {
+               fscache_enqueue_operation(&op->op);
        }
 
        _leave("");
index 04f91c2d3f7b93d88011236b07aa1f71d2a39def..b5043a9890d85a38d4e63d3ae40f546675639e30 100644 (file)
@@ -80,7 +80,7 @@ extern void setup_per_cpu_areas(void);
 
 #ifndef PER_CPU_BASE_SECTION
 #ifdef CONFIG_SMP
-#define PER_CPU_BASE_SECTION ".data.percpu"
+#define PER_CPU_BASE_SECTION ".data..percpu"
 #else
 #define PER_CPU_BASE_SECTION ".data"
 #endif
@@ -92,15 +92,15 @@ extern void setup_per_cpu_areas(void);
 #define PER_CPU_SHARED_ALIGNED_SECTION ""
 #define PER_CPU_ALIGNED_SECTION ""
 #else
-#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
-#define PER_CPU_ALIGNED_SECTION ".shared_aligned"
+#define PER_CPU_SHARED_ALIGNED_SECTION "..shared_aligned"
+#define PER_CPU_ALIGNED_SECTION "..shared_aligned"
 #endif
-#define PER_CPU_FIRST_SECTION ".first"
+#define PER_CPU_FIRST_SECTION "..first"
 
 #else
 
 #define PER_CPU_SHARED_ALIGNED_SECTION ""
-#define PER_CPU_ALIGNED_SECTION ".shared_aligned"
+#define PER_CPU_ALIGNED_SECTION "..shared_aligned"
 #define PER_CPU_FIRST_SECTION ""
 
 #endif
index ef779c6fc3d7e89571390a01bbdb3da137bc1af1..48c5299cbf26e796e3188f397faa96cd3889a112 100644 (file)
 #define NOSAVE_DATA                                                    \
        . = ALIGN(PAGE_SIZE);                                           \
        VMLINUX_SYMBOL(__nosave_begin) = .;                             \
-       *(.data.nosave)                                                 \
+       *(.data..nosave)                                                \
        . = ALIGN(PAGE_SIZE);                                           \
        VMLINUX_SYMBOL(__nosave_end) = .;
 
 #define PAGE_ALIGNED_DATA(page_align)                                  \
        . = ALIGN(page_align);                                          \
-       *(.data.page_aligned)
+       *(.data..page_aligned)
 
 #define READ_MOSTLY_DATA(align)                                                \
        . = ALIGN(align);                                               \
-       *(.data.read_mostly)
+       *(.data..read_mostly)
 
 #define CACHELINE_ALIGNED_DATA(align)                                  \
        . = ALIGN(align);                                               \
-       *(.data.cacheline_aligned)
+       *(.data..cacheline_aligned)
 
 #define INIT_TASK_DATA(align)                                          \
        . = ALIGN(align);                                               \
-       *(.data.init_task)
+       *(.data..init_task)
 
 /*
  * Read only Data
  */
 #define INIT_TASK_DATA_SECTION(align)                                  \
        . = ALIGN(align);                                               \
-       .data.init_task : {                                             \
+       .data..init_task : {                                            \
                INIT_TASK_DATA(align)                                   \
        }
 
 #define BSS(bss_align)                                                 \
        . = ALIGN(bss_align);                                           \
        .bss : AT(ADDR(.bss) - LOAD_OFFSET) {                           \
-               *(.bss.page_aligned)                                    \
+               *(.bss..page_aligned)                                   \
                *(.dynbss)                                              \
                *(.bss)                                                 \
                *(COMMON)                                               \
  */
 #define PERCPU_VADDR(vaddr, phdr)                                      \
        VMLINUX_SYMBOL(__per_cpu_load) = .;                             \
-       .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load)          \
+       .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load)         \
                                - LOAD_OFFSET) {                        \
                VMLINUX_SYMBOL(__per_cpu_start) = .;                    \
-               *(.data.percpu.first)                                   \
-               *(.data.percpu.page_aligned)                            \
-               *(.data.percpu)                                         \
-               *(.data.percpu.shared_aligned)                          \
+               *(.data..percpu..first)                                 \
+               *(.data..percpu..page_aligned)                          \
+               *(.data..percpu)                                        \
+               *(.data..percpu..shared_aligned)                        \
                VMLINUX_SYMBOL(__per_cpu_end) = .;                      \
        } phdr                                                          \
-       . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
+       . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
 
 /**
  * PERCPU - define output section for percpu area, simple version
  *
  * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except
  * that __per_cpu_load is defined as a relative symbol against
- * .data.percpu which is required for relocatable x86_32
+ * .data..percpu which is required for relocatable x86_32
  * configuration.
  */
 #define PERCPU(align)                                                  \
        . = ALIGN(align);                                               \
-       .data.percpu    : AT(ADDR(.data.percpu) - LOAD_OFFSET) {        \
+       .data..percpu   : AT(ADDR(.data..percpu) - LOAD_OFFSET) {       \
                VMLINUX_SYMBOL(__per_cpu_load) = .;                     \
                VMLINUX_SYMBOL(__per_cpu_start) = .;                    \
-               *(.data.percpu.first)                                   \
-               *(.data.percpu.page_aligned)                            \
-               *(.data.percpu)                                         \
-               *(.data.percpu.shared_aligned)                          \
+               *(.data..percpu..first)                                 \
+               *(.data..percpu..page_aligned)                          \
+               *(.data..percpu)                                        \
+               *(.data..percpu..shared_aligned)                        \
                VMLINUX_SYMBOL(__per_cpu_end) = .;                      \
        }
 
index dc5873c21e4566ceaf6628882abae905098763f9..1121f7799c6ff527838ec50052d51bc10b10e2e7 100644 (file)
@@ -130,4 +130,7 @@ extern int drm_helper_resume_force_mode(struct drm_device *dev);
 extern void drm_kms_helper_poll_init(struct drm_device *dev);
 extern void drm_kms_helper_poll_fini(struct drm_device *dev);
 extern void drm_helper_hpd_irq_event(struct drm_device *dev);
+
+extern void drm_kms_helper_poll_disable(struct drm_device *dev);
+extern void drm_kms_helper_poll_enable(struct drm_device *dev);
 #endif
index b64a8d7cdf6d291205f8b89edf3a78d4a6a4d9c6..7f0028e1010b97e253b29dffdaaa8edb152bab54 100644 (file)
@@ -275,6 +275,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_OVERLAY           7
 #define I915_PARAM_HAS_PAGEFLIPPING     8
 #define I915_PARAM_HAS_EXECBUF2          9
+#define I915_PARAM_HAS_BSD              10
 
 typedef struct drm_i915_getparam {
        int param;
@@ -616,7 +617,9 @@ struct drm_i915_gem_execbuffer2 {
        __u32 num_cliprects;
        /** This is a struct drm_clip_rect *cliprects */
        __u64 cliprects_ptr;
-       __u64 flags; /* currently unused */
+#define I915_EXEC_RENDER                 (1<<0)
+#define I915_EXEC_BSD                    (1<<1)
+       __u64 flags;
        __u64 rsvd1;
        __u64 rsvd2;
 };
index a6a9f4af5ebd8257d92dcd592551b6fb05f91931..fe917dee723a7357f44c285626189ae7acd5e863 100644 (file)
@@ -79,6 +79,7 @@ struct drm_nouveau_gpuobj_free {
 #define NOUVEAU_GETPARAM_CHIPSET_ID      11
 #define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
 #define NOUVEAU_GETPARAM_GRAPH_UNITS     13
+#define NOUVEAU_GETPARAM_PTIMER_TIME     14
 struct drm_nouveau_getparam {
        uint64_t param;
        uint64_t value;
index c7645f480d1219cb84c765e5962d86cdd470ec54..4d0842391edc666f8985329fed245b989e3a0c2d 100644 (file)
@@ -50,6 +50,8 @@
 #define DRM_VMW_EXECBUF              12
 #define DRM_VMW_FIFO_DEBUG           13
 #define DRM_VMW_FENCE_WAIT           14
+/* guarded by minor version >= 2 */
+#define DRM_VMW_UPDATE_LAYOUT        15
 
 
 /*************************************************************************/
@@ -585,4 +587,28 @@ struct drm_vmw_stream_arg {
  * sure that the stream has been stopped.
  */
 
+/*************************************************************************/
+/**
+ * DRM_VMW_UPDATE_LAYOUT - Update layout
+ *
+ * Updates the prefered modes and connection status for connectors. The
+ * command conisits of one drm_vmw_update_layout_arg pointing out a array
+ * of num_outputs drm_vmw_rect's.
+ */
+
+/**
+ * struct drm_vmw_update_layout_arg
+ *
+ * @num_outputs: number of active
+ * @rects: pointer to array of drm_vmw_rect
+ *
+ * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
+ */
+
+struct drm_vmw_update_layout_arg {
+       uint32_t num_outputs;
+       uint32_t pad64;
+       uint64_t rects;
+};
+
 #endif
index 97e24881c4c6f477496130c982e1962e770df9eb..4c570653ab84f9822ba9e1e1f19a41242c16b74f 100644 (file)
@@ -31,7 +31,7 @@
 #ifndef __cacheline_aligned
 #define __cacheline_aligned                                    \
   __attribute__((__aligned__(SMP_CACHE_BYTES),                 \
-                __section__(".data.cacheline_aligned")))
+                __section__(".data..cacheline_aligned")))
 #endif /* __cacheline_aligned */
 
 #ifndef __cacheline_aligned_in_smp
index ab1d31f9352bbcefb46369667c145c3615b29a2c..de994304e0bbb2a1e21e5d6dd7a59ebeea1ebd71 100644 (file)
@@ -301,7 +301,7 @@ void __init parse_early_options(char *cmdline);
 #endif
 
 /* Data marked not to be saved by software suspend */
-#define __nosavedata __section(.data.nosave)
+#define __nosavedata __section(.data..nosave)
 
 /* This means "can be init if no module support, otherwise module load
    may call it." */
index 2beaa13492beb5dffdb90c0041d942a3785181e1..1f43fa56f6001f821736e4b66e9fac5e6e0375ed 100644 (file)
@@ -183,7 +183,7 @@ extern struct cred init_cred;
 }
 
 /* Attach to the init_task data structure for proper alignment */
-#define __init_task_data __attribute__((__section__(".data.init_task")))
+#define __init_task_data __attribute__((__section__(".data..init_task")))
 
 
 #endif
index 5126cceb6ae97c7d401f197497f0a1311e55fe6f..7135ebc8428c5273fd62535b985e1fb00e9bfbe0 100644 (file)
@@ -18,8 +18,8 @@
 # define asmregparm
 #endif
 
-#define __page_aligned_data    __section(.data.page_aligned) __aligned(PAGE_SIZE)
-#define __page_aligned_bss     __section(.bss.page_aligned) __aligned(PAGE_SIZE)
+#define __page_aligned_data    __section(.data..page_aligned) __aligned(PAGE_SIZE)
+#define __page_aligned_bss     __section(.bss..page_aligned) __aligned(PAGE_SIZE)
 
 /*
  * For assembly routines.
@@ -27,8 +27,8 @@
  * Note when using these that you must specify the appropriate
  * alignment directives yourself
  */
-#define __PAGE_ALIGNED_DATA    .section ".data.page_aligned", "aw"
-#define __PAGE_ALIGNED_BSS     .section ".bss.page_aligned", "aw"
+#define __PAGE_ALIGNED_DATA    .section ".data..page_aligned", "aw"
+#define __PAGE_ALIGNED_BSS     .section ".bss..page_aligned", "aw"
 
 /*
  * This is used by architectures to keep arguments on the stack
index c00cc0c4d0b7c29614bbafdfabe73828a04a0fbd..24e5d01d27d07b860bfed06701fb2d864ee89bc3 100644 (file)
@@ -397,7 +397,7 @@ struct xt_table_info {
         * @stacksize jumps (number of user chains) can possibly be made.
         */
        unsigned int stacksize;
-       unsigned int *stackptr;
+       unsigned int __percpu *stackptr;
        void ***jumpstack;
        /* ipt_entry tables: one per CPU */
        /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
index 68567c0b3a5d4d29cb5006d42ad3ad38d178e291..ce2dc655cd1d40a6765acc2dd3f49e104bca4f5c 100644 (file)
  * Declaration/definition used for per-CPU variables that must be page aligned.
  */
 #define DECLARE_PER_CPU_PAGE_ALIGNED(type, name)                       \
-       DECLARE_PER_CPU_SECTION(type, name, ".page_aligned")            \
+       DECLARE_PER_CPU_SECTION(type, name, "..page_aligned")           \
        __aligned(PAGE_SIZE)
 
 #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name)                                \
-       DEFINE_PER_CPU_SECTION(type, name, ".page_aligned")             \
+       DEFINE_PER_CPU_SECTION(type, name, "..page_aligned")            \
        __aligned(PAGE_SIZE)
 
 /*
index fb6c91eac7e3eb7cef23b2be992a0ed6eece85a0..5d0266d94985c65acbd8b13a41961964cdde4a72 100644 (file)
@@ -585,6 +585,7 @@ enum perf_event_active_state {
 struct file;
 
 struct perf_mmap_data {
+       atomic_t                        refcount;
        struct rcu_head                 rcu_head;
 #ifdef CONFIG_PERF_USE_VMALLOC
        struct work_struct              work;
@@ -592,7 +593,6 @@ struct perf_mmap_data {
 #endif
        int                             nr_pages;       /* nr of data pages  */
        int                             writable;       /* are we writable   */
-       int                             nr_locked;      /* nr pages mlocked  */
 
        atomic_t                        poll;           /* POLL_ for wakeups */
 
@@ -631,6 +631,9 @@ struct swevent_hlist {
        struct rcu_head         rcu_head;
 };
 
+#define PERF_ATTACH_CONTEXT    0x01
+#define PERF_ATTACH_GROUP      0x02
+
 /**
  * struct perf_event - performance event kernel representation:
  */
@@ -643,10 +646,10 @@ struct perf_event {
        int                             nr_siblings;
        int                             group_flags;
        struct perf_event               *group_leader;
-       struct perf_event               *output;
        const struct pmu                *pmu;
 
        enum perf_event_active_state    state;
+       unsigned int                    attach_state;
        atomic64_t                      count;
 
        /*
@@ -704,6 +707,8 @@ struct perf_event {
        /* mmap bits */
        struct mutex                    mmap_mutex;
        atomic_t                        mmap_count;
+       int                             mmap_locked;
+       struct user_struct              *mmap_user;
        struct perf_mmap_data           *data;
 
        /* poll related */
index 7cdfb4d52847e6f733df1538f48fc73508e3d13e..bf243fc54959098e49d6a77dac955aea8cf9d4b6 100644 (file)
@@ -501,7 +501,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
        return __alloc_skb(size, priority, 1, -1);
 }
 
-extern int skb_recycle_check(struct sk_buff *skb, int skb_size);
+extern bool skb_recycle_check(struct sk_buff *skb, int skb_size);
 
 extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
 extern struct sk_buff *skb_clone(struct sk_buff *skb,
index 89fac6a3f78b5feb7a832816fc7665cb639ce83d..f8854655860e3a10f5d708b9b749c43ead2bd48d 100644 (file)
@@ -60,7 +60,7 @@
 /*
  * Must define these before including other files, inline functions need them
  */
-#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME
+#define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME
 
 #define LOCK_SECTION_START(extra)               \
         ".subsection 1\n\t"                     \
index 2dfaa293ae8c971303092235da547b5afb438319..c9a97597699522db33b2f309bd58368970eb9651 100644 (file)
@@ -5,6 +5,27 @@
  * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
  * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
  * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
+ *
  */
 
 #ifndef LINUX_VGA_H
index ca241ea148758a555d123343e2fe8639f7dd5bd3..731150d52799ecc5492b3590c3b7b5b34de09072 100644 (file)
@@ -1524,20 +1524,7 @@ extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
 
 extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 
-static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
-{
-       /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
-          number of warnings when compiling with -W --ANK
-        */
-       if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
-           (unsigned)sk->sk_rcvbuf)
-               return -ENOMEM;
-       skb_set_owner_r(skb, sk);
-       skb_queue_tail(&sk->sk_error_queue, skb);
-       if (!sock_flag(sk, SOCK_DEAD))
-               sk->sk_data_ready(sk, skb->len);
-       return 0;
-}
+extern int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb);
 
 /*
  *     Recover an error report and clear atomically
index 3d685d1f2a03f0099f159ac96eb648eed107a0a7..5a64905d7278a47fb683a0aceb63cef029dd467b 100644 (file)
@@ -725,7 +725,7 @@ perf_trace_##call(void *__data, proto)                                      \
                                                                        \
        { assign; }                                                     \
                                                                        \
-       head = per_cpu_ptr(event_call->perf_events, smp_processor_id());\
+       head = this_cpu_ptr(event_call->perf_events);                   \
        perf_trace_buf_submit(entry, __entry_size, rctx, __addr,        \
                __count, &__regs, head);                                \
 }
index 2cce9f343ad0b6397ba7ce2103a3d8c88eaedd0c..5cff9a980c397d48491145e9d1f9e4e42313cad4 100644 (file)
@@ -76,6 +76,14 @@ config INIT_ENV_ARG_LIMIT
          variables passed to init from the kernel command line.
 
 
+config CROSS_COMPILE
+       string "Cross-compiler tool prefix"
+       help
+         Same as running 'make CROSS_COMPILE=prefix-' but stored for
+         default make runs in this kernel build directory.  You don't
+         need to set this unless you want the configured kernel build
+         directory to select the cross-compiler automatically.
+
 config LOCALVERSION
        string "Local version - append to kernel release"
        help
index 8b92539b4754274528fdc380d45baf6d481001b1..97d1b426a4ac39bd49b41b9393ed9b565f8f7f33 100644 (file)
@@ -34,7 +34,7 @@ void cpu_maps_update_done(void)
        mutex_unlock(&cpu_add_remove_lock);
 }
 
-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
+static RAW_NOTIFIER_HEAD(cpu_chain);
 
 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
  * Should always be manipulated under cpu_add_remove_lock
index 333fbcc969783a7cca1728f141c870be7b24e918..0129769301e3106eb505576fbb495a64f289160c 100644 (file)
@@ -403,7 +403,7 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
                                 Elf_Shdr *sechdrs,
                                 const char *secstrings)
 {
-       return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
+       return find_sec(hdr, sechdrs, secstrings, ".data..percpu");
 }
 
 static void percpu_modcopy(struct module *mod,
@@ -2014,6 +2014,7 @@ static noinline struct module *load_module(void __user *umod,
        long err = 0;
        void *ptr = NULL; /* Stops spurious gcc warning */
        unsigned long symoffs, stroffs, *strmap;
+       void __percpu *percpu;
 
        mm_segment_t old_fs;
 
@@ -2158,6 +2159,8 @@ static noinline struct module *load_module(void __user *umod,
                        goto free_mod;
                sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
        }
+       /* Keep this around for failure path. */
+       percpu = mod_percpu(mod);
 
        /* Determine total sizes, and put offsets in sh_entsize.  For now
           this is done generically; there doesn't appear to be any
@@ -2463,7 +2466,7 @@ static noinline struct module *load_module(void __user *umod,
        module_free(mod, mod->module_core);
        /* mod will be freed with core. Don't access it beyond this line! */
  free_percpu:
-       percpu_modfree(mod);
+       free_percpu(percpu);
  free_mod:
        kfree(args);
        kfree(strmap);
index bd7ce8ca5bb9d7aff449674f1a8a24cdf1604be0..31d6afe9259412025f02e20bddcc37fa3bf4d62b 100644 (file)
@@ -283,14 +283,15 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx)
 static void
 list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 {
-       struct perf_event *group_leader = event->group_leader;
+       WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT);
+       event->attach_state |= PERF_ATTACH_CONTEXT;
 
        /*
-        * Depending on whether it is a standalone or sibling event,
-        * add it straight to the context's event list, or to the group
-        * leader's sibling list:
+        * If we're a stand alone event or group leader, we go to the context
+        * list, group events are kept attached to the group so that
+        * perf_group_detach can, at all times, locate all siblings.
         */
-       if (group_leader == event) {
+       if (event->group_leader == event) {
                struct list_head *list;
 
                if (is_software_event(event))
@@ -298,13 +299,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 
                list = ctx_group_list(event, ctx);
                list_add_tail(&event->group_entry, list);
-       } else {
-               if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
-                   !is_software_event(event))
-                       group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
-
-               list_add_tail(&event->group_entry, &group_leader->sibling_list);
-               group_leader->nr_siblings++;
        }
 
        list_add_rcu(&event->event_entry, &ctx->event_list);
@@ -313,6 +307,24 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
                ctx->nr_stat++;
 }
 
+static void perf_group_attach(struct perf_event *event)
+{
+       struct perf_event *group_leader = event->group_leader;
+
+       WARN_ON_ONCE(event->attach_state & PERF_ATTACH_GROUP);
+       event->attach_state |= PERF_ATTACH_GROUP;
+
+       if (group_leader == event)
+               return;
+
+       if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
+                       !is_software_event(event))
+               group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
+
+       list_add_tail(&event->group_entry, &group_leader->sibling_list);
+       group_leader->nr_siblings++;
+}
+
 /*
  * Remove a event from the lists for its context.
  * Must be called with ctx->mutex and ctx->lock held.
@@ -320,17 +332,22 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 static void
 list_del_event(struct perf_event *event, struct perf_event_context *ctx)
 {
-       if (list_empty(&event->group_entry))
+       /*
+        * We can have double detach due to exit/hot-unplug + close.
+        */
+       if (!(event->attach_state & PERF_ATTACH_CONTEXT))
                return;
+
+       event->attach_state &= ~PERF_ATTACH_CONTEXT;
+
        ctx->nr_events--;
        if (event->attr.inherit_stat)
                ctx->nr_stat--;
 
-       list_del_init(&event->group_entry);
        list_del_rcu(&event->event_entry);
 
-       if (event->group_leader != event)
-               event->group_leader->nr_siblings--;
+       if (event->group_leader == event)
+               list_del_init(&event->group_entry);
 
        update_group_times(event);
 
@@ -345,21 +362,39 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
                event->state = PERF_EVENT_STATE_OFF;
 }
 
-static void
-perf_destroy_group(struct perf_event *event, struct perf_event_context *ctx)
+static void perf_group_detach(struct perf_event *event)
 {
        struct perf_event *sibling, *tmp;
+       struct list_head *list = NULL;
+
+       /*
+        * We can have double detach due to exit/hot-unplug + close.
+        */
+       if (!(event->attach_state & PERF_ATTACH_GROUP))
+               return;
+
+       event->attach_state &= ~PERF_ATTACH_GROUP;
+
+       /*
+        * If this is a sibling, remove it from its group.
+        */
+       if (event->group_leader != event) {
+               list_del_init(&event->group_entry);
+               event->group_leader->nr_siblings--;
+               return;
+       }
+
+       if (!list_empty(&event->group_entry))
+               list = &event->group_entry;
 
        /*
         * If this was a group event with sibling events then
         * upgrade the siblings to singleton events by adding them
-        * to the context list directly:
+        * to whatever list we are on.
         */
        list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) {
-               struct list_head *list;
-
-               list = ctx_group_list(event, ctx);
-               list_move_tail(&sibling->group_entry, list);
+               if (list)
+                       list_move_tail(&sibling->group_entry, list);
                sibling->group_leader = sibling;
 
                /* Inherit group flags from the previous leader */
@@ -652,8 +687,11 @@ group_sched_in(struct perf_event *group_event,
        if (txn)
                pmu->start_txn(pmu);
 
-       if (event_sched_in(group_event, cpuctx, ctx))
+       if (event_sched_in(group_event, cpuctx, ctx)) {
+               if (txn)
+                       pmu->cancel_txn(pmu);
                return -EAGAIN;
+       }
 
        /*
         * Schedule in siblings as one group (if any):
@@ -675,9 +713,6 @@ group_sched_in(struct perf_event *group_event,
        }
 
 group_error:
-       if (txn)
-               pmu->cancel_txn(pmu);
-
        /*
         * Groups can be scheduled in as one unit only, so undo any
         * partial group before returning:
@@ -689,6 +724,9 @@ group_error:
        }
        event_sched_out(group_event, cpuctx, ctx);
 
+       if (txn)
+               pmu->cancel_txn(pmu);
+
        return -EAGAIN;
 }
 
@@ -727,6 +765,7 @@ static void add_event_to_ctx(struct perf_event *event,
                               struct perf_event_context *ctx)
 {
        list_add_event(event, ctx);
+       perf_group_attach(event);
        event->tstamp_enabled = ctx->time;
        event->tstamp_running = ctx->time;
        event->tstamp_stopped = ctx->time;
@@ -1841,6 +1880,7 @@ static void free_event_rcu(struct rcu_head *head)
 }
 
 static void perf_pending_sync(struct perf_event *event);
+static void perf_mmap_data_put(struct perf_mmap_data *data);
 
 static void free_event(struct perf_event *event)
 {
@@ -1856,9 +1896,9 @@ static void free_event(struct perf_event *event)
                        atomic_dec(&nr_task_events);
        }
 
-       if (event->output) {
-               fput(event->output->filp);
-               event->output = NULL;
+       if (event->data) {
+               perf_mmap_data_put(event->data);
+               event->data = NULL;
        }
 
        if (event->destroy)
@@ -1893,8 +1933,8 @@ int perf_event_release_kernel(struct perf_event *event)
         */
        mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
        raw_spin_lock_irq(&ctx->lock);
+       perf_group_detach(event);
        list_del_event(event, ctx);
-       perf_destroy_group(event, ctx);
        raw_spin_unlock_irq(&ctx->lock);
        mutex_unlock(&ctx->mutex);
 
@@ -2175,7 +2215,27 @@ unlock:
        return ret;
 }
 
-static int perf_event_set_output(struct perf_event *event, int output_fd);
+static const struct file_operations perf_fops;
+
+static struct perf_event *perf_fget_light(int fd, int *fput_needed)
+{
+       struct file *file;
+
+       file = fget_light(fd, fput_needed);
+       if (!file)
+               return ERR_PTR(-EBADF);
+
+       if (file->f_op != &perf_fops) {
+               fput_light(file, *fput_needed);
+               *fput_needed = 0;
+               return ERR_PTR(-EBADF);
+       }
+
+       return file->private_data;
+}
+
+static int perf_event_set_output(struct perf_event *event,
+                                struct perf_event *output_event);
 static int perf_event_set_filter(struct perf_event *event, void __user *arg);
 
 static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -2202,7 +2262,23 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return perf_event_period(event, (u64 __user *)arg);
 
        case PERF_EVENT_IOC_SET_OUTPUT:
-               return perf_event_set_output(event, arg);
+       {
+               struct perf_event *output_event = NULL;
+               int fput_needed = 0;
+               int ret;
+
+               if (arg != -1) {
+                       output_event = perf_fget_light(arg, &fput_needed);
+                       if (IS_ERR(output_event))
+                               return PTR_ERR(output_event);
+               }
+
+               ret = perf_event_set_output(event, output_event);
+               if (output_event)
+                       fput_light(output_event->filp, fput_needed);
+
+               return ret;
+       }
 
        case PERF_EVENT_IOC_SET_FILTER:
                return perf_event_set_filter(event, (void __user *)arg);
@@ -2335,8 +2411,6 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
        unsigned long size;
        int i;
 
-       WARN_ON(atomic_read(&event->mmap_count));
-
        size = sizeof(struct perf_mmap_data);
        size += nr_pages * sizeof(void *);
 
@@ -2452,8 +2526,6 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
        unsigned long size;
        void *all_buf;
 
-       WARN_ON(atomic_read(&event->mmap_count));
-
        size = sizeof(struct perf_mmap_data);
        size += sizeof(void *);
 
@@ -2536,7 +2608,7 @@ perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
        if (!data->watermark)
                data->watermark = max_size / 2;
 
-
+       atomic_set(&data->refcount, 1);
        rcu_assign_pointer(event->data, data);
 }
 
@@ -2548,13 +2620,26 @@ static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
        perf_mmap_data_free(data);
 }
 
-static void perf_mmap_data_release(struct perf_event *event)
+static struct perf_mmap_data *perf_mmap_data_get(struct perf_event *event)
 {
-       struct perf_mmap_data *data = event->data;
+       struct perf_mmap_data *data;
 
-       WARN_ON(atomic_read(&event->mmap_count));
+       rcu_read_lock();
+       data = rcu_dereference(event->data);
+       if (data) {
+               if (!atomic_inc_not_zero(&data->refcount))
+                       data = NULL;
+       }
+       rcu_read_unlock();
+
+       return data;
+}
+
+static void perf_mmap_data_put(struct perf_mmap_data *data)
+{
+       if (!atomic_dec_and_test(&data->refcount))
+               return;
 
-       rcu_assign_pointer(event->data, NULL);
        call_rcu(&data->rcu_head, perf_mmap_data_free_rcu);
 }
 
@@ -2569,15 +2654,18 @@ static void perf_mmap_close(struct vm_area_struct *vma)
 {
        struct perf_event *event = vma->vm_file->private_data;
 
-       WARN_ON_ONCE(event->ctx->parent_ctx);
        if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
                unsigned long size = perf_data_size(event->data);
-               struct user_struct *user = current_user();
+               struct user_struct *user = event->mmap_user;
+               struct perf_mmap_data *data = event->data;
 
                atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
-               vma->vm_mm->locked_vm -= event->data->nr_locked;
-               perf_mmap_data_release(event);
+               vma->vm_mm->locked_vm -= event->mmap_locked;
+               rcu_assign_pointer(event->data, NULL);
                mutex_unlock(&event->mmap_mutex);
+
+               perf_mmap_data_put(data);
+               free_uid(user);
        }
 }
 
@@ -2629,13 +2717,10 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 
        WARN_ON_ONCE(event->ctx->parent_ctx);
        mutex_lock(&event->mmap_mutex);
-       if (event->output) {
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-       if (atomic_inc_not_zero(&event->mmap_count)) {
-               if (nr_pages != event->data->nr_pages)
+       if (event->data) {
+               if (event->data->nr_pages == nr_pages)
+                       atomic_inc(&event->data->refcount);
+               else
                        ret = -EINVAL;
                goto unlock;
        }
@@ -2667,21 +2752,23 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
        WARN_ON(event->data);
 
        data = perf_mmap_data_alloc(event, nr_pages);
-       ret = -ENOMEM;
-       if (!data)
+       if (!data) {
+               ret = -ENOMEM;
                goto unlock;
+       }
 
-       ret = 0;
        perf_mmap_data_init(event, data);
-
-       atomic_set(&event->mmap_count, 1);
-       atomic_long_add(user_extra, &user->locked_vm);
-       vma->vm_mm->locked_vm += extra;
-       event->data->nr_locked = extra;
        if (vma->vm_flags & VM_WRITE)
                event->data->writable = 1;
 
+       atomic_long_add(user_extra, &user->locked_vm);
+       event->mmap_locked = extra;
+       event->mmap_user = get_current_user();
+       vma->vm_mm->locked_vm += event->mmap_locked;
+
 unlock:
+       if (!ret)
+               atomic_inc(&event->mmap_count);
        mutex_unlock(&event->mmap_mutex);
 
        vma->vm_flags |= VM_RESERVED;
@@ -2977,6 +3064,7 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle,
 
                len -= size;
                handle->addr += size;
+               buf += size;
                handle->size -= size;
                if (!handle->size) {
                        struct perf_mmap_data *data = handle->data;
@@ -2993,7 +3081,6 @@ int perf_output_begin(struct perf_output_handle *handle,
                      struct perf_event *event, unsigned int size,
                      int nmi, int sample)
 {
-       struct perf_event *output_event;
        struct perf_mmap_data *data;
        unsigned long tail, offset, head;
        int have_lost;
@@ -3010,10 +3097,6 @@ int perf_output_begin(struct perf_output_handle *handle,
        if (event->parent)
                event = event->parent;
 
-       output_event = rcu_dereference(event->output);
-       if (output_event)
-               event = output_event;
-
        data = rcu_dereference(event->data);
        if (!data)
                goto out;
@@ -3972,13 +4055,6 @@ static void perf_swevent_overflow(struct perf_event *event, u64 overflow,
        }
 }
 
-static void perf_swevent_unthrottle(struct perf_event *event)
-{
-       /*
-        * Nothing to do, we already reset hwc->interrupts.
-        */
-}
-
 static void perf_swevent_add(struct perf_event *event, u64 nr,
                               int nmi, struct perf_sample_data *data,
                               struct pt_regs *regs)
@@ -4193,11 +4269,22 @@ static void perf_swevent_disable(struct perf_event *event)
        hlist_del_rcu(&event->hlist_entry);
 }
 
+static void perf_swevent_void(struct perf_event *event)
+{
+}
+
+static int perf_swevent_int(struct perf_event *event)
+{
+       return 0;
+}
+
 static const struct pmu perf_ops_generic = {
        .enable         = perf_swevent_enable,
        .disable        = perf_swevent_disable,
+       .start          = perf_swevent_int,
+       .stop           = perf_swevent_void,
        .read           = perf_swevent_read,
-       .unthrottle     = perf_swevent_unthrottle,
+       .unthrottle     = perf_swevent_void, /* hwc->interrupts already reset */
 };
 
 /*
@@ -4478,8 +4565,10 @@ static int swevent_hlist_get(struct perf_event *event)
 static const struct pmu perf_ops_tracepoint = {
        .enable         = perf_trace_enable,
        .disable        = perf_trace_disable,
+       .start          = perf_swevent_int,
+       .stop           = perf_swevent_void,
        .read           = perf_swevent_read,
-       .unthrottle     = perf_swevent_unthrottle,
+       .unthrottle     = perf_swevent_void,
 };
 
 static int perf_tp_filter_match(struct perf_event *event,
@@ -4912,39 +5001,17 @@ err_size:
        goto out;
 }
 
-static int perf_event_set_output(struct perf_event *event, int output_fd)
+static int
+perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
 {
-       struct perf_event *output_event = NULL;
-       struct file *output_file = NULL;
-       struct perf_event *old_output;
-       int fput_needed = 0;
+       struct perf_mmap_data *data = NULL, *old_data = NULL;
        int ret = -EINVAL;
 
-       /*
-        * Don't allow output of inherited per-task events. This would
-        * create performance issues due to cross cpu access.
-        */
-       if (event->cpu == -1 && event->attr.inherit)
-               return -EINVAL;
-
-       if (!output_fd)
+       if (!output_event)
                goto set;
 
-       output_file = fget_light(output_fd, &fput_needed);
-       if (!output_file)
-               return -EBADF;
-
-       if (output_file->f_op != &perf_fops)
-               goto out;
-
-       output_event = output_file->private_data;
-
-       /* Don't chain output fds */
-       if (output_event->output)
-               goto out;
-
-       /* Don't set an output fd when we already have an output channel */
-       if (event->data)
+       /* don't allow circular references */
+       if (event == output_event)
                goto out;
 
        /*
@@ -4959,26 +5026,28 @@ static int perf_event_set_output(struct perf_event *event, int output_fd)
        if (output_event->cpu == -1 && output_event->ctx != event->ctx)
                goto out;
 
-       atomic_long_inc(&output_file->f_count);
-
 set:
        mutex_lock(&event->mmap_mutex);
-       old_output = event->output;
-       rcu_assign_pointer(event->output, output_event);
-       mutex_unlock(&event->mmap_mutex);
+       /* Can't redirect output if we've got an active mmap() */
+       if (atomic_read(&event->mmap_count))
+               goto unlock;
 
-       if (old_output) {
-               /*
-                * we need to make sure no existing perf_output_*()
-                * is still referencing this event.
-                */
-               synchronize_rcu();
-               fput(old_output->filp);
+       if (output_event) {
+               /* get the buffer we want to redirect to */
+               data = perf_mmap_data_get(output_event);
+               if (!data)
+                       goto unlock;
        }
 
+       old_data = event->data;
+       rcu_assign_pointer(event->data, data);
        ret = 0;
+unlock:
+       mutex_unlock(&event->mmap_mutex);
+
+       if (old_data)
+               perf_mmap_data_put(old_data);
 out:
-       fput_light(output_file, fput_needed);
        return ret;
 }
 
@@ -4994,7 +5063,7 @@ SYSCALL_DEFINE5(perf_event_open,
                struct perf_event_attr __user *, attr_uptr,
                pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
 {
-       struct perf_event *event, *group_leader;
+       struct perf_event *event, *group_leader = NULL, *output_event = NULL;
        struct perf_event_attr attr;
        struct perf_event_context *ctx;
        struct file *event_file = NULL;
@@ -5034,19 +5103,25 @@ SYSCALL_DEFINE5(perf_event_open,
                goto err_fd;
        }
 
+       if (group_fd != -1) {
+               group_leader = perf_fget_light(group_fd, &fput_needed);
+               if (IS_ERR(group_leader)) {
+                       err = PTR_ERR(group_leader);
+                       goto err_put_context;
+               }
+               group_file = group_leader->filp;
+               if (flags & PERF_FLAG_FD_OUTPUT)
+                       output_event = group_leader;
+               if (flags & PERF_FLAG_FD_NO_GROUP)
+                       group_leader = NULL;
+       }
+
        /*
         * Look up the group leader (we will attach this event to it):
         */
-       group_leader = NULL;
-       if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) {
+       if (group_leader) {
                err = -EINVAL;
-               group_file = fget_light(group_fd, &fput_needed);
-               if (!group_file)
-                       goto err_put_context;
-               if (group_file->f_op != &perf_fops)
-                       goto err_put_context;
 
-               group_leader = group_file->private_data;
                /*
                 * Do not allow a recursive hierarchy (this new sibling
                 * becoming part of another group-sibling):
@@ -5068,9 +5143,16 @@ SYSCALL_DEFINE5(perf_event_open,
 
        event = perf_event_alloc(&attr, cpu, ctx, group_leader,
                                     NULL, NULL, GFP_KERNEL);
-       err = PTR_ERR(event);
-       if (IS_ERR(event))
+       if (IS_ERR(event)) {
+               err = PTR_ERR(event);
                goto err_put_context;
+       }
+
+       if (output_event) {
+               err = perf_event_set_output(event, output_event);
+               if (err)
+                       goto err_free_put_context;
+       }
 
        event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR);
        if (IS_ERR(event_file)) {
@@ -5078,12 +5160,6 @@ SYSCALL_DEFINE5(perf_event_open,
                goto err_free_put_context;
        }
 
-       if (flags & PERF_FLAG_FD_OUTPUT) {
-               err = perf_event_set_output(event, group_fd);
-               if (err)
-                       goto err_fput_free_put_context;
-       }
-
        event->filp = event_file;
        WARN_ON_ONCE(ctx->parent_ctx);
        mutex_lock(&ctx->mutex);
@@ -5097,12 +5173,16 @@ SYSCALL_DEFINE5(perf_event_open,
        list_add_tail(&event->owner_entry, &current->perf_event_list);
        mutex_unlock(&current->perf_event_mutex);
 
+       /*
+        * Drop the reference on the group_event after placing the
+        * new event on the sibling_list. This ensures destruction
+        * of the group leader will find the pointer to itself in
+        * perf_group_detach().
+        */
        fput_light(group_file, fput_needed);
        fd_install(event_fd, event_file);
        return event_fd;
 
-err_fput_free_put_context:
-       fput(event_file);
 err_free_put_context:
        free_event(event);
 err_put_context:
@@ -5420,6 +5500,7 @@ static void perf_free_event(struct perf_event *event,
 
        fput(parent->filp);
 
+       perf_group_detach(event);
        list_del_event(event, ctx);
        free_event(event);
 }
index 36ea2b65dcdc65a281bef8e7fa1acf0a44434003..638711c175048b00b8adb1175ed192a0b8181102 100644 (file)
@@ -842,6 +842,7 @@ static void blk_add_trace_split(void *ignore,
 
 /**
  * blk_add_trace_remap - Add a trace for a remap operation
+ * @ignore:    trace callback data parameter (not used)
  * @q:         queue the io is for
  * @bio:       the source bio
  * @dev:       target device
@@ -873,6 +874,7 @@ static void blk_add_trace_remap(void *ignore,
 
 /**
  * blk_add_trace_rq_remap - Add a trace for a request-remap operation
+ * @ignore:    trace callback data parameter (not used)
  * @q:         queue the io is for
  * @rq:                the source request
  * @dev:       target device
index cb6f365016e48f0c7f7848cbaebb39d45fb80c45..e6f65887842c9a91649550daee07c593c818f9b5 100644 (file)
@@ -116,7 +116,7 @@ int perf_trace_enable(struct perf_event *p_event)
        if (WARN_ON_ONCE(!list))
                return -EINVAL;
 
-       list = per_cpu_ptr(list, smp_processor_id());
+       list = this_cpu_ptr(list);
        hlist_add_head_rcu(&p_event->hlist_entry, list);
 
        return 0;
@@ -132,8 +132,9 @@ void perf_trace_destroy(struct perf_event *p_event)
        struct ftrace_event_call *tp_event = p_event->tp_event;
        int i;
 
+       mutex_lock(&event_mutex);
        if (--tp_event->perf_refcount > 0)
-               return;
+               goto out;
 
        if (tp_event->class->reg)
                tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
@@ -142,6 +143,12 @@ void perf_trace_destroy(struct perf_event *p_event)
                                            tp_event->class->perf_probe,
                                            tp_event);
 
+       /*
+        * Ensure our callback won't be called anymore. See
+        * tracepoint_probe_unregister() and __DO_TRACE().
+        */
+       synchronize_sched();
+
        free_percpu(tp_event->perf_events);
        tp_event->perf_events = NULL;
 
@@ -151,6 +158,8 @@ void perf_trace_destroy(struct perf_event *p_event)
                        perf_trace_buf[i] = NULL;
                }
        }
+out:
+       mutex_unlock(&event_mutex);
 }
 
 __kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
@@ -169,7 +178,7 @@ __kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
        if (*rctxp < 0)
                return NULL;
 
-       raw_data = per_cpu_ptr(perf_trace_buf[*rctxp], smp_processor_id());
+       raw_data = this_cpu_ptr(perf_trace_buf[*rctxp]);
 
        /* zero the dead bytes from align to not leak stack to user */
        memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64));
index faf7cefd15daf985afaadacb1d7a4b466993aa30..f52b5f50299dae5cc74dfe807054cd7d0e3f875e 100644 (file)
@@ -1359,7 +1359,7 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
        for (i = 0; i < tp->nr_args; i++)
                call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
-       head = per_cpu_ptr(call->perf_events, smp_processor_id());
+       head = this_cpu_ptr(call->perf_events);
        perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
 }
 
@@ -1392,7 +1392,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
        for (i = 0; i < tp->nr_args; i++)
                call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
-       head = per_cpu_ptr(call->perf_events, smp_processor_id());
+       head = this_cpu_ptr(call->perf_events);
        perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head);
 }
 
index d2c859cec9ea85b6f2e32c4c016937bee450aacb..34e35804304b03a7549b2f3a00064e8ec4675d7f 100644 (file)
@@ -519,7 +519,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
        syscall_get_arguments(current, regs, 0, sys_data->nb_args,
                               (unsigned long *)&rec->args);
 
-       head = per_cpu_ptr(sys_data->enter_event->perf_events, smp_processor_id());
+       head = this_cpu_ptr(sys_data->enter_event->perf_events);
        perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
 }
 
@@ -595,7 +595,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
        rec->nr = syscall_nr;
        rec->ret = syscall_get_return_value(current, regs);
 
-       head = per_cpu_ptr(sys_data->exit_event->perf_events, smp_processor_id());
+       head = this_cpu_ptr(sys_data->exit_event->perf_events);
        perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
 }
 
index cb4325a3dc83184f4a4f8e382dbec6b7ac6c21f2..965c5baace40b10c401c8fff3ecaaacb612c0aa6 100644 (file)
@@ -59,16 +59,18 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
        u8 stx = CFSERL_STX;
        int ret;
        u16 expectlen = 0;
+
        caif_assert(newpkt != NULL);
        spin_lock(&layr->sync);
 
        if (layr->incomplete_frm != NULL) {
-
                layr->incomplete_frm =
                    cfpkt_append(layr->incomplete_frm, newpkt, expectlen);
                pkt = layr->incomplete_frm;
-               if (pkt == NULL)
+               if (pkt == NULL) {
+                       spin_unlock(&layr->sync);
                        return -ENOMEM;
+               }
        } else {
                pkt = newpkt;
        }
index f8abf68e3988f7cd5b4a83eb6a18b3ae25d52afd..9f07e749d7b15ce9451a8a9b8ac7ed5318568ff3 100644 (file)
@@ -482,22 +482,22 @@ EXPORT_SYMBOL(consume_skb);
  *     reference count dropping and cleans up the skbuff as if it
  *     just came from __alloc_skb().
  */
-int skb_recycle_check(struct sk_buff *skb, int skb_size)
+bool skb_recycle_check(struct sk_buff *skb, int skb_size)
 {
        struct skb_shared_info *shinfo;
 
        if (irqs_disabled())
-               return 0;
+               return false;
 
        if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
-               return 0;
+               return false;
 
        skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
        if (skb_end_pointer(skb) - skb->head < skb_size)
-               return 0;
+               return false;
 
        if (skb_shared(skb) || skb_cloned(skb))
-               return 0;
+               return false;
 
        skb_release_head_state(skb);
 
@@ -509,7 +509,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
        skb->data = skb->head + NET_SKB_PAD;
        skb_reset_tail_pointer(skb);
 
-       return 1;
+       return true;
 }
 EXPORT_SYMBOL(skb_recycle_check);
 
@@ -2965,6 +2965,34 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
 }
 EXPORT_SYMBOL_GPL(skb_cow_data);
 
+static void sock_rmem_free(struct sk_buff *skb)
+{
+       struct sock *sk = skb->sk;
+
+       atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+}
+
+/*
+ * Note: We dont mem charge error packets (no sk_forward_alloc changes)
+ */
+int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
+{
+       if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
+           (unsigned)sk->sk_rcvbuf)
+               return -ENOMEM;
+
+       skb_orphan(skb);
+       skb->sk = sk;
+       skb->destructor = sock_rmem_free;
+       atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+
+       skb_queue_tail(&sk->sk_error_queue, skb);
+       if (!sock_flag(sk, SOCK_DEAD))
+               sk->sk_data_ready(sk, skb->len);
+       return 0;
+}
+EXPORT_SYMBOL(sock_queue_err_skb);
+
 void skb_tstamp_tx(struct sk_buff *orig_skb,
                struct skb_shared_hwtstamps *hwtstamps)
 {
@@ -2996,7 +3024,9 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
        memset(serr, 0, sizeof(*serr));
        serr->ee.ee_errno = ENOMSG;
        serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
+
        err = sock_queue_err_skb(sk, skb);
+
        if (err)
                kfree_skb(skb);
 }
index 63958f3394a5d0fbe67e675ee72a10b9d27446cd..4b6c5ca610fc0a463db4995e8b58393916e0a35c 100644 (file)
@@ -336,7 +336,7 @@ ipt_do_table(struct sk_buff *skb,
        cpu        = smp_processor_id();
        table_base = private->entries[cpu];
        jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
-       stackptr   = &private->stackptr[cpu];
+       stackptr   = per_cpu_ptr(private->stackptr, cpu);
        origptr    = *stackptr;
 
        e = get_entry(table_base, private->hook_entry[hook]);
index 3e6dafcb1071663c2e0590da7c379b6b324bbe0f..548d575e6cc684673ef9c7a7a613e2f444ec509c 100644 (file)
@@ -2639,7 +2639,7 @@ static void DBGUNDO(struct sock *sk, const char *msg)
        if (sk->sk_family == AF_INET) {
                printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n",
                       msg,
-                      &inet->daddr, ntohs(inet->dport),
+                      &inet->inet_daddr, ntohs(inet->inet_dport),
                       tp->snd_cwnd, tcp_left_out(tp),
                       tp->snd_ssthresh, tp->prior_ssthresh,
                       tp->packets_out);
@@ -2649,7 +2649,7 @@ static void DBGUNDO(struct sock *sk, const char *msg)
                struct ipv6_pinfo *np = inet6_sk(sk);
                printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n",
                       msg,
-                      &np->daddr, ntohs(inet->dport),
+                      &np->daddr, ntohs(inet->inet_dport),
                       tp->snd_cwnd, tcp_left_out(tp),
                       tp->snd_ssthresh, tp->prior_ssthresh,
                       tp->packets_out);
index 58585748bdac7cc7be011c090409e37f492573a4..eec4ff456e332e0b086d5451478fa5874213e0d1 100644 (file)
@@ -633,9 +633,9 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
        if (!inet->recverr) {
                if (!harderr || sk->sk_state != TCP_ESTABLISHED)
                        goto out;
-       } else {
+       } else
                ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1));
-       }
+
        sk->sk_err = err;
        sk->sk_error_report(sk);
 out:
index 6f517bd8369254ae73d0ac9888792326dd610352..9d2d68f0e6053d97fdfc3f350135604309a35808 100644 (file)
@@ -363,7 +363,7 @@ ip6t_do_table(struct sk_buff *skb,
        cpu        = smp_processor_id();
        table_base = private->entries[cpu];
        jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
-       stackptr   = &private->stackptr[cpu];
+       stackptr   = per_cpu_ptr(private->stackptr, cpu);
        origptr    = *stackptr;
 
        e = get_entry(table_base, private->hook_entry[hook]);
index 294cbe8b0725f7ad9f58690f2b511829d391a672..252d76199c41e7589b85416bef1145e407239126 100644 (file)
@@ -814,7 +814,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
 {
        int flags = 0;
 
-       if (fl->oif || rt6_need_strict(&fl->fl6_dst))
+       if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst))
                flags |= RT6_LOOKUP_F_IFACE;
 
        if (!ipv6_addr_any(&fl->fl6_src))
index 5d218c530a4efae71826f33ac3b7868d741dd897..32be11e4c4d92dbe9d34d8cae84d7e0a482e8882 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/nl80211.h>
 #include "ieee80211_i.h"
 
-enum ieee80211_chan_mode
+static enum ieee80211_chan_mode
 __ieee80211_get_channel_mode(struct ieee80211_local *local,
                             struct ieee80211_sub_if_data *ignore)
 {
index 445de702b8b75a2dad66d96cf757a9f392ed7d80..e34622fa000357c5e24eeddd2aad835d616fd8ce 100644 (file)
@@ -699,10 +699,8 @@ void xt_free_table_info(struct xt_table_info *info)
                vfree(info->jumpstack);
        else
                kfree(info->jumpstack);
-       if (sizeof(unsigned int) * nr_cpu_ids > PAGE_SIZE)
-               vfree(info->stackptr);
-       else
-               kfree(info->stackptr);
+
+       free_percpu(info->stackptr);
 
        kfree(info);
 }
@@ -753,14 +751,9 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
        unsigned int size;
        int cpu;
 
-       size = sizeof(unsigned int) * nr_cpu_ids;
-       if (size > PAGE_SIZE)
-               i->stackptr = vmalloc(size);
-       else
-               i->stackptr = kmalloc(size, GFP_KERNEL);
+       i->stackptr = alloc_percpu(unsigned int);
        if (i->stackptr == NULL)
                return -ENOMEM;
-       memset(i->stackptr, 0, size);
 
        size = sizeof(void **) * nr_cpu_ids;
        if (size > PAGE_SIZE)
@@ -844,10 +837,6 @@ struct xt_table *xt_register_table(struct net *net,
        struct xt_table_info *private;
        struct xt_table *t, *table;
 
-       ret = xt_jumpstack_alloc(newinfo);
-       if (ret < 0)
-               return ERR_PTR(ret);
-
        /* Don't add one object to multiple lists. */
        table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL);
        if (!table) {
index 7b048a35ca5837368e4ace101a57564eacbb51fc..94d72e85a475ae094d14f8df5f4f54a936f0db15 100644 (file)
@@ -1045,12 +1045,12 @@ static void pep_sock_unhash(struct sock *sk)
        lock_sock(sk);
        if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
                skparent = pn->listener;
-               sk_del_node_init(sk);
                release_sock(sk);
 
-               sk = skparent;
                pn = pep_sk(skparent);
-               lock_sock(sk);
+               lock_sock(skparent);
+               sk_del_node_init(sk);
+               sk = skparent;
        }
        /* Unhash a listening sock only when it is closed
         * and all of its active connected pipes are closed. */
index 10ed0d55f75948702837e2154327876a521d3d8b..f68832798db224d6abffcc08f4ad494fa2b3bc17 100644 (file)
@@ -475,6 +475,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
        err = rds_ib_setup_qp(conn);
        if (err) {
                rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err);
+               mutex_unlock(&conn->c_cm_lock);
                goto out;
        }
 
index a9d951b4fbaec49dfea00dc6494639b0d32403ac..b5dd6ac39be86b87afc1bd7761971a11550e572f 100644 (file)
@@ -452,6 +452,7 @@ int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id,
        err = rds_iw_setup_qp(conn);
        if (err) {
                rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err);
+               mutex_unlock(&conn->c_cm_lock);
                goto out;
        }
 
index 0b94d2fa3a883ce4cf1b9bdd6219e30bc338f480..e4deb73e9a84971d46ac3dab9bd96cf8ffc8236f 100644 (file)
@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
 lib-target := $(obj)/lib.a
 endif
 
-ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
+ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),)
 builtin-target := $(obj)/built-in.o
 endif
 
index cbcd654215e68c2c0cc111737c94ae00074b9f3a..54fd1b700131e1e1fcb0ddd13d89ee3a06983ecb 100644 (file)
@@ -241,7 +241,7 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \
        lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
        (rm -f $@ ; false)
 
-quiet_cmd_lzo = LZO    $@
+quiet_cmd_lzo = LZO     $@
 cmd_lzo = (cat $(filter-out FORCE,$^) | \
        lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
        (rm -f $@ ; false)
index 676ddc07d6fa76b1a79603cf3be95a26eb7b7ec1..97b2c6143fe4f9d61cbc181b316e812e82dc456e 100755 (executable)
@@ -11,6 +11,8 @@
 # you do have real dups and do not have them under #ifdef's. You
 # could also just review the results.
 
+use strict;
+
 sub usage {
        print "Usage: checkincludes.pl [-r]\n";
        print "By default we just warn of duplicates\n";
@@ -35,23 +37,24 @@ if ($#ARGV >= 1) {
        }
 }
 
-foreach $file (@ARGV) {
-       open(FILE, $file) or die "Cannot open $file: $!.\n";
+foreach my $file (@ARGV) {
+       open(my $f, '<', $file)
+           or die "Cannot open $file: $!.\n";
 
        my %includedfiles = ();
        my @file_lines = ();
 
-       while (<FILE>) {
+       while (<$f>) {
                if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
                        ++$includedfiles{$1};
                }
                push(@file_lines, $_);
        }
 
-       close(FILE);
+       close($f);
 
        if (!$remove) {
-               foreach $filename (keys %includedfiles) {
+               foreach my $filename (keys %includedfiles) {
                        if ($includedfiles{$filename} > 1) {
                                print "$file: $filename is included more than once.\n";
                        }
@@ -59,27 +62,28 @@ foreach $file (@ARGV) {
                next;
        }
 
-       open(FILE,">$file") || die("Cannot write to $file: $!");
+       open($f, '>', $file)
+           or die("Cannot write to $file: $!");
 
        my $dups = 0;
        foreach (@file_lines) {
                if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
-                       foreach $filename (keys %includedfiles) {
+                       foreach my $filename (keys %includedfiles) {
                                if ($1 eq $filename) {
                                        if ($includedfiles{$filename} > 1) {
                                                $includedfiles{$filename}--;
                                                $dups++;
                                        } else {
-                                               print FILE $_;
+                                               print {$f} $_;
                                        }
                                }
                        }
                } else {
-                       print FILE $_;
+                       print {$f} $_;
                }
        }
        if ($dups > 0) {
                print "$file: removed $dups duplicate includes\n";
        }
-       close(FILE);
+       close($f);
 }
index 14ee68e991dd45767b8ded17747da02a59c703f1..1afff6658a7d2a657333ff8815486b998b5c16bd 100755 (executable)
@@ -21,6 +21,8 @@
 #
 #      TODO :  Port to all architectures (one regex per arch)
 
+use strict;
+
 # check for arch
 #
 # $re is used for two matches:
@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs);
        }
 }
 
-sub bysize($) {
-       my ($asize, $bsize);
-       ($asize = $a) =~ s/.*:  *(.*)$/$1/;
-       ($bsize = $b) =~ s/.*:  *(.*)$/$1/;
-       $bsize <=> $asize
-}
-
 #
 # main()
 #
 my $funcre = qr/^$x* <(.*)>:$/;
-my $func;
-my $file, $lastslash;
+my ($func, $file, $lastslash);
 
 while (my $line = <STDIN>) {
        if ($line =~ m/$funcre/) {
@@ -173,4 +167,6 @@ while (my $line = <STDIN>) {
        }
 }
 
-print sort bysize @stack;
+# Sort output by size (last field)
+print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
+
index ec7d21161bdcb873ee38926c4097a23b44702880..b444e89a0095dc16d207fb23a7600a148c67834b 100755 (executable)
@@ -5,23 +5,22 @@
 # including <linux/version.h> that don't need it.
 # Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
 
+use strict;
+
 $| = 1;
 
-my $debugging = 0;
+my $debugging;
 
-foreach $file (@ARGV)
-{
+foreach my $file (@ARGV) {
     # Open this file.
-    open(FILE, $file) || die "Can't open $file: $!\n";
+    open( my $f, '<', $file )
+      or die "Can't open $file: $!\n";
 
     # Initialize variables.
-    my $fInComment   = 0;
-    my $fInString    = 0;
-    my $fUseVersion   = 0;
+    my ($fInComment, $fInString, $fUseVersion);
     my $iLinuxVersion = 0;
 
-    LINE: while ( <FILE> )
-    {
+    while (<$f>) {
        # Strip comments.
        $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
        m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
@@ -43,8 +42,8 @@ foreach $file (@ARGV)
        # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
        if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
            $fUseVersion = 1;
-           last LINE if $iLinuxVersion;
-       }
+            last if $iLinuxVersion;
+        }
     }
 
     # Report used version IDs without include?
@@ -67,5 +66,5 @@ foreach $file (@ARGV)
         }
     }
 
-    close(FILE);
+    close($f);
 }
index 4b00647814bc46c9525dfc6e806d28af7641f9d6..8b30cc36744f8c2c1d5c24fcaebc9d2cfbd1889e 100755 (executable)
@@ -7,7 +7,7 @@
 # AFLAGS=--32 decodecode < 386.oops
 
 cleanup() {
-       rm -f $T $T.s $T.o $T.oo $T.aa  $T.aaa
+       rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
        exit 1
 }
 
@@ -39,6 +39,29 @@ fi
 echo $code
 code=`echo $code | sed -e 's/.*Code: //'`
 
+width=`expr index "$code" ' '`
+width=$[($width-1)/2]
+case $width in
+1) type=byte ;;
+2) type=2byte ;;
+4) type=4byte ;;
+esac
+
+disas() {
+       ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
+
+       if [ "$ARCH" == "arm" ]; then
+               if [ $width == 2 ]; then
+                       OBJDUMPFLAGS="-M force-thumb"
+               fi
+
+               ${CROSS_COMPILE}strip $1.o
+       fi
+
+       ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
+               grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
+}
+
 marker=`expr index "$code" "\<"`
 if [ $marker -eq 0 ]; then
        marker=`expr index "$code" "\("`
@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then
        echo All code >> $T.oo
        echo ======== >> $T.oo
        beforemark=`echo "$code"`
-       echo -n "       .byte 0x" > $T.s
-       echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s
-       as $AFLAGS -o $T.o $T.s &> /dev/null
-       objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo
-       cat $T.ooo >> $T.oo
-       rm -f $T.o $T.s  $T.ooo
+       echo -n "       .$type 0x" > $T.s
+       echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
+       disas $T
+       cat $T.dis >> $T.oo
+       rm -f $T.o $T.s $T.dis
 
 # and fix code at-and-after marker
        code=`echo "$code" | cut -c$((${marker} + 1))-`
 fi
 echo Code starting with the faulting instruction  > $T.aa
 echo =========================================== >> $T.aa
-code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'`
-echo -n "      .byte 0x" > $T.s
+code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
+echo -n "      .$type 0x" > $T.s
 echo $code >> $T.s
-as $AFLAGS -o $T.o $T.s &> /dev/null
-objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa
-cat $T.aaa >> $T.aa
+disas $T
+cat $T.dis >> $T.aa
 
-faultline=`cat $T.aaa | head -1 | cut -d":" -f2`
+faultline=`cat $T.dis | head -1 | cut -d":" -f2`
+faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
 
 cat $T.oo | sed -e "s/\($faultline\)/\*\1     <-- trapping instruction/g"
 echo
index 705b5ba7c1526c65bbcf2d0868f2a2f007a158e9..04dce7c15f8328c71f3ce5f6bff4ef9ef0882eac 100644 (file)
@@ -49,10 +49,10 @@ sub usage {
 }
 
 sub collectcfiles {
-        my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`;
-        @file = grep {s/\.ko/.mod.c/} @file;
-       chomp @file;
-        return @file;
+    my @file
+       = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
+    chomp @file;
+    return @file;
 }
 
 my (%SYMBOL, %MODULE, %opt, @allcfiles);
@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) {
        $opt{'k'} = "Module.symvers";
 }
 
-unless (open(MODULE_SYMVERS, $opt{'k'})) {
-       die "Sorry, cannot open $opt{'k'}: $!\n";
-}
+open (my $module_symvers, '<', $opt{'k'})
+    or die "Sorry, cannot open $opt{'k'}: $!\n";
 
 if (defined $opt{'o'}) {
-       unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) {
-               die "Sorry, cannot open $opt{'o'} $!\n";
-       }
-       select OUTPUT_HANDLE;
+    open (my $out, '>', $opt{'o'})
+       or die "Sorry, cannot open $opt{'o'} $!\n";
+
+    select $out;
 }
+
 #
 # collect all the symbols and their attributes from the
 # Module.symvers file
 #
-while ( <MODULE_SYMVERS> ) {
+while ( <$module_symvers> ) {
        chomp;
        my (undef, $symbol, $module, $gpl) = split;
        $SYMBOL { $symbol } =  [ $module , "0" , $symbol, $gpl];
 }
-close(MODULE_SYMVERS);
+close($module_symvers);
 
 #
 # collect the usage count of each symbol.
 #
 foreach my $thismod (@allcfiles) {
-       unless (open(MODULE_MODULE, $thismod)) {
-               print "Sorry, cannot open $thismod: $!\n";
+       my $module;
+
+       unless (open ($module, '<', $thismod)) {
+               warn "Sorry, cannot open $thismod: $!\n";
                next;
        }
+
        my $state=0;
-       while ( <MODULE_MODULE> ) {
+       while ( <$module> ) {
                chomp;
                if ($state == 0) {
                        $state = 1 if ($_ =~ /static const struct modversion_info/);
@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) {
        if ($state != 2) {
                print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
        }
-       close(MODULE_MODULE);
+       close($module);
 }
 
 print "\tThis file reports the exported symbols usage patterns by in-tree\n",
index a932ae52f921b5967b705432d0ef972f60c73c24..5958fffb2114fdedfb961858b524e6b42fe8ce2b 100644 (file)
@@ -202,6 +202,7 @@ input_file() {
                        print_mtime "$1" >> ${output}
                        cat "$1"         >> ${output}
                else
+                       echo "$1 \\"
                        cat "$1" | while read type dir file perm ; do
                                if [ "$type" == "file" ]; then
                                        echo "$file \\";
@@ -231,7 +232,7 @@ arg="$1"
 case "$arg" in
        "-l")   # files included in initramfs - used by kbuild
                dep_list="list_"
-               echo "deps_initramfs := \\"
+               echo "deps_initramfs := $0 \\"
                shift
                ;;
        "-o")   # generate compressed cpio image named $1
index af6b8363a2d51ffd1a0d2b61f40f10927e78cbce..f99115ebe9254a4ef630eabe127bc7cf25e2195c 100644 (file)
@@ -758,8 +758,10 @@ int main(int argc, char **argv)
                /* setlinebuf(debugfile); */
        }
 
-       if (flag_reference)
+       if (flag_reference) {
                read_reference(ref_file);
+               fclose(ref_file);
+       }
 
        yyparse();
 
index b7f6c560e24d2e88aabb36aea8272465eb94936c..8dd019bc5a7361631c71dc1d5e33095b6f42b6a1 100755 (executable)
@@ -80,8 +80,7 @@ sub search {
                my $path = "$i/$filename";
                return $path if -f $path;
        }
-
-       return undef;
+       return;
 }
 
 sub parse_all {
index db1dd7a549f2b9e1259148c39175ad6ee6df3d02..50d6cfd1fa778808b659a461884113de502f3f99 100644 (file)
@@ -28,11 +28,12 @@ my $lineno = 0;
 my $filename;
 
 foreach my $file (@files) {
-       local *FH;
        $filename = $file;
-       open(FH, "<$filename") or die "$filename: $!\n";
+
+       open(my $fh, '<', $filename)
+               or die "$filename: $!\n";
        $lineno = 0;
-       while ($line = <FH>) {
+       while ($line = <$fh>) {
                $lineno++;
                &check_include();
                &check_asm_types();
@@ -40,7 +41,7 @@ foreach my $file (@files) {
                &check_declarations();
                # Dropped for now. Too much noise &check_config();
        }
-       close FH;
+       close $fh;
 }
 exit $ret;
 
@@ -78,7 +79,7 @@ sub check_config
 }
 
 my $linux_asm_types;
-sub check_asm_types()
+sub check_asm_types
 {
        if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
                return;
index b89ca2c58fdbbe3592f97a27592675417713653c..4ca3be3b2e50ef90c0a0e5e5e054aec081405b1b 100644 (file)
@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV;
 my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
 
 foreach my $file (@files) {
-       local *INFILE;
-       local *OUTFILE;
        my $tmpfile = "$installdir/$file.tmp";
-       open(INFILE, "<$readdir/$file")
-               or die "$readdir/$file: $!\n";
-       open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n";
-       while (my $line = <INFILE>) {
+
+       open(my $in, '<', "$readdir/$file")
+           or die "$readdir/$file: $!\n";
+       open(my $out, '>', $tmpfile)
+           or die "$tmpfile: $!\n";
+       while (my $line = <$in>) {
                $line =~ s/([\s(])__user\s/$1/g;
                $line =~ s/([\s(])__force\s/$1/g;
                $line =~ s/([\s(])__iomem\s/$1/g;
@@ -39,10 +39,11 @@ foreach my $file (@files) {
                $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
                $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
                $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
-               printf OUTFILE "%s", $line;
+               printf {$out} "%s", $line;
        }
-       close OUTFILE;
-       close INFILE;
+       close $out;
+       close $in;
+
        system $unifdef . " $tmpfile > $installdir/$file";
        unlink $tmpfile;
 }
index 86c3896a1e01862b222adeaac4e33bc9b8a01aad..e3902fb39afd1f2c53f63c0cfa9aaa1273956a02 100644 (file)
@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s)
        rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
        if (rc != 3) {
                if (rc != EOF) {
-                       /* skip line */
-                       fgets(str, 500, in);
+                       /* skip line. sym is used as dummy to
+                        * shut of "warn_unused_result" warning.
+                        */
+                       sym = fgets(str, 500, in);
                }
                return -1;
        }
index 186c46604d0669f8f1d4cfbcaf7ad0cdc6d658fa..7cdae39b8f09fbb05c73c39424d7bb2f344a8360 100644 (file)
@@ -23,6 +23,9 @@ menuconfig: $(obj)/mconf
 config: $(obj)/conf
        $< $(Kconfig)
 
+nconfig: $(obj)/nconf
+       $< $(Kconfig)
+
 oldconfig: $(obj)/conf
        $< -o $(Kconfig)
 
@@ -120,6 +123,7 @@ endif
 # Help text used by make help
 help:
        @echo  '  config          - Update current config utilising a line-oriented program'
+       @echo  '  nconfig         - Update current config utilising a ncurses menu based program'
        @echo  '  menuconfig      - Update current config utilising a menu based program'
        @echo  '  xconfig         - Update current config utilising a QT based front-end'
        @echo  '  gconfig         - Update current config utilising a GTK based front-end'
@@ -147,6 +151,8 @@ HOST_EXTRACFLAGS += -DLOCALE
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
 # conf:          Used for defconfig, oldconfig and related targets
+# nconf:  Used for the nconfig target.
+#         Utilizes ncurses
 # mconf:  Used for the menuconfig target
 #         Utilizes the lxdialog package
 # qconf:  Used for the xconfig target
@@ -159,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
 lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
 
 conf-objs      := conf.o  zconf.tab.o
-mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
+mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
+nconf-objs     := nconf.o zconf.tab.o nconf.gui.o
 kxgettext-objs := kxgettext.o zconf.tab.o
 
 hostprogs-y := conf qconf gconf kxgettext
 
+ifeq ($(MAKECMDGOALS),nconfig)
+       hostprogs-y += nconf
+endif
+
 ifeq ($(MAKECMDGOALS),menuconfig)
        hostprogs-y += mconf
 endif
@@ -187,7 +198,7 @@ endif
 
 clean-files    := lkc_defs.h qconf.moc .tmp_qtcheck \
                   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
-clean-files     += mconf qconf gconf
+clean-files     += mconf qconf gconf nconf
 clean-files     += config.pot linux.pot
 
 # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
@@ -212,6 +223,7 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
 HOSTCFLAGS_gconf.o     = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
                           -D LKC_DIRECT_LINK
 
+HOSTLOADLIBES_nconf    = -lmenu -lpanel -lncurses
 $(obj)/qconf.o: $(obj)/.tmp_qtcheck
 
 ifeq ($(qconf-target),1)
index edd3f39a080a422175bf512c94dd1d5bf87e059b..d83f2322893a8adb10f027e2c4fa4757a33e26f0 100644 (file)
@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out)
 
 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
 {
-       str_append((struct gstr*)data, str);
+       struct gstr *gs = (struct gstr*)data;
+       const char *sym_str = NULL;
+
+       if (sym)
+               sym_str = sym_get_string_value(sym);
+
+       if (gs->max_width) {
+               unsigned extra_length = strlen(str);
+               const char *last_cr = strrchr(gs->s, '\n');
+               unsigned last_line_length;
+
+               if (sym_str)
+                       extra_length += 4 + strlen(sym_str);
+
+               if (!last_cr)
+                       last_cr = gs->s;
+
+               last_line_length = strlen(gs->s) - (last_cr - gs->s);
+
+               if ((last_line_length + extra_length) > gs->max_width)
+                       str_append(gs, "\\\n");
+       }
+
+       str_append(gs, str);
        if (sym)
-               str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym));
+               str_printf(gs, " [=%s]", sym_str);
 }
 
 void expr_gstr_print(struct expr *e, struct gstr *gs)
index 6408fefae083703e2fa3d8e8a3d4f8a814f44f0b..891cd9ce9ba21b915d0b0aa993fc2d0c8d2fb10c 100644 (file)
@@ -86,7 +86,7 @@ struct symbol {
        struct expr_value rev_dep;
 };
 
-#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
 
 #define SYMBOL_CONST      0x0001  /* symbol is const */
 #define SYMBOL_CHECK      0x0008  /* used during dependency checking */
@@ -108,8 +108,7 @@ struct symbol {
 #define SYMBOL_DEF4       0x80000  /* symbol.def[S_DEF_4] is valid */
 
 #define SYMBOL_MAXLENGTH       256
-#define SYMBOL_HASHSIZE                257
-#define SYMBOL_HASHMASK                0xff
+#define SYMBOL_HASHSIZE                9973
 
 /* A property represent the config options that can be associated
  * with a config "symbol".
index 65464366fe389ab67e631c64646717c67303d05b..bef10411837fb758bdf564818aa2c23888ad8958 100644 (file)
@@ -30,13 +30,16 @@ enum {
        SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
 };
 
+enum {
+       OPT_NORMAL, OPT_ALL, OPT_PROMPT
+};
+
 static gint view_mode = FULL_VIEW;
 static gboolean show_name = TRUE;
 static gboolean show_range = TRUE;
 static gboolean show_value = TRUE;
-static gboolean show_all = FALSE;
-static gboolean show_debug = FALSE;
 static gboolean resizeable = FALSE;
+static int opt_mode = OPT_NORMAL;
 
 GtkWidget *main_wnd = NULL;
 GtkWidget *tree1_w = NULL;     // left  frame
@@ -76,36 +79,7 @@ static void conf_changed(void);
 
 /* Helping/Debugging Functions */
 
-
-const char *dbg_print_stype(int val)
-{
-       static char buf[256];
-
-       bzero(buf, 256);
-
-       if (val == S_UNKNOWN)
-               strcpy(buf, "unknown");
-       if (val == S_BOOLEAN)
-               strcpy(buf, "boolean");
-       if (val == S_TRISTATE)
-               strcpy(buf, "tristate");
-       if (val == S_INT)
-               strcpy(buf, "int");
-       if (val == S_HEX)
-               strcpy(buf, "hex");
-       if (val == S_STRING)
-               strcpy(buf, "string");
-       if (val == S_OTHER)
-               strcpy(buf, "other");
-
-#ifdef DEBUG
-       printf("%s", buf);
-#endif
-
-       return buf;
-}
-
-const char *dbg_print_flags(int val)
+const char *dbg_sym_flags(int val)
 {
        static char buf[256];
 
@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val)
                strcat(buf, "auto/");
 
        buf[strlen(buf) - 1] = '\0';
-#ifdef DEBUG
-       printf("%s", buf);
-#endif
-
-       return buf;
-}
-
-const char *dbg_print_ptype(int val)
-{
-       static char buf[256];
-
-       bzero(buf, 256);
-
-       if (val == P_UNKNOWN)
-               strcpy(buf, "unknown");
-       if (val == P_PROMPT)
-               strcpy(buf, "prompt");
-       if (val == P_COMMENT)
-               strcpy(buf, "comment");
-       if (val == P_MENU)
-               strcpy(buf, "menu");
-       if (val == P_DEFAULT)
-               strcpy(buf, "default");
-       if (val == P_CHOICE)
-               strcpy(buf, "choice");
-
-#ifdef DEBUG
-       printf("%s", buf);
-#endif
 
        return buf;
 }
 
-
 void replace_button_icon(GladeXML * xml, GdkDrawable * window,
                         GtkStyle * style, gchar * btn_name, gchar ** xpm)
 {
@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
 
 
 void
-on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
+on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-       show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
+       opt_mode = OPT_NORMAL;
+       gtk_tree_store_clear(tree2);
+       display_tree(&rootmenu);        /* instead of update_tree to speed-up */
+}
+
 
+void
+on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
+{
+       opt_mode = OPT_ALL;
        gtk_tree_store_clear(tree2);
-       display_tree(&rootmenu);        // instead of update_tree to speed-up
+       display_tree(&rootmenu);        /* instead of update_tree to speed-up */
 }
 
 
 void
-on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
+on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-       show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
-       update_tree(&rootmenu, NULL);
+       opt_mode = OPT_PROMPT;
+       gtk_tree_store_clear(tree2);
+       display_tree(&rootmenu);        /* instead of update_tree to speed-up */
 }
 
 
@@ -1163,7 +1116,10 @@ static gchar **fill_row(struct menu *menu)
            g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
                            sym && sym_has_value(sym) ? "(NEW)" : "");
 
-       if (show_all && !menu_is_visible(menu))
+       if (opt_mode == OPT_ALL && !menu_is_visible(menu))
+               row[COL_COLOR] = g_strdup("DarkGray");
+       else if (opt_mode == OPT_PROMPT &&
+                       menu_has_prompt(menu) && !menu_is_visible(menu))
                row[COL_COLOR] = g_strdup("DarkGray");
        else
                row[COL_COLOR] = g_strdup("Black");
@@ -1386,16 +1342,19 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
                       menu2 ? menu_get_prompt(menu2) : "nil");
 #endif
 
-               if (!menu_is_visible(child1) && !show_all) {    // remove node
+               if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
+                   (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
+
+                       /* remove node */
                        if (gtktree_iter_find_node(dst, menu1) != NULL) {
                                memcpy(&tmp, child2, sizeof(GtkTreeIter));
                                valid = gtk_tree_model_iter_next(model2,
                                                                 child2);
                                gtk_tree_store_remove(tree2, &tmp);
                                if (!valid)
-                                       return; // next parent
+                                       return;         /* next parent */
                                else
-                                       goto reparse;   // next child
+                                       goto reparse;   /* next child */
                        } else
                                continue;
                }
@@ -1464,17 +1423,19 @@ static void display_tree(struct menu *menu)
                    && (tree == tree2))
                        continue;
 
-               if (menu_is_visible(child) || show_all)
+               if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
+                   (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
+                   (opt_mode == OPT_ALL))
                        place_node(child, fill_row(child));
 #ifdef DEBUG
                printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
                printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
-               dbg_print_ptype(ptype);
+               printf("%s", prop_get_type_name(ptype));
                printf(" | ");
                if (sym) {
-                       dbg_print_stype(sym->type);
+                       printf("%s", sym_type_name(sym->type));
                        printf(" | ");
-                       dbg_print_flags(sym->flags);
+                       printf("%s", dbg_sym_flags(sym->flags));
                        printf("\n");
                } else
                        printf("\n");
index b1c86c19292cb01d43b8637acddcf701bf93d844..d52b0a75d8247c69a1c153b3e39072c596c551ef 100644 (file)
                  </child>
 
                  <child>
-                   <widget class="GtkCheckMenuItem" id="show_all_options1">
+                   <widget class="GtkRadioMenuItem" id="set_option_mode1">
+                     <property name="visible">True</property>
+                     <property name="tooltip" translatable="yes">Show normal options</property>
+                     <property name="label" translatable="yes">Show normal options</property>
+                     <property name="use_underline">True</property>
+                     <property name="active">True</property>
+                     <signal name="activate" handler="on_set_option_mode1_activate"/>
+                   </widget>
+                 </child>
+
+                 <child>
+                   <widget class="GtkRadioMenuItem" id="set_option_mode2">
                      <property name="visible">True</property>
                      <property name="tooltip" translatable="yes">Show all options</property>
                      <property name="label" translatable="yes">Show all _options</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
-                     <signal name="activate" handler="on_show_all_options1_activate"/>
+                     <property name="group">set_option_mode1</property>
+                     <signal name="activate" handler="on_set_option_mode2_activate"/>
                    </widget>
                  </child>
 
                  <child>
-                   <widget class="GtkCheckMenuItem" id="show_debug_info1">
+                   <widget class="GtkRadioMenuItem" id="set_option_mode3">
                      <property name="visible">True</property>
-                     <property name="tooltip" translatable="yes">Show masked options</property>
-                     <property name="label" translatable="yes">Show _debug info</property>
+                     <property name="tooltip" translatable="yes">Show all options with prompts</property>
+                     <property name="label" translatable="yes">Show all prompt options</property>
                      <property name="use_underline">True</property>
                      <property name="active">False</property>
-                     <signal name="activate" handler="on_show_debug_info1_activate"/>
+                     <property name="group">set_option_mode1</property>
+                     <signal name="activate" handler="on_set_option_mode3_activate"/>
                    </widget>
                  </child>
+
                </widget>
              </child>
            </widget>
index f379b0bf8c9e7b8d45a6bd9a7f689af7165fcec6..ce6549cdaccf4b79443d1e06267502f68e769d89 100644 (file)
@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode);
 void kconfig_load(void);
 
 /* menu.c */
-void menu_init(void);
+void _menu_init(void);
 void menu_warn(struct menu *menu, const char *fmt, ...);
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
@@ -106,6 +106,11 @@ int file_write_dep(const char *name);
 struct gstr {
        size_t len;
        char  *s;
+       /*
+       * when max_width is not zero long lines in string s (if any) get
+       * wrapped not to exceed the max_width value
+       */
+       int max_width;
 };
 struct gstr str_new(void);
 struct gstr str_assign(const char *s);
index ffeb532b2cff3a71705693f132dc5a5eb9d94bf4..7cadcad8233bb37cd8c2e40ccae7d999a1284a63 100644 (file)
@@ -11,13 +11,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void)));
 /* menu.c */
 P(rootmenu,struct menu,);
 
-P(menu_is_visible,bool,(struct menu *menu));
+P(menu_is_visible, bool, (struct menu *menu));
+P(menu_has_prompt, bool, (struct menu *menu));
 P(menu_get_prompt,const char *,(struct menu *menu));
 P(menu_get_root_menu,struct menu *,(struct menu *menu));
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
 P(menu_has_help,bool,(struct menu *menu));
 P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str,void,(struct gstr *r, struct symbol *sym));
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
+P(get_relations_str, struct gstr, (struct symbol **sym_arr));
 P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 
 /* symbol.c */
index 616c60138183c8c9b74c3f2562f7e4a1e5b6d5d9..dd8e587c50e26eada18fe35995aaa0ec301f42fc 100644 (file)
@@ -180,7 +180,7 @@ do_resize:
                case KEY_LEFT:
                        switch (button) {
                        case -1:
-                               button = 1;     /* Indicates "Cancel" button is selected */
+                               button = 1;     /* Indicates "Help" button is selected */
                                print_buttons(dialog, height, width, 1);
                                break;
                        case 0:
@@ -204,7 +204,7 @@ do_resize:
                                print_buttons(dialog, height, width, 0);
                                break;
                        case 0:
-                               button = 1;     /* Indicates "Cancel" button is selected */
+                               button = 1;     /* Indicates "Help" button is selected */
                                print_buttons(dialog, height, width, 1);
                                break;
                        case 1:
index fa9d633f293c7c3a107b956e15774afd27560b12..1d604738fa1314a3479362082208b3591385d890 100644 (file)
@@ -383,6 +383,10 @@ do_resize:
                case 'n':
                case 'm':
                case '/':
+               case 'h':
+               case '?':
+               case 'z':
+               case '\n':
                        /* save scroll info */
                        *s_scroll = scroll;
                        delwin(menu);
@@ -390,8 +394,10 @@ do_resize:
                        item_set(scroll + choice);
                        item_set_selected(1);
                        switch (key) {
+                       case 'h':
+                       case '?':
+                               return 2;
                        case 's':
-                               return 3;
                        case 'y':
                                return 3;
                        case 'n':
@@ -402,18 +408,12 @@ do_resize:
                                return 6;
                        case '/':
                                return 7;
+                       case 'z':
+                               return 8;
+                       case '\n':
+                               return button;
                        }
                        return 0;
-               case 'h':
-               case '?':
-                       button = 2;
-               case '\n':
-                       *s_scroll = scroll;
-                       delwin(menu);
-                       delwin(dialog);
-                       item_set(scroll + choice);
-                       item_set_selected(1);
-                       return button;
                case 'e':
                case 'x':
                        key = KEY_ESC;
index 8413cf38ed277ea0061efb708c9db881ab4b6a12..2c83d3234d304dc0c3d25fac44b1af59c1a631fb 100644 (file)
@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_(
 "             there is a delayed response which you may find annoying.\n"
 "\n"
 "   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
-"   <Exit> and <Help>\n"
+"   <Exit> and <Help>.\n"
 "\n"
 "o  To get help with an item, use the cursor keys to highlight <Help>\n"
-"   and Press <ENTER>.\n"
+"   and press <ENTER>.\n"
 "\n"
 "   Shortcut: Press <H> or <?>.\n"
 "\n"
+"o  To show hidden options, press <Z>.\n"
+"\n"
 "\n"
 "Radiolists  (Choice lists)\n"
 "-----------\n"
@@ -272,6 +274,7 @@ static int indent;
 static struct menu *current_menu;
 static int child_count;
 static int single_menu_mode;
+static int show_all_options;
 
 static void conf(struct menu *menu);
 static void conf_choice(struct menu *menu);
@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
 
-static struct gstr get_relations_str(struct symbol **sym_arr)
-{
-       struct symbol *sym;
-       struct gstr res = str_new();
-       int i;
-
-       for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
-               get_symbol_str(&res, sym);
-       if (!i)
-               str_append(&res, _("No matches found.\n"));
-       return res;
-}
-
 static char filename[PATH_MAX+1];
 static void set_config_filename(const char *config_filename)
 {
@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu)
        int type, tmp, doint = 2;
        tristate val;
        char ch;
-
-       if (!menu_is_visible(menu))
+       bool visible;
+
+       /*
+        * note: menu_is_visible() has side effect that it will
+        * recalc the value of the symbol.
+        */
+       visible = menu_is_visible(menu);
+       if (show_all_options && !menu_has_prompt(menu))
+               return;
+       else if (!show_all_options && !visible)
                return;
 
        sym = menu->sym;
@@ -619,6 +617,9 @@ static void conf(struct menu *menu)
                case 7:
                        search_conf();
                        break;
+               case 8:
+                       show_all_options = !show_all_options;
+                       break;
                }
        }
 }
@@ -638,6 +639,7 @@ static void show_help(struct menu *menu)
 {
        struct gstr help = str_new();
 
+       help.max_width = getmaxx(stdscr) - 10;
        menu_get_ext_help(menu, &help);
 
        show_helptext(_(menu_get_prompt(menu)), str_get(&help));
index 059a2465c5744ffed6d3cff25e2d8135a16c0399..203632cc30bdbe12ad0644c3aff15ed07a4e7c0d 100644 (file)
@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
        va_end(ap);
 }
 
-void menu_init(void)
+void _menu_init(void)
 {
        current_entry = current_menu = &rootmenu;
        last_entry_ptr = &rootmenu.list;
@@ -197,7 +197,7 @@ static void sym_check_prop(struct symbol *sym)
                        if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
                            prop->expr->type != E_SYMBOL)
                                prop_warn(prop,
-                                   "default for config symbol '%'"
+                                   "default for config symbol '%s'"
                                    " must be a single symbol", sym->name);
                        break;
                case P_SELECT:
@@ -390,6 +390,13 @@ void menu_finalize(struct menu *parent)
        }
 }
 
+bool menu_has_prompt(struct menu *menu)
+{
+       if (!menu->prompt)
+               return false;
+       return true;
+}
+
 bool menu_is_visible(struct menu *menu)
 {
        struct menu *child;
@@ -398,6 +405,7 @@ bool menu_is_visible(struct menu *menu)
 
        if (!menu->prompt)
                return false;
+
        sym = menu->sym;
        if (sym) {
                sym_calc_value(sym);
@@ -407,12 +415,14 @@ bool menu_is_visible(struct menu *menu)
 
        if (visible != no)
                return true;
+
        if (!sym || sym_get_tristate_value(menu->sym) == no)
                return false;
 
        for (child = menu->list; child; child = child->next)
                if (menu_is_visible(child))
                        return true;
+
        return false;
 }
 
@@ -515,6 +525,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
        str_append(r, "\n\n");
 }
 
+struct gstr get_relations_str(struct symbol **sym_arr)
+{
+       struct symbol *sym;
+       struct gstr res = str_new();
+       int i;
+
+       for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+               get_symbol_str(&res, sym);
+       if (!i)
+               str_append(&res, _("No matches found.\n"));
+       return res;
+}
+
+
 void menu_get_ext_help(struct menu *menu, struct gstr *help)
 {
        struct symbol *sym = menu->sym;
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
new file mode 100644 (file)
index 0000000..762caf8
--- /dev/null
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * Derived from menuconfig.
+ *
+ */
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+#include "nconf.h"
+
+static const char nconf_readme[] = N_(
+"Overview\n"
+"--------\n"
+"Some kernel features may be built directly into the kernel.\n"
+"Some may be made into loadable runtime modules.  Some features\n"
+"may be completely removed altogether.  There are also certain\n"
+"kernel parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with following braces represent features that\n"
+"  [ ] can be built in or removed\n"
+"  < > can be built in, modularized or removed\n"
+"  { } can be built in or modularized (selected by other feature)\n"
+"  - - are selected by other feature,\n"
+"  XXX cannot be selected. use Symbol Info to find out why,\n"
+"while *, M or whitespace inside braces means to build in, build as\n"
+"a module or to exclude the feature respectively.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in, <M> to make it a module or\n"
+"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->M->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+"   you wish to change use <Enter> or <Space>. Goto submenu by \n"
+"   pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
+"   Submenus are designated by \"--->\".\n"
+"\n"
+"   Shortcut: Press the option's highlighted letter (hotkey).\n"
+"             Pressing a hotkey more than once will sequence\n"
+"             through all visible items which use that hotkey.\n"
+"\n"
+"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+"   unseen options into view.\n"
+"\n"
+"o  To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
+"\n"
+"o  To get help with an item, press <F1>\n"
+"   Shortcut: Press <h> or <?>.\n"
+"\n"
+"\n"
+"Radiolists  (Choice lists)\n"
+"-----------\n"
+"o  Use the cursor keys to select the option you wish to set and press\n"
+"   <S> or the <SPACE BAR>.\n"
+"\n"
+"   Shortcut: Press the first letter of the option you wish to set then\n"
+"             press <S> or <SPACE BAR>.\n"
+"\n"
+"o  To see available help for the item, press <F1>\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o  Enter the requested information and press <ENTER>\n"
+"   If you are entering hexadecimal values, it is not necessary to\n"
+"   add the '0x' prefix to the entry.\n"
+"\n"
+"o  For help, press <F1>.\n"
+"\n"
+"\n"
+"Text Box    (Help Window)\n"
+"--------\n"
+"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
+"   keys h,j,k,l function here as do <SPACE BAR> for those\n"
+"   who are familiar with less and lynx.\n"
+"\n"
+"o  Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"nconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different kernel configurations.\n"
+"\n"
+"At the end of the main menu you will find two options.  One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a nconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting nconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use nconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, nconfig will look rather bad.  nconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"nconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry.  I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment.  Some distributions\n"
+"export those variables via /etc/profile.  Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the kernel options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the nconfig\n"
+"with NCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make NCONFIG_MODE=single_menu nconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n"
+"\n"),
+menu_no_f_instructions[] = N_(
+" You do not have function keys support. Please follow the\n"
+" following instructions:\n"
+" Arrow keys navigate the menu.\n"
+" <Enter> or <right-arrow> selects submenus --->.\n"
+" Capital Letters are hotkeys.\n"
+" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
+" Pressing SpaceBar toggles between the above options\n"
+" Press <Esc> or <left-arrow> to go back one menu, \n"
+" <?> or <h> for Help, </> for Search.\n"
+" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
+" Legend: [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
+" <Esc> always leaves the current window\n"),
+menu_instructions[] = N_(
+" Arrow keys navigate the menu.\n"
+" <Enter> or <right-arrow> selects submenus --->.\n"
+" Capital Letters are hotkeys.\n"
+" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
+" Pressing SpaceBar toggles between the above options\n"
+" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
+" <?>, <F1> or <h> for Help, </> for Search.\n"
+" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
+" Legend: [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
+" <Esc> always leaves the current window\n"),
+radiolist_instructions[] = N_(
+" Use the arrow keys to navigate this window or\n"
+" press the hotkey of the item you wish to select\n"
+" followed by the <SPACE BAR>.\n"
+" Press <?>, <F1> or <h> for additional information about this option.\n"),
+inputbox_instructions_int[] = N_(
+"Please enter a decimal value.\n"
+"Fractions will not be accepted.\n"
+"Press <RETURN> to accept, <ESC> to cancel."),
+inputbox_instructions_hex[] = N_(
+"Please enter a hexadecimal value.\n"
+"Press <RETURN> to accept, <ESC> to cancel."),
+inputbox_instructions_string[] = N_(
+"Please enter a string value.\n"
+"Press <RETURN> to accept, <ESC> to cancel."),
+setmod_text[] = N_(
+"This feature depends on another which\n"
+"has been configured as a module.\n"
+"As a result, this feature will be built as a module."),
+nohelp_text[] = N_(
+"There is no help available for this kernel option.\n"),
+load_config_text[] = N_(
+"Enter the name of the configuration file you wish to load.\n"
+"Accept the name shown to restore the configuration you\n"
+"last retrieved.  Leave blank to abort."),
+load_config_help[] = N_(
+"\n"
+"For various reasons, one may wish to keep several different kernel\n"
+"configurations available on a single machine.\n"
+"\n"
+"If you have saved a previous configuration in a file other than the\n"
+"kernel's default, entering the name of the file here will allow you\n"
+"to modify that configuration.\n"
+"\n"
+"If you are uncertain, then you have probably never used alternate\n"
+"configuration files.  You should therefor leave this blank to abort.\n"),
+save_config_text[] = N_(
+"Enter a filename to which this configuration should be saved\n"
+"as an alternate.  Leave blank to abort."),
+save_config_help[] = N_(
+"\n"
+"For various reasons, one may wish to keep different kernel\n"
+"configurations available on a single machine.\n"
+"\n"
+"Entering a file name here will allow you to later retrieve, modify\n"
+"and use the current configuration as an alternate to whatever\n"
+"configuration options you have selected at that time.\n"
+"\n"
+"If you are uncertain what all this means then you should probably\n"
+"leave this blank.\n"),
+search_help[] = N_(
+"\n"
+"Search for CONFIG_ symbols and display their relations.\n"
+"Regular expressions are allowed.\n"
+"Example: search for \"^FOO\"\n"
+"Result:\n"
+"-----------------------------------------------------------------\n"
+"Symbol: FOO [ = m]\n"
+"Prompt: Foo bus is used to drive the bar HW\n"
+"Defined at drivers/pci/Kconfig:47\n"
+"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+"Location:\n"
+"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+"    -> PCI support (PCI [ = y])\n"
+"      -> PCI access mode (<choice> [ = y])\n"
+"Selects: LIBCRC32\n"
+"Selected by: BAR\n"
+"-----------------------------------------------------------------\n"
+"o The line 'Prompt:' shows the text used in the menu structure for\n"
+"  this CONFIG_ symbol\n"
+"o The 'Defined at' line tell at what file / line number the symbol\n"
+"  is defined\n"
+"o The 'Depends on:' line tell what symbols needs to be defined for\n"
+"  this symbol to be visible in the menu (selectable)\n"
+"o The 'Location:' lines tell where in the menu structure this symbol\n"
+"  is located\n"
+"    A location followed by a [ = y] indicate that this is a selectable\n"
+"    menu item - and current value is displayed inside brackets.\n"
+"o The 'Selects:' line tell what symbol will be automatically\n"
+"  selected if this symbol is selected (y or m)\n"
+"o The 'Selected by' line tell what symbol has selected this symbol\n"
+"\n"
+"Only relevant lines are shown.\n"
+"\n\n"
+"Search examples:\n"
+"Examples: USB   = > find all CONFIG_ symbols containing USB\n"
+"          ^USB => find all CONFIG_ symbols starting with USB\n"
+"          USB$ => find all CONFIG_ symbols ending with USB\n"
+"\n");
+
+struct mitem {
+       char str[256];
+       char tag;
+       void *usrptr;
+       int is_hot;
+       int is_visible;
+};
+
+#define MAX_MENU_ITEMS 4096
+static int show_all_items;
+static int indent;
+static struct menu *current_menu;
+static int child_count;
+static int single_menu_mode;
+/* the window in which all information appears */
+static WINDOW *main_window;
+/* the largest size of the menu window */
+static int mwin_max_lines;
+static int mwin_max_cols;
+/* the window in which we show option buttons */
+static MENU *curses_menu;
+static ITEM *curses_menu_items[MAX_MENU_ITEMS];
+static struct mitem k_menu_items[MAX_MENU_ITEMS];
+static int items_num;
+static int global_exit;
+/* the currently selected button */
+const char *current_instructions = menu_instructions;
+/* this array is used to implement hot keys. it is updated in item_make and
+ * resetted in clean_items. It would be better to use a hash, but lets keep it
+ * simple... */
+#define MAX_SAME_KEY MAX_MENU_ITEMS
+struct {
+       int count;
+       int ptrs[MAX_MENU_ITEMS];
+} hotkeys[1<<(sizeof(char)*8)];
+
+static void conf(struct menu *menu);
+static void conf_choice(struct menu *menu);
+static void conf_string(struct menu *menu);
+static void conf_load(void);
+static void conf_save(void);
+static void show_help(struct menu *menu);
+static int do_exit(void);
+static void setup_windows(void);
+
+typedef void (*function_key_handler_t)(int *key, struct menu *menu);
+static void handle_f1(int *key, struct menu *current_item);
+static void handle_f2(int *key, struct menu *current_item);
+static void handle_f3(int *key, struct menu *current_item);
+static void handle_f4(int *key, struct menu *current_item);
+static void handle_f5(int *key, struct menu *current_item);
+static void handle_f6(int *key, struct menu *current_item);
+static void handle_f7(int *key, struct menu *current_item);
+static void handle_f8(int *key, struct menu *current_item);
+
+struct function_keys {
+       const char *key_str;
+       const char *func;
+       function_key key;
+       function_key_handler_t handler;
+};
+
+static const int function_keys_num = 8;
+struct function_keys function_keys[] = {
+       {
+               .key_str = "F1",
+               .func = "Help",
+               .key = F_HELP,
+               .handler = handle_f1,
+       },
+       {
+               .key_str = "F2",
+               .func = "Symbol Info",
+               .key = F_SYMBOL,
+               .handler = handle_f2,
+       },
+       {
+               .key_str = "F3",
+               .func = "Instructions",
+               .key = F_INSTS,
+               .handler = handle_f3,
+       },
+       {
+               .key_str = "F4",
+               .func = "Config",
+               .key = F_CONF,
+               .handler = handle_f4,
+       },
+       {
+               .key_str = "F5",
+               .func = "Back",
+               .key = F_BACK,
+               .handler = handle_f5,
+       },
+       {
+               .key_str = "F6",
+               .func = "Save",
+               .key = F_SAVE,
+               .handler = handle_f6,
+       },
+       {
+               .key_str = "F7",
+               .func = "Load",
+               .key = F_LOAD,
+               .handler = handle_f7,
+       },
+       {
+               .key_str = "F8",
+               .func = "Exit",
+               .key = F_EXIT,
+               .handler = handle_f8,
+       },
+};
+
+static void print_function_line(void)
+{
+       int i;
+       int offset = 1;
+       const int skip = 1;
+
+       for (i = 0; i < function_keys_num; i++) {
+               wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
+               mvwprintw(main_window, LINES-3, offset,
+                               "%s",
+                               function_keys[i].key_str);
+               wattrset(main_window, attributes[FUNCTION_TEXT]);
+               offset += strlen(function_keys[i].key_str);
+               mvwprintw(main_window, LINES-3,
+                               offset, "%s",
+                               function_keys[i].func);
+               offset += strlen(function_keys[i].func) + skip;
+       }
+       wattrset(main_window, attributes[NORMAL]);
+}
+
+/* help */
+static void handle_f1(int *key, struct menu *current_item)
+{
+       show_scroll_win(main_window,
+                       _("README"), _(nconf_readme));
+       return;
+}
+
+/* symbole help */
+static void handle_f2(int *key, struct menu *current_item)
+{
+       show_help(current_item);
+       return;
+}
+
+/* instructions */
+static void handle_f3(int *key, struct menu *current_item)
+{
+       show_scroll_win(main_window,
+                       _("Instructions"),
+                       _(current_instructions));
+       return;
+}
+
+/* config */
+static void handle_f4(int *key, struct menu *current_item)
+{
+       int res = btn_dialog(main_window,
+                       _("Show all symbols?"),
+                       2,
+                       "   <Show All>   ",
+                       "<Don't show all>");
+       if (res == 0)
+               show_all_items = 1;
+       else if (res == 1)
+               show_all_items = 0;
+
+       return;
+}
+
+/* back */
+static void handle_f5(int *key, struct menu *current_item)
+{
+       *key = KEY_LEFT;
+       return;
+}
+
+/* save */
+static void handle_f6(int *key, struct menu *current_item)
+{
+       conf_save();
+       return;
+}
+
+/* load */
+static void handle_f7(int *key, struct menu *current_item)
+{
+       conf_load();
+       return;
+}
+
+/* exit */
+static void handle_f8(int *key, struct menu *current_item)
+{
+       do_exit();
+       return;
+}
+
+/* return != 0 to indicate the key was handles */
+static int process_special_keys(int *key, struct menu *menu)
+{
+       int i;
+
+       if (*key == KEY_RESIZE) {
+               setup_windows();
+               return 1;
+       }
+
+       for (i = 0; i < function_keys_num; i++) {
+               if (*key == KEY_F(function_keys[i].key) ||
+                   *key == '0' + function_keys[i].key){
+                       function_keys[i].handler(key, menu);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void clean_items(void)
+{
+       int i;
+       for (i = 0; curses_menu_items[i]; i++)
+               free_item(curses_menu_items[i]);
+       bzero(curses_menu_items, sizeof(curses_menu_items));
+       bzero(k_menu_items, sizeof(k_menu_items));
+       bzero(hotkeys, sizeof(hotkeys));
+       items_num = 0;
+}
+
+/* return the index of the next hot item, or -1 if no such item exists */
+static int get_next_hot(int c)
+{
+       static int hot_index;
+       static int hot_char;
+
+       if (c < 0 || c > 255 || hotkeys[c].count <= 0)
+               return -1;
+
+       if (hot_char == c) {
+               hot_index = (hot_index+1)%hotkeys[c].count;
+               return hotkeys[c].ptrs[hot_index];
+       } else {
+               hot_char = c;
+               hot_index = 0;
+               return hotkeys[c].ptrs[0];
+       }
+}
+
+/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
+static int canbhot(char c)
+{
+       c = tolower(c);
+       return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
+               c != 'n' && c != '?';
+}
+
+/* check if str already contains a hot key. */
+static int is_hot(int index)
+{
+       return k_menu_items[index].is_hot;
+}
+
+/* find the first possible hot key, and mark it.
+ * index is the index of the item in the menu
+ * return 0 on success*/
+static int make_hot(char *dest, int len, const char *org, int index)
+{
+       int position = -1;
+       int i;
+       int tmp;
+       int c;
+       int org_len = strlen(org);
+
+       if (org == NULL || is_hot(index))
+               return 1;
+
+       /* make sure not to make hot keys out of markers.
+        * find where to start looking for a hot key
+        */
+       i = 0;
+       /* skip white space */
+       while (i < org_len && org[i] == ' ')
+               i++;
+       if (i == org_len)
+               return -1;
+       /* if encountering '(' or '<' or '[', find the match and look from there
+        **/
+       if (org[i] == '[' || org[i] == '<' || org[i] == '(') {
+               i++;
+               for (; i < org_len; i++)
+                       if (org[i] == ']' || org[i] == '>' || org[i] == ')')
+                               break;
+       }
+       if (i == org_len)
+               return -1;
+       for (; i < org_len; i++) {
+               if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
+                       position = i;
+                       break;
+               }
+       }
+       if (position == -1)
+               return 1;
+
+       /* ok, char at org[position] should be a hot key to this item */
+       c = tolower(org[position]);
+       tmp = hotkeys[c].count;
+       hotkeys[c].ptrs[tmp] = index;
+       hotkeys[c].count++;
+       /*
+          snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
+          &org[position+1]);
+          */
+       /* make org[position] uppercase, and all leading letter small case */
+       strncpy(dest, org, len);
+       for (i = 0; i < position; i++)
+               dest[i] = tolower(dest[i]);
+       dest[position] = toupper(dest[position]);
+       k_menu_items[index].is_hot = 1;
+       return 0;
+}
+
+/* Make a new item. Add a hotkey mark in the first possible letter.
+ * As ncurses does not allow any attributes inside menue item, we mark the
+ * hot key as the first capitalized letter in the string */
+static void item_make(struct menu *menu, char tag, const char *fmt, ...)
+{
+       va_list ap;
+       char tmp_str[256];
+
+       if (items_num > MAX_MENU_ITEMS-1)
+               return;
+
+       bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
+       k_menu_items[items_num].tag = tag;
+       k_menu_items[items_num].usrptr = menu;
+       if (menu != NULL)
+               k_menu_items[items_num].is_visible =
+                       menu_is_visible(menu);
+       else
+               k_menu_items[items_num].is_visible = 1;
+
+       va_start(ap, fmt);
+       vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap);
+       if (!k_menu_items[items_num].is_visible)
+               memcpy(tmp_str, "XXX", 3);
+       va_end(ap);
+       if (make_hot(
+               k_menu_items[items_num].str,
+               sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0)
+               strncpy(k_menu_items[items_num].str,
+                       tmp_str,
+                       sizeof(k_menu_items[items_num].str));
+
+       curses_menu_items[items_num] = new_item(
+                       k_menu_items[items_num].str,
+                       k_menu_items[items_num].str);
+       set_item_userptr(curses_menu_items[items_num],
+                       &k_menu_items[items_num]);
+       /*
+       if (!k_menu_items[items_num].is_visible)
+               item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
+       */
+
+       items_num++;
+       curses_menu_items[items_num] = NULL;
+}
+
+/* very hackish. adds a string to the last item added */
+static void item_add_str(const char *fmt, ...)
+{
+       va_list ap;
+       int index = items_num-1;
+       char new_str[256];
+       char tmp_str[256];
+
+       if (index < 0)
+               return;
+
+       va_start(ap, fmt);
+       vsnprintf(new_str, sizeof(new_str), fmt, ap);
+       va_end(ap);
+       snprintf(tmp_str, sizeof(tmp_str), "%s%s",
+                       k_menu_items[index].str, new_str);
+       if (make_hot(k_menu_items[index].str,
+                       sizeof(k_menu_items[index].str), tmp_str, index) != 0)
+               strncpy(k_menu_items[index].str,
+                       tmp_str,
+                       sizeof(k_menu_items[index].str));
+
+       free_item(curses_menu_items[index]);
+       curses_menu_items[index] = new_item(
+                       k_menu_items[index].str,
+                       k_menu_items[index].str);
+       set_item_userptr(curses_menu_items[index],
+                       &k_menu_items[index]);
+}
+
+/* get the tag of the currently selected item */
+static char item_tag(void)
+{
+       ITEM *cur;
+       struct mitem *mcur;
+
+       cur = current_item(curses_menu);
+       if (cur == NULL)
+               return 0;
+       mcur = (struct mitem *) item_userptr(cur);
+       return mcur->tag;
+}
+
+static int curses_item_index(void)
+{
+       return  item_index(current_item(curses_menu));
+}
+
+static void *item_data(void)
+{
+       ITEM *cur;
+       struct mitem *mcur;
+
+       cur = current_item(curses_menu);
+       mcur = (struct mitem *) item_userptr(cur);
+       return mcur->usrptr;
+
+}
+
+static int item_is_tag(char tag)
+{
+       return item_tag() == tag;
+}
+
+static char filename[PATH_MAX+1];
+static char menu_backtitle[PATH_MAX+128];
+static const char *set_config_filename(const char *config_filename)
+{
+       int size;
+       struct symbol *sym;
+
+       sym = sym_lookup("KERNELVERSION", 0);
+       sym_calc_value(sym);
+       size = snprintf(menu_backtitle, sizeof(menu_backtitle),
+                       _("%s - Linux Kernel v%s Configuration"),
+                       config_filename, sym_get_string_value(sym));
+       if (size >= sizeof(menu_backtitle))
+               menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
+
+       size = snprintf(filename, sizeof(filename), "%s", config_filename);
+       if (size >= sizeof(filename))
+               filename[sizeof(filename)-1] = '\0';
+       return menu_backtitle;
+}
+
+/* command = 0 is supress, 1 is restore */
+static void supress_stdout(int command)
+{
+       static FILE *org_stdout;
+       static FILE *org_stderr;
+
+       if (command == 0) {
+               org_stdout = stdout;
+               org_stderr = stderr;
+               stdout = fopen("/dev/null", "a");
+               stderr = fopen("/dev/null", "a");
+       } else {
+               fclose(stdout);
+               fclose(stderr);
+               stdout = org_stdout;
+               stderr = org_stderr;
+       }
+}
+
+/* return = 0 means we are successful.
+ * -1 means go on doing what you were doing
+ */
+static int do_exit(void)
+{
+       int res;
+       if (!conf_get_changed()) {
+               global_exit = 1;
+               return 0;
+       }
+       res = btn_dialog(main_window,
+                       _("Do you wish to save your "
+                               "new kernel configuration?\n"
+                               "<ESC> to cancel and resume nconfig."),
+                       2,
+                       "   <save>   ",
+                       "<don't save>");
+       if (res == KEY_EXIT) {
+               global_exit = 0;
+               return -1;
+       }
+
+       /* if we got here, the user really wants to exit */
+       switch (res) {
+       case 0:
+               supress_stdout(0);
+               res = conf_write(filename);
+               supress_stdout(1);
+               if (res)
+                       btn_dialog(
+                               main_window,
+                               _("Error during writing of the kernel "
+                                 "configuration.\n"
+                                 "Your kernel configuration "
+                                 "changes were NOT saved."),
+                                 1,
+                                 "<OK>");
+               else {
+                       char buf[1024];
+                       snprintf(buf, 1024,
+                               _("Configuration written to %s\n"
+                                 "End of Linux kernel configuration.\n"
+                                 "Execute 'make' to build the kernel or try"
+                                 " 'make help'."), filename);
+                       btn_dialog(
+                               main_window,
+                               buf,
+                               1,
+                               "<OK>");
+               }
+               break;
+       default:
+               btn_dialog(
+                       main_window,
+                       _("Your kernel configuration changes were NOT saved."),
+                       1,
+                       "<OK>");
+               break;
+       }
+       global_exit = 1;
+       return 0;
+}
+
+
+static void search_conf(void)
+{
+       struct symbol **sym_arr;
+       struct gstr res;
+       char dialog_input_result[100];
+       char *dialog_input;
+       int dres;
+again:
+       dres = dialog_inputbox(main_window,
+                       _("Search Configuration Parameter"),
+                       _("Enter CONFIG_ (sub)string to search for "
+                               "(with or without \"CONFIG\")"),
+                       "", dialog_input_result, 99);
+       switch (dres) {
+       case 0:
+               break;
+       case 1:
+               show_scroll_win(main_window,
+                               _("Search Configuration"), search_help);
+               goto again;
+       default:
+               return;
+       }
+
+       /* strip CONFIG_ if necessary */
+       dialog_input = dialog_input_result;
+       if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
+               dialog_input += 7;
+
+       sym_arr = sym_re_search(dialog_input);
+       res = get_relations_str(sym_arr);
+       free(sym_arr);
+       show_scroll_win(main_window,
+                       _("Search Results"), str_get(&res));
+       str_free(&res);
+}
+
+
+static void build_conf(struct menu *menu)
+{
+       struct symbol *sym;
+       struct property *prop;
+       struct menu *child;
+       int type, tmp, doint = 2;
+       tristate val;
+       char ch;
+
+       if (!menu || (!show_all_items && !menu_is_visible(menu)))
+               return;
+
+       sym = menu->sym;
+       prop = menu->prompt;
+       if (!sym) {
+               if (prop && menu != current_menu) {
+                       const char *prompt = menu_get_prompt(menu);
+                       enum prop_type ptype;
+                       ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+                       switch (ptype) {
+                       case P_MENU:
+                               child_count++;
+                               prompt = _(prompt);
+                               if (single_menu_mode) {
+                                       item_make(menu, 'm',
+                                               "%s%*c%s",
+                                               menu->data ? "-->" : "++>",
+                                               indent + 1, ' ', prompt);
+                               } else
+                                       item_make(menu, 'm',
+                                               "   %*c%s  --->",
+                                               indent + 1,
+                                               ' ', prompt);
+
+                               if (single_menu_mode && menu->data)
+                                       goto conf_childs;
+                               return;
+                       case P_COMMENT:
+                               if (prompt) {
+                                       child_count++;
+                                       item_make(menu, ':',
+                                               "   %*c*** %s ***",
+                                               indent + 1, ' ',
+                                               _(prompt));
+                               }
+                               break;
+                       default:
+                               if (prompt) {
+                                       child_count++;
+                                       item_make(menu, ':', "---%*c%s",
+                                               indent + 1, ' ',
+                                               _(prompt));
+                               }
+                       }
+               } else
+                       doint = 0;
+               goto conf_childs;
+       }
+
+       type = sym_get_type(sym);
+       if (sym_is_choice(sym)) {
+               struct symbol *def_sym = sym_get_choice_value(sym);
+               struct menu *def_menu = NULL;
+
+               child_count++;
+               for (child = menu->list; child; child = child->next) {
+                       if (menu_is_visible(child) && child->sym == def_sym)
+                               def_menu = child;
+               }
+
+               val = sym_get_tristate_value(sym);
+               if (sym_is_changable(sym)) {
+                       switch (type) {
+                       case S_BOOLEAN:
+                               item_make(menu, 't', "[%c]",
+                                               val == no ? ' ' : '*');
+                               break;
+                       case S_TRISTATE:
+                               switch (val) {
+                               case yes:
+                                       ch = '*';
+                                       break;
+                               case mod:
+                                       ch = 'M';
+                                       break;
+                               default:
+                                       ch = ' ';
+                                       break;
+                               }
+                               item_make(menu, 't', "<%c>", ch);
+                               break;
+                       }
+               } else {
+                       item_make(menu, def_menu ? 't' : ':', "   ");
+               }
+
+               item_add_str("%*c%s", indent + 1,
+                               ' ', _(menu_get_prompt(menu)));
+               if (val == yes) {
+                       if (def_menu) {
+                               item_add_str(" (%s)",
+                                       _(menu_get_prompt(def_menu)));
+                               item_add_str("  --->");
+                               if (def_menu->list) {
+                                       indent += 2;
+                                       build_conf(def_menu);
+                                       indent -= 2;
+                               }
+                       }
+                       return;
+               }
+       } else {
+               if (menu == current_menu) {
+                       item_make(menu, ':',
+                               "---%*c%s", indent + 1,
+                               ' ', _(menu_get_prompt(menu)));
+                       goto conf_childs;
+               }
+               child_count++;
+               val = sym_get_tristate_value(sym);
+               if (sym_is_choice_value(sym) && val == yes) {
+                       item_make(menu, ':', "   ");
+               } else {
+                       switch (type) {
+                       case S_BOOLEAN:
+                               if (sym_is_changable(sym))
+                                       item_make(menu, 't', "[%c]",
+                                               val == no ? ' ' : '*');
+                               else
+                                       item_make(menu, 't', "-%c-",
+                                               val == no ? ' ' : '*');
+                               break;
+                       case S_TRISTATE:
+                               switch (val) {
+                               case yes:
+                                       ch = '*';
+                                       break;
+                               case mod:
+                                       ch = 'M';
+                                       break;
+                               default:
+                                       ch = ' ';
+                                       break;
+                               }
+                               if (sym_is_changable(sym)) {
+                                       if (sym->rev_dep.tri == mod)
+                                               item_make(menu,
+                                                       't', "{%c}", ch);
+                                       else
+                                               item_make(menu,
+                                                       't', "<%c>", ch);
+                               } else
+                                       item_make(menu, 't', "-%c-", ch);
+                               break;
+                       default:
+                               tmp = 2 + strlen(sym_get_string_value(sym));
+                               item_make(menu, 's', "    (%s)",
+                                               sym_get_string_value(sym));
+                               tmp = indent - tmp + 4;
+                               if (tmp < 0)
+                                       tmp = 0;
+                               item_add_str("%*c%s%s", tmp, ' ',
+                                               _(menu_get_prompt(menu)),
+                                               (sym_has_value(sym) ||
+                                                !sym_is_changable(sym)) ? "" :
+                                               _(" (NEW)"));
+                               goto conf_childs;
+                       }
+               }
+               item_add_str("%*c%s%s", indent + 1, ' ',
+                               _(menu_get_prompt(menu)),
+                               (sym_has_value(sym) || !sym_is_changable(sym)) ?
+                               "" : _(" (NEW)"));
+               if (menu->prompt && menu->prompt->type == P_MENU) {
+                       item_add_str("  --->");
+                       return;
+               }
+       }
+
+conf_childs:
+       indent += doint;
+       for (child = menu->list; child; child = child->next)
+               build_conf(child);
+       indent -= doint;
+}
+
+static void reset_menu(void)
+{
+       unpost_menu(curses_menu);
+       clean_items();
+}
+
+/* adjust the menu to show this item.
+ * prefer not to scroll the menu if possible*/
+static void center_item(int selected_index, int *last_top_row)
+{
+       int toprow;
+       int maxy, maxx;
+
+       scale_menu(curses_menu, &maxy, &maxx);
+       set_top_row(curses_menu, *last_top_row);
+       toprow = top_row(curses_menu);
+       if (selected_index >= toprow && selected_index < toprow+maxy) {
+               /* we can only move the selected item. no need to scroll */
+               set_current_item(curses_menu,
+                               curses_menu_items[selected_index]);
+       } else {
+               toprow = max(selected_index-maxy/2, 0);
+               if (toprow >= item_count(curses_menu)-maxy)
+                       toprow = item_count(curses_menu)-mwin_max_lines;
+               set_top_row(curses_menu, toprow);
+               set_current_item(curses_menu,
+                               curses_menu_items[selected_index]);
+       }
+       *last_top_row = toprow;
+       post_menu(curses_menu);
+       refresh_all_windows(main_window);
+}
+
+/* this function assumes reset_menu has been called before */
+static void show_menu(const char *prompt, const char *instructions,
+               int selected_index, int *last_top_row)
+{
+       int maxx, maxy;
+       WINDOW *menu_window;
+
+       current_instructions = instructions;
+
+       clear();
+       wattrset(main_window, attributes[NORMAL]);
+       print_in_middle(stdscr, 1, 0, COLS,
+                       menu_backtitle,
+                       attributes[MAIN_HEADING]);
+
+       wattrset(main_window, attributes[MAIN_MENU_BOX]);
+       box(main_window, 0, 0);
+       wattrset(main_window, attributes[MAIN_MENU_HEADING]);
+       mvwprintw(main_window, 0, 3, " %s ", prompt);
+       wattrset(main_window, attributes[NORMAL]);
+
+       set_menu_items(curses_menu, curses_menu_items);
+
+       /* position the menu at the middle of the screen */
+       scale_menu(curses_menu, &maxy, &maxx);
+       maxx = min(maxx, mwin_max_cols-2);
+       maxy = mwin_max_lines-2;
+       menu_window = derwin(main_window,
+                       maxy,
+                       maxx,
+                       2,
+                       (mwin_max_cols-maxx)/2);
+       keypad(menu_window, TRUE);
+       set_menu_win(curses_menu, menu_window);
+       set_menu_sub(curses_menu, menu_window);
+
+       /* must reassert this after changing items, otherwise returns to a
+        * default of 16
+        */
+       set_menu_format(curses_menu, maxy, 1);
+       center_item(selected_index, last_top_row);
+       set_menu_format(curses_menu, maxy, 1);
+
+       print_function_line();
+
+       /* Post the menu */
+       post_menu(curses_menu);
+       refresh_all_windows(main_window);
+}
+
+
+static void conf(struct menu *menu)
+{
+       char pattern[256];
+       struct menu *submenu = 0;
+       const char *prompt = menu_get_prompt(menu);
+       struct symbol *sym;
+       struct menu *active_menu = NULL;
+       int res;
+       int current_index = 0;
+       int last_top_row = 0;
+
+       bzero(pattern, sizeof(pattern));
+
+       while (!global_exit) {
+               reset_menu();
+               current_menu = menu;
+               build_conf(menu);
+               if (!child_count)
+                       break;
+
+               show_menu(prompt ? _(prompt) : _("Main Menu"),
+                               _(menu_instructions),
+                               current_index, &last_top_row);
+               keypad((menu_win(curses_menu)), TRUE);
+               while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
+                       if (process_special_keys(&res,
+                                               (struct menu *) item_data()))
+                               break;
+                       switch (res) {
+                       case KEY_DOWN:
+                               menu_driver(curses_menu, REQ_DOWN_ITEM);
+                               break;
+                       case KEY_UP:
+                               menu_driver(curses_menu, REQ_UP_ITEM);
+                               break;
+                       case KEY_NPAGE:
+                               menu_driver(curses_menu, REQ_SCR_DPAGE);
+                               break;
+                       case KEY_PPAGE:
+                               menu_driver(curses_menu, REQ_SCR_UPAGE);
+                               break;
+                       case KEY_HOME:
+                               menu_driver(curses_menu, REQ_FIRST_ITEM);
+                               break;
+                       case KEY_END:
+                               menu_driver(curses_menu, REQ_LAST_ITEM);
+                               break;
+                       case 'h':
+                       case '?':
+                               show_help((struct menu *) item_data());
+                               break;
+                       }
+                       if (res == 10 || res == 27 ||
+                               res == 32 || res == 'n' || res == 'y' ||
+                               res == KEY_LEFT || res == KEY_RIGHT ||
+                               res == 'm' || res == '/')
+                               break;
+                       else if (canbhot(res)) {
+                               /* check for hot keys: */
+                               int tmp = get_next_hot(res);
+                               if (tmp != -1)
+                                       center_item(tmp, &last_top_row);
+                       }
+                       refresh_all_windows(main_window);
+               }
+
+               refresh_all_windows(main_window);
+               /* if ESC  or left*/
+               if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
+                       break;
+
+               /* remember location in the menu */
+               last_top_row = top_row(curses_menu);
+               current_index = curses_item_index();
+
+               if (!item_tag())
+                       continue;
+
+               submenu = (struct menu *) item_data();
+               active_menu = (struct menu *)item_data();
+               if (!submenu || !menu_is_visible(submenu))
+                       continue;
+               if (submenu)
+                       sym = submenu->sym;
+               else
+                       sym = NULL;
+
+               switch (res) {
+               case ' ':
+                       if (item_is_tag('t'))
+                               sym_toggle_tristate_value(sym);
+                       else if (item_is_tag('m'))
+                               conf(submenu);
+                       break;
+               case KEY_RIGHT:
+               case 10: /* ENTER WAS PRESSED */
+                       switch (item_tag()) {
+                       case 'm':
+                               if (single_menu_mode)
+                                       submenu->data =
+                                               (void *) (long) !submenu->data;
+                               else
+                                       conf(submenu);
+                               break;
+                       case 't':
+                               if (sym_is_choice(sym) &&
+                                   sym_get_tristate_value(sym) == yes)
+                                       conf_choice(submenu);
+                               else if (submenu->prompt &&
+                                        submenu->prompt->type == P_MENU)
+                                       conf(submenu);
+                               else if (res == 10)
+                                       sym_toggle_tristate_value(sym);
+                               break;
+                       case 's':
+                               conf_string(submenu);
+                               break;
+                       }
+                       break;
+               case 'y':
+                       if (item_is_tag('t')) {
+                               if (sym_set_tristate_value(sym, yes))
+                                       break;
+                               if (sym_set_tristate_value(sym, mod))
+                                       btn_dialog(main_window, setmod_text, 0);
+                       }
+                       break;
+               case 'n':
+                       if (item_is_tag('t'))
+                               sym_set_tristate_value(sym, no);
+                       break;
+               case 'm':
+                       if (item_is_tag('t'))
+                               sym_set_tristate_value(sym, mod);
+                       break;
+               case '/':
+                       search_conf();
+                       break;
+               }
+       }
+}
+
+static void show_help(struct menu *menu)
+{
+       struct gstr help = str_new();
+
+       if (menu && menu->sym && menu_has_help(menu)) {
+               if (menu->sym->name) {
+                       str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
+                       str_append(&help, _(menu_get_help(menu)));
+                       str_append(&help, "\n");
+                       get_symbol_str(&help, menu->sym);
+               }
+       } else {
+               str_append(&help, nohelp_text);
+       }
+       show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
+       str_free(&help);
+}
+
+static void conf_choice(struct menu *menu)
+{
+       const char *prompt = _(menu_get_prompt(menu));
+       struct menu *child = 0;
+       struct symbol *active;
+       int selected_index = 0;
+       int last_top_row = 0;
+       int res, i = 0;
+
+       active = sym_get_choice_value(menu->sym);
+       /* this is mostly duplicated from the conf() function. */
+       while (!global_exit) {
+               reset_menu();
+
+               for (i = 0, child = menu->list; child; child = child->next) {
+                       if (!show_all_items && !menu_is_visible(child))
+                               continue;
+
+                       if (child->sym == sym_get_choice_value(menu->sym))
+                               item_make(child, ':', "<X> %s",
+                                               _(menu_get_prompt(child)));
+                       else
+                               item_make(child, ':', "    %s",
+                                               _(menu_get_prompt(child)));
+                       if (child->sym == active){
+                               last_top_row = top_row(curses_menu);
+                               selected_index = i;
+                       }
+                       i++;
+               }
+               show_menu(prompt ? _(prompt) : _("Choice Menu"),
+                               _(radiolist_instructions),
+                               selected_index,
+                               &last_top_row);
+               while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
+                       if (process_special_keys(
+                                               &res,
+                                               (struct menu *) item_data()))
+                               break;
+                       switch (res) {
+                       case KEY_DOWN:
+                               menu_driver(curses_menu, REQ_DOWN_ITEM);
+                               break;
+                       case KEY_UP:
+                               menu_driver(curses_menu, REQ_UP_ITEM);
+                               break;
+                       case KEY_NPAGE:
+                               menu_driver(curses_menu, REQ_SCR_DPAGE);
+                               break;
+                       case KEY_PPAGE:
+                               menu_driver(curses_menu, REQ_SCR_UPAGE);
+                               break;
+                       case KEY_HOME:
+                               menu_driver(curses_menu, REQ_FIRST_ITEM);
+                               break;
+                       case KEY_END:
+                               menu_driver(curses_menu, REQ_LAST_ITEM);
+                               break;
+                       case 'h':
+                       case '?':
+                               show_help((struct menu *) item_data());
+                               break;
+                       }
+                       if (res == 10 || res == 27 || res == ' ' ||
+                               res == KEY_LEFT)
+                               break;
+                       else if (canbhot(res)) {
+                               /* check for hot keys: */
+                               int tmp = get_next_hot(res);
+                               if (tmp != -1)
+                                       center_item(tmp, &last_top_row);
+                       }
+                       refresh_all_windows(main_window);
+               }
+               /* if ESC or left */
+               if (res == 27 || res == KEY_LEFT)
+                       break;
+
+               child = item_data();
+               if (!child || !menu_is_visible(child))
+                       continue;
+               switch (res) {
+               case ' ':
+               case  10:
+               case KEY_RIGHT:
+                       sym_set_tristate_value(child->sym, yes);
+                       return;
+               case 'h':
+               case '?':
+                       show_help(child);
+                       active = child->sym;
+                       break;
+               case KEY_EXIT:
+                       return;
+               }
+       }
+}
+
+static void conf_string(struct menu *menu)
+{
+       const char *prompt = menu_get_prompt(menu);
+       char dialog_input_result[256];
+
+       while (1) {
+               int res;
+               const char *heading;
+
+               switch (sym_get_type(menu->sym)) {
+               case S_INT:
+                       heading = _(inputbox_instructions_int);
+                       break;
+               case S_HEX:
+                       heading = _(inputbox_instructions_hex);
+                       break;
+               case S_STRING:
+                       heading = _(inputbox_instructions_string);
+                       break;
+               default:
+                       heading = _("Internal nconf error!");
+               }
+               res = dialog_inputbox(main_window,
+                               prompt ? _(prompt) : _("Main Menu"),
+                               heading,
+                               sym_get_string_value(menu->sym),
+                               dialog_input_result,
+                               sizeof(dialog_input_result));
+               switch (res) {
+               case 0:
+                       if (sym_set_string_value(menu->sym,
+                                               dialog_input_result))
+                               return;
+                       btn_dialog(main_window,
+                               _("You have made an invalid entry."), 0);
+                       break;
+               case 1:
+                       show_help(menu);
+                       break;
+               case KEY_EXIT:
+                       return;
+               }
+       }
+}
+
+static void conf_load(void)
+{
+       char dialog_input_result[256];
+       while (1) {
+               int res;
+               res = dialog_inputbox(main_window,
+                               NULL, load_config_text,
+                               filename,
+                               dialog_input_result,
+                               sizeof(dialog_input_result));
+               switch (res) {
+               case 0:
+                       if (!dialog_input_result[0])
+                               return;
+                       if (!conf_read(dialog_input_result)) {
+                               set_config_filename(dialog_input_result);
+                               sym_set_change_count(1);
+                               return;
+                       }
+                       btn_dialog(main_window, _("File does not exist!"), 0);
+                       break;
+               case 1:
+                       show_scroll_win(main_window,
+                                       _("Load Alternate Configuration"),
+                                       load_config_help);
+                       break;
+               case KEY_EXIT:
+                       return;
+               }
+       }
+}
+
+static void conf_save(void)
+{
+       char dialog_input_result[256];
+       while (1) {
+               int res;
+               res = dialog_inputbox(main_window,
+                               NULL, save_config_text,
+                               filename,
+                               dialog_input_result,
+                               sizeof(dialog_input_result));
+               switch (res) {
+               case 0:
+                       if (!dialog_input_result[0])
+                               return;
+                       supress_stdout(0);
+                       res = conf_write(dialog_input_result);
+                       supress_stdout(1);
+                       if (!res) {
+                               char buf[1024];
+                               sprintf(buf, "%s %s",
+                                       _("configuration file saved to: "),
+                                       dialog_input_result);
+                               btn_dialog(main_window,
+                                          buf, 1, "<OK>");
+                               set_config_filename(dialog_input_result);
+                               return;
+                       }
+                       btn_dialog(main_window, _("Can't create file! "
+                               "Probably a nonexistent directory."),
+                               1, "<OK>");
+                       break;
+               case 1:
+                       show_scroll_win(main_window,
+                               _("Save Alternate Configuration"),
+                               save_config_help);
+                       break;
+               case KEY_EXIT:
+                       return;
+               }
+       }
+}
+
+void setup_windows(void)
+{
+       if (main_window != NULL)
+               delwin(main_window);
+
+       /* set up the menu and menu window */
+       main_window = newwin(LINES-2, COLS-2, 2, 1);
+       keypad(main_window, TRUE);
+       mwin_max_lines = LINES-6;
+       mwin_max_cols = COLS-6;
+
+       /* panels order is from bottom to top */
+       new_panel(main_window);
+}
+
+int main(int ac, char **av)
+{
+       char *mode;
+
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+
+       conf_parse(av[1]);
+       conf_read(NULL);
+
+       mode = getenv("NCONFIG_MODE");
+       if (mode) {
+               if (!strcasecmp(mode, "single_menu"))
+                       single_menu_mode = 1;
+       }
+
+       /* Initialize curses */
+       initscr();
+       /* set color theme */
+       set_colors();
+
+       cbreak();
+       noecho();
+       keypad(stdscr, TRUE);
+       curs_set(0);
+
+       if (COLS < 75 || LINES < 20) {
+               endwin();
+               printf("Your terminal should have at "
+                       "least 20 lines and 75 columns\n");
+               return 1;
+       }
+
+       notimeout(stdscr, FALSE);
+       ESCDELAY = 1;
+
+       /* set btns menu */
+       curses_menu = new_menu(curses_menu_items);
+       menu_opts_off(curses_menu, O_SHOWDESC);
+       menu_opts_off(curses_menu, O_SHOWMATCH);
+       menu_opts_on(curses_menu, O_ONEVALUE);
+       menu_opts_on(curses_menu, O_NONCYCLIC);
+       set_menu_mark(curses_menu, " ");
+       set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
+       set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
+       set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
+
+       set_config_filename(conf_get_configname());
+       setup_windows();
+
+       /* check for KEY_FUNC(1) */
+       if (has_key(KEY_F(1)) == FALSE) {
+               show_scroll_win(main_window,
+                               _("Instructions"),
+                               _(menu_no_f_instructions));
+       }
+
+
+
+       /* do the work */
+       while (!global_exit) {
+               conf(&rootmenu);
+               if (!global_exit && do_exit() == 0)
+                       break;
+       }
+       /* ok, we are done */
+       unpost_menu(curses_menu);
+       free_menu(curses_menu);
+       delwin(main_window);
+       clear();
+       refresh();
+       endwin();
+       return 0;
+}
+
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
new file mode 100644 (file)
index 0000000..115edb4
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * Derived from menuconfig.
+ *
+ */
+#include "nconf.h"
+
+/* a list of all the different widgets we use */
+attributes_t attributes[ATTR_MAX+1] = {0};
+
+/* available colors:
+   COLOR_BLACK   0
+   COLOR_RED     1
+   COLOR_GREEN   2
+   COLOR_YELLOW  3
+   COLOR_BLUE    4
+   COLOR_MAGENTA 5
+   COLOR_CYAN    6
+   COLOR_WHITE   7
+   */
+static void set_normal_colors(void)
+{
+       init_pair(NORMAL, -1, -1);
+       init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
+
+       /* FORE is for the selected item */
+       init_pair(MAIN_MENU_FORE, -1, -1);
+       /* BACK for all the rest */
+       init_pair(MAIN_MENU_BACK, -1, -1);
+       init_pair(MAIN_MENU_GREY, -1, -1);
+       init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
+       init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
+
+       init_pair(SCROLLWIN_TEXT, -1, -1);
+       init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
+       init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
+
+       init_pair(DIALOG_TEXT, -1, -1);
+       init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
+       init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
+       init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
+
+       init_pair(INPUT_BOX, COLOR_YELLOW, -1);
+       init_pair(INPUT_HEADING, COLOR_GREEN, -1);
+       init_pair(INPUT_TEXT, -1, -1);
+       init_pair(INPUT_FIELD, -1, -1);
+
+       init_pair(FUNCTION_HIGHLIGHT, -1, -1);
+       init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
+}
+
+/* available attributes:
+   A_NORMAL        Normal display (no highlight)
+   A_STANDOUT      Best highlighting mode of the terminal.
+   A_UNDERLINE     Underlining
+   A_REVERSE       Reverse video
+   A_BLINK         Blinking
+   A_DIM           Half bright
+   A_BOLD          Extra bright or bold
+   A_PROTECT       Protected mode
+   A_INVIS         Invisible or blank mode
+   A_ALTCHARSET    Alternate character set
+   A_CHARTEXT      Bit-mask to extract a character
+   COLOR_PAIR(n)   Color-pair number n
+   */
+static void normal_color_theme(void)
+{
+       /* automatically add color... */
+#define mkattr(name, attr) do { \
+attributes[name] = attr | COLOR_PAIR(name); } while (0)
+       mkattr(NORMAL, NORMAL);
+       mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
+
+       mkattr(MAIN_MENU_FORE, A_REVERSE);
+       mkattr(MAIN_MENU_BACK, A_NORMAL);
+       mkattr(MAIN_MENU_GREY, A_NORMAL);
+       mkattr(MAIN_MENU_HEADING, A_BOLD);
+       mkattr(MAIN_MENU_BOX, A_NORMAL);
+
+       mkattr(SCROLLWIN_TEXT, A_NORMAL);
+       mkattr(SCROLLWIN_HEADING, A_BOLD);
+       mkattr(SCROLLWIN_BOX, A_BOLD);
+
+       mkattr(DIALOG_TEXT, A_BOLD);
+       mkattr(DIALOG_BOX, A_BOLD);
+       mkattr(DIALOG_MENU_FORE, A_STANDOUT);
+       mkattr(DIALOG_MENU_BACK, A_NORMAL);
+
+       mkattr(INPUT_BOX, A_NORMAL);
+       mkattr(INPUT_HEADING, A_BOLD);
+       mkattr(INPUT_TEXT, A_NORMAL);
+       mkattr(INPUT_FIELD, A_UNDERLINE);
+
+       mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
+       mkattr(FUNCTION_TEXT, A_REVERSE);
+}
+
+static void no_colors_theme(void)
+{
+       /* automatically add highlight, no color */
+#define mkattrn(name, attr) { attributes[name] = attr; }
+
+       mkattrn(NORMAL, NORMAL);
+       mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
+
+       mkattrn(MAIN_MENU_FORE, A_STANDOUT);
+       mkattrn(MAIN_MENU_BACK, A_NORMAL);
+       mkattrn(MAIN_MENU_GREY, A_NORMAL);
+       mkattrn(MAIN_MENU_HEADING, A_BOLD);
+       mkattrn(MAIN_MENU_BOX, A_NORMAL);
+
+       mkattrn(SCROLLWIN_TEXT, A_NORMAL);
+       mkattrn(SCROLLWIN_HEADING, A_BOLD);
+       mkattrn(SCROLLWIN_BOX, A_BOLD);
+
+       mkattrn(DIALOG_TEXT, A_NORMAL);
+       mkattrn(DIALOG_BOX, A_BOLD);
+       mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
+       mkattrn(DIALOG_MENU_BACK, A_NORMAL);
+
+       mkattrn(INPUT_BOX, A_BOLD);
+       mkattrn(INPUT_HEADING, A_BOLD);
+       mkattrn(INPUT_TEXT, A_NORMAL);
+       mkattrn(INPUT_FIELD, A_UNDERLINE);
+
+       mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
+       mkattrn(FUNCTION_TEXT, A_REVERSE);
+}
+
+void set_colors()
+{
+       start_color();
+       use_default_colors();
+       set_normal_colors();
+       if (has_colors()) {
+               normal_color_theme();
+       } else {
+               /* give deafults */
+               no_colors_theme();
+       }
+}
+
+
+/* this changes the windows attributes !!! */
+void print_in_middle(WINDOW *win,
+               int starty,
+               int startx,
+               int width,
+               const char *string,
+               chtype color)
+{      int length, x, y;
+       float temp;
+
+
+       if (win == NULL)
+               win = stdscr;
+       getyx(win, y, x);
+       if (startx != 0)
+               x = startx;
+       if (starty != 0)
+               y = starty;
+       if (width == 0)
+               width = 80;
+
+       length = strlen(string);
+       temp = (width - length) / 2;
+       x = startx + (int)temp;
+       wattrset(win, color);
+       mvwprintw(win, y, x, "%s", string);
+       refresh();
+}
+
+int get_line_no(const char *text)
+{
+       int i;
+       int total = 1;
+
+       if (!text)
+               return 0;
+
+       for (i = 0; text[i] != '\0'; i++)
+               if (text[i] == '\n')
+                       total++;
+       return total;
+}
+
+const char *get_line(const char *text, int line_no)
+{
+       int i;
+       int lines = 0;
+
+       if (!text)
+               return 0;
+
+       for (i = 0; text[i] != '\0' && lines < line_no; i++)
+               if (text[i] == '\n')
+                       lines++;
+       return text+i;
+}
+
+int get_line_length(const char *line)
+{
+       int res = 0;
+       while (*line != '\0' && *line != '\n') {
+               line++;
+               res++;
+       }
+       return res;
+}
+
+/* print all lines to the window. */
+void fill_window(WINDOW *win, const char *text)
+{
+       int x, y;
+       int total_lines = get_line_no(text);
+       int i;
+
+       getmaxyx(win, y, x);
+       /* do not go over end of line */
+       total_lines = min(total_lines, y);
+       for (i = 0; i < total_lines; i++) {
+               char tmp[x+10];
+               const char *line = get_line(text, i);
+               int len = get_line_length(line);
+               strncpy(tmp, line, min(len, x));
+               tmp[len] = '\0';
+               mvwprintw(win, i, 0, tmp);
+       }
+}
+
+/* get the message, and buttons.
+ * each button must be a char*
+ * return the selected button
+ *
+ * this dialog is used for 2 different things:
+ * 1) show a text box, no buttons.
+ * 2) show a dialog, with horizontal buttons
+ */
+int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
+{
+       va_list ap;
+       char *btn;
+       int btns_width = 0;
+       int msg_lines = 0;
+       int msg_width = 0;
+       int total_width;
+       int win_rows = 0;
+       WINDOW *win;
+       WINDOW *msg_win;
+       WINDOW *menu_win;
+       MENU *menu;
+       ITEM *btns[btn_num+1];
+       int i, x, y;
+       int res = -1;
+
+
+       va_start(ap, btn_num);
+       for (i = 0; i < btn_num; i++) {
+               btn = va_arg(ap, char *);
+               btns[i] = new_item(btn, "");
+               btns_width += strlen(btn)+1;
+       }
+       va_end(ap);
+       btns[btn_num] = NULL;
+
+       /* find the widest line of msg: */
+       msg_lines = get_line_no(msg);
+       for (i = 0; i < msg_lines; i++) {
+               const char *line = get_line(msg, i);
+               int len = get_line_length(line);
+               if (msg_width < len)
+                       msg_width = len;
+       }
+
+       total_width = max(msg_width, btns_width);
+       /* place dialog in middle of screen */
+       y = (LINES-(msg_lines+4))/2;
+       x = (COLS-(total_width+4))/2;
+
+
+       /* create the windows */
+       if (btn_num > 0)
+               win_rows = msg_lines+4;
+       else
+               win_rows = msg_lines+2;
+
+       win = newwin(win_rows, total_width+4, y, x);
+       keypad(win, TRUE);
+       menu_win = derwin(win, 1, btns_width, win_rows-2,
+                       1+(total_width+2-btns_width)/2);
+       menu = new_menu(btns);
+       msg_win = derwin(win, win_rows-2, msg_width, 1,
+                       1+(total_width+2-msg_width)/2);
+
+       set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
+       set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
+
+       wattrset(win, attributes[DIALOG_BOX]);
+       box(win, 0, 0);
+
+       /* print message */
+       wattrset(msg_win, attributes[DIALOG_TEXT]);
+       fill_window(msg_win, msg);
+
+       set_menu_win(menu, win);
+       set_menu_sub(menu, menu_win);
+       set_menu_format(menu, 1, btn_num);
+       menu_opts_off(menu, O_SHOWDESC);
+       menu_opts_off(menu, O_SHOWMATCH);
+       menu_opts_on(menu, O_ONEVALUE);
+       menu_opts_on(menu, O_NONCYCLIC);
+       set_menu_mark(menu, "");
+       post_menu(menu);
+
+
+       touchwin(win);
+       refresh_all_windows(main_window);
+       while ((res = wgetch(win))) {
+               switch (res) {
+               case KEY_LEFT:
+                       menu_driver(menu, REQ_LEFT_ITEM);
+                       break;
+               case KEY_RIGHT:
+                       menu_driver(menu, REQ_RIGHT_ITEM);
+                       break;
+               case 10: /* ENTER */
+               case 27: /* ESCAPE */
+               case ' ':
+               case KEY_F(F_BACK):
+               case KEY_F(F_EXIT):
+                       break;
+               }
+               touchwin(win);
+               refresh_all_windows(main_window);
+
+               if (res == 10 || res == ' ') {
+                       res = item_index(current_item(menu));
+                       break;
+               } else if (res == 27 || res == KEY_F(F_BACK) ||
+                               res == KEY_F(F_EXIT)) {
+                       res = KEY_EXIT;
+                       break;
+               }
+       }
+
+       unpost_menu(menu);
+       free_menu(menu);
+       for (i = 0; i < btn_num; i++)
+               free_item(btns[i]);
+
+       delwin(win);
+       return res;
+}
+
+int dialog_inputbox(WINDOW *main_window,
+               const char *title, const char *prompt,
+               const char *init, char *result, int result_len)
+{
+       int prompt_lines = 0;
+       int prompt_width = 0;
+       WINDOW *win;
+       WINDOW *prompt_win;
+       WINDOW *form_win;
+       PANEL *panel;
+       int i, x, y;
+       int res = -1;
+       int cursor_position = strlen(init);
+
+
+       /* find the widest line of msg: */
+       prompt_lines = get_line_no(prompt);
+       for (i = 0; i < prompt_lines; i++) {
+               const char *line = get_line(prompt, i);
+               int len = get_line_length(line);
+               prompt_width = max(prompt_width, len);
+       }
+
+       if (title)
+               prompt_width = max(prompt_width, strlen(title));
+
+       /* place dialog in middle of screen */
+       y = (LINES-(prompt_lines+4))/2;
+       x = (COLS-(prompt_width+4))/2;
+
+       strncpy(result, init, result_len);
+
+       /* create the windows */
+       win = newwin(prompt_lines+6, prompt_width+7, y, x);
+       prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
+       form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
+       keypad(form_win, TRUE);
+
+       wattrset(form_win, attributes[INPUT_FIELD]);
+
+       wattrset(win, attributes[INPUT_BOX]);
+       box(win, 0, 0);
+       wattrset(win, attributes[INPUT_HEADING]);
+       if (title)
+               mvwprintw(win, 0, 3, "%s", title);
+
+       /* print message */
+       wattrset(prompt_win, attributes[INPUT_TEXT]);
+       fill_window(prompt_win, prompt);
+
+       mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
+       mvwprintw(form_win, 0, 0, "%s", result);
+
+       /* create panels */
+       panel = new_panel(win);
+
+       /* show the cursor */
+       curs_set(1);
+
+       touchwin(win);
+       refresh_all_windows(main_window);
+       while ((res = wgetch(form_win))) {
+               int len = strlen(result);
+               switch (res) {
+               case 10: /* ENTER */
+               case 27: /* ESCAPE */
+               case KEY_F(F_HELP):
+               case KEY_F(F_EXIT):
+               case KEY_F(F_BACK):
+                       break;
+               case 127:
+               case KEY_BACKSPACE:
+                       if (cursor_position > 0) {
+                               memmove(&result[cursor_position-1],
+                                               &result[cursor_position],
+                                               len-cursor_position+1);
+                               cursor_position--;
+                       }
+                       break;
+               case KEY_DC:
+                       if (cursor_position >= 0 && cursor_position < len) {
+                               memmove(&result[cursor_position],
+                                               &result[cursor_position+1],
+                                               len-cursor_position+1);
+                       }
+                       break;
+               case KEY_UP:
+               case KEY_RIGHT:
+                       if (cursor_position < len &&
+                           cursor_position < min(result_len, prompt_width))
+                               cursor_position++;
+                       break;
+               case KEY_DOWN:
+               case KEY_LEFT:
+                       if (cursor_position > 0)
+                               cursor_position--;
+                       break;
+               default:
+                       if ((isgraph(res) || isspace(res)) &&
+                                       len-2 < result_len) {
+                               /* insert the char at the proper position */
+                               memmove(&result[cursor_position+1],
+                                               &result[cursor_position],
+                                               len+1);
+                               result[cursor_position] = res;
+                               cursor_position++;
+                       } else {
+                               mvprintw(0, 0, "unknow key: %d\n", res);
+                       }
+                       break;
+               }
+               wmove(form_win, 0, 0);
+               wclrtoeol(form_win);
+               mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
+               mvwprintw(form_win, 0, 0, "%s", result);
+               wmove(form_win, 0, cursor_position);
+               touchwin(win);
+               refresh_all_windows(main_window);
+
+               if (res == 10) {
+                       res = 0;
+                       break;
+               } else if (res == 27 || res == KEY_F(F_BACK) ||
+                               res == KEY_F(F_EXIT)) {
+                       res = KEY_EXIT;
+                       break;
+               } else if (res == KEY_F(F_HELP)) {
+                       res = 1;
+                       break;
+               }
+       }
+
+       /* hide the cursor */
+       curs_set(0);
+       del_panel(panel);
+       delwin(prompt_win);
+       delwin(form_win);
+       delwin(win);
+       return res;
+}
+
+/* refresh all windows in the correct order */
+void refresh_all_windows(WINDOW *main_window)
+{
+       update_panels();
+       touchwin(main_window);
+       refresh();
+}
+
+/* layman's scrollable window... */
+void show_scroll_win(WINDOW *main_window,
+               const char *title,
+               const char *text)
+{
+       int res;
+       int total_lines = get_line_no(text);
+       int x, y;
+       int start_x = 0, start_y = 0;
+       int text_lines = 0, text_cols = 0;
+       int total_cols = 0;
+       int win_cols = 0;
+       int win_lines = 0;
+       int i = 0;
+       WINDOW *win;
+       WINDOW *pad;
+       PANEL *panel;
+
+       /* find the widest line of msg: */
+       total_lines = get_line_no(text);
+       for (i = 0; i < total_lines; i++) {
+               const char *line = get_line(text, i);
+               int len = get_line_length(line);
+               total_cols = max(total_cols, len+2);
+       }
+
+       /* create the pad */
+       pad = newpad(total_lines+10, total_cols+10);
+       wattrset(pad, attributes[SCROLLWIN_TEXT]);
+       fill_window(pad, text);
+
+       win_lines = min(total_lines+4, LINES-2);
+       win_cols = min(total_cols+2, COLS-2);
+       text_lines = max(win_lines-4, 0);
+       text_cols = max(win_cols-2, 0);
+
+       /* place window in middle of screen */
+       y = (LINES-win_lines)/2;
+       x = (COLS-win_cols)/2;
+
+       win = newwin(win_lines, win_cols, y, x);
+       keypad(win, TRUE);
+       /* show the help in the help window, and show the help panel */
+       wattrset(win, attributes[SCROLLWIN_BOX]);
+       box(win, 0, 0);
+       wattrset(win, attributes[SCROLLWIN_HEADING]);
+       mvwprintw(win, 0, 3, " %s ", title);
+       panel = new_panel(win);
+
+       /* handle scrolling */
+       do {
+
+               copywin(pad, win, start_y, start_x, 2, 2, text_lines,
+                               text_cols, 0);
+               print_in_middle(win,
+                               text_lines+2,
+                               0,
+                               text_cols,
+                               "<OK>",
+                               attributes[DIALOG_MENU_FORE]);
+               wrefresh(win);
+
+               res = wgetch(win);
+               switch (res) {
+               case KEY_NPAGE:
+               case ' ':
+                       start_y += text_lines-2;
+                       break;
+               case KEY_PPAGE:
+                       start_y -= text_lines+2;
+                       break;
+               case KEY_HOME:
+                       start_y = 0;
+                       break;
+               case KEY_END:
+                       start_y = total_lines-text_lines;
+                       break;
+               case KEY_DOWN:
+               case 'j':
+                       start_y++;
+                       break;
+               case KEY_UP:
+               case 'k':
+                       start_y--;
+                       break;
+               case KEY_LEFT:
+               case 'h':
+                       start_x--;
+                       break;
+               case KEY_RIGHT:
+               case 'l':
+                       start_x++;
+                       break;
+               }
+               if (res == 10 || res == 27 || res == 'q'
+                   || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
+                       break;
+               }
+               if (start_y < 0)
+                       start_y = 0;
+               if (start_y >= total_lines-text_lines)
+                       start_y = total_lines-text_lines;
+               if (start_x < 0)
+                       start_x = 0;
+               if (start_x >= total_cols-text_cols)
+                       start_x = total_cols-text_cols;
+       } while (res);
+
+       del_panel(panel);
+       delwin(win);
+       refresh_all_windows(main_window);
+}
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
new file mode 100644 (file)
index 0000000..fb42966
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * Derived from menuconfig.
+ *
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <locale.h>
+#include <curses.h>
+#include <menu.h>
+#include <panel.h>
+#include <form.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include "ncurses.h"
+
+#define max(a, b) ({\
+               typeof(a) _a = a;\
+               typeof(b) _b = b;\
+               _a > _b ? _a : _b; })
+
+#define min(a, b) ({\
+               typeof(a) _a = a;\
+               typeof(b) _b = b;\
+               _a < _b ? _a : _b; })
+
+typedef enum {
+       NORMAL = 1,
+       MAIN_HEADING,
+       MAIN_MENU_BOX,
+       MAIN_MENU_FORE,
+       MAIN_MENU_BACK,
+       MAIN_MENU_GREY,
+       MAIN_MENU_HEADING,
+       SCROLLWIN_TEXT,
+       SCROLLWIN_HEADING,
+       SCROLLWIN_BOX,
+       DIALOG_TEXT,
+       DIALOG_MENU_FORE,
+       DIALOG_MENU_BACK,
+       DIALOG_BOX,
+       INPUT_BOX,
+       INPUT_HEADING,
+       INPUT_TEXT,
+       INPUT_FIELD,
+       FUNCTION_TEXT,
+       FUNCTION_HIGHLIGHT,
+       ATTR_MAX
+} attributes_t;
+extern attributes_t attributes[];
+
+typedef enum {
+       F_HELP = 1,
+       F_SYMBOL = 2,
+       F_INSTS = 3,
+       F_CONF = 4,
+       F_BACK = 5,
+       F_SAVE = 6,
+       F_LOAD = 7,
+       F_EXIT = 8
+} function_key;
+
+void set_colors(void);
+
+/* this changes the windows attributes !!! */
+void print_in_middle(WINDOW *win,
+               int starty,
+               int startx,
+               int width,
+               const char *string,
+               chtype color);
+int get_line_length(const char *line);
+int get_line_no(const char *text);
+const char *get_line(const char *text, int line_no);
+void fill_window(WINDOW *win, const char *text);
+int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
+int dialog_inputbox(WINDOW *main_window,
+               const char *title, const char *prompt,
+               const char *init, char *result, int result_len);
+void refresh_all_windows(WINDOW *main_window);
+void show_scroll_win(WINDOW *main_window,
+               const char *title,
+               const char *text);
index 6c8fbbb66ebcaddefff183696d1c5d89bc2d6c09..2e7a048e0cfceb32970d4d0a6fa8b211d70ef83e 100644 (file)
@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym)
        return sym->visible > sym->rev_dep.tri;
 }
 
+static unsigned strhash(const char *s)
+{
+       /* fnv32 hash */
+       unsigned hash = 2166136261U;
+       for (; *s; s++)
+               hash = (hash ^ *s) * 0x01000193;
+       return hash;
+}
+
 struct symbol *sym_lookup(const char *name, int flags)
 {
        struct symbol *symbol;
-       const char *ptr;
        char *new_name;
-       int hash = 0;
+       int hash;
 
        if (name) {
                if (name[0] && !name[1]) {
@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags)
                        case 'n': return &symbol_no;
                        }
                }
-               for (ptr = name; *ptr; ptr++)
-                       hash += *ptr;
-               hash &= 0xff;
+               hash = strhash(name) % SYMBOL_HASHSIZE;
 
                for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
-                       if (!strcmp(symbol->name, name) &&
+                       if (symbol->name &&
+                           !strcmp(symbol->name, name) &&
                            (flags ? symbol->flags & flags
                                   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
                                return symbol;
@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags)
                new_name = strdup(name);
        } else {
                new_name = NULL;
-               hash = 256;
+               hash = 0;
        }
 
        symbol = malloc(sizeof(*symbol));
@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags)
 struct symbol *sym_find(const char *name)
 {
        struct symbol *symbol = NULL;
-       const char *ptr;
        int hash = 0;
 
        if (!name)
@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name)
                case 'n': return &symbol_no;
                }
        }
-       for (ptr = name; *ptr; ptr++)
-               hash += *ptr;
-       hash &= 0xff;
+       hash = strhash(name) % SYMBOL_HASHSIZE;
 
        for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
-               if (!strcmp(symbol->name, name) &&
+               if (symbol->name &&
+                   !strcmp(symbol->name, name) &&
                    !(symbol->flags & SYMBOL_CONST))
                                break;
        }
@@ -750,6 +755,7 @@ struct symbol **sym_re_search(const char *pattern)
                                return NULL;
                        }
                }
+               sym_calc_value(sym);
                sym_arr[cnt++] = sym;
        }
        if (sym_arr)
index 25d1ec4ca28a0e5ed3090291df8f2f67e2a20b4b..78b5c04e736bcfad3f25d7f85fe2b5660572cb52 100644 (file)
@@ -78,6 +78,7 @@ struct gstr str_new(void)
        struct gstr gs;
        gs.s = malloc(sizeof(char) * 64);
        gs.len = 64;
+       gs.max_width = 0;
        strcpy(gs.s, "\0");
        return gs;
 }
@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s)
        struct gstr gs;
        gs.s = strdup(s);
        gs.len = strlen(s) + 1;
+       gs.max_width = 0;
        return gs;
 }
 
index 6e9dcd59aa87c5cc53378b9a789aad92fdf1d5f6..32a9eefd842cb132322045ec45d360abdd3b141a 100644 (file)
@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...);
 static void zconferror(const char *err);
 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 
-struct symbol *symbol_hash[257];
+struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 static struct menu *current_menu, *current_entry;
 
@@ -2220,7 +2220,7 @@ void conf_parse(const char *name)
        zconf_initscan(name);
 
        sym_init();
-       menu_init();
+       _menu_init();
        modules_sym = sym_lookup(NULL, 0);
        modules_sym->type = S_BOOLEAN;
        modules_sym->flags |= SYMBOL_AUTO;
@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu)
        struct property *prop;
 
        if (sym_is_choice(sym))
-               fprintf(out, "choice\n");
+               fprintf(out, "\nchoice\n");
        else
-               fprintf(out, "config %s\n", sym->name);
+               fprintf(out, "\nconfig %s\n", sym->name);
        switch (sym->type) {
        case S_BOOLEAN:
                fputs("  boolean\n", out);
@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu)
                case P_CHOICE:
                        fputs("  #choice value\n", out);
                        break;
+               case P_SELECT:
+                       fputs( "  select ", out);
+                       expr_fprint(prop->expr, out);
+                       fputc('\n', out);
+                       break;
+               case P_RANGE:
+                       fputs( "  range ", out);
+                       expr_fprint(prop->expr, out);
+                       fputc('\n', out);
+                       break;
+               case P_MENU:
+                       fputs( "  menu ", out);
+                       print_quoted_string(out, prop->text);
+                       fputc('\n', out);
+                       break;
                default:
                        fprintf(out, "  unknown prop %d!\n", prop->type);
                        break;
@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu)
                        menu->help[len] = 0;
                fprintf(out, "  help\n%s\n", menu->help);
        }
-       fputc('\n', out);
 }
 
 void zconfdump(FILE *out)
@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out)
                                expr_fprint(prop->visible.expr, out);
                                fputc('\n', out);
                        }
-                       fputs("\n", out);
                }
 
                if (menu->list)
index 8c43491f8cc9635cde61b9f80a98598a77948d75..23dfd3baa7a1ba906c80a0df0383fbfcf8979bad 100644 (file)
@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...);
 static void zconferror(const char *err);
 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
 
-struct symbol *symbol_hash[257];
+struct symbol *symbol_hash[SYMBOL_HASHSIZE];
 
 static struct menu *current_menu, *current_entry;
 
@@ -475,7 +475,7 @@ void conf_parse(const char *name)
        zconf_initscan(name);
 
        sym_init();
-       menu_init();
+       _menu_init();
        modules_sym = sym_lookup(NULL, 0);
        modules_sym->type = S_BOOLEAN;
        modules_sym->flags |= SYMBOL_AUTO;
@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu)
        struct property *prop;
 
        if (sym_is_choice(sym))
-               fprintf(out, "choice\n");
+               fprintf(out, "\nchoice\n");
        else
-               fprintf(out, "config %s\n", sym->name);
+               fprintf(out, "\nconfig %s\n", sym->name);
        switch (sym->type) {
        case S_BOOLEAN:
                fputs("  boolean\n", out);
@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu)
                case P_CHOICE:
                        fputs("  #choice value\n", out);
                        break;
+               case P_SELECT:
+                       fputs( "  select ", out);
+                       expr_fprint(prop->expr, out);
+                       fputc('\n', out);
+                       break;
+               case P_RANGE:
+                       fputs( "  range ", out);
+                       expr_fprint(prop->expr, out);
+                       fputc('\n', out);
+                       break;
+               case P_MENU:
+                       fputs( "  menu ", out);
+                       print_quoted_string(out, prop->text);
+                       fputc('\n', out);
+                       break;
                default:
                        fprintf(out, "  unknown prop %d!\n", prop->type);
                        break;
@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu)
                        menu->help[len] = 0;
                fprintf(out, "  help\n%s\n", menu->help);
        }
-       fputc('\n', out);
 }
 
 void zconfdump(FILE *out)
@@ -683,7 +697,6 @@ void zconfdump(FILE *out)
                                expr_fprint(prop->visible.expr, out);
                                fputc('\n', out);
                        }
-                       fputs("\n", out);
                }
 
                if (menu->list)
index e950f9cde0199194f8db3e0ceb4579178f186bbe..827896f56501aaebba885e70adc24a477fd31884 100644 (file)
@@ -2,6 +2,7 @@
 
 use File::Basename;
 use Math::BigInt;
+use Getopt::Long;
 
 # Copyright 2008, Intel Corporation
 #
@@ -15,6 +16,16 @@ use Math::BigInt;
 #      Arjan van de Ven <arjan@linux.intel.com>
 
 
+my $cross_compile = "";
+my $vmlinux_name = "";
+my $modulefile = "";
+
+# Get options
+Getopt::Long::GetOptions(
+       'cross-compile|c=s'     => \$cross_compile,
+       'module|m=s'            => \$modulefile,
+       'help|h'                => \&usage,
+) || usage ();
 my $vmlinux_name = $ARGV[0];
 if (!defined($vmlinux_name)) {
        my $kerver = `uname -r`;
@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) {
        print "No vmlinux specified, assuming $vmlinux_name\n";
 }
 my $filename = $vmlinux_name;
-#
-# Step 1: Parse the oops to find the EIP value
-#
+
+# Parse the oops to find the EIP value
 
 my $target = "0";
 my $function;
@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("
 my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
 if ($target eq "0") {
        print "No oops found!\n";
-       print "Usage: \n";
-       print "    dmesg | perl scripts/markup_oops.pl vmlinux\n";
-       exit;
+       usage();
 }
 
 # if it's a module, we need to find the .ko file and calculate a load offset
 if ($module ne "") {
-       my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`;
-       chomp($modulefile);
+       if ($modulefile eq "") {
+               $modulefile = `modinfo -F filename $module`;
+               chomp($modulefile);
+       }
        $filename = $modulefile;
        if ($filename eq "") {
                print "Module .ko file for $module not found. Aborting\n";
                exit;
        }
        # ok so we found the module, now we need to calculate the vma offset
-       open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
+       open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
        while (<FILE>) {
                if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
                        my $fu = $1;
-                       $vmaoffset = hex($target) - hex($fu) - hex($func_offset);
+                       $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
                }
        }
        close(FILE);
@@ -204,7 +214,7 @@ if ($module ne "") {
 
 my $counter = 0;
 my $state   = 0;
-my $center  = 0;
+my $center  = -1;
 my @lines;
 my @reglines;
 
@@ -212,7 +222,7 @@ sub InRange {
        my ($address, $target) = @_;
        my $ad = "0x".$address;
        my $ta = "0x".$target;
-       my $delta = hex($ad) - hex($ta);
+       my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
 
        if (($delta > -4096) && ($delta < 4096)) {
                return 1;
@@ -225,7 +235,7 @@ sub InRange {
 # first, parse the input into the lines array, but to keep size down,
 # we only do this for 4Kb around the sweet spot
 
-open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
+open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
 
 while (<FILE>) {
        my $line = $_;
@@ -236,7 +246,8 @@ while (<FILE>) {
                                $state = 1;
                        }
                }
-       } else {
+       }
+       if ($state == 1) {
                if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
                        my $val = $1;
                        if (!InRange($val, $target)) {
@@ -259,7 +270,7 @@ if ($counter == 0) {
        exit;
 }
 
-if ($center == 0) {
+if ($center == -1) {
        print "No matching code found \n";
        exit;
 }
@@ -344,3 +355,16 @@ while ($i < $finish) {
        $i = $i +1;
 }
 
+sub usage {
+       print <<EOT;
+Usage:
+  dmesg | perl $0 [OPTION] [VMLINUX]
+
+OPTION:
+  -c, --cross-compile CROSS_COMPILE    Specify the prefix used for toolchain.
+  -m, --module MODULE_DIRNAME          Specify the module filename.
+  -h, --help                           Help.
+EOT
+       exit;
+}
+
index 23dbad80cce9e16ce885d61163a5f79c1ca2b981..50ad317a4bf9b41bc62d074ee8bd19a9864ffda6 100755 (executable)
@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
   echo \#define LINUX_COMPILE_BY \"`whoami`\"
   echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
 
-  if [ -x /bin/dnsdomainname ]; then
-    domain=`dnsdomainname 2> /dev/null`
-  elif [ -x /bin/domainname ]; then
+  domain=`dnsdomainname 2> /dev/null`
+  if [ -z "$domain" ]; then
     domain=`domainname 2> /dev/null`
   fi
 
index 20923613467cf376db195e17a9df754e934ab470..3318692e4e761ffecaf1849693e376291b5a7655 100644 (file)
@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf,
 #define ALL_EXIT_TEXT_SECTIONS \
        ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
 
-#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \
-       CPU_INIT_SECTIONS, MEM_INIT_SECTIONS
-#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \
-       CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS
+#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
+       MEM_INIT_SECTIONS
+#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
+       MEM_EXIT_SECTIONS
+
+#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
+#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
 
 #define DATA_SECTIONS ".data$", ".data.rel$"
 #define TEXT_SECTIONS ".text$"
@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
 
 
 /* symbols in .data that may refer to init/exit sections */
-static const char *symbol_white_list[] =
-{
-       "*driver",
-       "*_template", /* scsi uses *_template a lot */
-       "*_timer",    /* arm uses ops structures named _timer a lot */
-       "*_sht",      /* scsi also used *_sht to some extent */
-       "*_ops",
-       "*_probe",
-       "*_probe_one",
-       "*_console",
-       NULL
-};
+#define DEFAULT_SYMBOL_WHITE_LIST                                      \
+       "*driver",                                                      \
+       "*_template", /* scsi uses *_template a lot */                  \
+       "*_timer",    /* arm uses ops structures named _timer a lot */  \
+       "*_sht",      /* scsi also used *_sht to some extent */         \
+       "*_ops",                                                        \
+       "*_probe",                                                      \
+       "*_probe_one",                                                  \
+       "*_console"
 
 static const char *head_sections[] = { ".head.text*", NULL };
 static const char *linker_symbols[] =
        { "__init_begin", "_sinittext", "_einittext", NULL };
 
 enum mismatch {
-       NO_MISMATCH,
-       TEXT_TO_INIT,
-       DATA_TO_INIT,
-       TEXT_TO_EXIT,
-       DATA_TO_EXIT,
-       XXXINIT_TO_INIT,
-       XXXEXIT_TO_EXIT,
-       INIT_TO_EXIT,
-       EXIT_TO_INIT,
+       TEXT_TO_ANY_INIT,
+       DATA_TO_ANY_INIT,
+       TEXT_TO_ANY_EXIT,
+       DATA_TO_ANY_EXIT,
+       XXXINIT_TO_SOME_INIT,
+       XXXEXIT_TO_SOME_EXIT,
+       ANY_INIT_TO_ANY_EXIT,
+       ANY_EXIT_TO_ANY_INIT,
        EXPORT_TO_INIT_EXIT,
 };
 
@@ -848,6 +847,7 @@ struct sectioncheck {
        const char *fromsec[20];
        const char *tosec[20];
        enum mismatch mismatch;
+       const char *symbol_white_list[20];
 };
 
 const struct sectioncheck sectioncheck[] = {
@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = {
 {
        .fromsec = { TEXT_SECTIONS, NULL },
        .tosec   = { ALL_INIT_SECTIONS, NULL },
-       .mismatch = TEXT_TO_INIT,
+       .mismatch = TEXT_TO_ANY_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 {
        .fromsec = { DATA_SECTIONS, NULL },
-       .tosec   = { ALL_INIT_SECTIONS, NULL },
-       .mismatch = DATA_TO_INIT,
+       .tosec   = { ALL_XXXINIT_SECTIONS, NULL },
+       .mismatch = DATA_TO_ANY_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
+},
+{
+       .fromsec = { DATA_SECTIONS, NULL },
+       .tosec   = { INIT_SECTIONS, NULL },
+       .mismatch = DATA_TO_ANY_INIT,
+       .symbol_white_list = {
+               "*_template", "*_timer", "*_sht", "*_ops",
+               "*_probe", "*_probe_one", "*_console", NULL
+       },
 },
 {
        .fromsec = { TEXT_SECTIONS, NULL },
        .tosec   = { ALL_EXIT_SECTIONS, NULL },
-       .mismatch = TEXT_TO_EXIT,
+       .mismatch = TEXT_TO_ANY_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 {
        .fromsec = { DATA_SECTIONS, NULL },
        .tosec   = { ALL_EXIT_SECTIONS, NULL },
-       .mismatch = DATA_TO_EXIT,
+       .mismatch = DATA_TO_ANY_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference init code/data from devinit/cpuinit/meminit code/data */
 {
-       .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL },
+       .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
        .tosec   = { INIT_SECTIONS, NULL },
-       .mismatch = XXXINIT_TO_INIT,
+       .mismatch = XXXINIT_TO_SOME_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference cpuinit code/data from meminit code/data */
 {
        .fromsec = { MEM_INIT_SECTIONS, NULL },
        .tosec   = { CPU_INIT_SECTIONS, NULL },
-       .mismatch = XXXINIT_TO_INIT,
+       .mismatch = XXXINIT_TO_SOME_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference meminit code/data from cpuinit code/data */
 {
        .fromsec = { CPU_INIT_SECTIONS, NULL },
        .tosec   = { MEM_INIT_SECTIONS, NULL },
-       .mismatch = XXXINIT_TO_INIT,
+       .mismatch = XXXINIT_TO_SOME_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
 {
-       .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL },
+       .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
        .tosec   = { EXIT_SECTIONS, NULL },
-       .mismatch = XXXEXIT_TO_EXIT,
+       .mismatch = XXXEXIT_TO_SOME_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference cpuexit code/data from memexit code/data */
 {
        .fromsec = { MEM_EXIT_SECTIONS, NULL },
        .tosec   = { CPU_EXIT_SECTIONS, NULL },
-       .mismatch = XXXEXIT_TO_EXIT,
+       .mismatch = XXXEXIT_TO_SOME_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not reference memexit code/data from cpuexit code/data */
 {
        .fromsec = { CPU_EXIT_SECTIONS, NULL },
        .tosec   = { MEM_EXIT_SECTIONS, NULL },
-       .mismatch = XXXEXIT_TO_EXIT,
+       .mismatch = XXXEXIT_TO_SOME_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not use exit code/data from init code */
 {
        .fromsec = { ALL_INIT_SECTIONS, NULL },
        .tosec   = { ALL_EXIT_SECTIONS, NULL },
-       .mismatch = INIT_TO_EXIT,
+       .mismatch = ANY_INIT_TO_ANY_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not use init code/data from exit code */
 {
        .fromsec = { ALL_EXIT_SECTIONS, NULL },
        .tosec   = { ALL_INIT_SECTIONS, NULL },
-       .mismatch = EXIT_TO_INIT,
+       .mismatch = ANY_EXIT_TO_ANY_INIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 },
 /* Do not export init/exit functions or data */
 {
        .fromsec = { "__ksymtab*", NULL },
        .tosec   = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
-       .mismatch = EXPORT_TO_INIT_EXIT
+       .mismatch = EXPORT_TO_INIT_EXIT,
+       .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
 }
 };
 
-static int section_mismatch(const char *fromsec, const char *tosec)
+static const struct sectioncheck *section_mismatch(
+               const char *fromsec, const char *tosec)
 {
        int i;
        int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
        for (i = 0; i < elems; i++) {
                if (match(fromsec, check->fromsec) &&
                    match(tosec, check->tosec))
-                       return check->mismatch;
+                       return check;
                check++;
        }
-       return NO_MISMATCH;
+       return NULL;
 }
 
 /**
@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)
  * Pattern 2:
  *   Many drivers utilise a *driver container with references to
  *   add, remove, probe functions etc.
- *   These functions may often be marked __init and we do not want to
+ *   These functions may often be marked __devinit and we do not want to
  *   warn here.
  *   the pattern is identified by:
  *   tosec   = init or exit section
@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
  *   refsymname = __init_begin, _sinittext, _einittext
  *
  **/
-static int secref_whitelist(const char *fromsec, const char *fromsym,
+static int secref_whitelist(const struct sectioncheck *mismatch,
+                           const char *fromsec, const char *fromsym,
                            const char *tosec, const char *tosym)
 {
        /* Check for pattern 1 */
@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
        /* Check for pattern 2 */
        if (match(tosec, init_exit_sections) &&
            match(fromsec, data_sections) &&
-           match(fromsym, symbol_white_list))
+           match(fromsym, mismatch->symbol_white_list))
                return 0;
 
        /* Check for pattern 3 */
@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym)
  * Try to find symbols near it so user can find it.
  * Check whitelist before warning - it may be a false positive.
  */
-static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
+static void report_sec_mismatch(const char *modname,
+                               const struct sectioncheck *mismatch,
                                 const char *fromsec,
                                 unsigned long long fromaddr,
                                 const char *fromsym,
@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
             modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
             tosym, to_p);
 
-       switch (mismatch) {
-       case TEXT_TO_INIT:
+       switch (mismatch->mismatch) {
+       case TEXT_TO_ANY_INIT:
                fprintf(stderr,
                "The function %s%s() references\n"
                "the %s %s%s%s.\n"
@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                to, sec2annotation(tosec), tosym, to_p,
                fromsym, sec2annotation(tosec), tosym);
                break;
-       case DATA_TO_INIT: {
-               const char **s = symbol_white_list;
+       case DATA_TO_ANY_INIT: {
+               const char *const *s = mismatch->symbol_white_list;
                fprintf(stderr,
                "The variable %s references\n"
                "the %s %s%s%s\n"
@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                fprintf(stderr, "\n");
                break;
        }
-       case TEXT_TO_EXIT:
+       case TEXT_TO_ANY_EXIT:
                fprintf(stderr,
                "The function %s() references a %s in an exit section.\n"
                "Often the %s %s%s has valid usage outside the exit section\n"
                "and the fix is to remove the %sannotation of %s.\n",
                fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
                break;
-       case DATA_TO_EXIT: {
-               const char **s = symbol_white_list;
+       case DATA_TO_ANY_EXIT: {
+               const char *const *s = mismatch->symbol_white_list;
                fprintf(stderr,
                "The variable %s references\n"
                "the %s %s%s%s\n"
@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                fprintf(stderr, "\n");
                break;
        }
-       case XXXINIT_TO_INIT:
-       case XXXEXIT_TO_EXIT:
+       case XXXINIT_TO_SOME_INIT:
+       case XXXEXIT_TO_SOME_EXIT:
                fprintf(stderr,
                "The %s %s%s%s references\n"
                "a %s %s%s%s.\n"
@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                to, sec2annotation(tosec), tosym, to_p,
                tosym, fromsym, tosym);
                break;
-       case INIT_TO_EXIT:
+       case ANY_INIT_TO_ANY_EXIT:
                fprintf(stderr,
                "The %s %s%s%s references\n"
                "a %s %s%s%s.\n"
@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                to, sec2annotation(tosec), tosym, to_p,
                sec2annotation(tosec), tosym, to_p);
                break;
-       case EXIT_TO_INIT:
+       case ANY_EXIT_TO_ANY_INIT:
                fprintf(stderr,
                "The %s %s%s%s references\n"
                "a %s %s%s%s.\n"
@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
                "Fix this by removing the %sannotation of %s "
                "or drop the export.\n",
                tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
-       case NO_MISMATCH:
-               /* To get warnings on missing members */
                break;
        }
        fprintf(stderr, "\n");
@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
                                    Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
 {
        const char *tosec;
-       enum mismatch mismatch;
+       const struct sectioncheck *mismatch;
 
        tosec = sec_name(elf, sym->st_shndx);
        mismatch = section_mismatch(fromsec, tosec);
-       if (mismatch != NO_MISMATCH) {
+       if (mismatch) {
                Elf_Sym *to;
                Elf_Sym *from;
                const char *tosym;
@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
                tosym = sym_name(elf, to);
 
                /* check whitelist - we may ignore it */
-               if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
+               if (secref_whitelist(mismatch,
+                                       fromsec, fromsym, tosec, tosym)) {
                        report_sec_mismatch(modname, mismatch,
                           fromsec, r->r_offset, fromsym,
                           is_function(from), tosec, tosym,
index c6e88c652c2f941647f0d04b3cd982fc6c4e7ab5..361d0f71184bbf6748f1251cef81ef07f14c6129 100755 (executable)
@@ -175,12 +175,11 @@ sub do_nm
        }
        if (! -e "$source.c" && ! -e "$source.S") {
                # No obvious source, exclude the object if it is conglomerate
-               if (! open(OBJDUMPDATA, "$objdump $basename|")) {
-                       printf STDERR "$objdump $fullname failed $!\n";
-                       return;
-               }
+               open(my $objdumpdata, "$objdump $basename|")
+                   or die "$objdump $fullname failed $!\n";
+
                my $comment;
-               while (<OBJDUMPDATA>) {
+               while (<$objdumpdata>) {
                        chomp();
                        if (/^In archive/) {
                                # Archives are always conglomerate
@@ -190,18 +189,18 @@ sub do_nm
                        next if (! /^[ 0-9a-f]{5,} /);
                        $comment .= substr($_, 43);
                }
-               close(OBJDUMPDATA);
+               close($objdumpdata);
+
                if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
                        printf STDERR "No source file found for $fullname\n";
                }
                return;
        }
-       if (! open(NMDATA, "$nm $basename|")) {
-               printf STDERR "$nm $fullname failed $!\n";
-               return;
-       }
+       open (my $nmdata, "$nm $basename|")
+           or die "$nm $fullname failed $!\n";
+
        my @nmdata;
-       while (<NMDATA>) {
+       while (<$nmdata>) {
                chop;
                ($type, $name) = (split(/ +/, $_, 3))[1..2];
                # Expected types
@@ -268,7 +267,8 @@ sub do_nm
                        }
                }
        }
-       close(NMDATA);
+       close($nmdata);
+
        if ($#nmdata < 0) {
                if (
                        $fullname ne "lib/brlock.o"
@@ -316,8 +316,7 @@ sub drop_def
 
 sub list_multiply_defined
 {
-       my ($name, $module);
-       foreach $name (keys(%def)) {
+       foreach my $name (keys(%def)) {
                if ($#{$def{$name}} > 0) {
                        # Special case for cond_syscall
                        if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
@@ -333,8 +332,9 @@ sub list_multiply_defined
                                &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
                                next;
                        }
+
                        printf "$name is multiply defined in :-\n";
-                       foreach $module (@{$def{$name}}) {
+                       foreach my $module (@{$def{$name}}) {
                                printf "\t$module\n";
                        }
                }
@@ -343,12 +343,13 @@ sub list_multiply_defined
 
 sub resolve_external_references
 {
-       my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export);
+       my ($kstrtab, $ksymtab, $export);
+
        printf "\n";
-       foreach $object (keys(%nmdata)) {
+       foreach my $object (keys(%nmdata)) {
                my $nmdata = $nmdata{$object};
-               for ($i = 0; $i <= $#{$nmdata}; ++$i) {
-                       ($type, $name) = split(' ', $nmdata->[$i], 2);
+               for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
+                       my ($type, $name) = split(' ', $nmdata->[$i], 2);
                        if ($type eq "U" || $type eq "w") {
                                if (exists($def{$name}) || exists($ksymtab{$name})) {
                                        # add the owning object to the nmdata
@@ -357,7 +358,7 @@ sub resolve_external_references
                                        $kstrtab = "R __kstrtab_$name";
                                        $ksymtab = "R __ksymtab_$name";
                                        $export = 0;
-                                       for ($j = 0; $j <= $#{$nmdata}; ++$j) {
+                                       for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
                                                if ($nmdata->[$j] eq $kstrtab ||
                                                    $nmdata->[$j] eq $ksymtab) {
                                                        $export = 1;
@@ -424,11 +425,11 @@ sub resolve_external_references
 sub list_extra_externals
 {
        my %noref = ();
-       my ($name, @module, $module, $export);
-       foreach $name (keys(%def)) {
+
+       foreach my $name (keys(%def)) {
                if (! exists($ref{$name})) {
-                       @module = @{$def{$name}};
-                       foreach $module (@module) {
+                       my @module = @{$def{$name}};
+                       foreach my $module (@module) {
                                if (! exists($noref{$module})) {
                                        $noref{$module} = [];
                                }
@@ -438,16 +439,16 @@ sub list_extra_externals
        }
        if (%noref) {
                printf "\nExternally defined symbols with no external references\n";
-               foreach $module (sort(keys(%noref))) {
+               foreach my $module (sort(keys(%noref))) {
                        printf "  $module\n";
                        foreach (sort(@{$noref{$module}})) {
-                               if (exists($export{$_})) {
-                                       $export = " (export only)";
-                               }
-                               else {
-                                       $export = "";
-                               }
-                               printf "    $_$export\n";
+                           my $export;
+                           if (exists($export{$_})) {
+                               $export = " (export only)";
+                           } else {
+                               $export = "";
+                           }
+                           printf "    $_$export\n";
                        }
                }
        }
index 8b357b0bd250b0e04012a08815c01cd3f95f22a3..07f2fbde2abf85a5f92040a10608a38e23db3905 100644 (file)
@@ -18,6 +18,8 @@ create_package() {
        cp debian/copyright "$pdir/usr/share/doc/$pname/"
        cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
        gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
+       sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
+               | xargs -r0 md5sum > DEBIAN/md5sums"
 
        # Fix ownership and permissions
        chown -R root:root "$pdir"
index fa27f3dac76992c3e37fa49bbfc61e294464d306..15440f55aef67f05d071156570b7f8e5c14927d6 100755 (executable)
@@ -39,7 +39,7 @@ if ! $PREBUILT; then
 echo "Source: kernel-$__KERNELRELEASE.tar.gz"
 fi
 
-echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root"
+echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
 echo "Provides: $PROVIDES"
 echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
 echo "%define debug_package %{nil}"
index cb4260ebdb9192a91a93e2244ca45adc86efcc9b..6943fa7cc95b646d9f1a10752cf2577f4b1a2185 100644 (file)
@@ -7,15 +7,13 @@
 # usage:
 #       readprofile | sort -rn | perl profile2linkerlist.pl > functionlist
 #
+use strict;
 
 while (<>) {
   my $line = $_;
 
   $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/;
 
-  if ( ($line =~ /unknown/) || ($line =~ /total/)) {
-
-  } else {
-    print "*(.text.$1)\n";
-  }
+  print "*(.text.$1)\n"
+      unless ($line =~ /unknown/) || ($line =~ /total/);
 }
index 4c79660793cf31b79f83aec51ac0a9aaaedd5566..44423b4dcb820959b82f6bf126e42a6c6d08f44c 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python
 #
 # rt-mutex tester
 #
index 48a706ab3d0c3d591e4b6758c58852a7a64f8a89..17df3051747a93ee68a75255764408c813f1a14e 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python
 #
 # show_deltas: Read list of printk messages instrumented with
 # time data, and format with time deltas.
index 1a0c44d7c4a75308ca6addf915a6951cf30a603d..8509bb51293530fae488f60594199031cd16bf07 100755 (executable)
@@ -5,7 +5,7 @@
 # mode may be any of: tags, TAGS, cscope
 #
 # Uses the following environment variables:
-# ARCH, SUBARCH, srctree, src, obj
+# ARCH, SUBARCH, SRCARCH, srctree, src, obj
 
 if [ "$KBUILD_VERBOSE" = "1" ]; then
        set -x
@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
           -name .git )                                   \
           -prune -o"
 
-# Do not use full path is we do not use O=.. builds
+# Do not use full path if we do not use O=.. builds
+# Use make O=. {tags|cscope}
+# to force full paths for a non-O= build
 if [ "${KBUILD_SRC}" = "" ]; then
        tree=
 else
        tree=${srctree}/
 fi
 
+# Find all available archs
+find_all_archs()
+{
+       ALLSOURCE_ARCHS=""
+       for arch in `ls ${tree}arch`; do
+               ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
+       done
+}
+
 # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
 if [ "${ALLSOURCE_ARCHS}" = "" ]; then
        ALLSOURCE_ARCHS=${SRCARCH}
+elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
+       find_all_archs
 fi
 
 # find sources in arch/$ARCH
 find_arch_sources()
 {
-       find ${tree}arch/$1 $ignore -name "$2" -print;
+       for i in $archincludedir; do
+               prune="$prune -wholename $i -prune -o"
+       done
+       find ${tree}arch/$1 $ignore $prune -name "$2" -print;
 }
 
 # find sources in arch/$1/include
 find_arch_include_sources()
 {
-       find ${tree}arch/$1/include $ignore -name "$2" -print;
+       include=$(find ${tree}arch/$1/ -name include -type d);
+       if [ -n "$include" ]; then
+               archincludedir="$archincludedir $include"
+               find $include $ignore -name "$2" -print;
+       fi
 }
 
 # find sources in include/
@@ -63,14 +83,15 @@ find_sources()
 
 all_sources()
 {
-       for arch in $ALLSOURCE_ARCHS
-       do
-               find_sources $arch '*.[chS]'
-       done
+       find_arch_include_sources ${SRCARCH} '*.[chS]'
        if [ ! -z "$archinclude" ]; then
                find_arch_include_sources $archinclude '*.[chS]'
        fi
        find_include_sources '*.[chS]'
+       for arch in $ALLSOURCE_ARCHS
+       do
+               find_sources $arch '*.[chS]'
+       done
        find_other_sources '*.[chS]'
 }
 
@@ -89,13 +110,7 @@ all_defconfigs()
 
 docscope()
 {
-       # always use absolute paths for cscope, as recommended by cscope
-       # upstream
-       case "$tree" in
-               /*) ;;
-               *) tree=$PWD/$tree ;;
-       esac
-       (cd /; echo \-k; echo \-q; all_sources) > cscope.files
+       (echo \-k; echo \-q; all_sources) > cscope.files
        cscope -b -f cscope.out
 }
 
index 67893372173581601fbcd5c71ca9c30cab0b5a7a..3ff8cc5f487a832c6620b656cb477797695c2f70 100644 (file)
@@ -437,9 +437,11 @@ static int i2sbus_shutdown(struct macio_dev* dev)
 }
 
 static struct macio_driver i2sbus_drv = {
-       .name = "soundbus-i2s",
-       .owner = THIS_MODULE,
-       .match_table = i2sbus_match,
+       .driver = {
+               .name = "soundbus-i2s",
+               .owner = THIS_MODULE,
+               .of_match_table = i2sbus_match,
+       },
        .probe = i2sbus_probe,
        .remove = i2sbus_remove,
 #ifdef CONFIG_PM
index 44a47e13bd673eb362f956b80bd02adbec367d45..99890728409eba3bc390d2060a58d140f543c488 100644 (file)
@@ -43,8 +43,10 @@ static int __cmd_buildid_list(void)
        if (session == NULL)
                return -1;
 
-       if (with_hits)
+       if (with_hits) {
+               symbol_conf.full_paths = true;
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
+       }
 
        perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
 
index 9bc89050e6f8642cf65cbfbd354c7a8f209cd816..dc3435e18bdeb18cfdcb8e2a08a21a98cc695a2d 100644 (file)
@@ -503,7 +503,6 @@ static int __cmd_record(int argc, const char **argv)
 {
        int i, counter;
        struct stat st;
-       pid_t pid = 0;
        int flags;
        int err;
        unsigned long waking = 0;
@@ -572,7 +571,7 @@ static int __cmd_record(int argc, const char **argv)
 
        if (forks) {
                child_pid = fork();
-               if (pid < 0) {
+               if (child_pid < 0) {
                        perror("failed to fork");
                        exit(-1);
                }
index f67bce2a83b4e090d86a0ecc2dd5a1240521db0a..55f3b5dcc731417198a2e5fd29ac8eefd96e1a5e 100644 (file)
@@ -1645,6 +1645,7 @@ static struct perf_event_ops event_ops = {
        .sample                 = process_sample_event,
        .comm                   = event__process_comm,
        .lost                   = event__process_lost,
+       .fork                   = event__process_task,
        .ordered_samples        = true,
 };
 
index 964d934395ff67d57b65a17660400bff8a1483e2..d9f7893e315c0d5aa064df04a8cc3ac870aebdad 100644 (file)
@@ -51,8 +51,7 @@ def kmem__kmalloc(event_name, context, common_cpu,
 
                flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)),
 
-def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs,
-               common_pid, common_comm):
+def trace_unhandled(event_name, context, event_fields_dict):
     try:
         unhandled[event_name] += 1
     except TypeError:
index 50771b5813ee6e15a6843a232b108415f77a4a29..1f08f008d289f841f7ae0089462129f97e313afc 100644 (file)
@@ -370,9 +370,9 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
 
 int event__process_comm(event_t *self, struct perf_session *session)
 {
-       struct thread *thread = perf_session__findnew(session, self->comm.pid);
+       struct thread *thread = perf_session__findnew(session, self->comm.tid);
 
-       dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
+       dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid);
 
        if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
                dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
@@ -532,16 +532,11 @@ out_problem:
 
 int event__process_task(event_t *self, struct perf_session *session)
 {
-       struct thread *thread = perf_session__findnew(session, self->fork.pid);
-       struct thread *parent = perf_session__findnew(session, self->fork.ppid);
+       struct thread *thread = perf_session__findnew(session, self->fork.tid);
+       struct thread *parent = perf_session__findnew(session, self->fork.ptid);
 
        dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
                    self->fork.ppid, self->fork.ptid);
-       /*
-        * A thread clone will have the same PID for both parent and child.
-        */
-       if (thread == parent)
-               return 0;
 
        if (self->header.type == PERF_RECORD_EXIT)
                return 0;
index cbf7eae2ce0909326afa68cb534315df11badeae..07f89b66b318e43748f666f495f87b75f6a34462 100644 (file)
@@ -965,7 +965,7 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file,
                 * Parse hexa addresses followed by ':'
                 */
                line_ip = strtoull(tmp, &tmp2, 16);
-               if (*tmp2 != ':')
+               if (*tmp2 != ':' || tmp == tmp2)
                        line_ip = -1;
        }
 
index 81f39cab3aaa5981b60d38e7402e21d5a359e3b2..33a632523743deff80cb9e3636bd9144b84b2f76 100644 (file)
@@ -208,7 +208,7 @@ static void python_process_event(int cpu, void *data,
                                 int size __unused,
                                 unsigned long long nsecs, char *comm)
 {
-       PyObject *handler, *retval, *context, *t, *obj;
+       PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
        static char handler_name[256];
        struct format_field *field;
        unsigned long long val;
@@ -232,6 +232,14 @@ static void python_process_event(int cpu, void *data,
 
        sprintf(handler_name, "%s__%s", event->system, event->name);
 
+       handler = PyDict_GetItemString(main_dict, handler_name);
+       if (handler && !PyCallable_Check(handler))
+               handler = NULL;
+       if (!handler) {
+               dict = PyDict_New();
+               if (!dict)
+                       Py_FatalError("couldn't create Python dict");
+       }
        s = nsecs / NSECS_PER_SEC;
        ns = nsecs - s * NSECS_PER_SEC;
 
@@ -242,12 +250,20 @@ static void python_process_event(int cpu, void *data,
        PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
        PyTuple_SetItem(t, n++,
                        PyCObject_FromVoidPtr(scripting_context, NULL));
-       PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
-       PyTuple_SetItem(t, n++, PyInt_FromLong(s));
-       PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
-       PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
-       PyTuple_SetItem(t, n++, PyString_FromString(comm));
 
+       if (handler) {
+               PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
+               PyTuple_SetItem(t, n++, PyInt_FromLong(s));
+               PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
+               PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
+               PyTuple_SetItem(t, n++, PyString_FromString(comm));
+       } else {
+               PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu));
+               PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s));
+               PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns));
+               PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid));
+               PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm));
+       }
        for (field = event->format.fields; field; field = field->next) {
                if (field->flags & FIELD_IS_STRING) {
                        int offset;
@@ -272,27 +288,31 @@ static void python_process_event(int cpu, void *data,
                                        obj = PyLong_FromUnsignedLongLong(val);
                        }
                }
-               PyTuple_SetItem(t, n++, obj);
+               if (handler)
+                       PyTuple_SetItem(t, n++, obj);
+               else
+                       PyDict_SetItemString(dict, field->name, obj);
+
        }
+       if (!handler)
+               PyTuple_SetItem(t, n++, dict);
 
        if (_PyTuple_Resize(&t, n) == -1)
                Py_FatalError("error resizing Python tuple");
 
-       handler = PyDict_GetItemString(main_dict, handler_name);
-       if (handler && PyCallable_Check(handler)) {
+       if (handler) {
                retval = PyObject_CallObject(handler, t);
                if (retval == NULL)
                        handler_call_die(handler_name);
        } else {
                handler = PyDict_GetItemString(main_dict, "trace_unhandled");
                if (handler && PyCallable_Check(handler)) {
-                       if (_PyTuple_Resize(&t, N_COMMON_FIELDS) == -1)
-                               Py_FatalError("error resizing Python tuple");
 
                        retval = PyObject_CallObject(handler, t);
                        if (retval == NULL)
                                handler_call_die("trace_unhandled");
                }
+               Py_DECREF(dict);
        }
 
        Py_DECREF(t);
@@ -548,12 +568,10 @@ static int python_generate_script(const char *outfile)
        }
 
        fprintf(ofp, "def trace_unhandled(event_name, context, "
-               "common_cpu, common_secs, common_nsecs,\n\t\t"
-               "common_pid, common_comm):\n");
+               "event_fields_dict):\n");
 
-       fprintf(ofp, "\t\tprint_header(event_name, common_cpu, "
-               "common_secs, common_nsecs,\n\t\tcommon_pid, "
-               "common_comm)\n\n");
+       fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))"
+               "for k,v in sorted(event_fields_dict.items())])\n\n");
 
        fprintf(ofp, "def print_header("
                "event_name, cpu, secs, nsecs, pid, comm):\n"