Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2009 19:32:42 +0000 (11:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2009 19:32:42 +0000 (11:32 -0800)
* master.kernel.org:/home/rmk/linux-2.6-arm:
  ARM: Use a definition for the userspace cmpxchg emulation syscall
  [ARM] Fix test for unimplemented ARM syscalls
  ARM: 5784/1: fix early boot machine ID mismatch error display
  [ARM] orion5x: update defconfig
  [ARM] Kirkwood: update defconfig
  [ARM] Kirkwood: clarify PCIe MEM bus/physical address distinction
  [ARM] kirkwood: fix PCI I/O port assignment
  [ARM] kirkwood: fix section mismatch
  [ARM] OpenRD base: Initialize PCI express and i2c
  [ARM] properly report mv78100 stepping A1
  ARM: 5780/1: KS8695: Fix macro definition bug in regs-switch.c
  ARM: 5779/1: ep93xx/micro9.c: fix implicit declaration of function __raw_readl and IOMEM
  RealView: Add sparsemem support for the RealView PBX platform
  RealView: Remove duplicated #define REALVIEW_SYS_FLAGS* statements
  RealView: Add default memory configuration
  Check whether the SCU was already initialised
  ARMv7: Check whether the SMP/nAMP mode was already enabled
  [ARM] pxa: fix resume failure by saving/restoring IPRx registers
  [ARM] pxa/palm: fix incorrect initialization of Palm Tungsten C keyboard
  [ARM] pxa/zaurus: fix NAND flash OOB layout for Borzoi

221 files changed:
Documentation/i2c/busses/i2c-piix4
Documentation/thermal/sysfs-api.txt
MAINTAINERS
arch/arm/mach-s3c6400/include/mach/dma.h
arch/arm/mach-s3c6410/Kconfig
arch/arm/mach-s3c6410/mach-smdk6410.c
arch/arm/plat-s3c64xx/dma.c
arch/m32r/Kconfig
arch/m32r/boot/compressed/Makefile
arch/m32r/boot/compressed/misc.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/time.c
arch/m32r/kernel/vmlinux.lds.S
arch/powerpc/Kconfig
arch/powerpc/kernel/time.c
arch/powerpc/kvm/timing.h
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/platforms/pseries/xics.c
arch/sh/include/asm/rwsem.h
arch/sh/kernel/dwarf.c
arch/sh/mm/cache-sh4.c
arch/sparc/include/asm/system_64.h
arch/sparc/kernel/prom_common.c
arch/sparc/kernel/visemul.c
arch/x86/include/asm/amd_iommu.h
arch/x86/include/asm/desc.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/topology.h
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/cpu/mtrr/cleanup.c
arch/x86/kernel/microcode_amd.c
arch/x86/kernel/process_64.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup.c
arch/x86/kvm/x86.c
arch/x86/mm/ioremap.c
arch/x86/xen/enlighten.c
drivers/acpi/acpica/acconfig.h
drivers/acpi/acpica/exregion.c
drivers/acpi/power_meter.c
drivers/acpi/proc.c
drivers/acpi/processor_core.c
drivers/acpi/processor_throttling.c
drivers/acpi/sleep.c
drivers/acpi/video.c
drivers/char/hvc_xen.c
drivers/edac/amd64_edac.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_benchmark.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cursor.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c [new file with mode: 0644]
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770d.h
drivers/gpu/drm/ttm/ttm_tt.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-piix4.c
drivers/ide/ide-probe.c
drivers/isdn/hardware/eicon/maintidi.c
drivers/isdn/hardware/eicon/message.c
drivers/isdn/hisax/amd7930_fn.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa_ser.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hscx_irq.c
drivers/isdn/hisax/icc.c
drivers/isdn/mISDN/stack.c
drivers/md/md.c
drivers/md/raid5.c
drivers/media/common/tuners/tda18271-fe.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/ce6230.c
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/firewire/firedtv-avc.c
drivers/media/dvb/firewire/firedtv-fe.c
drivers/media/dvb/frontends/dib0070.h
drivers/media/dvb/frontends/dib7000p.c
drivers/media/dvb/pt1/pt1.c
drivers/media/dvb/siano/smsusb.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/em28xx/em28xx-audio.c
drivers/media/video/gspca/m5602/m5602_s5k4aa.c
drivers/media/video/gspca/mr97310a.c
drivers/media/video/gspca/ov519.c
drivers/media/video/gspca/stv06xx/stv06xx.c
drivers/media/video/pxa_camera.c
drivers/media/video/s2255drv.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-ts.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/saa7164/saa7164-cmd.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_video.c
drivers/misc/sgi-gru/gruprocfs.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/nand/nand_base.c
drivers/net/benet/be.h
drivers/net/benet/be_cmds.h
drivers/net/benet/be_ethtool.c
drivers/net/benet/be_main.c
drivers/net/can/dev.c
drivers/net/can/usb/ems_usb.c
drivers/net/cassini.c
drivers/net/davinci_emac.c
drivers/net/fsl_pq_mdio.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/macsonic.c
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/sfc/sfe4001.c
drivers/net/usb/Kconfig
drivers/net/usb/cdc_ether.c
drivers/net/virtio_net.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw.h
drivers/net/wireless/ipw2x00/libipw_module.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00link.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rtl818x/rtl8187_leds.c
drivers/platform/x86/eeepc-laptop.c
drivers/serial/sh-sci.c
drivers/thermal/thermal_sys.c
drivers/watchdog/sbc_fitpc2_wdt.c
fs/Kconfig
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/readdir.c
fs/compat.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/fuse/dir.c
fs/fuse/file.c
fs/nilfs2/ioctl.c
fs/sysfs/dir.c
include/linux/i2c.h
include/linux/pci_ids.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_nat_helper.h
init/Kconfig
kernel/irq/spurious.c
kernel/kthread.c
kernel/rcutree.c
kernel/rcutree.h
kernel/sched.c
kernel/sched_fair.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/user.c
lib/dma-debug.c
mm/highmem.c
mm/ksm.c
net/bridge/br_if.c
net/can/bcm.c
net/decnet/sysctl_net_decnet.c
net/ipv4/ipip.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_helper.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/xt_connlimit.c
net/rose/rose_route.c
sound/oss/dmasound/dmasound_core.c
sound/oss/sb_common.c
sound/oss/sb_ess.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_sigmatel.c
sound/pci/intel8x0.c
sound/sh/aica.c
sound/soc/omap/omap-pcm.c
sound/soc/s3c24xx/s3c64xx-i2s.c
sound/usb/usbaudio.h
tools/perf/builtin-record.c
tools/perf/builtin-top.c

index c5b37c5..ac540c7 100644 (file)
@@ -8,7 +8,7 @@ Supported adapters:
     Datasheet: Only available via NDA from ServerWorks
   * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
     Datasheet: Not publicly available
-  * AMD SB900
+  * AMD Hudson-2
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
index 70d68ce..a87dc27 100644 (file)
@@ -1,5 +1,5 @@
 Generic Thermal Sysfs driver How To
-=========================
+===================================
 
 Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>
 
@@ -10,20 +10,20 @@ Copyright (c)  2008 Intel Corporation
 
 0. Introduction
 
-The generic thermal sysfs provides a set of interfaces for thermal zone devices (sensors)
-and thermal cooling devices (fan, processor...) to register with the thermal management
-solution and to be a part of it.
+The generic thermal sysfs provides a set of interfaces for thermal zone
+devices (sensors) and thermal cooling devices (fan, processor...) to register
+with the thermal management solution and to be a part of it.
 
-This how-to focuses on enabling new thermal zone and cooling devices to participate
-in thermal management.
-This solution is platform independent and any type of thermal zone devices and
-cooling devices should be able to make use of the infrastructure.
+This how-to focuses on enabling new thermal zone and cooling devices to
+participate in thermal management.
+This solution is platform independent and any type of thermal zone devices
+and cooling devices should be able to make use of the infrastructure.
 
-The main task of the thermal sysfs driver is to expose thermal zone attributes as well
-as cooling device attributes to the user space.
-An intelligent thermal management application can make decisions based on inputs
-from thermal zone attributes (the current temperature and trip point temperature)
-and throttle appropriate devices.
+The main task of the thermal sysfs driver is to expose thermal zone attributes
+as well as cooling device attributes to the user space.
+An intelligent thermal management application can make decisions based on
+inputs from thermal zone attributes (the current temperature and trip point
+temperature) and throttle appropriate devices.
 
 [0-*]  denotes any positive number starting from 0
 [1-*]  denotes any positive number starting from 1
@@ -31,77 +31,77 @@ and throttle appropriate devices.
 1. thermal sysfs driver interface functions
 
 1.1 thermal zone device interface
-1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name, int trips,
-                               void *devdata, struct thermal_zone_device_ops *ops)
-
-       This interface function adds a new thermal zone device (sensor) to
-       /sys/class/thermal folder as thermal_zone[0-*].
-       It tries to bind all the thermal cooling devices registered at the same time.
-
-       name: the thermal zone name.
-       trips: the total number of trip points this thermal zone supports.
-       devdata: device private data
-       ops: thermal zone device call-backs.
-               .bind: bind the thermal zone device with a thermal cooling device.
-               .unbind: unbind the thermal zone device with a thermal cooling device.
-               .get_temp: get the current temperature of the thermal zone.
-               .get_mode: get the current mode (user/kernel) of the thermal zone.
-                          "kernel" means thermal management is done in kernel.
-                          "user" will prevent kernel thermal driver actions upon trip points
-                          so that user applications can take charge of thermal management.
-               .set_mode: set the mode (user/kernel) of the thermal zone.
-               .get_trip_type: get the type of certain trip point.
-               .get_trip_temp: get the temperature above which the certain trip point
-                               will be fired.
+1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name,
+               int trips, void *devdata, struct thermal_zone_device_ops *ops)
+
+    This interface function adds a new thermal zone device (sensor) to
+    /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
+    thermal cooling devices registered at the same time.
+
+    name: the thermal zone name.
+    trips: the total number of trip points this thermal zone supports.
+    devdata: device private data
+    ops: thermal zone device call-backs.
+       .bind: bind the thermal zone device with a thermal cooling device.
+       .unbind: unbind the thermal zone device with a thermal cooling device.
+       .get_temp: get the current temperature of the thermal zone.
+       .get_mode: get the current mode (user/kernel) of the thermal zone.
+           - "kernel" means thermal management is done in kernel.
+           - "user" will prevent kernel thermal driver actions upon trip points
+             so that user applications can take charge of thermal management.
+       .set_mode: set the mode (user/kernel) of the thermal zone.
+       .get_trip_type: get the type of certain trip point.
+       .get_trip_temp: get the temperature above which the certain trip point
+                       will be fired.
 
 1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 
-       This interface function removes the thermal zone device.
-       It deletes the corresponding entry form /sys/class/thermal folder and unbind all
-       the thermal cooling devices it uses.
+    This interface function removes the thermal zone device.
+    It deletes the corresponding entry form /sys/class/thermal folder and
+    unbind all the thermal cooling devices it uses.
 
 1.2 thermal cooling device interface
 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name,
-                                       void *devdata, struct thermal_cooling_device_ops *)
-
-       This interface function adds a new thermal cooling device (fan/processor/...) to
-       /sys/class/thermal/ folder as cooling_device[0-*].
-       It tries to bind itself to all the thermal zone devices register at the same time.
-       name: the cooling device name.
-       devdata: device private data.
-       ops: thermal cooling devices call-backs.
-               .get_max_state: get the Maximum throttle state of the cooling device.
-               .get_cur_state: get the Current throttle state of the cooling device.
-               .set_cur_state: set the Current throttle state of the cooling device.
+               void *devdata, struct thermal_cooling_device_ops *)
+
+    This interface function adds a new thermal cooling device (fan/processor/...)
+    to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
+    to all the thermal zone devices register at the same time.
+    name: the cooling device name.
+    devdata: device private data.
+    ops: thermal cooling devices call-backs.
+       .get_max_state: get the Maximum throttle state of the cooling device.
+       .get_cur_state: get the Current throttle state of the cooling device.
+       .set_cur_state: set the Current throttle state of the cooling device.
 
 1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
 
-       This interface function remove the thermal cooling device.
-       It deletes the corresponding entry form /sys/class/thermal folder and unbind
-       itself from all the thermal zone devices using it.
+    This interface function remove the thermal cooling device.
+    It deletes the corresponding entry form /sys/class/thermal folder and
+    unbind itself from all the thermal zone devices using it.
 
 1.3 interface for binding a thermal zone device with a thermal cooling device
 1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
-                       int trip, struct thermal_cooling_device *cdev);
+               int trip, struct thermal_cooling_device *cdev);
 
-       This interface function bind a thermal cooling device to the certain trip point
-       of a thermal zone device.
-       This function is usually called in the thermal zone device .bind callback.
-       tz: the thermal zone device
-       cdev: thermal cooling device
-       trip: indicates which trip point the cooling devices is associated with
-                in this thermal zone.
+    This interface function bind a thermal cooling device to the certain trip
+    point of a thermal zone device.
+    This function is usually called in the thermal zone device .bind callback.
+    tz: the thermal zone device
+    cdev: thermal cooling device
+    trip: indicates which trip point the cooling devices is associated with
+         in this thermal zone.
 
 1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
-                               int trip, struct thermal_cooling_device *cdev);
+               int trip, struct thermal_cooling_device *cdev);
 
-       This interface function unbind a thermal cooling device from the certain trip point
-       of a thermal zone device.
-       This function is usually called in the thermal zone device .unbind callback.
-       tz: the thermal zone device
-       cdev: thermal cooling device
-       trip: indicates which trip point the cooling devices is associated with
-               in this thermal zone.
+    This interface function unbind a thermal cooling device from the certain
+    trip point of a thermal zone device. This function is usually called in
+    the thermal zone device .unbind callback.
+    tz: the thermal zone device
+    cdev: thermal cooling device
+    trip: indicates which trip point the cooling devices is associated with
+         in this thermal zone.
 
 2. sysfs attributes structure
 
@@ -114,153 +114,166 @@ if hwmon is compiled in or built as a module.
 
 Thermal zone device sys I/F, created once it's registered:
 /sys/class/thermal/thermal_zone[0-*]:
-       |-----type:                     Type of the thermal zone
-       |-----temp:                     Current temperature
-       |-----mode:                     Working mode of the thermal zone
-       |-----trip_point_[0-*]_temp:    Trip point temperature
-       |-----trip_point_[0-*]_type:    Trip point type
+    |---type:                  Type of the thermal zone
+    |---temp:                  Current temperature
+    |---mode:                  Working mode of the thermal zone
+    |---trip_point_[0-*]_temp: Trip point temperature
+    |---trip_point_[0-*]_type: Trip point type
 
 Thermal cooling device sys I/F, created once it's registered:
 /sys/class/thermal/cooling_device[0-*]:
-       |-----type :                    Type of the cooling device(processor/fan/...)
-       |-----max_state:                Maximum cooling state of the cooling device
-       |-----cur_state:                Current cooling state of the cooling device
+    |---type:                  Type of the cooling device(processor/fan/...)
+    |---max_state:             Maximum cooling state of the cooling device
+    |---cur_state:             Current cooling state of the cooling device
 
 
-These two dynamic attributes are created/removed in pairs.
-They represent the relationship between a thermal zone and its associated cooling device.
-They are created/removed for each
-thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution.
+Then next two dynamic attributes are created/removed in pairs. They represent
+the relationship between a thermal zone and its associated cooling device.
+They are created/removed for each successful execution of
+thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.
 
-/sys/class/thermal/thermal_zone[0-*]
-       |-----cdev[0-*]:                The [0-*]th cooling device in the current thermal zone
-       |-----cdev[0-*]_trip_point:     Trip point that cdev[0-*] is associated with
+/sys/class/thermal/thermal_zone[0-*]:
+    |---cdev[0-*]:             [0-*]th cooling device in current thermal zone
+    |---cdev[0-*]_trip_point:  Trip point that cdev[0-*] is associated with
 
 Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
-the generic thermal driver also creates a hwmon sysfs I/F for each _type_ of
-thermal zone device. E.g. the generic thermal driver registers one hwmon class device
-and build the associated hwmon sysfs I/F for all the registered ACPI thermal zones.
+the generic thermal driver also creates a hwmon sysfs I/F for each _type_
+of thermal zone device. E.g. the generic thermal driver registers one hwmon
+class device and build the associated hwmon sysfs I/F for all the registered
+ACPI thermal zones.
+
 /sys/class/hwmon/hwmon[0-*]:
-       |-----name:                     The type of the thermal zone devices.
-       |-----temp[1-*]_input:          The current temperature of thermal zone [1-*].
-       |-----temp[1-*]_critical:       The critical trip point of thermal zone [1-*].
+    |---name:                  The type of the thermal zone devices
+    |---temp[1-*]_input:       The current temperature of thermal zone [1-*]
+    |---temp[1-*]_critical:    The critical trip point of thermal zone [1-*]
+
 Please read Documentation/hwmon/sysfs-interface for additional information.
 
 ***************************
 * Thermal zone attributes *
 ***************************
 
-type                           Strings which represent the thermal zone type.
-                               This is given by thermal zone driver as part of registration.
-                               Eg: "acpitz" indicates it's an ACPI thermal device.
-                               In order to keep it consistent with hwmon sys attribute,
-                               this should be a short, lowercase string,
-                               not containing spaces nor dashes.
-                               RO
-                               Required
-
-temp                           Current temperature as reported by thermal zone (sensor)
-                               Unit: millidegree Celsius
-                               RO
-                               Required
-
-mode                           One of the predefined values in [kernel, user]
-                               This file gives information about the algorithm
-                               that is currently managing the thermal zone.
-                               It can be either default kernel based algorithm
-                               or user space application.
-                               RW
-                               Optional
-                               kernel  = Thermal management in kernel thermal zone driver.
-                               user    = Preventing kernel thermal zone driver actions upon
-                                         trip points so that user application can take full
-                                         charge of the thermal management.
-
-trip_point_[0-*]_temp          The temperature above which trip point will be fired
-                               Unit: millidegree Celsius
-                               RO
-                               Optional
-
-trip_point_[0-*]_type          Strings which indicate the type of the trip point
-                               E.g. it can be one of critical, hot, passive,
-                                   active[0-*] for ACPI thermal zone.
-                               RO
-                               Optional
-
-cdev[0-*]                      Sysfs link to the thermal cooling device node where the sys I/F
-                               for cooling device throttling control represents.
-                               RO
-                               Optional
-
-cdev[0-*]_trip_point           The trip point with which cdev[0-*] is associated in this thermal zone
-                               -1 means the cooling device is not associated with any trip point.
-                               RO
-                               Optional
-
-******************************
-* Cooling device  attributes *
-******************************
-
-type                           String which represents the type of device
-                               eg: For generic ACPI: this should be "Fan",
-                               "Processor" or "LCD"
-                               eg. For memory controller device on intel_menlow platform:
-                               this should be "Memory controller"
-                               RO
-                               Required
-
-max_state                      The maximum permissible cooling state of this cooling device.
-                               RO
-                               Required
-
-cur_state                      The current cooling state of this cooling device.
-                               the value can any integer numbers between 0 and max_state,
-                               cur_state == 0 means no cooling
-                               cur_state == max_state means the maximum cooling.
-                               RW
-                               Required
+type
+       Strings which represent the thermal zone type.
+       This is given by thermal zone driver as part of registration.
+       E.g: "acpitz" indicates it's an ACPI thermal device.
+       In order to keep it consistent with hwmon sys attribute; this should
+       be a short, lowercase string, not containing spaces nor dashes.
+       RO, Required
+
+temp
+       Current temperature as reported by thermal zone (sensor).
+       Unit: millidegree Celsius
+       RO, Required
+
+mode
+       One of the predefined values in [kernel, user].
+       This file gives information about the algorithm that is currently
+       managing the thermal zone. It can be either default kernel based
+       algorithm or user space application.
+       kernel  = Thermal management in kernel thermal zone driver.
+       user    = Preventing kernel thermal zone driver actions upon
+                 trip points so that user application can take full
+                 charge of the thermal management.
+       RW, Optional
+
+trip_point_[0-*]_temp
+       The temperature above which trip point will be fired.
+       Unit: millidegree Celsius
+       RO, Optional
+
+trip_point_[0-*]_type
+       Strings which indicate the type of the trip point.
+       E.g. it can be one of critical, hot, passive, active[0-*] for ACPI
+       thermal zone.
+       RO, Optional
+
+cdev[0-*]
+       Sysfs link to the thermal cooling device node where the sys I/F
+       for cooling device throttling control represents.
+       RO, Optional
+
+cdev[0-*]_trip_point
+       The trip point with which cdev[0-*] is associated in this thermal
+       zone; -1 means the cooling device is not associated with any trip
+       point.
+       RO, Optional
+
+passive
+       Attribute is only present for zones in which the passive cooling
+       policy is not supported by native thermal driver. Default is zero
+       and can be set to a temperature (in millidegrees) to enable a
+       passive trip point for the zone. Activation is done by polling with
+       an interval of 1 second.
+       Unit: millidegrees Celsius
+       RW, Optional
+
+*****************************
+* Cooling device attributes *
+*****************************
+
+type
+       String which represents the type of device, e.g:
+       - for generic ACPI: should be "Fan", "Processor" or "LCD"
+       - for memory controller device on intel_menlow platform:
+         should be "Memory controller".
+       RO, Required
+
+max_state
+       The maximum permissible cooling state of this cooling device.
+       RO, Required
+
+cur_state
+       The current cooling state of this cooling device.
+       The value can any integer numbers between 0 and max_state:
+       - cur_state == 0 means no cooling
+       - cur_state == max_state means the maximum cooling.
+       RW, Required
 
 3. A simple implementation
 
-ACPI thermal zone may support multiple trip points like critical/hot/passive/active.
-If an ACPI thermal zone supports critical, passive, active[0] and active[1] at the same time,
-it may register itself as a thermal_zone_device (thermal_zone1) with 4 trip points in all.
-It has one processor and one fan, which are both registered as thermal_cooling_device.
-If the processor is listed in _PSL method, and the fan is listed in _AL0 method,
-the sys I/F structure will be built like this:
+ACPI thermal zone may support multiple trip points like critical, hot,
+passive, active. If an ACPI thermal zone supports critical, passive,
+active[0] and active[1] at the same time, it may register itself as a
+thermal_zone_device (thermal_zone1) with 4 trip points in all.
+It has one processor and one fan, which are both registered as
+thermal_cooling_device.
+
+If the processor is listed in _PSL method, and the fan is listed in _AL0
+method, the sys I/F structure will be built like this:
 
 /sys/class/thermal:
 
 |thermal_zone1:
-       |-----type:                     acpitz
-       |-----temp:                     37000
-       |-----mode:                     kernel
-       |-----trip_point_0_temp:        100000
-       |-----trip_point_0_type:        critical
-       |-----trip_point_1_temp:        80000
-       |-----trip_point_1_type:        passive
-       |-----trip_point_2_temp:        70000
-       |-----trip_point_2_type:        active0
-       |-----trip_point_3_temp:        60000
-       |-----trip_point_3_type:        active1
-       |-----cdev0:                    --->/sys/class/thermal/cooling_device0
-       |-----cdev0_trip_point:         1       /* cdev0 can be used for passive */
-       |-----cdev1:                    --->/sys/class/thermal/cooling_device3
-       |-----cdev1_trip_point:         2       /* cdev1 can be used for active[0]*/
+    |---type:                  acpitz
+    |---temp:                  37000
+    |---mode:                  kernel
+    |---trip_point_0_temp:     100000
+    |---trip_point_0_type:     critical
+    |---trip_point_1_temp:     80000
+    |---trip_point_1_type:     passive
+    |---trip_point_2_temp:     70000
+    |---trip_point_2_type:     active0
+    |---trip_point_3_temp:     60000
+    |---trip_point_3_type:     active1
+    |---cdev0:                 --->/sys/class/thermal/cooling_device0
+    |---cdev0_trip_point:      1       /* cdev0 can be used for passive */
+    |---cdev1:                 --->/sys/class/thermal/cooling_device3
+    |---cdev1_trip_point:      2       /* cdev1 can be used for active[0]*/
 
 |cooling_device0:
-       |-----type:                     Processor
-       |-----max_state:                8
-       |-----cur_state:                0
+    |---type:                  Processor
+    |---max_state:             8
+    |---cur_state:             0
 
 |cooling_device3:
-       |-----type:                     Fan
-       |-----max_state:                2
-       |-----cur_state:                0
+    |---type:                  Fan
+    |---max_state:             2
+    |---cur_state:             0
 
 /sys/class/hwmon:
 
 |hwmon0:
-       |-----name:                     acpitz
-       |-----temp1_input:              37000
-       |-----temp1_crit:               100000
+    |---name:                  acpitz
+    |---temp1_input:           37000
+    |---temp1_crit:            100000
index a1a2ace..8264e6b 100644 (file)
@@ -3665,6 +3665,7 @@ L:        netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net
 W:     http://patchwork.ozlabs.org/project/netdev/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
 S:     Maintained
 F:     net/
 F:     include/net/
index 004edab..6723860 100644 (file)
@@ -58,21 +58,13 @@ enum dma_ch {
        DMACH_MAX               /* the end */
 };
 
-static __inline__ int s3c_dma_has_circular(void)
+static __inline__ bool s3c_dma_has_circular(void)
 {
-       /* we will be supporting ciruclar buffers as soon as we have DMA
-        * engine support.
-        */
-       return 1;
+       return true;
 }
 
 #define S3C2410_DMAF_CIRCULAR          (1 << 0)
 
-static inline bool s3c_dma_has_circular(void)
-{
-       return false;
-}
-
 #include <plat/dma.h>
 
 #endif /* __ASM_ARCH_IRQ_H */
index 53fc3ff..72d4b11 100644 (file)
@@ -77,6 +77,7 @@ config SMDK6410_WM1190_EV1
        depends on MACH_SMDK6410
        select REGULATOR
        select REGULATOR_WM8350
+       select S3C24XX_GPIO_EXTRA64
        select MFD_WM8350_I2C
        select MFD_WM8350_CONFIG_MODE_0
        select MFD_WM8350_CONFIG_MODE_3
index ea51dbe..9f1a214 100644 (file)
@@ -320,6 +320,9 @@ static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
 {
        int i;
 
+       /* Configure the IRQ line */
+       s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
        /* Instantiate the regulators */
        for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
                wm8350_register_regulator(wm8350,
index 266a107..d554b93 100644 (file)
@@ -151,8 +151,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
                src = chan->dev_addr;
                dst = data;
                control0 = PL080_CONTROL_SRC_AHB2;
-               control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
-               control0 |= 2 << PL080_CONTROL_DWIDTH_SHIFT;
                control0 |= PL080_CONTROL_DST_INCR;
                break;
 
@@ -160,8 +158,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
                src = data;
                dst = chan->dev_addr;
                control0 = PL080_CONTROL_DST_AHB2;
-               control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
-               control0 |= 2 << PL080_CONTROL_SWIDTH_SHIFT;
                control0 |= PL080_CONTROL_SRC_INCR;
                break;
        default:
@@ -173,6 +169,8 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
        control1 = size >> chan->hw_width;      /* size in no of xfers */
        control0 |= PL080_CONTROL_PROT_SYS;     /* always in priv. mode */
        control0 |= PL080_CONTROL_TC_IRQ_EN;    /* always fire IRQ */
+       control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
+       control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
 
        lli->src_addr = src;
        lli->dst_addr = dst;
@@ -339,6 +337,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
        struct s3c64xx_dma_buff *next;
        struct s3c64xx_dma_buff *buff;
        struct pl080s_lli *lli;
+       unsigned long flags;
        int ret;
 
        WARN_ON(!chan);
@@ -366,6 +365,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
 
        s3c64xx_dma_fill_lli(chan, lli, data, size);
 
+       local_irq_save(flags);
+
        if ((next = chan->next) != NULL) {
                struct s3c64xx_dma_buff *end = chan->end;
                struct pl080s_lli *endlli = end->lli;
@@ -397,6 +398,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
                s3c64xx_lli_to_regs(chan, lli);
        }
 
+       local_irq_restore(flags);
+
        show_lli(lli);
 
        dbg_showchan(chan);
@@ -560,26 +563,11 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
 
 EXPORT_SYMBOL(s3c2410_dma_free);
 
-
-static void s3c64xx_dma_tcirq(struct s3c64xx_dmac *dmac, int offs)
-{
-       struct s3c2410_dma_chan *chan = dmac->channels + offs;
-
-       /* note, we currently do not bother to work out which buffer
-        * or buffers have been completed since the last tc-irq. */
-
-       if (chan->callback_fn)
-               (chan->callback_fn)(chan, chan->curr->pw, 0, S3C2410_RES_OK);
-}
-
-static void s3c64xx_dma_errirq(struct s3c64xx_dmac *dmac, int offs)
-{
-       printk(KERN_DEBUG "%s: offs %d\n", __func__, offs);
-}
-
 static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
 {
        struct s3c64xx_dmac *dmac = pw;
+       struct s3c2410_dma_chan *chan;
+       enum s3c2410_dma_buffresult res;
        u32 tcstat, errstat;
        u32 bit;
        int offs;
@@ -588,14 +576,54 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
        errstat = readl(dmac->regs + PL080_ERR_STATUS);
 
        for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
+               struct s3c64xx_dma_buff *buff;
+
+               if (!(errstat & bit) && !(tcstat & bit))
+                       continue;
+
+               chan = dmac->channels + offs;
+               res = S3C2410_RES_ERR;
+
                if (tcstat & bit) {
                        writel(bit, dmac->regs + PL080_TC_CLEAR);
-                       s3c64xx_dma_tcirq(dmac, offs);
+                       res = S3C2410_RES_OK;
                }
 
-               if (errstat & bit) {
-                       s3c64xx_dma_errirq(dmac, offs);
+               if (errstat & bit)
                        writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+               /* 'next' points to the buffer that is next to the
+                * currently active buffer.
+                * For CIRCULAR queues, 'next' will be same as 'curr'
+                * when 'end' is the active buffer.
+                */
+               buff = chan->curr;
+               while (buff && buff != chan->next
+                               && buff->next != chan->next)
+                       buff = buff->next;
+
+               if (!buff)
+                       BUG();
+
+               if (buff == chan->next)
+                       buff = chan->end;
+
+               s3c64xx_dma_bufffdone(chan, buff, res);
+
+               /* Free the node and update curr, if non-circular queue */
+               if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
+                       chan->curr = buff->next;
+                       s3c64xx_dma_freebuff(buff);
+               }
+
+               /* Update 'next' */
+               buff = chan->next;
+               if (chan->next == chan->end) {
+                       chan->next = chan->curr;
+                       if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+                               chan->end = NULL;
+               } else {
+                       chan->next = buff->next;
                }
        }
 
index c41234f..3a9319f 100644 (file)
@@ -11,6 +11,9 @@ config M32R
        select HAVE_IDE
        select HAVE_OPROFILE
        select INIT_ALL_POSSIBLE
+       select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_BZIP2
+       select HAVE_KERNEL_LZMA
 
 config SBUS
        bool
index 560484a..177716b 100644 (file)
@@ -1,11 +1,11 @@
 #
-# linux/arch/sh/boot/compressed/Makefile
+# linux/arch/m32r/boot/compressed/Makefile
 #
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \
-                  piggy.o vmlinux.lds
+targets                := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+                  vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds
 
 OBJECTS = $(obj)/head.o $(obj)/misc.o
 
@@ -27,6 +27,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
        $(call if_changed,gzip)
 
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,lzma)
+
 CFLAGS_misc.o += -fpic
 
 ifdef CONFIG_MMU
@@ -37,5 +43,9 @@ endif
 
 OBJCOPYFLAGS += -R .empty_zero_page
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+suffix_$(CONFIG_KERNEL_GZIP)   = gz
+suffix_$(CONFIG_KERNEL_BZIP2)  = bz2
+suffix_$(CONFIG_KERNEL_LZMA)   = lzma
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
        $(call if_changed,ld)
index d394292..370d608 100644 (file)
  * Adapted for SH by Stuart Menefy, Aug 1999
  *
  * 2003-02-12: Support M32R by Takeo Takahashi
- *             This is based on arch/sh/boot/compressed/misc.c.
  */
 
-#include <linux/string.h>
-
 /*
  * gzip declarations
  */
-
-#define OF(args)  args
 #define STATIC static
 
 #undef memset
 #undef memcpy
 #define memzero(s, n)     memset ((s), 0, (n))
 
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000           /* Window size must be at least 32k, */
-                               /* and a power of two */
-
-static uch *inbuf;          /* input buffer */
-static uch window[WSIZE];    /* Sliding window buffer */
-
-static unsigned insize = 0;  /* valid bytes in inbuf */
-static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;  /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
-#define COMMENT      0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0 /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int  fill_inbuf(void);
-static void flush_window(void);
 static void error(char *m);
 
-static unsigned char *input_data;
-static int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
 #include "m32r_sio.c"
 
 static unsigned long free_mem_ptr;
 static unsigned long free_mem_end_ptr;
 
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-void* memset(void* s, int c, size_t n)
+#ifdef CONFIG_KERNEL_BZIP2
+static void *memset(void *s, int c, size_t n)
 {
-       int i;
-       char *ss = (char*)s;
+       char *ss = s;
 
-       for (i=0;i<n;i++) ss[i] = c;
+       while (n--)
+               *ss++ = c;
        return s;
 }
+#endif
 
-void* memcpy(void* __dest, __const void* __src,
-                           size_t __n)
-{
-       int i;
-       char *d = (char *)__dest, *s = (char *)__src;
-
-       for (i=0;i<__n;i++) d[i] = s[i];
-       return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-       if (insize != 0) {
-               error("ran out of input data");
-       }
-
-       inbuf = input_data;
-       insize = input_len;
-       inptr = 1;
-       return inbuf[0];
-}
+#ifdef CONFIG_KERNEL_GZIP
+#define BOOT_HEAP_SIZE             0x10000
+#include "../../../../lib/decompress_inflate.c"
+#endif
 
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, *out, ch;
+#ifdef CONFIG_KERNEL_BZIP2
+#define BOOT_HEAP_SIZE             0x400000
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
 
-    in = window;
-    out = &output_data[output_ptr];
-    for (n = 0; n < outcnt; n++) {
-           ch = *out++ = *in++;
-           c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    output_ptr += (ulg)outcnt;
-    outcnt = 0;
-}
+#ifdef CONFIG_KERNEL_LZMA
+#define BOOT_HEAP_SIZE             0x10000
+#include "../../../../lib/decompress_unlzma.c"
+#endif
 
 static void error(char *x)
 {
@@ -153,20 +62,20 @@ static void error(char *x)
        while(1);       /* Halt */
 }
 
-/* return decompressed size */
 void
 decompress_kernel(int mmu_on, unsigned char *zimage_data,
                  unsigned int zimage_len, unsigned long heap)
 {
+       unsigned char *input_data = zimage_data;
+       int input_len = zimage_len;
+       unsigned char *output_data;
+
        output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000
                + (mmu_on ? 0x80000000 : 0);
        free_mem_ptr = heap;
-       free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-       input_data = zimage_data;
-       input_len = zimage_len;
+       free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE;
 
-       makecrc();
-       puts("Uncompressing Linux... ");
-       gunzip();
-       puts("Ok, booting the kernel.\n");
+       puts("\nDecompressing Linux... ");
+       decompress(input_data, input_len, NULL, NULL, output_data, NULL, error);
+       puts("done.\nBooting the kernel.\n");
 }
index 8a88f1f..31cef20 100644 (file)
@@ -806,7 +806,7 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
 
        if (mask & ~physids_coerce(phys_cpu_present_map))
                BUG();
-       if (ipi_num >= NR_IPIS)
+       if (ipi_num >= NR_IPIS || ipi_num < 0)
                BUG();
 
        mask <<= IPI_SHIFT;
index e7fee0f..9cedcef 100644 (file)
@@ -75,7 +75,7 @@ u32 arch_gettimeoffset(void)
                count = 0;
 
        count = (latch - count) * TICK_SIZE;
-       elapsed_time = (count + latch / 2) / latch;
+       elapsed_time = DIV_ROUND_CLOSEST(count, latch);
        /* NOTE: LATCH is equal to the "interval" value (= reload count). */
 
 #else /* CONFIG_SMP */
@@ -93,7 +93,7 @@ u32 arch_gettimeoffset(void)
        p_count = count;
 
        count = (latch - count) * TICK_SIZE;
-       elapsed_time = (count + latch / 2) / latch;
+       elapsed_time = DIV_ROUND_CLOSEST(count, latch);
        /* NOTE: LATCH is equal to the "interval" value (= reload count). */
 #endif /* CONFIG_SMP */
 #elif defined(CONFIG_CHIP_M32310)
@@ -211,7 +211,7 @@ void __init time_init(void)
 
                bus_clock = boot_cpu_data.bus_clock;
                divide = boot_cpu_data.timer_divide;
-               latch = (bus_clock/divide + HZ / 2) / HZ;
+               latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ);
 
                printk("Timer start : latch = %ld\n", latch);
 
index 8ceb618..7da94ea 100644 (file)
@@ -42,6 +42,8 @@ SECTIONS
   _etext = .;                  /* End of text section */
 
   EXCEPTION_TABLE(16)
+  NOTES
+
   RODATA
   RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
   _edata = .;                  /* End of data section */
index 10a0a54..2ba14e7 100644 (file)
@@ -414,6 +414,10 @@ config ARCH_SPARSEMEM_DEFAULT
 config ARCH_POPULATES_NODE_MAP
        def_bool y
 
+config SYS_SUPPORTS_HUGETLBFS
+       def_bool y
+       depends on PPC_BOOK3S_64
+
 source "mm/Kconfig"
 
 config ARCH_MEMORY_PROBE
index 92dc844..a136a11 100644 (file)
@@ -777,7 +777,7 @@ int update_persistent_clock(struct timespec now)
        return ppc_md.set_rtc_time(&tm);
 }
 
-void read_persistent_clock(struct timespec *ts)
+static void __read_persistent_clock(struct timespec *ts)
 {
        struct rtc_time tm;
        static int first = 1;
@@ -800,10 +800,23 @@ void read_persistent_clock(struct timespec *ts)
                return;
        }
        ppc_md.get_rtc_time(&tm);
+
        ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
                            tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
 
+void read_persistent_clock(struct timespec *ts)
+{
+       __read_persistent_clock(ts);
+
+       /* Sanitize it in case real time clock is set below EPOCH */
+       if (ts->tv_sec < 0) {
+               ts->tv_sec = 0;
+               ts->tv_nsec = 0;
+       }
+               
+}
+
 /* clocksource code */
 static cycle_t rtc_read(struct clocksource *cs)
 {
index bb13b1f..806ef67 100644 (file)
@@ -48,7 +48,11 @@ static inline void kvmppc_set_exit_type(struct kvm_vcpu *vcpu, int type) {}
 static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type)
 {
        /* type has to be known at build time for optimization */
+
+       /* The BUILD_BUG_ON below breaks in funny ways, commented out
+        * for now ... -BenH
        BUILD_BUG_ON(__builtin_constant_p(type));
+       */
        switch (type) {
        case EXT_INTR_EXITS:
                vcpu->stat.ext_intr_exits++;
index c2f93dc..be4f34c 100644 (file)
@@ -25,8 +25,8 @@
  *     also clear mm->cpu_vm_mask bits when processes are migrated
  */
 
-#define DEBUG_MAP_CONSISTENCY
-#define DEBUG_CLAMP_LAST_CONTEXT   31
+//#define DEBUG_MAP_CONSISTENCY
+//#define DEBUG_CLAMP_LAST_CONTEXT   31
 //#define DEBUG_HARDER
 
 /* We don't use DEBUG because it tends to be compiled in always nowadays
index bf2e1ac..1164c34 100644 (file)
@@ -432,8 +432,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                /* Read config space back so we can restore after reset */
                read_msi_msg(virq, &msg);
                entry->msg = msg;
-
-               unmask_msi_irq(virq);
        }
 
        return 0;
index 419f8a6..b9bf0ee 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/radix-tree.h>
 #include <linux/cpu.h>
+#include <linux/msi.h>
 #include <linux/of.h>
 
 #include <asm/firmware.h>
@@ -219,6 +220,14 @@ static void xics_unmask_irq(unsigned int virq)
 
 static unsigned int xics_startup(unsigned int virq)
 {
+       /*
+        * The generic MSI code returns with the interrupt disabled on the
+        * card, using the MSI mask bits. Firmware doesn't appear to unmask
+        * at that level, so we do it here by hand.
+        */
+       if (irq_to_desc(virq)->msi_desc)
+               unmask_msi_irq(virq);
+
        /* unmask it */
        xics_unmask_irq(virq);
        return 0;
index 1987f3e..06e2251 100644 (file)
@@ -41,7 +41,7 @@ struct rw_semaphore {
 #endif
 
 #define __RWSEM_INITIALIZER(name) \
-       { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+       { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
          LIST_HEAD_INIT((name).wait_list) \
          __RWSEM_DEP_MAP_INIT(name) }
 
index 2d07084..d76a231 100644 (file)
@@ -555,7 +555,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
         * NOTE: the return address is guaranteed to be setup by the
         * time this function makes its first function call.
         */
-       if (!pc && !prev)
+       if (!pc || !prev)
                pc = (unsigned long)current_text_addr();
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
index 519e2d1..b7f235c 100644 (file)
@@ -72,6 +72,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
 
        for (v = start; v < end; v += L1_CACHE_BYTES) {
                unsigned long icacheaddr;
+               int j, n;
 
                __ocbwb(v);
 
@@ -79,8 +80,10 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
                                cpu_data->icache.entry_mask);
 
                /* Clear i-cache line valid-bit */
+               n = boot_cpu_data.icache.n_aliases;
                for (i = 0; i < cpu_data->icache.ways; i++) {
-                       __raw_writel(0, icacheaddr);
+                       for (j = 0; j < n; j++)
+                               __raw_writel(0, icacheaddr + (j * PAGE_SIZE));
                        icacheaddr += cpu_data->icache.way_incr;
                }
        }
index 25e848f..d47a98e 100644 (file)
@@ -63,6 +63,10 @@ do { __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
                             : : : "memory"); \
 } while (0)
 
+/* The kernel always executes in TSO memory model these days,
+ * and furthermore most sparc64 chips implement more stringent
+ * memory ordering than required by the specifications.
+ */
 #define mb()   membar_safe("#StoreLoad")
 #define rmb()  __asm__ __volatile__("":::"memory")
 #define wmb()  __asm__ __volatile__("":::"memory")
index 138910c..d80a65d 100644 (file)
@@ -79,6 +79,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
 
        err = -ENODEV;
 
+       mutex_lock(&of_set_property_mutex);
        write_lock(&devtree_lock);
        prevp = &dp->properties;
        while (*prevp) {
@@ -88,9 +89,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                        void *old_val = prop->value;
                        int ret;
 
-                       mutex_lock(&of_set_property_mutex);
                        ret = prom_setprop(dp->node, name, val, len);
-                       mutex_unlock(&of_set_property_mutex);
 
                        err = -EINVAL;
                        if (ret >= 0) {
@@ -109,6 +108,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                prevp = &(*prevp)->next;
        }
        write_unlock(&devtree_lock);
+       mutex_unlock(&of_set_property_mutex);
 
        /* XXX Upate procfs if necessary... */
 
index b956fd7..d231cbd 100644 (file)
@@ -617,7 +617,7 @@ static void pmul(struct pt_regs *regs, unsigned int insn, unsigned int opf)
                rs2 = fps_regval(f, RS2(insn));
 
                rd_val = 0;
-               src2 = (rs2 >> (opf == FMUL8x16AU_OPF) ? 16 : 0);
+               src2 = rs2 >> (opf == FMUL8x16AU_OPF ? 16 : 0);
                for (byte = 0; byte < 4; byte++) {
                        u16 src1 = (rs1 >> (byte * 8)) & 0x00ff;
                        u32 prod = src1 * src2;
index ac95995..4b18089 100644 (file)
@@ -31,6 +31,7 @@ extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
 extern void amd_iommu_flush_all_domains(void);
 extern void amd_iommu_flush_all_devices(void);
 extern void amd_iommu_shutdown(void);
+extern void amd_iommu_apply_erratum_63(u16 devid);
 #else
 static inline int amd_iommu_init(void) { return -ENODEV; }
 static inline void amd_iommu_detect(void) { }
index e8de2f6..617bd56 100644 (file)
@@ -288,7 +288,7 @@ static inline void load_LDT(mm_context_t *pc)
 
 static inline unsigned long get_desc_base(const struct desc_struct *desc)
 {
-       return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
+       return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
 }
 
 static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
index c3429e8..c978648 100644 (file)
@@ -1000,7 +1000,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
 #define thread_saved_pc(t)     (*(unsigned long *)((t)->thread.sp - 8))
 
 #define task_pt_regs(tsk)      ((struct pt_regs *)(tsk)->thread.sp0 - 1)
-#define KSTK_ESP(tsk)          -1 /* sorry. doesn't work for syscall. */
+extern unsigned long KSTK_ESP(struct task_struct *task);
 #endif /* CONFIG_X86_64 */
 
 extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
index d823c24..40e37b1 100644 (file)
@@ -143,7 +143,7 @@ extern unsigned long node_remap_size[];
                                | 1*SD_BALANCE_FORK                     \
                                | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_PREFER_LOCAL                     \
+                               | 0*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
                                | 0*SD_SHARE_PKG_RESOURCES              \
index 98f230f..0285521 100644 (file)
@@ -1220,6 +1220,8 @@ static void __detach_device(struct protection_domain *domain, u16 devid)
        amd_iommu_dev_table[devid].data[1] = 0;
        amd_iommu_dev_table[devid].data[2] = 0;
 
+       amd_iommu_apply_erratum_63(devid);
+
        /* decrease reference counter */
        domain->dev_cnt -= 1;
 
index b4b61d4..c20001e 100644 (file)
@@ -240,7 +240,7 @@ static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
        writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
 }
 
-static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
+static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
 {
        u32 ctrl;
 
@@ -519,6 +519,26 @@ static void set_dev_entry_bit(u16 devid, u8 bit)
        amd_iommu_dev_table[devid].data[i] |= (1 << _bit);
 }
 
+static int get_dev_entry_bit(u16 devid, u8 bit)
+{
+       int i = (bit >> 5) & 0x07;
+       int _bit = bit & 0x1f;
+
+       return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit;
+}
+
+
+void amd_iommu_apply_erratum_63(u16 devid)
+{
+       int sysmgt;
+
+       sysmgt = get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT1) |
+                (get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT2) << 1);
+
+       if (sysmgt == 0x01)
+               set_dev_entry_bit(devid, DEV_ENTRY_IW);
+}
+
 /* Writes the specific IOMMU for a device into the rlookup table */
 static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid)
 {
@@ -547,6 +567,8 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
        if (flags & ACPI_DEVFLAG_LINT1)
                set_dev_entry_bit(devid, DEV_ENTRY_LINT1_PASS);
 
+       amd_iommu_apply_erratum_63(devid);
+
        set_iommu_for_device(iommu, devid);
 }
 
index 315738c..73c86db 100644 (file)
@@ -846,7 +846,7 @@ int __init mtrr_cleanup(unsigned address_bits)
        sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
 
        range_sums = sum_ranges(range, nr_range);
-       printk(KERN_INFO "total RAM coverred: %ldM\n",
+       printk(KERN_INFO "total RAM covered: %ldM\n",
               range_sums >> (20 - PAGE_SHIFT));
 
        if (mtrr_chunk_size && mtrr_gran_size) {
index 366baa1..f4c538b 100644 (file)
@@ -317,6 +317,12 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device)
                return UCODE_NFOUND;
        }
 
+       if (*(u32 *)firmware->data != UCODE_MAGIC) {
+               printk(KERN_ERR "microcode: invalid UCODE_MAGIC (0x%08x)\n",
+                      *(u32 *)firmware->data);
+               return UCODE_ERROR;
+       }
+
        ret = generic_load_microcode(cpu, firmware->data, firmware->size);
 
        release_firmware(firmware);
index ad535b6..eb62cbc 100644 (file)
@@ -664,3 +664,8 @@ long sys_arch_prctl(int code, unsigned long addr)
        return do_arch_prctl(current, code, addr);
 }
 
+unsigned long KSTK_ESP(struct task_struct *task)
+{
+       return (test_tsk_thread_flag(task, TIF_IA32)) ?
+                       (task_pt_regs(task)->sp) : ((task)->thread.usersp);
+}
index a1a3cdd..f930787 100644 (file)
@@ -436,6 +436,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"),
                },
        },
+       {       /* Handle problems with rebooting on Apple Macmini3,1 */
+               .callback = set_pci_reboot,
+               .ident = "Apple Macmini3,1",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"),
+               },
+       },
        { }
 };
 
index e09f0e2..2a34f9c 100644 (file)
@@ -660,6 +660,13 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
                },
        },
        {
+               .callback = dmi_low_memory_corruption,
+               .ident = "Phoenix/MSC BIOS",
+               .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
+               },
+       },
+       {
        /*
         * AMI BIOS with low memory corruption was found on Intel DG45ID board.
         * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
index 9b96953..ae07d26 100644 (file)
@@ -1692,7 +1692,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
        unsigned bank_num = mcg_cap & 0xff, bank;
 
        r = -EINVAL;
-       if (!bank_num)
+       if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS)
                goto out;
        if (mcg_cap & ~(KVM_MCE_CAP_SUPPORTED | 0xff | 0xff0000))
                goto out;
@@ -4051,7 +4051,7 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
        return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
 }
 
-static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
+static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu,
                             struct desc_struct *seg_desc)
 {
        u32 base_addr = get_desc_base(seg_desc);
index 334e63c..2feb9bd 100644 (file)
@@ -170,8 +170,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
                                (unsigned long long)phys_addr,
                                (unsigned long long)(phys_addr + size),
                                prot_val, new_prot_val);
-                       free_memtype(phys_addr, phys_addr + size);
-                       return NULL;
+                       goto err_free_memtype;
                }
                prot_val = new_prot_val;
        }
@@ -197,26 +196,25 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
         */
        area = get_vm_area_caller(size, VM_IOREMAP, caller);
        if (!area)
-               return NULL;
+               goto err_free_memtype;
        area->phys_addr = phys_addr;
        vaddr = (unsigned long) area->addr;
 
-       if (kernel_map_sync_memtype(phys_addr, size, prot_val)) {
-               free_memtype(phys_addr, phys_addr + size);
-               free_vm_area(area);
-               return NULL;
-       }
+       if (kernel_map_sync_memtype(phys_addr, size, prot_val))
+               goto err_free_area;
 
-       if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
-               free_memtype(phys_addr, phys_addr + size);
-               free_vm_area(area);
-               return NULL;
-       }
+       if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot))
+               goto err_free_area;
 
        ret_addr = (void __iomem *) (vaddr + offset);
        mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr);
 
        return ret_addr;
+err_free_area:
+       free_vm_area(area);
+err_free_memtype:
+       free_memtype(phys_addr, phys_addr + size);
+       return NULL;
 }
 
 /**
index 23a4d80..dfbf70e 100644 (file)
@@ -178,6 +178,7 @@ static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
 static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                      unsigned int *cx, unsigned int *dx)
 {
+       unsigned maskebx = ~0;
        unsigned maskecx = ~0;
        unsigned maskedx = ~0;
 
@@ -185,9 +186,16 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
         * Mask out inconvenient features, to try and disable as many
         * unsupported kernel subsystems as possible.
         */
-       if (*ax == 1) {
+       switch (*ax) {
+       case 1:
                maskecx = cpuid_leaf1_ecx_mask;
                maskedx = cpuid_leaf1_edx_mask;
+               break;
+
+       case 0xb:
+               /* Suppress extended topology stuff */
+               maskebx = 0;
+               break;
        }
 
        asm(XEN_EMULATE_PREFIX "cpuid"
@@ -197,6 +205,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                  "=d" (*dx)
                : "0" (*ax), "2" (*cx));
 
+       *bx &= maskebx;
        *cx &= maskecx;
        *dx &= maskedx;
 }
index 8e679ef..a4471e3 100644 (file)
 
 #define ACPI_MAX_REFERENCE_COUNT        0x1000
 
-/* Size of cached memory mapping for system memory operation region */
+/* Default page size for use in mapping memory for operation regions */
 
-#define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
+#define ACPI_DEFAULT_PAGE_SIZE          4096   /* Must be power of 2 */
 
 /* owner_id tracking. 8 entries allows for 255 owner_ids */
 
index 3a54b73..2bd83ac 100644 (file)
@@ -77,7 +77,8 @@ acpi_ex_system_memory_space_handler(u32 function,
        void *logical_addr_ptr = NULL;
        struct acpi_mem_space_context *mem_info = region_context;
        u32 length;
-       acpi_size window_size;
+       acpi_size map_length;
+       acpi_size page_boundary_map_length;
 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
        u32 remainder;
 #endif
@@ -144,25 +145,39 @@ acpi_ex_system_memory_space_handler(u32 function,
                }
 
                /*
-                * Don't attempt to map memory beyond the end of the region, and
-                * constrain the maximum mapping size to something reasonable.
+                * Attempt to map from the requested address to the end of the region.
+                * However, we will never map more than one page, nor will we cross
+                * a page boundary.
                 */
-               window_size = (acpi_size)
+               map_length = (acpi_size)
                    ((mem_info->address + mem_info->length) - address);
 
-               if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
-                       window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
+               /*
+                * If mapping the entire remaining portion of the region will cross
+                * a page boundary, just map up to the page boundary, do not cross.
+                * On some systems, crossing a page boundary while mapping regions
+                * can cause warnings if the pages have different attributes
+                * due to resource management
+                */
+               page_boundary_map_length =
+                   ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address;
+
+               if (!page_boundary_map_length) {
+                       page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
+               }
+
+               if (map_length > page_boundary_map_length) {
+                       map_length = page_boundary_map_length;
                }
 
                /* Create a new mapping starting at the address given */
 
-               mem_info->mapped_logical_address =
-                       acpi_os_map_memory((acpi_physical_address) address, window_size);
+               mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length);
                if (!mem_info->mapped_logical_address) {
                        ACPI_ERROR((AE_INFO,
                                    "Could not map memory at %8.8X%8.8X, size %X",
                                    ACPI_FORMAT_NATIVE_UINT(address),
-                                   (u32) window_size));
+                                   (u32) map_length));
                        mem_info->mapped_length = 0;
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
@@ -170,7 +185,7 @@ acpi_ex_system_memory_space_handler(u32 function,
                /* Save the physical address and mapping size */
 
                mem_info->mapped_physical_address = address;
-               mem_info->mapped_length = window_size;
+               mem_info->mapped_length = map_length;
        }
 
        /*
index e6bfd77..2ef7030 100644 (file)
@@ -294,7 +294,11 @@ static int set_acpi_trip(struct acpi_power_meter_resource *resource)
                return -EINVAL;
        }
 
-       return data;
+       /* _PTP returns 0 on success, nonzero otherwise */
+       if (data)
+               return -EINVAL;
+
+       return 0;
 }
 
 static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
index f8b6f55..d0d25e2 100644 (file)
@@ -393,7 +393,7 @@ acpi_system_write_wakeup_device(struct file *file,
        struct list_head *node, *next;
        char strbuf[5];
        char str[5] = "";
-       int len = count;
+       unsigned int len = count;
        struct acpi_device *found_dev = NULL;
 
        if (len > 4)
index c567b46..ec742a4 100644 (file)
@@ -770,7 +770,7 @@ static struct notifier_block acpi_cpu_notifier =
            .notifier_call = acpi_cpu_soft_notify,
 };
 
-static int acpi_processor_add(struct acpi_device *device)
+static int __cpuinit acpi_processor_add(struct acpi_device *device)
 {
        struct acpi_processor *pr = NULL;
        int result = 0;
index 4c6c14c..1c5d7a8 100644 (file)
@@ -1133,15 +1133,15 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
        int result = 0;
        struct acpi_processor_throttling *pthrottling;
 
+       if (!pr)
+               return -EINVAL;
+
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
                          pr->throttling.address,
                          pr->throttling.duty_offset,
                          pr->throttling.duty_width));
 
-       if (!pr)
-               return -EINVAL;
-
        /*
         * Evaluate _PTC, _TSS and _TPC
         * They must all be present or none of them can be used.
index a90afcc..4cc1b81 100644 (file)
@@ -413,6 +413,30 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                },
        },
        {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Hewlett-Packard Pavilion dv4",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Hewlett-Packard Pavilion dv7",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"),
+               },
+       },
+       {
        .callback = init_old_suspend_ordering,
        .ident = "Panasonic CF51-2L",
        .matches = {
index 64e3c58..05dff63 100644 (file)
@@ -1223,7 +1223,7 @@ acpi_video_device_write_state(struct file *file,
        u32 state = 0;
 
 
-       if (!dev || count + 1 > sizeof str)
+       if (!dev || count >= sizeof(str))
                return -EINVAL;
 
        if (copy_from_user(str, buffer, count))
@@ -1280,7 +1280,7 @@ acpi_video_device_write_brightness(struct file *file,
        int i;
 
 
-       if (!dev || !dev->brightness || count + 1 > sizeof str)
+       if (!dev || !dev->brightness || count >= sizeof(str))
                return -EINVAL;
 
        if (copy_from_user(str, buffer, count))
@@ -1562,7 +1562,7 @@ acpi_video_bus_write_POST(struct file *file,
        unsigned long long opt, options;
 
 
-       if (!video || count + 1 > sizeof str)
+       if (!video || count >= sizeof(str))
                return -EINVAL;
 
        status = acpi_video_bus_POST_options(video, &options);
@@ -1602,7 +1602,7 @@ acpi_video_bus_write_DOS(struct file *file,
        unsigned long opt;
 
 
-       if (!video || count + 1 > sizeof str)
+       if (!video || count >= sizeof(str))
                return -EINVAL;
 
        if (copy_from_user(str, buffer, count))
index eba999f..a6ee32b 100644 (file)
@@ -55,7 +55,7 @@ static inline void notify_daemon(void)
        notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
 }
 
-static int write_console(uint32_t vtermno, const char *data, int len)
+static int __write_console(const char *data, int len)
 {
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
@@ -76,6 +76,29 @@ static int write_console(uint32_t vtermno, const char *data, int len)
        return sent;
 }
 
+static int write_console(uint32_t vtermno, const char *data, int len)
+{
+       int ret = len;
+
+       /*
+        * Make sure the whole buffer is emitted, polling if
+        * necessary.  We don't ever want to rely on the hvc daemon
+        * because the most interesting console output is when the
+        * kernel is crippled.
+        */
+       while (len) {
+               int sent = __write_console(data, len);
+               
+               data += sent;
+               len -= sent;
+
+               if (unlikely(len))
+                       HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+       }
+
+       return ret;
+}
+
 static int read_console(uint32_t vtermno, char *buf, int len)
 {
        struct xencons_interface *intf = xencons_interface();
index d4560d9..a38831c 100644 (file)
@@ -2254,7 +2254,7 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
 {
        u32 ec  = ERROR_CODE(info->nbsl);
        u32 xec = EXT_ERROR_CODE(info->nbsl);
-       int ecc_type = info->nbsh & (0x3 << 13);
+       int ecc_type = (info->nbsh >> 13) & 0x3;
 
        /* Bail early out if this was an 'observed' error */
        if (PP(ec) == K8_NBSL_PP_OBS)
@@ -3163,7 +3163,7 @@ static int __init amd64_edac_init(void)
        opstate_init();
 
        if (cache_k8_northbridges() < 0)
-               goto err_exit;
+               return err;
 
        err = pci_register_driver(&amd64_pci_driver);
        if (err)
@@ -3189,8 +3189,6 @@ static int __init amd64_edac_init(void)
 
 err_2nd_stage:
        debugf0("2nd stage failed\n");
-
-err_exit:
        pci_unregister_driver(&amd64_pci_driver);
 
        return err;
index 1fe4e1d..bbfd110 100644 (file)
@@ -331,6 +331,7 @@ create_mode:
                            cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
                            cmdline_mode->rb, cmdline_mode->interlace,
                            cmdline_mode->margins);
+       drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
        list_add(&mode->head, &connector->modes);
        return mode;
 }
index 9c92461..dc8e374 100644 (file)
@@ -707,7 +707,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
 
                if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
                        mutex_lock(&dev->mode_config.mutex);
-                       ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
+                       ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
                        mutex_unlock(&dev->mode_config.mutex);
                        if (ret)
                                return ret;
index 09a2892..b5713ee 100644 (file)
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \
        radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.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
+       r600_blit_kms.o radeon_pm.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 
index 5d40208..c11dddd 100644 (file)
@@ -2314,7 +2314,7 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT {
        UCHAR ucSS_Step;
        UCHAR ucSS_Delay;
        UCHAR ucSS_Id;
-       UCHAR ucRecommandedRef_Div;
+       UCHAR ucRecommendedRef_Div;
        UCHAR ucSS_Range;       /* it was reserved for V11 */
 } ATOM_SPREAD_SPECTRUM_ASSIGNMENT;
 
index 14fa970..c15287a 100644 (file)
 #include "atom.h"
 #include "atom-bits.h"
 
-/* evil but including atombios.h is much worse */
-bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
-                               SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
-                               int32_t *pixel_clock);
 static void atombios_overscan_setup(struct drm_crtc *crtc,
                                    struct drm_display_mode *mode,
                                    struct drm_display_mode *adjusted_mode)
@@ -248,18 +244,18 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
+               atombios_enable_crtc(crtc, 1);
                if (ASIC_IS_DCE3(rdev))
                        atombios_enable_crtc_memreq(crtc, 1);
-               atombios_enable_crtc(crtc, 1);
                atombios_blank_crtc(crtc, 0);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
                atombios_blank_crtc(crtc, 1);
-               atombios_enable_crtc(crtc, 0);
                if (ASIC_IS_DCE3(rdev))
                        atombios_enable_crtc_memreq(crtc, 0);
+               atombios_enable_crtc(crtc, 0);
                break;
        }
 
@@ -270,59 +266,147 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
 
 static void
 atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
-                            SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param)
+                            struct drm_display_mode *mode)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
-       SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
+       SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
        int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
+       u16 misc = 0;
 
-       conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size);
-       conv_param.usH_Blanking_Time =
-           cpu_to_le16(crtc_param->usH_Blanking_Time);
-       conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size);
-       conv_param.usV_Blanking_Time =
-           cpu_to_le16(crtc_param->usV_Blanking_Time);
-       conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset);
-       conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
-       conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset);
-       conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
-       conv_param.susModeMiscInfo.usAccess =
-           cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
-       conv_param.ucCRTC = crtc_param->ucCRTC;
+       memset(&args, 0, sizeof(args));
+       args.usH_Size = cpu_to_le16(mode->crtc_hdisplay);
+       args.usH_Blanking_Time =
+               cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay);
+       args.usV_Size = cpu_to_le16(mode->crtc_vdisplay);
+       args.usV_Blanking_Time =
+           cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay);
+       args.usH_SyncOffset =
+               cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay);
+       args.usH_SyncWidth =
+               cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
+       args.usV_SyncOffset =
+               cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay);
+       args.usV_SyncWidth =
+               cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
+       /*args.ucH_Border = mode->hborder;*/
+       /*args.ucV_Border = mode->vborder;*/
+
+       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+               misc |= ATOM_VSYNC_POLARITY;
+       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+               misc |= ATOM_HSYNC_POLARITY;
+       if (mode->flags & DRM_MODE_FLAG_CSYNC)
+               misc |= ATOM_COMPOSITESYNC;
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               misc |= ATOM_INTERLACE;
+       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+               misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+       args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
+       args.ucCRTC = radeon_crtc->crtc_id;
 
        printk("executing set crtc dtd timing\n");
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-void atombios_crtc_set_timing(struct drm_crtc *crtc,
-                             SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *
-                             crtc_param)
+static void atombios_crtc_set_timing(struct drm_crtc *crtc,
+                                    struct drm_display_mode *mode)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
-       SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
+       SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
        int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
+       u16 misc = 0;
 
-       conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total);
-       conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp);
-       conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart);
-       conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
-       conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total);
-       conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp);
-       conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart);
-       conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
-       conv_param.susModeMiscInfo.usAccess =
-           cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
-       conv_param.ucCRTC = crtc_param->ucCRTC;
-       conv_param.ucOverscanRight = crtc_param->ucOverscanRight;
-       conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft;
-       conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom;
-       conv_param.ucOverscanTop = crtc_param->ucOverscanTop;
-       conv_param.ucReserved = crtc_param->ucReserved;
+       memset(&args, 0, sizeof(args));
+       args.usH_Total = cpu_to_le16(mode->crtc_htotal);
+       args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
+       args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
+       args.usH_SyncWidth =
+               cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
+       args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
+       args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
+       args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
+       args.usV_SyncWidth =
+               cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
+
+       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+               misc |= ATOM_VSYNC_POLARITY;
+       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+               misc |= ATOM_HSYNC_POLARITY;
+       if (mode->flags & DRM_MODE_FLAG_CSYNC)
+               misc |= ATOM_COMPOSITESYNC;
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               misc |= ATOM_INTERLACE;
+       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+               misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+       args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
+       args.ucCRTC = radeon_crtc->crtc_id;
 
        printk("executing set crtc timing\n");
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+static void atombios_set_ss(struct drm_crtc *crtc, int enable)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_encoder *encoder = NULL;
+       struct radeon_encoder *radeon_encoder = NULL;
+       struct radeon_encoder_atom_dig *dig = NULL;
+       int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
+       ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args;
+       ENABLE_LVDS_SS_PARAMETERS legacy_args;
+       uint16_t percentage = 0;
+       uint8_t type = 0, step = 0, delay = 0, range = 0;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc == crtc) {
+                       radeon_encoder = to_radeon_encoder(encoder);
+                       /* only enable spread spectrum on LVDS */
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               dig = radeon_encoder->enc_priv;
+                               if (dig && dig->ss) {
+                                       percentage = dig->ss->percentage;
+                                       type = dig->ss->type;
+                                       step = dig->ss->step;
+                                       delay = dig->ss->delay;
+                                       range = dig->ss->range;
+                               } else if (enable)
+                                       return;
+                       } else if (enable)
+                               return;
+                       break;
+               }
+       }
+
+       if (!radeon_encoder)
+               return;
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               memset(&args, 0, sizeof(args));
+               args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+               args.ucSpreadSpectrumType = type;
+               args.ucSpreadSpectrumStep = step;
+               args.ucSpreadSpectrumDelay = delay;
+               args.ucSpreadSpectrumRange = range;
+               args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+               args.ucEnable = enable;
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       } else {
+               memset(&legacy_args, 0, sizeof(legacy_args));
+               legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+               legacy_args.ucSpreadSpectrumType = type;
+               legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
+               legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
+               legacy_args.ucEnable = enable;
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args);
+       }
 }
 
 void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
@@ -333,12 +417,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
        struct drm_encoder *encoder = NULL;
        struct radeon_encoder *radeon_encoder = NULL;
        uint8_t frev, crev;
-       int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+       int index;
        SET_PIXEL_CLOCK_PS_ALLOCATION args;
        PIXEL_CLOCK_PARAMETERS *spc1_ptr;
        PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
        PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
-       uint32_t sclock = mode->clock;
+       uint32_t pll_clock = mode->clock;
+       uint32_t adjusted_clock;
        uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
        struct radeon_pll *pll;
        int pll_flags = 0;
@@ -346,8 +431,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
        memset(&args, 0, sizeof(args));
 
        if (ASIC_IS_AVIVO(rdev)) {
-               uint32_t ss_cntl;
-
                if ((rdev->family == CHIP_RS600) ||
                    (rdev->family == CHIP_RS690) ||
                    (rdev->family == CHIP_RS740))
@@ -358,15 +441,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                        pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
                else
                        pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
-
-               /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
-               if (radeon_crtc->crtc_id == 0) {
-                       ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
-                       WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1);
-               } else {
-                       ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
-                       WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1);
-               }
        } else {
                pll_flags |= RADEON_PLL_LEGACY;
 
@@ -393,14 +467,43 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                }
        }
 
+       /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
+        * accordingly based on the encoder/transmitter to work around
+        * special hw requirements.
+        */
+       if (ASIC_IS_DCE3(rdev)) {
+               ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args;
+
+               if (!encoder)
+                       return;
+
+               memset(&adjust_pll_args, 0, sizeof(adjust_pll_args));
+               adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10);
+               adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id;
+               adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
+
+               index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+               atom_execute_table(rdev->mode_info.atom_context,
+                                  index, (uint32_t *)&adjust_pll_args);
+               adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10;
+       } else {
+               /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
+               if (ASIC_IS_AVIVO(rdev) &&
+                   (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))
+                       adjusted_clock = mode->clock * 2;
+               else
+                       adjusted_clock = mode->clock;
+       }
+
        if (radeon_crtc->crtc_id == 0)
                pll = &rdev->clock.p1pll;
        else
                pll = &rdev->clock.p2pll;
 
-       radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div,
+       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
                           &ref_div, &post_div, pll_flags);
 
+       index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
                              &crev);
 
@@ -409,7 +512,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                switch (crev) {
                case 1:
                        spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
-                       spc1_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc1_ptr->ucFracFbDiv = frac_fb_div;
@@ -422,7 +525,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                case 2:
                        spc2_ptr =
                            (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
-                       spc2_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc2_ptr->ucFracFbDiv = frac_fb_div;
@@ -437,7 +540,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                                return;
                        spc3_ptr =
                            (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
-                       spc3_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc3_ptr->ucFracFbDiv = frac_fb_div;
@@ -527,6 +630,16 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                WREG32(AVIVO_D1VGA_CONTROL, 0);
        else
                WREG32(AVIVO_D2VGA_CONTROL, 0);
+
+       if (rdev->family >= CHIP_RV770) {
+               if (radeon_crtc->crtc_id) {
+                       WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
+                       WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+               } else {
+                       WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
+                       WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+               }
+       }
        WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
               (u32) fb_location);
        WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
@@ -563,6 +676,10 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                radeon_fb = to_radeon_framebuffer(old_fb);
                radeon_gem_object_unpin(radeon_fb->obj);
        }
+
+       /* Bytes per pixel may have changed */
+       radeon_bandwidth_update(rdev);
+
        return 0;
 }
 
@@ -574,134 +691,24 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
-       struct drm_encoder *encoder;
-       SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
-       int need_tv_timings = 0;
-       bool ret;
 
        /* TODO color tiling */
-       memset(&crtc_timing, 0, sizeof(crtc_timing));
-
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               /* find tv std */
-               if (encoder->crtc == crtc) {
-                       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-
-                       if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
-                               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
-                               if (tv_dac) {
-                                       if (tv_dac->tv_std == TV_STD_NTSC ||
-                                           tv_dac->tv_std == TV_STD_NTSC_J ||
-                                           tv_dac->tv_std == TV_STD_PAL_M)
-                                               need_tv_timings = 1;
-                                       else
-                                               need_tv_timings = 2;
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       crtc_timing.ucCRTC = radeon_crtc->crtc_id;
-       if (need_tv_timings) {
-               ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
-                                                &crtc_timing, &adjusted_mode->clock);
-               if (ret == false)
-                       need_tv_timings = 0;
-       }
-
-       if (!need_tv_timings) {
-               crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
-               crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
-               crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
-               crtc_timing.usH_SyncWidth =
-                       adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
-
-               crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
-               crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
-               crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
-               crtc_timing.usV_SyncWidth =
-                       adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
-
-               if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
-                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
-
-               if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
-                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
-
-               if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
-                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
-
-               if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
-
-               if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
-                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
-       }
 
+       atombios_set_ss(crtc, 0);
        atombios_crtc_set_pll(crtc, adjusted_mode);
-       atombios_crtc_set_timing(crtc, &crtc_timing);
+       atombios_set_ss(crtc, 1);
+       atombios_crtc_set_timing(crtc, adjusted_mode);
 
        if (ASIC_IS_AVIVO(rdev))
                atombios_crtc_set_base(crtc, x, y, old_fb);
        else {
-               if (radeon_crtc->crtc_id == 0) {
-                       SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
-                       memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
-
-                       /* setup FP shadow regs on R4xx */
-                       crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
-                       crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay;
-                       crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay;
-                       crtc_dtd_timing.usH_Blanking_Time =
-                           adjusted_mode->crtc_hblank_end -
-                           adjusted_mode->crtc_hdisplay;
-                       crtc_dtd_timing.usV_Blanking_Time =
-                           adjusted_mode->crtc_vblank_end -
-                           adjusted_mode->crtc_vdisplay;
-                       crtc_dtd_timing.usH_SyncOffset =
-                           adjusted_mode->crtc_hsync_start -
-                           adjusted_mode->crtc_hdisplay;
-                       crtc_dtd_timing.usV_SyncOffset =
-                           adjusted_mode->crtc_vsync_start -
-                           adjusted_mode->crtc_vdisplay;
-                       crtc_dtd_timing.usH_SyncWidth =
-                           adjusted_mode->crtc_hsync_end -
-                           adjusted_mode->crtc_hsync_start;
-                       crtc_dtd_timing.usV_SyncWidth =
-                           adjusted_mode->crtc_vsync_end -
-                           adjusted_mode->crtc_vsync_start;
-                       /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */
-                       /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */
-
-                       if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
-                               crtc_dtd_timing.susModeMiscInfo.usAccess |=
-                                   ATOM_VSYNC_POLARITY;
-
-                       if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
-                               crtc_dtd_timing.susModeMiscInfo.usAccess |=
-                                   ATOM_HSYNC_POLARITY;
-
-                       if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
-                               crtc_dtd_timing.susModeMiscInfo.usAccess |=
-                                   ATOM_COMPOSITESYNC;
-
-                       if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-                               crtc_dtd_timing.susModeMiscInfo.usAccess |=
-                                   ATOM_INTERLACE;
-
-                       if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
-                               crtc_dtd_timing.susModeMiscInfo.usAccess |=
-                                   ATOM_DOUBLE_CLOCK_MODE;
-
-                       atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing);
-               }
+               if (radeon_crtc->crtc_id == 0)
+                       atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
                radeon_crtc_set_base(crtc, x, y, old_fb);
                radeon_legacy_atom_set_surface(crtc);
        }
        atombios_overscan_setup(crtc, mode, adjusted_mode);
        atombios_scaler_setup(crtc);
-       radeon_bandwidth_update(rdev);
        return 0;
 }
 
index 161094c..c9e93ea 100644 (file)
@@ -186,7 +186,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
 
 int r100_irq_process(struct radeon_device *rdev)
 {
-       uint32_t status;
+       uint32_t status, msi_rearm;
 
        status = r100_irq_ack(rdev);
        if (!status) {
@@ -209,6 +209,21 @@ int r100_irq_process(struct radeon_device *rdev)
                }
                status = r100_irq_ack(rdev);
        }
+       if (rdev->msi_enabled) {
+               switch (rdev->family) {
+               case CHIP_RS400:
+               case CHIP_RS480:
+                       msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM;
+                       WREG32(RADEON_AIC_CNTL, msi_rearm);
+                       WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
+                       break;
+               default:
+                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       break;
+               }
+       }
        return IRQ_HANDLED;
 }
 
@@ -240,7 +255,7 @@ int r100_wb_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096,
+               r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
                                         true,
                                         RADEON_GEM_DOMAIN_GTT,
                                         false, &rdev->wb.wb_obj);
@@ -563,19 +578,19 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        indirect1_start = 16;
        /* cp setup */
        WREG32(0x718, pre_write_timer | (pre_write_limit << 28));
-       WREG32(RADEON_CP_RB_CNTL,
-#ifdef __BIG_ENDIAN
-              RADEON_BUF_SWAP_32BIT |
-#endif
-              REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
+       tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
               REG_SET(RADEON_RB_BLKSZ, rb_blksz) |
               REG_SET(RADEON_MAX_FETCH, max_fetch) |
               RADEON_RB_NO_UPDATE);
+#ifdef __BIG_ENDIAN
+       tmp |= RADEON_BUF_SWAP_32BIT;
+#endif
+       WREG32(RADEON_CP_RB_CNTL, tmp);
+
        /* Set ring address */
        DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr);
        WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr);
        /* Force read & write ptr to 0 */
-       tmp = RREG32(RADEON_CP_RB_CNTL);
        WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
        WREG32(RADEON_CP_RB_RPTR_WR, 0);
        WREG32(RADEON_CP_RB_WPTR, 0);
@@ -2364,7 +2379,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)
        /*
          Find the total latency for the display data.
        */
-       disp_latency_overhead.full = rfixed_const(80);
+       disp_latency_overhead.full = rfixed_const(8);
        disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff);
        mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full;
        mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full;
@@ -2562,8 +2577,11 @@ void r100_bandwidth_update(struct radeon_device *rdev)
 static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
 {
        DRM_ERROR("pitch                      %d\n", t->pitch);
+       DRM_ERROR("use_pitch                  %d\n", t->use_pitch);
        DRM_ERROR("width                      %d\n", t->width);
+       DRM_ERROR("width_11                   %d\n", t->width_11);
        DRM_ERROR("height                     %d\n", t->height);
+       DRM_ERROR("height_11                  %d\n", t->height_11);
        DRM_ERROR("num levels                 %d\n", t->num_levels);
        DRM_ERROR("depth                      %d\n", t->txdepth);
        DRM_ERROR("bpp                        %d\n", t->cpp);
@@ -2623,15 +2641,17 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
                                else
                                        w = track->textures[u].pitch / (1 << i);
                        } else {
-                               w = track->textures[u].width / (1 << i);
+                               w = track->textures[u].width;
                                if (rdev->family >= CHIP_RV515)
                                        w |= track->textures[u].width_11;
+                               w = w / (1 << i);
                                if (track->textures[u].roundup_w)
                                        w = roundup_pow_of_two(w);
                        }
-                       h = track->textures[u].height / (1 << i);
+                       h = track->textures[u].height;
                        if (rdev->family >= CHIP_RV515)
                                h |= track->textures[u].height_11;
+                       h = h / (1 << i);
                        if (track->textures[u].roundup_h)
                                h = roundup_pow_of_two(h);
                        size += w * h;
index e08c4a8..2f43ee8 100644 (file)
@@ -113,7 +113,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
        tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
        WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
        WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location);
-       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096;
+       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE;
        WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp);
        WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
        WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
index 5c7fe52..1cefdbc 100644 (file)
@@ -311,6 +311,8 @@ int r420_init(struct radeon_device *rdev)
        }
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        r300_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
index 868add6..7baa739 100644 (file)
 #       define AVIVO_D1GRPH_TILED                               (1 << 20)
 #       define AVIVO_D1GRPH_MACRO_ADDRESS_MODE                  (1 << 21)
 
+/* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2
+ * block and vice versa.  This applies to GRPH, CUR, etc.
+ */
 #define AVIVO_D1GRPH_LUT_SEL                                    0x6108
 #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS                    0x6110
+#define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH                0x6914
+#define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH                0x6114
 #define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS                  0x6118
+#define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH              0x691c
+#define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH              0x611c
 #define AVIVO_D1GRPH_PITCH                                      0x6120
 #define AVIVO_D1GRPH_SURFACE_OFFSET_X                           0x6124
 #define AVIVO_D1GRPH_SURFACE_OFFSET_Y                           0x6128
 #       define AVIVO_D1CURSOR_MODE_MASK         (3 << 8)
 #       define AVIVO_D1CURSOR_MODE_24BPP        2
 #define AVIVO_D1CUR_SURFACE_ADDRESS             0x6408
+#define R700_D1CUR_SURFACE_ADDRESS_HIGH         0x6c0c
+#define R700_D2CUR_SURFACE_ADDRESS_HIGH         0x640c
 #define AVIVO_D1CUR_SIZE                        0x6410
 #define AVIVO_D1CUR_POSITION                    0x6414
 #define AVIVO_D1CUR_HOT_SPOT                    0x6418
index a555b7b..f743518 100644 (file)
@@ -260,6 +260,8 @@ int r520_init(struct radeon_device *rdev)
        }
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        r520_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
index 6097194..278f646 100644 (file)
@@ -339,11 +339,10 @@ int r600_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
        u32 tmp;
-       int chansize;
+       int chansize, numchan;
        int r;
 
        /* Get VRAM informations */
-       rdev->mc.vram_width = 128;
        rdev->mc.vram_is_ddr = true;
        tmp = RREG32(RAMCFG);
        if (tmp & CHANSIZE_OVERRIDE) {
@@ -353,17 +352,23 @@ int r600_mc_init(struct radeon_device *rdev)
        } else {
                chansize = 32;
        }
-       if (rdev->family == CHIP_R600) {
-               rdev->mc.vram_width = 8 * chansize;
-       } else if (rdev->family == CHIP_RV670) {
-               rdev->mc.vram_width = 4 * chansize;
-       } else if ((rdev->family == CHIP_RV610) ||
-                       (rdev->family == CHIP_RV620)) {
-               rdev->mc.vram_width = chansize;
-       } else if ((rdev->family == CHIP_RV630) ||
-                       (rdev->family == CHIP_RV635)) {
-               rdev->mc.vram_width = 2 * chansize;
+       tmp = RREG32(CHMAP);
+       switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+       case 0:
+       default:
+               numchan = 1;
+               break;
+       case 1:
+               numchan = 2;
+               break;
+       case 2:
+               numchan = 4;
+               break;
+       case 3:
+               numchan = 8;
+               break;
        }
+       rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
        rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
        rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
@@ -404,35 +409,29 @@ int r600_mc_init(struct radeon_device *rdev)
                        rdev->mc.gtt_location = rdev->mc.mc_vram_size;
                }
        } else {
-               if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
-                       rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
-                                                               0xFFFF) << 24;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-                       tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
-                       if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
-                               /* Enough place after vram */
-                               rdev->mc.gtt_location = tmp;
-                       } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
-                               /* Enough place before vram */
+               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+               rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
+                                                       0xFFFF) << 24;
+               tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+               if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
+                       /* Enough place after vram */
+                       rdev->mc.gtt_location = tmp;
+               } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
+                       /* Enough place before vram */
+                       rdev->mc.gtt_location = 0;
+               } else {
+                       /* Not enough place after or before shrink
+                        * gart size
+                        */
+                       if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
                                rdev->mc.gtt_location = 0;
+                               rdev->mc.gtt_size = rdev->mc.vram_location;
                        } else {
-                               /* Not enough place after or before shrink
-                                * gart size
-                                */
-                               if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
-                                       rdev->mc.gtt_location = 0;
-                                       rdev->mc.gtt_size = rdev->mc.vram_location;
-                               } else {
-                                       rdev->mc.gtt_location = tmp;
-                                       rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
-                               }
+                               rdev->mc.gtt_location = tmp;
+                               rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
                        }
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               } else {
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
                }
+               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
        }
        rdev->mc.vram_start = rdev->mc.vram_location;
        rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
@@ -859,7 +858,8 @@ void r600_gpu_init(struct radeon_device *rdev)
            ((rdev->family) == CHIP_RV630) ||
            ((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
        } else {
                WREG32(DB_DEBUG, 0);
@@ -876,7 +876,8 @@ void r600_gpu_init(struct radeon_device *rdev)
        tmp = RREG32(SQ_MS_FIFO_SIZES);
        if (((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                tmp = (CACHE_FIFO_SIZE(0xa) |
                       FETCH_FIFO_HIWATER(0xa) |
                       DONE_FIFO_HIWATER(0xe0) |
@@ -919,7 +920,8 @@ void r600_gpu_init(struct radeon_device *rdev)
                                            NUM_ES_STACK_ENTRIES(0));
        } else if (((rdev->family) == CHIP_RV610) ||
                   ((rdev->family) == CHIP_RV620) ||
-                  ((rdev->family) == CHIP_RS780)) {
+                  ((rdev->family) == CHIP_RS780) ||
+                  ((rdev->family) == CHIP_RS880)) {
                /* no vertex cache */
                sq_config &= ~VC_ENABLE;
 
@@ -976,7 +978,8 @@ void r600_gpu_init(struct radeon_device *rdev)
 
        if (((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
        } else {
                WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
@@ -1002,8 +1005,9 @@ void r600_gpu_init(struct radeon_device *rdev)
        tmp = rdev->config.r600.max_pipes * 16;
        switch (rdev->family) {
        case CHIP_RV610:
-       case CHIP_RS780:
        case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
                tmp += 32;
                break;
        case CHIP_RV670:
@@ -1044,8 +1048,9 @@ void r600_gpu_init(struct radeon_device *rdev)
 
        switch (rdev->family) {
        case CHIP_RV610:
-       case CHIP_RS780:
        case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
                tmp = TC_L2_SIZE(8);
                break;
        case CHIP_RV630:
@@ -1267,19 +1272,17 @@ int r600_cp_resume(struct radeon_device *rdev)
 
        /* Set ring buffer size */
        rb_bufsz = drm_order(rdev->cp.ring_size / 8);
+       tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
 #ifdef __BIG_ENDIAN
-       WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE |
-               (drm_order(4096/8) << 8) | rb_bufsz);
-#else
-       WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz);
+       tmp |= BUF_SWAP_32BIT;
 #endif
+       WREG32(CP_RB_CNTL, tmp);
        WREG32(CP_SEM_WAIT_TIMER, 0x4);
 
        /* Set the write pointer delay */
        WREG32(CP_RB_WPTR_DELAY, 0);
 
        /* Initialize the ring buffer's read and write pointers */
-       tmp = RREG32(CP_RB_CNTL);
        WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
        WREG32(CP_RB_RPTR_WR, 0);
        WREG32(CP_RB_WPTR, 0);
@@ -1400,7 +1403,7 @@ int r600_wb_enable(struct radeon_device *rdev)
        int r;
 
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096, true,
+               r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
                if (r) {
                        dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
@@ -1450,8 +1453,8 @@ int r600_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset, uint64_t dst_offset,
                   unsigned num_pages, struct radeon_fence *fence)
 {
-       r600_blit_prepare_copy(rdev, num_pages * 4096);
-       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096);
+       r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
        r600_blit_done_copy(rdev, fence);
        return 0;
 }
@@ -1632,10 +1635,13 @@ int r600_init(struct radeon_device *rdev)
        r600_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
        r = radeon_clocks_init(rdev);
        if (r)
                return r;
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index dec5010..5ea4323 100644 (file)
@@ -582,6 +582,8 @@ r600_blit_copy(struct drm_device *dev,
        u64 vb_addr;
        u32 *vb;
 
+       vb = r600_nomm_get_vb_ptr(dev);
+
        if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
                max_bytes = 8192;
 
@@ -617,8 +619,8 @@ r600_blit_copy(struct drm_device *dev,
                                if (!dev_priv->blit_vb)
                                        return;
                                set_shaders(dev);
+                               vb = r600_nomm_get_vb_ptr(dev);
                        }
-                       vb = r600_nomm_get_vb_ptr(dev);
 
                        vb[0] = i2f(dst_x);
                        vb[1] = 0;
@@ -706,8 +708,8 @@ r600_blit_copy(struct drm_device *dev,
                                        return;
 
                                set_shaders(dev);
+                               vb = r600_nomm_get_vb_ptr(dev);
                        }
-                       vb = r600_nomm_get_vb_ptr(dev);
 
                        vb[0] = i2f(dst_x / 4);
                        vb[1] = 0;
@@ -772,6 +774,7 @@ r600_blit_swap(struct drm_device *dev,
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
        int cb_format, tex_format;
+       int sx2, sy2, dx2, dy2;
        u64 vb_addr;
        u32 *vb;
 
@@ -786,16 +789,10 @@ r600_blit_swap(struct drm_device *dev,
        }
        vb = r600_nomm_get_vb_ptr(dev);
 
-       if (cpp == 4) {
-               cb_format = COLOR_8_8_8_8;
-               tex_format = FMT_8_8_8_8;
-       } else if (cpp == 2) {
-               cb_format = COLOR_5_6_5;
-               tex_format = FMT_5_6_5;
-       } else {
-               cb_format = COLOR_8;
-               tex_format = FMT_8;
-       }
+       sx2 = sx + w;
+       sy2 = sy + h;
+       dx2 = dx + w;
+       dy2 = dy + h;
 
        vb[0] = i2f(dx);
        vb[1] = i2f(dy);
@@ -803,31 +800,46 @@ r600_blit_swap(struct drm_device *dev,
        vb[3] = i2f(sy);
 
        vb[4] = i2f(dx);
-       vb[5] = i2f(dy + h);
+       vb[5] = i2f(dy2);
        vb[6] = i2f(sx);
-       vb[7] = i2f(sy + h);
+       vb[7] = i2f(sy2);
+
+       vb[8] = i2f(dx2);
+       vb[9] = i2f(dy2);
+       vb[10] = i2f(sx2);
+       vb[11] = i2f(sy2);
 
-       vb[8] = i2f(dx + w);
-       vb[9] = i2f(dy + h);
-       vb[10] = i2f(sx + w);
-       vb[11] = i2f(sy + h);
+       switch(cpp) {
+       case 4:
+               cb_format = COLOR_8_8_8_8;
+               tex_format = FMT_8_8_8_8;
+               break;
+       case 2:
+               cb_format = COLOR_5_6_5;
+               tex_format = FMT_5_6_5;
+               break;
+       default:
+               cb_format = COLOR_8;
+               tex_format = FMT_8;
+               break;
+       }
 
        /* src */
        set_tex_resource(dev_priv, tex_format,
                         src_pitch / cpp,
-                        sy + h, src_pitch / cpp,
+                        sy2, src_pitch / cpp,
                         src_gpu_addr);
 
        cp_set_surface_sync(dev_priv,
-                           R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
+                           R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr);
 
        /* dst */
        set_render_target(dev_priv, cb_format,
-                         dst_pitch / cpp, dy + h,
+                         dst_pitch / cpp, dy2,
                          dst_gpu_addr);
 
        /* scissors */
-       set_scissors(dev_priv, dx, dy, dx + w, dy + h);
+       set_scissors(dev_priv, dx, dy, dx2, dy2);
 
        /* Vertex buffer setup */
        vb_addr = dev_priv->gart_buffers_offset +
@@ -840,7 +852,7 @@ r600_blit_swap(struct drm_device *dev,
 
        cp_set_surface_sync(dev_priv,
                            R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
-                           dst_pitch * (dy + h), dst_gpu_addr);
+                           dst_pitch * dy2, dst_gpu_addr);
 
        dev_priv->blit_vb->used += 12 * 4;
 }
index 93108bb..dbf716e 100644 (file)
@@ -368,7 +368,7 @@ set_default_state(struct radeon_device *rdev)
        if ((rdev->family == CHIP_RV610) ||
            (rdev->family == CHIP_RV620) ||
            (rdev->family == CHIP_RS780) ||
-           (rdev->family == CHIP_RS780) ||
+           (rdev->family == CHIP_RS880) ||
            (rdev->family == CHIP_RV710))
                sq_config = 0;
        else
@@ -610,6 +610,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
 
        DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
                  size_bytes, rdev->r600_blit.vb_used);
+       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
        if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
                max_bytes = 8192;
 
@@ -652,7 +653,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                                vb = r600_nomm_get_vb_ptr(dev);
 #endif
                        }
-                       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
 
                        vb[0] = i2f(dst_x);
                        vb[1] = 0;
@@ -747,7 +747,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                                vb = r600_nomm_get_vb_ptr(dev);
                        }
 #endif
-                       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
 
                        vb[0] = i2f(dst_x / 4);
                        vb[1] = 0;
index 17e4219..0d82076 100644 (file)
@@ -466,6 +466,23 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                for (i = 0; i < pkt->count; i++) {
                        reg = start_reg + (4 * i);
                        switch (reg) {
+                       case SQ_ESGS_RING_BASE:
+                       case SQ_GSVS_RING_BASE:
+                       case SQ_ESTMP_RING_BASE:
+                       case SQ_GSTMP_RING_BASE:
+                       case SQ_VSTMP_RING_BASE:
+                       case SQ_PSTMP_RING_BASE:
+                       case SQ_FBUF_RING_BASE:
+                       case SQ_REDUC_RING_BASE:
+                       case SX_MEMORY_EXPORT_BASE:
+                               r = r600_cs_packet_next_reloc(p, &reloc);
+                               if (r) {
+                                       DRM_ERROR("bad SET_CONFIG_REG "
+                                                       "0x%04X\n", reg);
+                                       return -EINVAL;
+                               }
+                               ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+                               break;
                        case CP_COHER_BASE:
                                /* use PACKET3_SURFACE_SYNC */
                                return -EINVAL;
@@ -487,6 +504,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                        reg = start_reg + (4 * i);
                        switch (reg) {
                        case DB_DEPTH_BASE:
+                       case DB_HTILE_DATA_BASE:
                        case CB_COLOR0_BASE:
                        case CB_COLOR1_BASE:
                        case CB_COLOR2_BASE:
index 9b64d47..27ab428 100644 (file)
 #define        DB_DEBUG                                        0x9830
 #define                PREZ_MUST_WAIT_FOR_POSTZ_DONE                   (1 << 31)
 #define        DB_DEPTH_BASE                                   0x2800C
+#define        DB_HTILE_DATA_BASE                              0x28014
 #define        DB_WATERMARKS                                   0x9838
 #define                DEPTH_FREE(x)                                   ((x) << 0)
 #define                DEPTH_FLUSH(x)                                  ((x) << 5)
 #define SQ_STACK_RESOURCE_MGMT_2                          0x8c14
 #       define NUM_GS_STACK_ENTRIES(x)                    ((x) << 0)
 #       define NUM_ES_STACK_ENTRIES(x)                    ((x) << 16)
+#define SQ_ESGS_RING_BASE                               0x8c40
+#define SQ_GSVS_RING_BASE                               0x8c48
+#define SQ_ESTMP_RING_BASE                              0x8c50
+#define SQ_GSTMP_RING_BASE                              0x8c58
+#define SQ_VSTMP_RING_BASE                              0x8c60
+#define SQ_PSTMP_RING_BASE                              0x8c68
+#define SQ_FBUF_RING_BASE                               0x8c70
+#define SQ_REDUC_RING_BASE                              0x8c78
 
 #define GRBM_CNTL                                       0x8000
 #       define GRBM_READ_TIMEOUT(x)                     ((x) << 0)
 #define        PCIE_PORT_INDEX                                 0x0038
 #define        PCIE_PORT_DATA                                  0x003C
 
+#define CHMAP                                          0x2004
+#define                NOOFCHAN_SHIFT                                  12
+#define                NOOFCHAN_MASK                                   0x00003000
+
 #define RAMCFG                                         0x2408
 #define                NOOFBANK_SHIFT                                  0
 #define                NOOFBANK_MASK                                   0x00000001
 
 
 #define        SX_MISC                                         0x28350
+#define        SX_MEMORY_EXPORT_BASE                           0x9010
 #define        SX_DEBUG_1                                      0x9054
 #define                SMX_EVENT_RELEASE                               (1 << 0)
 #define                ENABLE_NEW_SMX_ADDRESS                          (1 << 16)
index 5ab35b8..757f5cd 100644 (file)
@@ -139,6 +139,10 @@ struct radeon_clock {
        uint32_t default_sclk;
 };
 
+/*
+ * Power management
+ */
+int radeon_pm_init(struct radeon_device *rdev);
 
 /*
  * Fences.
@@ -276,6 +280,8 @@ union radeon_gart_table {
        struct radeon_gart_table_vram   vram;
 };
 
+#define RADEON_GPU_PAGE_SIZE 4096
+
 struct radeon_gart {
        dma_addr_t                      table_addr;
        unsigned                        num_gpu_pages;
@@ -621,7 +627,9 @@ struct radeon_asic {
                    uint64_t dst_offset,
                    unsigned num_pages,
                    struct radeon_fence *fence);
+       uint32_t (*get_engine_clock)(struct radeon_device *rdev);
        void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
+       uint32_t (*get_memory_clock)(struct radeon_device *rdev);
        void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock);
        void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
        void (*set_clock_gating)(struct radeon_device *rdev, int enable);
@@ -783,6 +791,7 @@ struct radeon_device {
        const struct firmware *me_fw;   /* all family ME firmware */
        const struct firmware *pfp_fw;  /* r6/700 PFP firmware */
        struct r600_blit r600_blit;
+       int msi_enabled; /* msi enabled */
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -952,7 +961,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f))
 #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f))
 #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f))
+#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
 #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
+#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
 #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
 #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
index c3532c7..c18fbee 100644 (file)
 /*
  * common functions
  */
+uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev);
 void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
 void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
 
+uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev);
 void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
+uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev);
 void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock);
 void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 
@@ -95,7 +98,9 @@ static struct radeon_asic r100_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = NULL,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -148,7 +153,9 @@ static struct radeon_asic r300_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -185,7 +192,9 @@ static struct radeon_asic r420_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -227,7 +236,9 @@ static struct radeon_asic rs400_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@ -273,7 +284,9 @@ static struct radeon_asic rs600_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -312,7 +325,9 @@ static struct radeon_asic rs690_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r300_copy_dma,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -357,7 +372,9 @@ static struct radeon_asic rv515_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -393,7 +410,9 @@ static struct radeon_asic r520_asic = {
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -456,7 +475,9 @@ static struct radeon_asic r600_asic = {
        .copy_blit = &r600_copy_blit,
        .copy_dma = &r600_copy_blit,
        .copy = &r600_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@ -493,7 +514,9 @@ static struct radeon_asic rv770_asic = {
        .copy_blit = &r600_copy_blit,
        .copy_dma = &r600_copy_blit,
        .copy = &r600_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
index 5b6c08c..2ed88a8 100644 (file)
@@ -46,7 +46,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                          uint32_t supported_device,
                          int connector_type,
                          struct radeon_i2c_bus_rec *i2c_bus,
-                         bool linkb, uint32_t igp_lane_info);
+                         bool linkb, uint32_t igp_lane_info,
+                         uint16_t connector_object_id);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -193,6 +194,23 @@ const int supported_devices_connector_convert[] = {
        DRM_MODE_CONNECTOR_DisplayPort
 };
 
+const uint16_t supported_devices_connector_object_id_convert[] = {
+       CONNECTOR_OBJECT_ID_NONE,
+       CONNECTOR_OBJECT_ID_VGA,
+       CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */
+       CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */
+       CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */
+       CONNECTOR_OBJECT_ID_COMPOSITE,
+       CONNECTOR_OBJECT_ID_SVIDEO,
+       CONNECTOR_OBJECT_ID_LVDS,
+       CONNECTOR_OBJECT_ID_9PIN_DIN,
+       CONNECTOR_OBJECT_ID_9PIN_DIN,
+       CONNECTOR_OBJECT_ID_DISPLAYPORT,
+       CONNECTOR_OBJECT_ID_HDMI_TYPE_A,
+       CONNECTOR_OBJECT_ID_HDMI_TYPE_B,
+       CONNECTOR_OBJECT_ID_SVIDEO
+};
+
 const int object_connector_convert[] = {
        DRM_MODE_CONNECTOR_Unknown,
        DRM_MODE_CONNECTOR_DVII,
@@ -229,7 +247,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        ATOM_OBJECT_HEADER *obj_header;
        int i, j, path_size, device_support;
        int connector_type;
-       uint16_t igp_lane_info, conn_id;
+       uint16_t igp_lane_info, conn_id, connector_object_id;
        bool linkb;
        struct radeon_i2c_bus_rec ddc_bus;
 
@@ -277,7 +295,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                ATOM_DEVICE_CV_SUPPORT)
                                continue;
 
-                       if ((rdev->family == CHIP_RS780) &&
+                       /* IGP chips */
+                       if ((rdev->flags & RADEON_IS_IGP) &&
                            (con_obj_id ==
                             CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
                                uint16_t igp_offset = 0;
@@ -311,6 +330,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                connector_type =
                                                    object_connector_convert
                                                    [ct];
+                                               connector_object_id = ct;
                                                igp_lane_info =
                                                    slot_config & 0xffff;
                                        } else
@@ -321,6 +341,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                igp_lane_info = 0;
                                connector_type =
                                    object_connector_convert[con_obj_id];
+                               connector_object_id = con_obj_id;
                        }
 
                        if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -425,7 +446,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                  le16_to_cpu(path->
                                                              usDeviceTag),
                                                  connector_type, &ddc_bus,
-                                                 linkb, igp_lane_info);
+                                                 linkb, igp_lane_info,
+                                                 connector_object_id);
 
                }
        }
@@ -435,6 +457,45 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        return true;
 }
 
+static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
+                                                int connector_type,
+                                                uint16_t devices)
+{
+       struct radeon_device *rdev = dev->dev_private;
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               return supported_devices_connector_object_id_convert
+                       [connector_type];
+       } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) ||
+                   (connector_type == DRM_MODE_CONNECTOR_DVID)) &&
+                  (devices & ATOM_DEVICE_DFP2_SUPPORT))  {
+               struct radeon_mode_info *mode_info = &rdev->mode_info;
+               struct atom_context *ctx = mode_info->atom_context;
+               int index = GetIndexIntoMasterTable(DATA, XTMDS_Info);
+               uint16_t size, data_offset;
+               uint8_t frev, crev;
+               ATOM_XTMDS_INFO *xtmds;
+
+               atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+               xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
+
+               if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
+                       if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                               return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+                       else
+                               return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+               } else {
+                       if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                               return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+                       else
+                               return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+               }
+       } else {
+               return supported_devices_connector_object_id_convert
+                       [connector_type];
+       }
+}
+
 struct bios_connector {
        bool valid;
        uint16_t line_mux;
@@ -593,14 +654,20 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
 
        /* add the connectors */
        for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
-               if (bios_connectors[i].valid)
+               if (bios_connectors[i].valid) {
+                       uint16_t connector_object_id =
+                               atombios_get_connector_object_id(dev,
+                                                     bios_connectors[i].connector_type,
+                                                     bios_connectors[i].devices);
                        radeon_add_atom_connector(dev,
                                                  bios_connectors[i].line_mux,
                                                  bios_connectors[i].devices,
                                                  bios_connectors[i].
                                                  connector_type,
                                                  &bios_connectors[i].ddc_bus,
-                                                 false, 0);
+                                                 false, 0,
+                                                 connector_object_id);
+               }
        }
 
        radeon_link_encoder_connector(dev);
@@ -641,8 +708,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                    le16_to_cpu(firmware_info->info.usReferenceClock);
                p1pll->reference_div = 0;
 
-               p1pll->pll_out_min =
-                   le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
+               if (crev < 2)
+                       p1pll->pll_out_min =
+                               le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
+               else
+                       p1pll->pll_out_min =
+                               le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
                p1pll->pll_out_max =
                    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
@@ -651,6 +722,16 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                                p1pll->pll_out_min = 64800;
                        else
                                p1pll->pll_out_min = 20000;
+               } else if (p1pll->pll_out_min > 64800) {
+                       /* Limiting the pll output range is a good thing generally as
+                        * it limits the number of possible pll combinations for a given
+                        * frequency presumably to the ones that work best on each card.
+                        * However, certain duallink DVI monitors seem to like
+                        * pll combinations that would be limited by this at least on
+                        * pre-DCE 3.0 r6xx hardware.  This might need to be adjusted per
+                        * family.
+                        */
+                       p1pll->pll_out_min = 64800;
                }
 
                p1pll->pll_in_min =
@@ -767,6 +848,46 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
        return false;
 }
 
+static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
+                                                         radeon_encoder
+                                                         *encoder,
+                                                         int id)
+{
+       struct drm_device *dev = encoder->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_mode_info *mode_info = &rdev->mode_info;
+       int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info);
+       uint16_t data_offset;
+       struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
+       uint8_t frev, crev;
+       struct radeon_atom_ss *ss = NULL;
+
+       if (id > ATOM_MAX_SS_ENTRY)
+               return NULL;
+
+       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
+                              &crev, &data_offset);
+
+       ss_info =
+           (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
+
+       if (ss_info) {
+               ss =
+                   kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
+
+               if (!ss)
+                       return NULL;
+
+               ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage);
+               ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType;
+               ss->step = ss_info->asSS_Info[id].ucSS_Step;
+               ss->delay = ss_info->asSS_Info[id].ucSS_Delay;
+               ss->range = ss_info->asSS_Info[id].ucSS_Range;
+               ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div;
+       }
+       return ss;
+}
+
 union lvds_info {
        struct _ATOM_LVDS_INFO info;
        struct _ATOM_LVDS_INFO_V12 info_12;
@@ -798,27 +919,31 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
                if (!lvds)
                        return NULL;
 
-               lvds->native_mode.dotclock =
+               lvds->native_mode.clock =
                    le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
-               lvds->native_mode.panel_xres =
+               lvds->native_mode.hdisplay =
                    le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
-               lvds->native_mode.panel_yres =
+               lvds->native_mode.vdisplay =
                    le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
-               lvds->native_mode.hblank =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
-               lvds->native_mode.hoverplus =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
-               lvds->native_mode.hsync_width =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
-               lvds->native_mode.vblank =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
-               lvds->native_mode.voverplus =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
-               lvds->native_mode.vsync_width =
-                   le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
+               lvds->native_mode.htotal = lvds->native_mode.hdisplay +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
+               lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
+               lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
+               lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
+               lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
+               lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
+                       le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
                lvds->panel_pwr_delay =
                    le16_to_cpu(lvds_info->info.usOffDelayInMs);
                lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
+               /* set crtc values */
+               drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
+
+               lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id);
 
                encoder->native_mode = lvds->native_mode;
        }
@@ -857,8 +982,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
 }
 
 bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
-                               SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
-                               int32_t *pixel_clock)
+                               struct drm_display_mode *mode)
 {
        struct radeon_mode_info *mode_info = &rdev->mode_info;
        ATOM_ANALOG_TV_INFO *tv_info;
@@ -866,7 +990,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
        ATOM_DTD_FORMAT *dtd_timings;
        int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
        u8 frev, crev;
-       uint16_t data_offset;
+       u16 data_offset, misc;
 
        atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
 
@@ -876,28 +1000,37 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
                if (index > MAX_SUPPORTED_TV_TIMING)
                        return false;
 
-               crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
-               crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
-               crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
-               crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
-
-               crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
-               crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
-               crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
-               crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
-
-               crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
-
-               crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
-               crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
-               crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
-               crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
-               *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
+               mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
+               mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
+               mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
+               mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
+                       le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
+
+               mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
+               mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
+               mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
+               mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
+                       le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
+
+               mode->flags = 0;
+               misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
+               if (misc & ATOM_VSYNC_POLARITY)
+                       mode->flags |= DRM_MODE_FLAG_NVSYNC;
+               if (misc & ATOM_HSYNC_POLARITY)
+                       mode->flags |= DRM_MODE_FLAG_NHSYNC;
+               if (misc & ATOM_COMPOSITESYNC)
+                       mode->flags |= DRM_MODE_FLAG_CSYNC;
+               if (misc & ATOM_INTERLACE)
+                       mode->flags |= DRM_MODE_FLAG_INTERLACE;
+               if (misc & ATOM_DOUBLE_CLOCK_MODE)
+                       mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+               mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
 
                if (index == 1) {
                        /* PAL timings appear to have wrong values for totals */
-                       crtc_timing->usH_Total -= 1;
-                       crtc_timing->usV_Total -= 1;
+                       mode->crtc_htotal -= 1;
+                       mode->crtc_vtotal -= 1;
                }
                break;
        case 2:
@@ -906,17 +1039,36 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
                        return false;
 
                dtd_timings = &tv_info_v1_2->aModeTimings[index];
-               crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
-               crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
-               crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
-               crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
-               crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
-               crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
-               crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
-               crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
-
-               crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
-               *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+               mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) +
+                       le16_to_cpu(dtd_timings->usHBlanking_Time);
+               mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive);
+               mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) +
+                       le16_to_cpu(dtd_timings->usHSyncOffset);
+               mode->crtc_hsync_end = mode->crtc_hsync_start +
+                       le16_to_cpu(dtd_timings->usHSyncWidth);
+
+               mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) +
+                       le16_to_cpu(dtd_timings->usVBlanking_Time);
+               mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive);
+               mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) +
+                       le16_to_cpu(dtd_timings->usVSyncOffset);
+               mode->crtc_vsync_end = mode->crtc_vsync_start +
+                       le16_to_cpu(dtd_timings->usVSyncWidth);
+
+               mode->flags = 0;
+               misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
+               if (misc & ATOM_VSYNC_POLARITY)
+                       mode->flags |= DRM_MODE_FLAG_NVSYNC;
+               if (misc & ATOM_HSYNC_POLARITY)
+                       mode->flags |= DRM_MODE_FLAG_NHSYNC;
+               if (misc & ATOM_COMPOSITESYNC)
+                       mode->flags |= DRM_MODE_FLAG_CSYNC;
+               if (misc & ATOM_INTERLACE)
+                       mode->flags |= DRM_MODE_FLAG_INTERLACE;
+               if (misc & ATOM_DOUBLE_CLOCK_MODE)
+                       mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+               mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
                break;
        }
        return true;
@@ -981,6 +1133,24 @@ void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable)
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)
+{
+       GET_ENGINE_CLOCK_PS_ALLOCATION args;
+       int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       return args.ulReturnEngineClock;
+}
+
+uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
+{
+       GET_MEMORY_CLOCK_PS_ALLOCATION args;
+       int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       return args.ulReturnMemoryClock;
+}
+
 void radeon_atom_set_engine_clock(struct radeon_device *rdev,
                                  uint32_t eng_clock)
 {
index 2e938f7..10bd50a 100644 (file)
@@ -63,7 +63,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
                if (r) {
                        goto out_cleanup;
                }
-               r = radeon_copy_dma(rdev, saddr, daddr, size / 4096, fence);
+               r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence);
                if (r) {
                        goto out_cleanup;
                }
@@ -88,7 +88,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
                if (r) {
                        goto out_cleanup;
                }
-               r = radeon_copy_blit(rdev, saddr, daddr, size / 4096, fence);
+               r = radeon_copy_blit(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence);
                if (r) {
                        goto out_cleanup;
                }
index 34a9b91..9069217 100644 (file)
@@ -50,19 +50,16 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
        vram_base = drm_get_resource_start(rdev->ddev, 0);
        bios = ioremap(vram_base, size);
        if (!bios) {
-               DRM_ERROR("Unable to mmap vram\n");
                return false;
        }
 
        if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
                iounmap(bios);
-               DRM_ERROR("bad rom signature\n");
                return false;
        }
        rdev->bios = kmalloc(size, GFP_KERNEL);
        if (rdev->bios == NULL) {
                iounmap(bios);
-               DRM_ERROR("kmalloc failed\n");
                return false;
        }
        memcpy(rdev->bios, bios, size);
index f5c32a7..a813541 100644 (file)
@@ -32,7 +32,7 @@
 #include "atom.h"
 
 /* 10 khz */
-static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
+uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
 {
        struct radeon_pll *spll = &rdev->clock.spll;
        uint32_t fb_div, ref_div, post_div, sclk;
index 748265a..5253cbf 100644 (file)
@@ -49,7 +49,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                            uint32_t connector_id,
                            uint32_t supported_device,
                            int connector_type,
-                           struct radeon_i2c_bus_rec *i2c_bus);
+                           struct radeon_i2c_bus_rec *i2c_bus,
+                           uint16_t connector_object_id);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -808,25 +809,25 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
        lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
 
        if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
-               lvds->native_mode.panel_yres =
+               lvds->native_mode.vdisplay =
                    ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
                     RADEON_VERT_PANEL_SHIFT) + 1;
        else
-               lvds->native_mode.panel_yres =
+               lvds->native_mode.vdisplay =
                    (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
 
        if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
-               lvds->native_mode.panel_xres =
+               lvds->native_mode.hdisplay =
                    (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
                      RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
        else
-               lvds->native_mode.panel_xres =
+               lvds->native_mode.hdisplay =
                    ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
 
-       if ((lvds->native_mode.panel_xres < 640) ||
-           (lvds->native_mode.panel_yres < 480)) {
-               lvds->native_mode.panel_xres = 640;
-               lvds->native_mode.panel_yres = 480;
+       if ((lvds->native_mode.hdisplay < 640) ||
+           (lvds->native_mode.vdisplay < 480)) {
+               lvds->native_mode.hdisplay = 640;
+               lvds->native_mode.vdisplay = 480;
        }
 
        ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
@@ -846,8 +847,8 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
        lvds->panel_vcc_delay = 200;
 
        DRM_INFO("Panel info derived from registers\n");
-       DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
-                lvds->native_mode.panel_yres);
+       DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
+                lvds->native_mode.vdisplay);
 
        return lvds;
 }
@@ -882,11 +883,11 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
 
                DRM_INFO("Panel ID String: %s\n", stmp);
 
-               lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19);
-               lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b);
+               lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
+               lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
 
-               DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
-                        lvds->native_mode.panel_yres);
+               DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
+                        lvds->native_mode.vdisplay);
 
                lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
                if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0)
@@ -944,27 +945,25 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
                        if (tmp == 0)
                                break;
 
-                       if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) &&
+                       if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
                            (RBIOS16(tmp + 2) ==
-                            lvds->native_mode.panel_yres)) {
-                               lvds->native_mode.hblank =
-                                   (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
-                               lvds->native_mode.hoverplus =
-                                   (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) -
-                                    1) * 8;
-                               lvds->native_mode.hsync_width =
-                                   RBIOS8(tmp + 23) * 8;
-
-                               lvds->native_mode.vblank = (RBIOS16(tmp + 24) -
-                                                           RBIOS16(tmp + 26));
-                               lvds->native_mode.voverplus =
-                                   ((RBIOS16(tmp + 28) & 0x7ff) -
-                                    RBIOS16(tmp + 26));
-                               lvds->native_mode.vsync_width =
-                                   ((RBIOS16(tmp + 28) & 0xf800) >> 11);
-                               lvds->native_mode.dotclock =
-                                   RBIOS16(tmp + 9) * 10;
+                            lvds->native_mode.vdisplay)) {
+                               lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8;
+                               lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8;
+                               lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) +
+                                                              RBIOS16(tmp + 21)) * 8;
+
+                               lvds->native_mode.vtotal = RBIOS16(tmp + 24);
+                               lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff;
+                               lvds->native_mode.vsync_end =
+                                       ((RBIOS16(tmp + 28) & 0xf800) >> 11) +
+                                       (RBIOS16(tmp + 28) & 0x7ff);
+
+                               lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
                                lvds->native_mode.flags = 0;
+                               /* set crtc values */
+                               drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
+
                        }
                }
        } else {
@@ -1178,7 +1177,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        radeon_add_legacy_connector(dev, 0,
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_VGA);
                } else if (rdev->flags & RADEON_IS_MOBILITY) {
                        /* LVDS */
                        ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
@@ -1190,7 +1190,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        radeon_add_legacy_connector(dev, 0,
                                                    ATOM_DEVICE_LCD1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_LVDS,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_LVDS);
 
                        /* VGA - primary dac */
                        ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
@@ -1202,7 +1203,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        radeon_add_legacy_connector(dev, 1,
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_VGA);
                } else {
                        /* DVI-I - tv dac, int tmds */
                        ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
@@ -1220,7 +1222,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                    ATOM_DEVICE_DFP1_SUPPORT |
                                                    ATOM_DEVICE_CRT2_SUPPORT,
                                                    DRM_MODE_CONNECTOR_DVII,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
 
                        /* VGA - primary dac */
                        ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
@@ -1232,7 +1235,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        radeon_add_legacy_connector(dev, 1,
                                                    ATOM_DEVICE_CRT1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_VGA,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_VGA);
                }
 
                if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
@@ -1245,7 +1249,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        radeon_add_legacy_connector(dev, 2,
                                                    ATOM_DEVICE_TV1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_SVIDEO,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_SVIDEO);
                }
                break;
        case CT_IBOOK:
@@ -1259,7 +1264,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                0),
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_LVDS);
                /* VGA - TV DAC */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1268,7 +1274,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                2),
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
-                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_VGA);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1277,7 +1284,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_POWERBOOK_EXTERNAL:
                DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
@@ -1290,7 +1298,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                0),
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_LVDS);
                /* DVI-I - primary dac, ext tmds */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1303,10 +1312,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                ATOM_DEVICE_CRT1_SUPPORT,
                                                                1),
                                          ATOM_DEVICE_CRT1_SUPPORT);
+               /* XXX some are SL */
                radeon_add_legacy_connector(dev, 1,
                                            ATOM_DEVICE_DFP2_SUPPORT |
                                            ATOM_DEVICE_CRT1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1315,7 +1326,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_POWERBOOK_INTERNAL:
                DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
@@ -1328,7 +1340,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                0),
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_LVDS);
                /* DVI-I - primary dac, int tmds */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1344,7 +1357,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 1,
                                            ATOM_DEVICE_DFP1_SUPPORT |
                                            ATOM_DEVICE_CRT1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1353,7 +1367,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_POWERBOOK_VGA:
                DRM_INFO("Connector Table: %d (powerbook vga)\n",
@@ -1366,7 +1381,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                0),
                                          ATOM_DEVICE_LCD1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_LVDS);
                /* VGA - primary dac */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1375,7 +1391,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                1),
                                          ATOM_DEVICE_CRT1_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_VGA);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1384,7 +1401,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_MINI_EXTERNAL:
                DRM_INFO("Connector Table: %d (mini external tmds)\n",
@@ -1401,10 +1419,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                ATOM_DEVICE_CRT2_SUPPORT,
                                                                2),
                                          ATOM_DEVICE_CRT2_SUPPORT);
+               /* XXX are any DL? */
                radeon_add_legacy_connector(dev, 0,
                                            ATOM_DEVICE_DFP2_SUPPORT |
                                            ATOM_DEVICE_CRT2_SUPPORT,
-                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1413,7 +1433,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_MINI_INTERNAL:
                DRM_INFO("Connector Table: %d (mini internal tmds)\n",
@@ -1433,7 +1454,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                radeon_add_legacy_connector(dev, 0,
                                            ATOM_DEVICE_DFP1_SUPPORT |
                                            ATOM_DEVICE_CRT2_SUPPORT,
-                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1442,7 +1464,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_IMAC_G5_ISIGHT:
                DRM_INFO("Connector Table: %d (imac g5 isight)\n",
@@ -1455,7 +1478,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                0),
                                          ATOM_DEVICE_DFP1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_DVID, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
                /* VGA - tv dac */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1464,7 +1488,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                2),
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
-                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_VGA);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1473,7 +1498,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        case CT_EMAC:
                DRM_INFO("Connector Table: %d (emac)\n",
@@ -1486,7 +1512,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                1),
                                          ATOM_DEVICE_CRT1_SUPPORT);
                radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
-                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_VGA);
                /* VGA - tv dac */
                ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
                radeon_add_legacy_encoder(dev,
@@ -1495,7 +1522,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                                                2),
                                          ATOM_DEVICE_CRT2_SUPPORT);
                radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
-                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c);
+                                           DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_VGA);
                /* TV - TV DAC */
                radeon_add_legacy_encoder(dev,
                                          radeon_get_encoder_id(dev,
@@ -1504,7 +1532,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                          ATOM_DEVICE_TV1_SUPPORT);
                radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
                                            DRM_MODE_CONNECTOR_SVIDEO,
-                                           &ddc_i2c);
+                                           &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SVIDEO);
                break;
        default:
                DRM_INFO("Connector table: %d (invalid)\n",
@@ -1581,11 +1610,63 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
        return true;
 }
 
+static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
+{
+       /* Acer 5102 has non-existent TV port */
+       if (dev->pdev->device == 0x5975 &&
+           dev->pdev->subsystem_vendor == 0x1025 &&
+           dev->pdev->subsystem_device == 0x009f)
+               return false;
+
+       /* HP dc5750 has non-existent TV port */
+       if (dev->pdev->device == 0x5974 &&
+           dev->pdev->subsystem_vendor == 0x103c &&
+           dev->pdev->subsystem_device == 0x280a)
+               return false;
+
+       return true;
+}
+
+static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
+{
+       struct radeon_device *rdev = dev->dev_private;
+       uint32_t ext_tmds_info;
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               if (is_dvi_d)
+                       return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+               else
+                       return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+       }
+       ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+       if (ext_tmds_info) {
+               uint8_t rev = RBIOS8(ext_tmds_info);
+               uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
+               if (rev >= 3) {
+                       if (is_dvi_d)
+                               return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+                       else
+                               return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+               } else {
+                       if (flags & 1) {
+                               if (is_dvi_d)
+                                       return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+                               else
+                                       return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+                       }
+               }
+       }
+       if (is_dvi_d)
+               return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+       else
+               return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+}
+
 bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
 {
        struct radeon_device *rdev = dev->dev_private;
        uint32_t conn_info, entry, devices;
-       uint16_t tmp;
+       uint16_t tmp, connector_object_id;
        enum radeon_combios_ddc ddc_type;
        enum radeon_combios_connector connector;
        int i = 0;
@@ -1628,8 +1709,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                break;
                        }
 
-                       radeon_apply_legacy_quirks(dev, i, &connector,
-                                                  &ddc_i2c);
+                       if (!radeon_apply_legacy_quirks(dev, i, &connector,
+                                                      &ddc_i2c))
+                               continue;
 
                        switch (connector) {
                        case CONNECTOR_PROPRIETARY_LEGACY:
@@ -1644,7 +1726,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                radeon_add_legacy_connector(dev, i, devices,
                                                            legacy_connector_convert
                                                            [connector],
-                                                           &ddc_i2c);
+                                                           &ddc_i2c,
+                                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
                                break;
                        case CONNECTOR_CRT_LEGACY:
                                if (tmp & 0x1) {
@@ -1669,7 +1752,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            devices,
                                                            legacy_connector_convert
                                                            [connector],
-                                                           &ddc_i2c);
+                                                           &ddc_i2c,
+                                                           CONNECTOR_OBJECT_ID_VGA);
                                break;
                        case CONNECTOR_DVI_I_LEGACY:
                                devices = 0;
@@ -1698,6 +1782,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                   ATOM_DEVICE_DFP2_SUPPORT,
                                                                   0),
                                                                  ATOM_DEVICE_DFP2_SUPPORT);
+                                       connector_object_id = combios_check_dl_dvi(dev, 0);
                                } else {
                                        devices |= ATOM_DEVICE_DFP1_SUPPORT;
                                        radeon_add_legacy_encoder(dev,
@@ -1706,19 +1791,24 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                   ATOM_DEVICE_DFP1_SUPPORT,
                                                                   0),
                                                                  ATOM_DEVICE_DFP1_SUPPORT);
+                                       connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
                                }
                                radeon_add_legacy_connector(dev,
                                                            i,
                                                            devices,
                                                            legacy_connector_convert
                                                            [connector],
-                                                           &ddc_i2c);
+                                                           &ddc_i2c,
+                                                           connector_object_id);
                                break;
                        case CONNECTOR_DVI_D_LEGACY:
-                               if ((tmp >> 4) & 0x1)
+                               if ((tmp >> 4) & 0x1) {
                                        devices = ATOM_DEVICE_DFP2_SUPPORT;
-                               else
+                                       connector_object_id = combios_check_dl_dvi(dev, 1);
+                               } else {
                                        devices = ATOM_DEVICE_DFP1_SUPPORT;
+                                       connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+                               }
                                radeon_add_legacy_encoder(dev,
                                                          radeon_get_encoder_id
                                                          (dev, devices, 0),
@@ -1726,7 +1816,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                radeon_add_legacy_connector(dev, i, devices,
                                                            legacy_connector_convert
                                                            [connector],
-                                                           &ddc_i2c);
+                                                           &ddc_i2c,
+                                                           connector_object_id);
                                break;
                        case CONNECTOR_CTV_LEGACY:
                        case CONNECTOR_STV_LEGACY:
@@ -1740,7 +1831,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                            ATOM_DEVICE_TV1_SUPPORT,
                                                            legacy_connector_convert
                                                            [connector],
-                                                           &ddc_i2c);
+                                                           &ddc_i2c,
+                                                           CONNECTOR_OBJECT_ID_SVIDEO);
                                break;
                        default:
                                DRM_ERROR("Unknown connector type: %d\n",
@@ -1772,10 +1864,29 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                    ATOM_DEVICE_CRT1_SUPPORT |
                                                    ATOM_DEVICE_DFP1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_DVII,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
                } else {
-                       DRM_DEBUG("No connector info found\n");
-                       return false;
+                       uint16_t crt_info =
+                               combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
+                       DRM_DEBUG("Found CRT table, assuming VGA connector\n");
+                       if (crt_info) {
+                               radeon_add_legacy_encoder(dev,
+                                                         radeon_get_encoder_id(dev,
+                                                                               ATOM_DEVICE_CRT1_SUPPORT,
+                                                                               1),
+                                                         ATOM_DEVICE_CRT1_SUPPORT);
+                               ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+                               radeon_add_legacy_connector(dev,
+                                                           0,
+                                                           ATOM_DEVICE_CRT1_SUPPORT,
+                                                           DRM_MODE_CONNECTOR_VGA,
+                                                           &ddc_i2c,
+                                                           CONNECTOR_OBJECT_ID_VGA);
+                       } else {
+                               DRM_DEBUG("No connector info found\n");
+                               return false;
+                       }
                }
        }
 
@@ -1870,7 +1981,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                    5,
                                                    ATOM_DEVICE_LCD1_SUPPORT,
                                                    DRM_MODE_CONNECTOR_LVDS,
-                                                   &ddc_i2c);
+                                                   &ddc_i2c,
+                                                   CONNECTOR_OBJECT_ID_LVDS);
                }
        }
 
@@ -1880,16 +1992,19 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                    combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
                if (tv_info) {
                        if (RBIOS8(tv_info + 6) == 'T') {
-                               radeon_add_legacy_encoder(dev,
-                                                         radeon_get_encoder_id
-                                                         (dev,
-                                                          ATOM_DEVICE_TV1_SUPPORT,
-                                                          2),
-                                                         ATOM_DEVICE_TV1_SUPPORT);
-                               radeon_add_legacy_connector(dev, 6,
-                                                           ATOM_DEVICE_TV1_SUPPORT,
-                                                           DRM_MODE_CONNECTOR_SVIDEO,
-                                                           &ddc_i2c);
+                               if (radeon_apply_legacy_tv_quirks(dev)) {
+                                       radeon_add_legacy_encoder(dev,
+                                                                 radeon_get_encoder_id
+                                                                 (dev,
+                                                                  ATOM_DEVICE_TV1_SUPPORT,
+                                                                  2),
+                                                                 ATOM_DEVICE_TV1_SUPPORT);
+                                       radeon_add_legacy_connector(dev, 6,
+                                                                   ATOM_DEVICE_TV1_SUPPORT,
+                                                                   DRM_MODE_CONNECTOR_SVIDEO,
+                                                                   &ddc_i2c,
+                                                                   CONNECTOR_OBJECT_ID_SVIDEO);
+                               }
                        }
                }
        }
index e376be4..fce4c40 100644 (file)
@@ -178,25 +178,12 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
        struct drm_device *dev = encoder->dev;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_display_mode *mode = NULL;
-       struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
-
-       if (native_mode->panel_xres != 0 &&
-           native_mode->panel_yres != 0 &&
-           native_mode->dotclock != 0) {
-               mode = drm_mode_create(dev);
-
-               mode->hdisplay = native_mode->panel_xres;
-               mode->vdisplay = native_mode->panel_yres;
-
-               mode->htotal = mode->hdisplay + native_mode->hblank;
-               mode->hsync_start = mode->hdisplay + native_mode->hoverplus;
-               mode->hsync_end = mode->hsync_start + native_mode->hsync_width;
-               mode->vtotal = mode->vdisplay + native_mode->vblank;
-               mode->vsync_start = mode->vdisplay + native_mode->voverplus;
-               mode->vsync_end = mode->vsync_start + native_mode->vsync_width;
-               mode->clock = native_mode->dotclock;
-               mode->flags = 0;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
 
+       if (native_mode->hdisplay != 0 &&
+           native_mode->vdisplay != 0 &&
+           native_mode->clock != 0) {
+               mode = drm_mode_duplicate(dev, native_mode);
                mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
                drm_mode_set_name(mode);
 
@@ -210,7 +197,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
        struct drm_device *dev = encoder->dev;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_display_mode *mode = NULL;
-       struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
        int i;
        struct mode_size {
                int w;
@@ -236,11 +223,16 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
        };
 
        for (i = 0; i < 17; i++) {
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
+                       if (common_modes[i].w > 1024 ||
+                           common_modes[i].h > 768)
+                               continue;
+               }
                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                       if (common_modes[i].w > native_mode->panel_xres ||
-                           common_modes[i].h > native_mode->panel_yres ||
-                           (common_modes[i].w == native_mode->panel_xres &&
-                            common_modes[i].h == native_mode->panel_yres))
+                       if (common_modes[i].w > native_mode->hdisplay ||
+                           common_modes[i].h > native_mode->vdisplay ||
+                           (common_modes[i].w == native_mode->hdisplay &&
+                            common_modes[i].h == native_mode->vdisplay))
                                continue;
                }
                if (common_modes[i].w < 320 || common_modes[i].h < 200)
@@ -344,28 +336,23 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
                                          struct drm_connector *connector)
 {
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
 
        /* Try to get native mode details from EDID if necessary */
-       if (!native_mode->dotclock) {
+       if (!native_mode->clock) {
                struct drm_display_mode *t, *mode;
 
                list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
-                       if (mode->hdisplay == native_mode->panel_xres &&
-                           mode->vdisplay == native_mode->panel_yres) {
-                               native_mode->hblank = mode->htotal - mode->hdisplay;
-                               native_mode->hoverplus = mode->hsync_start - mode->hdisplay;
-                               native_mode->hsync_width = mode->hsync_end - mode->hsync_start;
-                               native_mode->vblank = mode->vtotal - mode->vdisplay;
-                               native_mode->voverplus = mode->vsync_start - mode->vdisplay;
-                               native_mode->vsync_width = mode->vsync_end - mode->vsync_start;
-                               native_mode->dotclock = mode->clock;
+                       if (mode->hdisplay == native_mode->hdisplay &&
+                           mode->vdisplay == native_mode->vdisplay) {
+                               *native_mode = *mode;
+                               drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
                                DRM_INFO("Determined LVDS native mode details from EDID\n");
                                break;
                        }
                }
        }
-       if (!native_mode->dotclock) {
+       if (!native_mode->clock) {
                DRM_INFO("No LVDS native mode details, disabling RMX\n");
                radeon_encoder->rmx_type = RMX_OFF;
        }
@@ -410,13 +397,64 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
 static int radeon_lvds_mode_valid(struct drm_connector *connector,
                                  struct drm_display_mode *mode)
 {
+       struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+
+       if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
+               return MODE_PANEL;
+
+       if (encoder) {
+               struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+               /* AVIVO hardware supports downscaling modes larger than the panel
+                * to the panel size, but I'm not sure this is desirable.
+                */
+               if ((mode->hdisplay > native_mode->hdisplay) ||
+                   (mode->vdisplay > native_mode->vdisplay))
+                       return MODE_PANEL;
+
+               /* if scaling is disabled, block non-native modes */
+               if (radeon_encoder->rmx_type == RMX_OFF) {
+                       if ((mode->hdisplay != native_mode->hdisplay) ||
+                           (mode->vdisplay != native_mode->vdisplay))
+                               return MODE_PANEL;
+               }
+       }
+
        return MODE_OK;
 }
 
 static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
 {
-       enum drm_connector_status ret = connector_status_connected;
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+       enum drm_connector_status ret = connector_status_disconnected;
+
+       if (encoder) {
+               struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+               /* check if panel is valid */
+               if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
+                       ret = connector_status_connected;
+
+       }
+
+       /* check for edid as well */
+       if (radeon_connector->edid)
+               ret = connector_status_connected;
+       else {
+               if (radeon_connector->ddc_bus) {
+                       radeon_i2c_do_lock(radeon_connector, 1);
+                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+                                                             &radeon_connector->ddc_bus->adapter);
+                       radeon_i2c_do_lock(radeon_connector, 0);
+                       if (radeon_connector->edid)
+                               ret = connector_status_connected;
+               }
+       }
        /* check acpi lid status ??? */
+
        radeon_connector_update_scratch_regs(connector, ret);
        return ret;
 }
@@ -427,6 +465,8 @@ static void radeon_connector_destroy(struct drm_connector *connector)
 
        if (radeon_connector->ddc_bus)
                radeon_i2c_destroy(radeon_connector->ddc_bus);
+       if (radeon_connector->edid)
+               kfree(radeon_connector->edid);
        kfree(radeon_connector->con_priv);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
@@ -496,6 +536,8 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
 static int radeon_vga_mode_valid(struct drm_connector *connector,
                                  struct drm_display_mode *mode)
 {
+       /* XXX check mode bandwidth */
+       /* XXX verify against max DAC output frequency */
        return MODE_OK;
 }
 
@@ -514,9 +556,32 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
        radeon_i2c_do_lock(radeon_connector, 1);
        dret = radeon_ddc_probe(radeon_connector);
        radeon_i2c_do_lock(radeon_connector, 0);
-       if (dret)
-               ret = connector_status_connected;
-       else {
+       if (dret) {
+               if (radeon_connector->edid) {
+                       kfree(radeon_connector->edid);
+                       radeon_connector->edid = NULL;
+               }
+               radeon_i2c_do_lock(radeon_connector, 1);
+               radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+               radeon_i2c_do_lock(radeon_connector, 0);
+
+               if (!radeon_connector->edid) {
+                       DRM_ERROR("DDC responded but not EDID found for %s\n",
+                                 drm_get_connector_name(connector));
+               } else {
+                       radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+
+                       /* some oems have boards with separate digital and analog connectors
+                        * with a shared ddc line (often vga + hdmi)
+                        */
+                       if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
+                               kfree(radeon_connector->edid);
+                               radeon_connector->edid = NULL;
+                               ret = connector_status_disconnected;
+                       } else
+                               ret = connector_status_connected;
+               }
+       } else {
                if (radeon_connector->dac_load_detect) {
                        encoder_funcs = encoder->helper_private;
                        ret = encoder_funcs->detect(encoder, connector);
@@ -570,6 +635,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector)
 static int radeon_tv_mode_valid(struct drm_connector *connector,
                                struct drm_display_mode *mode)
 {
+       if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
+               return MODE_CLOCK_RANGE;
        return MODE_OK;
 }
 
@@ -644,6 +711,10 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
        dret = radeon_ddc_probe(radeon_connector);
        radeon_i2c_do_lock(radeon_connector, 0);
        if (dret) {
+               if (radeon_connector->edid) {
+                       kfree(radeon_connector->edid);
+                       radeon_connector->edid = NULL;
+               }
                radeon_i2c_do_lock(radeon_connector, 1);
                radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
                radeon_i2c_do_lock(radeon_connector, 0);
@@ -654,10 +725,15 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
                } else {
                        radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
-                       /* if this isn't a digital monitor
-                          then we need to make sure we don't have any
-                          TV conflicts */
-                       ret = connector_status_connected;
+                       /* some oems have boards with separate digital and analog connectors
+                        * with a shared ddc line (often vga + hdmi)
+                        */
+                       if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
+                               kfree(radeon_connector->edid);
+                               radeon_connector->edid = NULL;
+                               ret = connector_status_disconnected;
+                       } else
+                               ret = connector_status_connected;
                }
        }
 
@@ -753,9 +829,27 @@ static void radeon_dvi_force(struct drm_connector *connector)
                radeon_connector->use_digital = true;
 }
 
+static int radeon_dvi_mode_valid(struct drm_connector *connector,
+                                 struct drm_display_mode *mode)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+       /* XXX check mode bandwidth */
+
+       if (radeon_connector->use_digital && (mode->clock > 165000)) {
+               if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
+                   (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
+                   (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
+                       return MODE_OK;
+               else
+                       return MODE_CLOCK_HIGH;
+       }
+       return MODE_OK;
+}
+
 struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
        .get_modes = radeon_dvi_get_modes,
-       .mode_valid = radeon_vga_mode_valid,
+       .mode_valid = radeon_dvi_mode_valid,
        .best_encoder = radeon_dvi_encoder,
 };
 
@@ -775,13 +869,15 @@ radeon_add_atom_connector(struct drm_device *dev,
                          int connector_type,
                          struct radeon_i2c_bus_rec *i2c_bus,
                          bool linkb,
-                         uint32_t igp_lane_info)
+                         uint32_t igp_lane_info,
+                         uint16_t connector_object_id)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
        struct radeon_connector *radeon_connector;
        struct radeon_connector_atom_dig *radeon_dig_connector;
        uint32_t subpixel_order = SubPixelNone;
+       bool shared_ddc = false;
        int ret;
 
        /* fixme - tv/cv/din */
@@ -795,6 +891,13 @@ radeon_add_atom_connector(struct drm_device *dev,
                        radeon_connector->devices |= supported_device;
                        return;
                }
+               if (radeon_connector->ddc_bus && i2c_bus->valid) {
+                       if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus,
+                                   sizeof(struct radeon_i2c_bus_rec)) == 0) {
+                               radeon_connector->shared_ddc = true;
+                               shared_ddc = true;
+                       }
+               }
        }
 
        radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
@@ -805,6 +908,8 @@ radeon_add_atom_connector(struct drm_device *dev,
 
        radeon_connector->connector_id = connector_id;
        radeon_connector->devices = supported_device;
+       radeon_connector->shared_ddc = shared_ddc;
+       radeon_connector->connector_object_id = connector_object_id;
        switch (connector_type) {
        case DRM_MODE_CONNECTOR_VGA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -956,7 +1061,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                            uint32_t connector_id,
                            uint32_t supported_device,
                            int connector_type,
-                           struct radeon_i2c_bus_rec *i2c_bus)
+                           struct radeon_i2c_bus_rec *i2c_bus,
+                           uint16_t connector_object_id)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -985,6 +1091,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
 
        radeon_connector->connector_id = connector_id;
        radeon_connector->devices = supported_device;
+       radeon_connector->connector_object_id = connector_object_id;
        switch (connector_type) {
        case DRM_MODE_CONNECTOR_VGA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
index b13c79e..28772a3 100644 (file)
@@ -109,9 +109,15 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct radeon_device *rdev = crtc->dev->dev_private;
 
-       if (ASIC_IS_AVIVO(rdev))
+       if (ASIC_IS_AVIVO(rdev)) {
+               if (rdev->family >= CHIP_RV770) {
+                       if (radeon_crtc->crtc_id)
+                               WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0);
+                       else
+                               WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
+               }
                WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
-       else {
+       else {
                radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
                /* offset is from DISP(2)_BASE_ADDRESS */
                WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
index df98814..e3f9edf 100644 (file)
@@ -444,20 +444,24 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
        return r;
 }
 
-static struct card_info atom_card_info = {
-       .dev = NULL,
-       .reg_read = cail_reg_read,
-       .reg_write = cail_reg_write,
-       .mc_read = cail_mc_read,
-       .mc_write = cail_mc_write,
-       .pll_read = cail_pll_read,
-       .pll_write = cail_pll_write,
-};
-
 int radeon_atombios_init(struct radeon_device *rdev)
 {
-       atom_card_info.dev = rdev->ddev;
-       rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios);
+       struct card_info *atom_card_info =
+           kzalloc(sizeof(struct card_info), GFP_KERNEL);
+
+       if (!atom_card_info)
+               return -ENOMEM;
+
+       rdev->mode_info.atom_card_info = atom_card_info;
+       atom_card_info->dev = rdev->ddev;
+       atom_card_info->reg_read = cail_reg_read;
+       atom_card_info->reg_write = cail_reg_write;
+       atom_card_info->mc_read = cail_mc_read;
+       atom_card_info->mc_write = cail_mc_write;
+       atom_card_info->pll_read = cail_pll_read;
+       atom_card_info->pll_write = cail_pll_write;
+
+       rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
        radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
        return 0;
 }
@@ -465,6 +469,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
 void radeon_atombios_fini(struct radeon_device *rdev)
 {
        kfree(rdev->mode_info.atom_context);
+       kfree(rdev->mode_info.atom_card_info);
 }
 
 int radeon_combios_init(struct radeon_device *rdev)
index 3655d91..c85df4a 100644 (file)
@@ -137,9 +137,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
        if (size != 256) {
                return;
        }
-       if (crtc->fb == NULL) {
-               return;
-       }
 
        /* userspace palettes are always correct as is */
        for (i = 0; i < 256; i++) {
@@ -147,7 +144,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                radeon_crtc->lut_g[i] = green[i] >> 6;
                radeon_crtc->lut_b[i] = blue[i] >> 6;
        }
-
        radeon_crtc_load_lut(crtc);
 }
 
@@ -338,27 +334,19 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
 
 int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 {
-       struct edid *edid;
        int ret = 0;
 
        if (!radeon_connector->ddc_bus)
                return -1;
        if (!radeon_connector->edid) {
                radeon_i2c_do_lock(radeon_connector, 1);
-               edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+               radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
                radeon_i2c_do_lock(radeon_connector, 0);
-       } else
-               edid = radeon_connector->edid;
+       }
 
-       if (edid) {
-               /* update digital bits here */
-               if (edid->input & DRM_EDID_INPUT_DIGITAL)
-                       radeon_connector->use_digital = 1;
-               else
-                       radeon_connector->use_digital = 0;
-               drm_mode_connector_update_edid_property(&radeon_connector->base, edid);
-               ret = drm_add_edid_modes(&radeon_connector->base, edid);
-               kfree(edid);
+       if (radeon_connector->edid) {
+               drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
+               ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
                return ret;
        }
        drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
@@ -765,7 +753,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                        radeon_crtc->rmx_type = radeon_encoder->rmx_type;
                        memcpy(&radeon_crtc->native_mode,
                                &radeon_encoder->native_mode,
-                               sizeof(struct radeon_native_mode));
+                               sizeof(struct drm_display_mode));
                        first = false;
                } else {
                        if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
@@ -783,10 +771,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
        if (radeon_crtc->rmx_type != RMX_OFF) {
                fixed20_12 a, b;
                a.full = rfixed_const(crtc->mode.vdisplay);
-               b.full = rfixed_const(radeon_crtc->native_mode.panel_xres);
+               b.full = rfixed_const(radeon_crtc->native_mode.hdisplay);
                radeon_crtc->vsc.full = rfixed_div(a, b);
                a.full = rfixed_const(crtc->mode.hdisplay);
-               b.full = rfixed_const(radeon_crtc->native_mode.panel_yres);
+               b.full = rfixed_const(radeon_crtc->native_mode.vdisplay);
                radeon_crtc->hsc.full = rfixed_div(a, b);
        } else {
                radeon_crtc->vsc.full = rfixed_const(1);
index a65ab1a..d42bc51 100644 (file)
 
 extern int atom_debug;
 
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+                               struct drm_display_mode *mode);
+
 uint32_t
 radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
 {
@@ -167,49 +171,17 @@ void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
-       struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
-
-       if (mode->hdisplay < native_mode->panel_xres ||
-           mode->vdisplay < native_mode->panel_yres) {
-               if (ASIC_IS_AVIVO(rdev)) {
-                       adjusted_mode->hdisplay = native_mode->panel_xres;
-                       adjusted_mode->vdisplay = native_mode->panel_yres;
-                       adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
-                       adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
-                       adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
-                       adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
-                       adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
-                       adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
-                       /* update crtc values */
-                       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-                       /* adjust crtc values */
-                       adjusted_mode->crtc_hdisplay = native_mode->panel_xres;
-                       adjusted_mode->crtc_vdisplay = native_mode->panel_yres;
-                       adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
-                       adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
-                       adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
-                       adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
-                       adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
-                       adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
-               } else {
-                       adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
-                       adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
-                       adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
-                       adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
-                       adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
-                       adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
-                       /* update crtc values */
-                       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-                       /* adjust crtc values */
-                       adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
-                       adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
-                       adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
-                       adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
-                       adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
-                       adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+       if (mode->hdisplay < native_mode->hdisplay ||
+           mode->vdisplay < native_mode->vdisplay) {
+               int mode_id = adjusted_mode->base.id;
+               *adjusted_mode = *native_mode;
+               if (!ASIC_IS_AVIVO(rdev)) {
+                       adjusted_mode->hdisplay = mode->hdisplay;
+                       adjusted_mode->vdisplay = mode->vdisplay;
                }
-               adjusted_mode->flags = native_mode->flags;
-               adjusted_mode->clock = native_mode->dotclock;
+               adjusted_mode->base.id = mode_id;
        }
 }
 
@@ -219,7 +191,11 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
                                   struct drm_display_mode *adjusted_mode)
 {
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
 
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        if (radeon_encoder->rmx_type != RMX_OFF)
@@ -230,6 +206,18 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
            && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
                adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+               if (tv_dac) {
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J ||
+                           tv_dac->tv_std == TV_STD_PAL_M)
+                               radeon_atom_get_tv_timings(rdev, 0, adjusted_mode);
+                       else
+                               radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);
+               }
+       }
+
        return true;
 }
 
@@ -461,7 +449,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
                case 1:
                        args.v1.ucMisc = 0;
                        args.v1.ucAction = action;
-                       if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+                       if (drm_detect_hdmi_monitor(radeon_connector->edid))
                                args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
                        args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
@@ -486,7 +474,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
                                if (dig->coherent_mode)
                                        args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
                        }
-                       if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+                       if (drm_detect_hdmi_monitor(radeon_connector->edid))
                                args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
                        args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
                        args.v2.ucTruncate = 0;
@@ -544,7 +532,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        switch (connector->connector_type) {
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
-               if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+               if (drm_detect_hdmi_monitor(radeon_connector->edid))
                        return ATOM_ENCODER_MODE_HDMI;
                else if (radeon_connector->use_digital)
                        return ATOM_ENCODER_MODE_DVI;
@@ -554,7 +542,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_DVID:
        case DRM_MODE_CONNECTOR_HDMIA:
        default:
-               if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+               if (drm_detect_hdmi_monitor(radeon_connector->edid))
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
@@ -566,7 +554,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                /*if (radeon_output->MonType == MT_DP)
                  return ATOM_ENCODER_MODE_DP;
                  else*/
-               if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
+               if (drm_detect_hdmi_monitor(radeon_connector->edid))
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
@@ -734,14 +722,17 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
        atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
 
        args.v1.ucAction = action;
-
+       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+               args.v1.usInitInfo = radeon_connector->connector_object_id;
+       } else {
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+               else
+                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+       }
        if (ASIC_IS_DCE32(rdev)) {
-               if (radeon_encoder->pixel_clock > 165000) {
-                       args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100);
-                       args.v2.acConfig.fDualLinkConnector = 1;
-               } else {
-                       args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100);
-               }
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
                if (dig->dig_block)
                        args.v2.acConfig.ucEncoderSel = 1;
 
@@ -766,7 +757,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
                }
        } else {
                args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-               args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10);
 
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -874,16 +864,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
        int index = 0;
        bool is_dig = false;
-       int devices;
 
        memset(&args, 0, sizeof(args));
 
-       /* on DPMS off we have no idea if active device is meaningful */
-       if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device)
-               devices = radeon_encoder->devices;
-       else
-               devices = radeon_encoder->active_device;
-
        DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
                  radeon_encoder->encoder_id, mode, radeon_encoder->devices,
                  radeon_encoder->active_device);
@@ -914,18 +897,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-               if (devices & (ATOM_DEVICE_TV_SUPPORT))
+               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
                        index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-               else if (devices & (ATOM_DEVICE_CV_SUPPORT))
+               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                        index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
                else
                        index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               if (devices & (ATOM_DEVICE_TV_SUPPORT))
+               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
                        index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-               else if (devices & (ATOM_DEVICE_CV_SUPPORT))
+               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                        index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
                else
                        index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
@@ -1104,8 +1087,11 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
        }
 
        /* set scaler clears this on some chips */
-       if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
-               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
+       if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
+               if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
+                       WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+                              AVIVO_D1MODE_INTERLEAVE_EN);
+       }
 }
 
 static void
@@ -1153,6 +1139,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 
                /* setup and enable the encoder and transmitter */
                atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
+               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
                atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
                atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
                break;
@@ -1268,8 +1255,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
        radeon_atom_output_lock(encoder, true);
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
index a931af0..a68d756 100644 (file)
@@ -140,15 +140,15 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
                WARN(1, "trying to unbind memory to unitialized GART !\n");
                return;
        }
-       t = offset / 4096;
-       p = t / (PAGE_SIZE / 4096);
+       t = offset / RADEON_GPU_PAGE_SIZE;
+       p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
        for (i = 0; i < pages; i++, p++) {
                if (rdev->gart.pages[p]) {
                        pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p],
                                       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
                        rdev->gart.pages[p] = NULL;
                        rdev->gart.pages_addr[p] = 0;
-                       for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) {
+                       for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
                                radeon_gart_set_page(rdev, t, 0);
                        }
                }
@@ -169,8 +169,8 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
                DRM_ERROR("trying to bind memory to unitialized GART !\n");
                return -EINVAL;
        }
-       t = offset / 4096;
-       p = t / (PAGE_SIZE / 4096);
+       t = offset / RADEON_GPU_PAGE_SIZE;
+       p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
 
        for (i = 0; i < pages; i++, p++) {
                /* we need to support large memory configurations */
@@ -185,9 +185,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
                }
                rdev->gart.pages[p] = pagelist[i];
                page_base = rdev->gart.pages_addr[p];
-               for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) {
+               for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
                        radeon_gart_set_page(rdev, t, page_base);
-                       page_base += 4096;
+                       page_base += RADEON_GPU_PAGE_SIZE;
                }
        }
        mb();
@@ -200,14 +200,14 @@ int radeon_gart_init(struct radeon_device *rdev)
        if (rdev->gart.pages) {
                return 0;
        }
-       /* We need PAGE_SIZE >= 4096 */
-       if (PAGE_SIZE < 4096) {
+       /* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */
+       if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) {
                DRM_ERROR("Page size is smaller than GPU page size!\n");
                return -EINVAL;
        }
        /* Compute table size */
        rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE;
-       rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096;
+       rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE;
        DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
                 rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages);
        /* Allocate pages table */
index 8e0a875..a0fe623 100644 (file)
@@ -92,6 +92,13 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
        if (r) {
                return r;
        }
+       /* enable msi */
+       rdev->msi_enabled = 0;
+       if (rdev->family >= CHIP_RV380) {
+               int ret = pci_enable_msi(rdev->pdev);
+               if (!ret)
+                       rdev->msi_enabled = 1;
+       }
        drm_irq_install(rdev->ddev);
        rdev->irq.installed = true;
        DRM_INFO("radeon: irq initialized.\n");
@@ -103,5 +110,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
        if (rdev->irq.installed) {
                rdev->irq.installed = false;
                drm_irq_uninstall(rdev->ddev);
+               if (rdev->msi_enabled)
+                       pci_disable_msi(rdev->pdev);
        }
 }
index 36410f8..8d0b7aa 100644 (file)
@@ -48,7 +48,7 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
        u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active;
        u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp;
        u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp;
-       struct radeon_native_mode *native_mode = &radeon_crtc->native_mode;
+       struct drm_display_mode *native_mode = &radeon_crtc->native_mode;
 
        fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) &
                (RADEON_VERT_STRETCH_RESERVED |
@@ -95,19 +95,19 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
 
        fp_horz_vert_active = 0;
 
-       if (native_mode->panel_xres == 0 ||
-           native_mode->panel_yres == 0) {
+       if (native_mode->hdisplay == 0 ||
+           native_mode->vdisplay == 0) {
                hscale = false;
                vscale = false;
        } else {
-               if (xres > native_mode->panel_xres)
-                       xres = native_mode->panel_xres;
-               if (yres > native_mode->panel_yres)
-                       yres = native_mode->panel_yres;
+               if (xres > native_mode->hdisplay)
+                       xres = native_mode->hdisplay;
+               if (yres > native_mode->vdisplay)
+                       yres = native_mode->vdisplay;
 
-               if (xres == native_mode->panel_xres)
+               if (xres == native_mode->hdisplay)
                        hscale = false;
-               if (yres == native_mode->panel_yres)
+               if (yres == native_mode->vdisplay)
                        vscale = false;
        }
 
@@ -119,11 +119,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
                else {
                        inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
                        scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
-                               / native_mode->panel_xres + 1;
+                               / native_mode->hdisplay + 1;
                        fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
                                        RADEON_HORZ_STRETCH_BLEND |
                                        RADEON_HORZ_STRETCH_ENABLE |
-                                       ((native_mode->panel_xres/8-1) << 16));
+                                       ((native_mode->hdisplay/8-1) << 16));
                }
 
                if (!vscale)
@@ -131,11 +131,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
                else {
                        inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
                        scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
-                               / native_mode->panel_yres + 1;
+                               / native_mode->vdisplay + 1;
                        fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
                                        RADEON_VERT_STRETCH_ENABLE |
                                        RADEON_VERT_STRETCH_BLEND |
-                                       ((native_mode->panel_yres-1) << 12));
+                                       ((native_mode->vdisplay-1) << 12));
                }
                break;
        case RMX_CENTER:
@@ -175,8 +175,8 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
                                                ? RADEON_CRTC_V_SYNC_POL
                                                : 0)));
 
-               fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) |
-                               (((native_mode->panel_xres / 8) & 0x1ff) << 16));
+               fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) |
+                               (((native_mode->hdisplay / 8) & 0x1ff) << 16));
                break;
        case RMX_OFF:
        default:
@@ -532,6 +532,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                radeon_fb = to_radeon_framebuffer(old_fb);
                radeon_gem_object_unpin(radeon_fb->obj);
        }
+
+       /* Bytes per pixel may have changed */
+       radeon_bandwidth_update(rdev);
+
        return 0;
 }
 
@@ -664,6 +668,9 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
 
                WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl);
                WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+               WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid);
+               WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid);
        } else {
                uint32_t crtc_gen_cntl;
                uint32_t crtc_ext_cntl;
@@ -1015,14 +1022,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
                                 int x, int y, struct drm_framebuffer *old_fb)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-       struct drm_device *dev = crtc->dev;
-       struct radeon_device *rdev = dev->dev_private;
 
        /* TODO TV */
        radeon_crtc_set_base(crtc, x, y, old_fb);
        radeon_set_crtc_timing(crtc, adjusted_mode);
        radeon_set_pll(crtc, adjusted_mode);
-       radeon_bandwidth_update(rdev);
        if (radeon_crtc->crtc_id == 0) {
                radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
        } else {
index 6ceb958..0038212 100644 (file)
@@ -107,8 +107,6 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
        else
                radeon_combios_output_lock(encoder, true);
        radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
-
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
@@ -192,6 +190,8 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
 {
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        if (radeon_encoder->rmx_type != RMX_OFF)
@@ -218,7 +218,8 @@ static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
                                                 struct drm_display_mode *mode,
                                                 struct drm_display_mode *adjusted_mode)
 {
-
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
@@ -272,7 +273,6 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
        else
                radeon_combios_output_lock(encoder, true);
        radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
@@ -468,7 +468,6 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
        else
                radeon_combios_output_lock(encoder, true);
        radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
@@ -543,6 +542,14 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
 
     fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
 
+    fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN |
+                    RADEON_FP_DFP_SYNC_SEL |
+                    RADEON_FP_CRT_SYNC_SEL |
+                    RADEON_FP_CRTC_LOCK_8DOT |
+                    RADEON_FP_USE_SHADOW_EN |
+                    RADEON_FP_CRTC_USE_SHADOW_VEND |
+                    RADEON_FP_CRT_SYNC_ALT);
+
     if (1) /*  FIXME rgbBits == 8 */
            fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;  /* 24 bit format */
     else
@@ -556,7 +563,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
                    else
                            fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
            } else
-                   fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+                   fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2;
     } else {
            if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) {
                    fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
@@ -593,7 +600,8 @@ static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
                                              struct drm_display_mode *mode,
                                              struct drm_display_mode *adjusted_mode)
 {
-
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
@@ -636,7 +644,6 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
        else
                radeon_combios_output_lock(encoder, true);
        radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
@@ -735,7 +742,8 @@ static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
                                            struct drm_display_mode *mode,
                                            struct drm_display_mode *adjusted_mode)
 {
-
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
@@ -839,7 +847,6 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
        else
                radeon_combios_output_lock(encoder, true);
        radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
-       radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
index e612268..ace726a 100644 (file)
@@ -172,6 +172,7 @@ enum radeon_connector_table {
 
 struct radeon_mode_info {
        struct atom_context *atom_context;
+       struct card_info *atom_card_info;
        enum radeon_connector_table connector_table;
        bool mode_config_initialized;
        struct radeon_crtc *crtcs[2];
@@ -186,17 +187,6 @@ struct radeon_mode_info {
 
 };
 
-struct radeon_native_mode {
-       /* preferred mode */
-       uint32_t panel_xres, panel_yres;
-       uint32_t hoverplus, hsync_width;
-       uint32_t hblank;
-       uint32_t voverplus, vsync_width;
-       uint32_t vblank;
-       uint32_t dotclock;
-       uint32_t flags;
-};
-
 #define MAX_H_CODE_TIMING_LEN 32
 #define MAX_V_CODE_TIMING_LEN 32
 
@@ -228,7 +218,7 @@ struct radeon_crtc {
        enum radeon_rmx_type rmx_type;
        fixed20_12 vsc;
        fixed20_12 hsc;
-       struct radeon_native_mode native_mode;
+       struct drm_display_mode native_mode;
 };
 
 struct radeon_encoder_primary_dac {
@@ -248,7 +238,7 @@ struct radeon_encoder_lvds {
        bool     use_bios_dividers;
        uint32_t lvds_gen_cntl;
        /* panel mode */
-       struct radeon_native_mode native_mode;
+       struct drm_display_mode native_mode;
 };
 
 struct radeon_encoder_tv_dac {
@@ -271,6 +261,16 @@ struct radeon_encoder_int_tmds {
        struct radeon_tmds_pll tmds_pll[4];
 };
 
+/* spread spectrum */
+struct radeon_atom_ss {
+       uint16_t percentage;
+       uint8_t type;
+       uint8_t step;
+       uint8_t delay;
+       uint8_t range;
+       uint8_t refdiv;
+};
+
 struct radeon_encoder_atom_dig {
        /* atom dig */
        bool coherent_mode;
@@ -278,8 +278,9 @@ struct radeon_encoder_atom_dig {
        /* atom lvds */
        uint32_t lvds_misc;
        uint16_t panel_pwr_delay;
+       struct radeon_atom_ss *ss;
        /* panel mode */
-       struct radeon_native_mode native_mode;
+       struct drm_display_mode native_mode;
 };
 
 struct radeon_encoder_atom_dac {
@@ -294,7 +295,7 @@ struct radeon_encoder {
        uint32_t flags;
        uint32_t pixel_clock;
        enum radeon_rmx_type rmx_type;
-       struct radeon_native_mode native_mode;
+       struct drm_display_mode native_mode;
        void *enc_priv;
 };
 
@@ -308,12 +309,15 @@ struct radeon_connector {
        uint32_t connector_id;
        uint32_t devices;
        struct radeon_i2c_chan *ddc_bus;
+       /* some systems have a an hdmi and vga port with a shared ddc line */
+       bool shared_ddc;
        bool use_digital;
        /* we need to mind the EDID between detect
           and get modes due to analog/digital/tvencoder */
        struct edid *edid;
        void *con_priv;
        bool dac_load_detect;
+       uint16_t connector_object_id;
 };
 
 struct radeon_framebuffer {
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
new file mode 100644 (file)
index 0000000..46146c6
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+ */
+#include "drmP.h"
+#include "radeon.h"
+
+int radeon_debugfs_pm_init(struct radeon_device *rdev);
+
+int radeon_pm_init(struct radeon_device *rdev)
+{
+       if (radeon_debugfs_pm_init(rdev)) {
+               DRM_ERROR("Failed to register debugfs file for CP !\n");
+       }
+
+       return 0;
+}
+
+/*
+ * Debugfs info
+ */
+#if defined(CONFIG_DEBUG_FS)
+
+static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct radeon_device *rdev = dev->dev_private;
+
+       seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
+       seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
+
+       return 0;
+}
+
+static struct drm_info_list radeon_pm_info_list[] = {
+       {"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL},
+};
+#endif
+
+int radeon_debugfs_pm_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+       return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list));
+#else
+       return 0;
+#endif
+}
index bfa1ab9..29ab759 100644 (file)
 #define RADEON_BUS_CNTL                     0x0030
 #       define RADEON_BUS_MASTER_DIS         (1 << 6)
 #       define RADEON_BUS_BIOS_DIS_ROM       (1 << 12)
+#      define RS600_BUS_MASTER_DIS          (1 << 14)
+#      define RS600_MSI_REARM               (1 << 20) /* rs600/rs690/rs740 */
 #       define RADEON_BUS_RD_DISCARD_EN      (1 << 24)
 #       define RADEON_BUS_RD_ABORT_EN        (1 << 25)
 #       define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28)
 #       define RADEON_BUS_READ_BURST         (1 << 30)
 #define RADEON_BUS_CNTL1                    0x0034
 #       define RADEON_BUS_WAIT_ON_LOCK_EN    (1 << 4)
+/* rv370/rv380, rv410, r423/r430/r480, r5xx */
+#define RADEON_MSI_REARM_EN                0x0160
+#      define RV370_MSI_REARM_EN            (1 << 0)
 
 /* #define RADEON_PCIE_INDEX                   0x0030 */
 /* #define RADEON_PCIE_DATA                    0x0034 */
 #define RADEON_AIC_CNTL                     0x01d0
 #       define RADEON_PCIGART_TRANSLATE_EN     (1 << 0)
 #       define RADEON_DIS_OUT_OF_PCI_GART_ACCESS     (1 << 1)
+#      define RS400_MSI_REARM                  (1 << 3) /* rs400/rs480 */
 #define RADEON_AIC_LO_ADDR                  0x01dc
 #define RADEON_AIC_PT_BASE             0x01d8
 #define RADEON_AIC_HI_ADDR             0x01e0
index 03c33cf..f8a465d 100644 (file)
@@ -42,7 +42,7 @@ void radeon_test_moves(struct radeon_device *rdev)
        /* Number of tests =
         * (Total GTT - IB pool - writeback page - ring buffer) / test size
         */
-       n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - 4096 -
+       n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
             rdev->cp.ring_size) / size;
 
        gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
@@ -102,7 +102,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                        goto out_cleanup;
                }
 
-               r = radeon_copy(rdev, gtt_addr, vram_addr, size / 4096, fence);
+               r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence);
                if (r) {
                        DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
                        goto out_cleanup;
@@ -145,7 +145,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                        goto out_cleanup;
                }
 
-               r = radeon_copy(rdev, vram_addr, gtt_addr, size / 4096, fence);
+               r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence);
                if (r) {
                        DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
                        goto out_cleanup;
index 765bd18..1381e06 100644 (file)
@@ -295,6 +295,12 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
        if (unlikely(r)) {
                return r;
        }
+
+       r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement);
+       if (unlikely(r)) {
+               goto out_cleanup;
+       }
+
        r = ttm_tt_bind(bo->ttm, &tmp_mem);
        if (unlikely(r)) {
                goto out_cleanup;
index a769c29..ca03716 100644 (file)
@@ -418,6 +418,8 @@ int rs400_resume(struct radeon_device *rdev)
        rs400_gart_disable(rdev);
        /* Resume clock before doing reset */
        r300_clock_startup(rdev);
+       /* setup MC before calling post tables */
+       rs400_mc_program(rdev);
        /* Reset gpu before posting otherwise ATOM will enter infinite loop */
        if (radeon_gpu_reset(rdev)) {
                dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
index 10dfa78..5f117cd 100644 (file)
@@ -242,7 +242,7 @@ void rs600_irq_disable(struct radeon_device *rdev)
 
 int rs600_irq_process(struct radeon_device *rdev)
 {
-       uint32_t status;
+       uint32_t status, msi_rearm;
        uint32_t r500_disp_int;
 
        status = rs600_irq_ack(rdev, &r500_disp_int);
@@ -260,6 +260,22 @@ int rs600_irq_process(struct radeon_device *rdev)
                        drm_handle_vblank(rdev->ddev, 1);
                status = rs600_irq_ack(rdev, &r500_disp_int);
        }
+       if (rdev->msi_enabled) {
+               switch (rdev->family) {
+               case CHIP_RS600:
+               case CHIP_RS690:
+               case CHIP_RS740:
+                       msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM;
+                       WREG32(RADEON_BUS_CNTL, msi_rearm);
+                       WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM);
+                       break;
+               default:
+                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       break;
+               }
+       }
        return IRQ_HANDLED;
 }
 
@@ -472,6 +488,8 @@ int rs600_init(struct radeon_device *rdev)
        }
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        rs600_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
index 025e322..2754717 100644 (file)
@@ -706,6 +706,8 @@ int rs690_init(struct radeon_device *rdev)
        }
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        rs690_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
index 41a34c2..7935f79 100644 (file)
@@ -137,6 +137,8 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev)
 
 void rv515_vga_render_disable(struct radeon_device *rdev)
 {
+       WREG32(R_000330_D1VGA_CONTROL, 0);
+       WREG32(R_000338_D2VGA_CONTROL, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL,
                RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
 }
@@ -585,6 +587,8 @@ int rv515_init(struct radeon_device *rdev)
        }
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        rv515_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
index 595ac63..b0efd0d 100644 (file)
@@ -529,11 +529,11 @@ static void rv770_gpu_init(struct radeon_device *rdev)
        if (rdev->family == CHIP_RV770)
                gb_tiling_config |= BANK_TILING(1);
        else
-               gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK);
+               gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
 
        gb_tiling_config |= GROUP_SIZE(0);
 
-       if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) {
+       if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
                gb_tiling_config |= ROW_TILING(3);
                gb_tiling_config |= SAMPLE_SPLIT(3);
        } else {
@@ -579,14 +579,14 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
        /* set HW defaults for 3D engine */
        WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
-                                               ROQ_IB2_START(0x2b)));
+                                    ROQ_IB2_START(0x2b)));
 
        WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
 
        WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
-                                       SYNC_GRADIENT |
-                                       SYNC_WALKER |
-                                       SYNC_ALIGNER));
+                            SYNC_GRADIENT |
+                            SYNC_WALKER |
+                            SYNC_ALIGNER));
 
        sx_debug_1 = RREG32(SX_DEBUG_1);
        sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
@@ -598,9 +598,9 @@ static void rv770_gpu_init(struct radeon_device *rdev)
        WREG32(SMX_DC_CTL0, smx_dc_ctl0);
 
        WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
-                                         GS_FLUSH_CTL(4) |
-                                         ACK_FLUSH_CTL(3) |
-                                         SYNC_FLUSH_CTL));
+                              GS_FLUSH_CTL(4) |
+                              ACK_FLUSH_CTL(3) |
+                              SYNC_FLUSH_CTL));
 
        if (rdev->family == CHIP_RV770)
                WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
@@ -611,12 +611,12 @@ static void rv770_gpu_init(struct radeon_device *rdev)
        }
 
        WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
-                                                  POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
-                                                  SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
+                                       POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
+                                       SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
 
        WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
-                                                SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
-                                                SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
+                                SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
+                                SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
 
        WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
 
@@ -774,14 +774,36 @@ int rv770_mc_init(struct radeon_device *rdev)
 {
        fixed20_12 a;
        u32 tmp;
+       int chansize, numchan;
        int r;
 
        /* Get VRAM informations */
-       /* FIXME: Don't know how to determine vram width, need to check
-        * vram_width usage
-        */
-       rdev->mc.vram_width = 128;
        rdev->mc.vram_is_ddr = true;
+       tmp = RREG32(MC_ARB_RAMCFG);
+       if (tmp & CHANSIZE_OVERRIDE) {
+               chansize = 16;
+       } else if (tmp & CHANSIZE_MASK) {
+               chansize = 64;
+       } else {
+               chansize = 32;
+       }
+       tmp = RREG32(MC_SHARED_CHMAP);
+       switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+       case 0:
+       default:
+               numchan = 1;
+               break;
+       case 1:
+               numchan = 2;
+               break;
+       case 2:
+               numchan = 4;
+               break;
+       case 3:
+               numchan = 8;
+               break;
+       }
+       rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
        rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
        rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
@@ -961,10 +983,13 @@ int rv770_init(struct radeon_device *rdev)
        r600_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
        r = radeon_clocks_init(rdev);
        if (r)
                return r;
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index 4b9c3d6..a1367ab 100644 (file)
 #define HDP_REG_COHERENCY_FLUSH_CNTL                   0x54A0
 #define        HDP_TILING_CONFIG                               0x2F3C
 
+#define MC_SHARED_CHMAP                                                0x2004
+#define                NOOFCHAN_SHIFT                                  12
+#define                NOOFCHAN_MASK                                   0x00003000
+
 #define        MC_ARB_RAMCFG                                   0x2760
 #define                NOOFBANK_SHIFT                                  0
 #define                NOOFBANK_MASK                                   0x00000003
 #define                CHANSIZE_MASK                                   0x00000100
 #define                BURSTLENGTH_SHIFT                               9
 #define                BURSTLENGTH_MASK                                0x00000200
+#define                CHANSIZE_OVERRIDE                               (1 << 11)
 #define        MC_VM_AGP_TOP                                   0x2028
 #define        MC_VM_AGP_BOT                                   0x202C
 #define        MC_VM_AGP_BASE                                  0x2030
index a55ee1a..7bcb89f 100644 (file)
@@ -279,6 +279,7 @@ int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement)
 
        return ttm_tt_set_caching(ttm, state);
 }
+EXPORT_SYMBOL(ttm_tt_set_placement_caching);
 
 static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
 {
index 737335f..e8fe7f1 100644 (file)
@@ -128,7 +128,7 @@ config I2C_PIIX4
            ATI SB600
            ATI SB700
            ATI SB800
-           AMD SB900
+           AMD Hudson-2
            Serverworks OSB4
            Serverworks CSB5
            Serverworks CSB6
index d26a972..1e245e9 100644 (file)
@@ -22,7 +22,7 @@
        Intel PIIX4, 440MX
        Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
        ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
-       AMD SB900
+       AMD Hudson-2
        SMSC Victory66
 
    Note: we assume there can only be one device, with one SMBus interface.
@@ -233,9 +233,9 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
        unsigned short smba_idx = 0xcd6;
        u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
 
-       /* SB800 SMBus does not support forcing address */
+       /* SB800 and later SMBus does not support forcing address */
        if (force || force_addr) {
-               dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
+               dev_err(&PIIX4_dev->dev, "SMBus does not support "
                        "forcing address!\n");
                return -EINVAL;
        }
@@ -480,7 +480,7 @@ static struct pci_device_id piix4_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
-       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
                     PCI_DEVICE_ID_SERVERWORKS_OSB4) },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
index 63c53d6..4d76ba4 100644 (file)
@@ -1046,15 +1046,6 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
                if (port_ops && port_ops->init_dev)
                        port_ops->init_dev(drive);
        }
-
-       ide_port_for_each_dev(i, drive, hwif) {
-               /*
-                * default to PIO Mode 0 before we figure out
-                * the most suited mode for the attached device
-                */
-               if (port_ops && port_ops->set_pio_mode)
-                       port_ops->set_pio_mode(drive, 0);
-       }
 }
 
 static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
index 23960cb..41c26e7 100644 (file)
@@ -959,8 +959,9 @@ static int process_idi_event (diva_strace_context_t* pLib,
        }
        if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
                char* tmp = &pLib->lines[0].pInterface->Layer2[0];
-    dword l2_state;
-    diva_strace_read_uint (pVar, &l2_state);
+               dword l2_state;
+               if (diva_strace_read_uint(pVar, &l2_state))
+                       return -1;
 
                switch (l2_state) {
                        case 0:
index 27d5dd6..ae89fb8 100644 (file)
@@ -2692,7 +2692,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
           if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
            || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
           {
-            len = (byte)(&(((T30_INFO *) 0)->universal_6));
+            len = offsetof(T30_INFO, universal_6);
             fax_info_change = false;
             if (ncpi->length >= 4)
             {
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
                     for (i = 0; i < w; i++)
                       ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
                     ((T30_INFO   *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-                    len = (byte)(((T30_INFO *) 0)->station_id + 20);
+                    len = offsetof(T30_INFO, station_id) + 20;
                     w = fax_parms[5].length;
                     if (w > 20)
                       w = 20;
@@ -2788,7 +2788,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
                 }
                 else
                 {
-                  len = (byte)(&(((T30_INFO *) 0)->universal_6));
+                  len = offsetof(T30_INFO, universal_6);
                 }
                 fax_info_change = true;
 
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
    {
-            len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+            len = offsetof(T30_INFO, station_id) + 20;
             if (plci->fax_connect_info_length < len)
             {
               ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
       break;
     }
     ncpi = &m_parms[1];
-    len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+    len = offsetof(T30_INFO, station_id) + 20;
     if (plci->fax_connect_info_length < len)
     {
       ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
         {
-          i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
+          i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
           while (i < plci->NL.RBuffer->length)
             plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
         }
@@ -7236,7 +7236,7 @@ static void nl_ind(PLCI *plci)
     {
       plci->RData[1].P = plci->RData[0].P;
       plci->RData[1].PLength = plci->RData[0].PLength;
-      plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3);
+      plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
       if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
         plci->RData[0].PLength = 1;
       else
@@ -8473,7 +8473,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
             fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
           }
             len = nlc[0];
-          pos = ((byte)(((T30_INFO *) 0)->station_id + 20));
+          pos = offsetof(T30_INFO, station_id) + 20;
    if (pos < plci->fax_connect_info_length)
    {
      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8525,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
       }
 
       PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
-      len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+      len = offsetof(T30_INFO, station_id) + 20;
       for (i = 0; i < len; i++)
         plci->fax_connect_info_buffer[i] = nlc[1+i];
       ((T30_INFO   *) plci->fax_connect_info_buffer)->head_line_len = 0;
index bf526a7..d6fdf1f 100644 (file)
@@ -594,6 +594,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
                                if (cs->debug & L1_DEB_WARN)
                                        debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
                                skb_queue_tail(&cs->sq, skb);
+                               spin_unlock_irqrestore(&cs->lock, flags);
                                break;
                        }
                        if (cs->debug & DEB_DLOG_HEX)
index 018bd29..0b0c2e5 100644 (file)
@@ -382,7 +382,7 @@ MemwaitforXFW(struct IsdnCardState *cs, int hscx)
 {
        int to = 50;
 
-       while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
+       while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) {
                udelay(1);
                to--;
        }
index f181db4..1657bba 100644 (file)
@@ -477,62 +477,62 @@ static void
 modem_set_init(struct IsdnCardState *cs) {
        int timeout;
 
-#define RCV_DELAY 20000        
+#define RCV_DELAY 20
        modem_write_cmd(cs, MInit_1, strlen(MInit_1));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_2, strlen(MInit_2));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_3, strlen(MInit_3));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_4, strlen(MInit_4));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY );
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_5, strlen(MInit_5));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_6, strlen(MInit_6));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_7, strlen(MInit_7));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
 }
 
 static void
 modem_set_dial(struct IsdnCardState *cs, int outgoing) {
        int timeout;
-#define RCV_DELAY 20000        
+#define RCV_DELAY 20
 
        modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
        if (outgoing)
                modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
        else
@@ -541,7 +541,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
        debugl1(cs, "msi tout=%d", timeout);
-       udelay(RCV_DELAY);
+       mdelay(RCV_DELAY);
 }
 
 static void
index 9de5420..a420b64 100644 (file)
@@ -817,8 +817,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
        }
        /* we have a complete hdlc packet */
        if (finish) {
-               if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
-                   && (fifo->skbuff->len > 3)) {
+               if (fifo->skbuff->len > 3 &&
+                               !fifo->skbuff->data[fifo->skbuff->len - 1]) {
 
                        if (fifon == HFCUSB_D_RX) {
                                DBG(HFCUSB_DBG_DCHANNEL,
index 7b1ad5e..2387d76 100644 (file)
@@ -32,7 +32,7 @@ waitforXFW(struct IsdnCardState *cs, int hscx)
 {
        int to = 50;
 
-       while ((!(READHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
+       while (((READHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) {
                udelay(1);
                to--;
        }
index 9aba646..c80cbb8 100644 (file)
@@ -468,6 +468,7 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
                                if (cs->debug & L1_DEB_WARN)
                                        debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
                                skb_queue_tail(&cs->sq, skb);
+                               spin_unlock_irqrestore(&cs->lock, flags);
                                break;
                        }
                        if (cs->debug & DEB_DLOG_HEX)
index 3e1532a..0d05ec4 100644 (file)
@@ -364,7 +364,7 @@ add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
 static int
 st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 {
-       if (!ch->st || ch->st->layer1)
+       if (!ch->st || !ch->st->layer1)
                return -EINVAL;
        return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
 }
index 10eb1fc..e64c971 100644 (file)
@@ -6504,8 +6504,9 @@ void md_do_sync(mddev_t *mddev)
  skip:
        mddev->curr_resync = 0;
        mddev->curr_resync_completed = 0;
-       mddev->resync_min = 0;
-       mddev->resync_max = MaxSector;
+       if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
+               /* We completed so max setting can be forgotten. */
+               mddev->resync_max = MaxSector;
        sysfs_notify(&mddev->kobj, NULL, "sync_completed");
        wake_up(&resync_wait);
        set_bit(MD_RECOVERY_DONE, &mddev->recovery);
index 81abefc..dcce204 100644 (file)
@@ -4049,6 +4049,8 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
                        sector_nr = conf->reshape_progress;
                sector_div(sector_nr, new_data_disks);
                if (sector_nr) {
+                       mddev->curr_resync_completed = sector_nr;
+                       sysfs_notify(&mddev->kobj, NULL, "sync_completed");
                        *skipped = 1;
                        return sector_nr;
                }
index 6459511..3a50ce9 100644 (file)
@@ -616,13 +616,13 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
                case RF2:
                        map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] -
                                        prog_cal[RF1] + prog_tab[RF1]) /
-                               ((rf_freq[RF2] - rf_freq[RF1]) / 1000);
+                               (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000);
                        map[i].rf2   = rf_freq[RF2] / 1000;
                        break;
                case RF3:
                        map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] -
                                        prog_cal[RF2] + prog_tab[RF2]) /
-                               ((rf_freq[RF3] - rf_freq[RF2]) / 1000);
+                               (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000);
                        map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2];
                        map[i].rf3   = rf_freq[RF3] / 1000;
                        break;
@@ -1000,12 +1000,12 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe,
        struct tda18271_std_map_item *map;
        char *mode;
        int ret;
-       u32 freq = params->frequency * 62500;
+       u32 freq = params->frequency * 125 *
+               ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;
 
        priv->mode = TDA18271_ANALOG;
 
        if (params->mode == V4L2_TUNER_RADIO) {
-               freq = freq / 1000;
                map = &std_map->fm_radio;
                mode = "fm";
        } else if (params->std & V4L2_STD_MN) {
index 9744b06..0e4b97f 100644 (file)
@@ -75,7 +75,7 @@ config DVB_USB_DIB0700
        select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
        select DVB_S5H1411 if !DVB_FE_CUSTOMISE
        select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
-       select DVB_TUNER_DIB0070
+       select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
        select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
index 0737c63..3df2045 100644 (file)
@@ -105,7 +105,7 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
        int i = 0;
        struct req_t req;
        int ret = 0;
-       memset(&req, 0, sizeof(&req));
+       memset(&req, 0, sizeof(req));
 
        if (num > 2)
                return -EINVAL;
index 0b2812a..6bd8951 100644 (file)
@@ -1925,7 +1925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { NULL },
                        },
                        {   "Leadtek Winfast DTV Dongle (STK7700P based)",
-                               { &dib0700_usb_id_table[8] },
+                               { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
                                { NULL },
                        },
                        {   "AVerMedia AVerTV DVB-T Express",
@@ -2064,7 +2064,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        },
                },
 
-               .num_device_descs = 12,
+               .num_device_descs = 11,
                .devices = {
                        {   "DiBcom STK7070P reference design",
                                { &dib0700_usb_id_table[15], NULL },
@@ -2098,11 +2098,6 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { &dib0700_usb_id_table[30], NULL },
                                { NULL },
                        },
-                       {   "Terratec Cinergy T USB XXS/ T3",
-                               { &dib0700_usb_id_table[33],
-                                       &dib0700_usb_id_table[52], NULL },
-                               { NULL },
-                       },
                        {   "Elgato EyeTV DTT",
                                { &dib0700_usb_id_table[49], NULL },
                                { NULL },
@@ -2343,8 +2338,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { &dib0700_usb_id_table[59], NULL },
                                { NULL },
                        },
-                       {   "Terratec Cinergy T USB XXS (HD)",
-                               { &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
+                       {   "Terratec Cinergy T USB XXS (HD)/ T3",
+                               { &dib0700_usb_id_table[33],
+                                       &dib0700_usb_id_table[52],
+                                       &dib0700_usb_id_table[60], NULL},
                                { NULL },
                        },
                },
index d1b67fe..485d061 100644 (file)
@@ -1050,28 +1050,28 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
        c->operand[4] = 0; /* slot */
        c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
        c->operand[6] = 0; /* more/last */
-       /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */
-       c->operand[8] = list_management;
-       c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */
+       /* Use three bytes for length field in case length > 127 */
+       c->operand[10] = list_management;
+       c->operand[11] = 0x01; /* pmt_cmd=OK_descramble */
 
        /* TS program map table */
 
-       c->operand[10] = 0x02; /* Table id=2 */
-       c->operand[11] = 0x80; /* Section syntax + length */
-       /* c->operand[12] = XXXprogram_info_length + 12; */
-       c->operand[13] = msg[1]; /* Program number */
-       c->operand[14] = msg[2];
-       c->operand[15] = 0x01; /* Version number=0 + current/next=1 */
-       c->operand[16] = 0x00; /* Section number=0 */
-       c->operand[17] = 0x00; /* Last section number=0 */
-       c->operand[18] = 0x1f; /* PCR_PID=1FFF */
-       c->operand[19] = 0xff;
-       c->operand[20] = (program_info_length >> 8); /* Program info length */
-       c->operand[21] = (program_info_length & 0xff);
+       c->operand[12] = 0x02; /* Table id=2 */
+       c->operand[13] = 0x80; /* Section syntax + length */
+       /* c->operand[14] = XXXprogram_info_length + 12; */
+       c->operand[15] = msg[1]; /* Program number */
+       c->operand[16] = msg[2];
+       c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
+       c->operand[18] = 0x00; /* Section number=0 */
+       c->operand[19] = 0x00; /* Last section number=0 */
+       c->operand[20] = 0x1f; /* PCR_PID=1FFF */
+       c->operand[21] = 0xff;
+       c->operand[22] = (program_info_length >> 8); /* Program info length */
+       c->operand[23] = (program_info_length & 0xff);
 
        /* CA descriptors at programme level */
        read_pos = 6;
-       write_pos = 22;
+       write_pos = 24;
        if (program_info_length > 0) {
                pmt_cmd_id = msg[read_pos++];
                if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
@@ -1113,8 +1113,10 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
        c->operand[write_pos++] = 0x00;
        c->operand[write_pos++] = 0x00;
 
-       c->operand[7] = write_pos - 8;
-       c->operand[12] = write_pos - 13;
+       c->operand[7] = 0x82;
+       c->operand[8] = (write_pos - 10) >> 8;
+       c->operand[9] = (write_pos - 10) & 0xff;
+       c->operand[14] = write_pos - 15;
 
        crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
        c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
index 7ba4363..e49cdc8 100644 (file)
@@ -141,18 +141,12 @@ static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
        return -EOPNOTSUPP;
 }
 
-#define ACCEPTED 0x9
-
 static int fdtv_set_frontend(struct dvb_frontend *fe,
                             struct dvb_frontend_parameters *params)
 {
        struct firedtv *fdtv = fe->sec_priv;
 
-       /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
-       if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
-               return -EINVAL;
-       else
-               return 0; /* not sure of this... */
+       return avc_tuner_dsd(fdtv, params);
 }
 
 static int fdtv_get_frontend(struct dvb_frontend *fe,
index 8a2e1e7..eec9e52 100644 (file)
@@ -51,6 +51,7 @@ struct dib0070_config {
 #if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
 extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
 #else
 static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
 {
@@ -63,7 +64,11 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
        return -ENODEV;
 }
+
+static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
 #endif
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
 
 #endif
index 55ef6ee..0781f94 100644 (file)
@@ -1375,6 +1375,11 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
        if (dib7000p_identify(st) != 0)
                goto error;
 
+       /* FIXME: make sure the dev.parent field is initialized, or else
+       request_firmware() will hit an OOPS (this should be moved somewhere
+       more common) */
+       st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
+
        dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
 
        dib7000p_demod_reset(st);
index 81e623a..1fd8306 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/vmalloc.h>
 
 #include "dvbdev.h"
 #include "dvb_demux.h"
index cb8a358..8f88a58 100644 (file)
@@ -529,6 +529,12 @@ struct usb_device_id smsusb_id_table[] = {
                .driver_info = SMS1XXX_BOARD_SIANO_NICE },
        { USB_DEVICE(0x187f, 0x0301),
                .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
+       { USB_DEVICE(0x2040, 0xb900),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xb910),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc000),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
        { } /* Terminating entry */
        };
 
index 939d1e5..a672401 100644 (file)
@@ -1299,7 +1299,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
 
        tvnorm = &bttv_tvnorms[norm];
 
-       if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+       if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
                    sizeof (tvnorm->cropcap))) {
                bttv_crop_reset(&btv->crop[0], norm);
                btv->crop[1] = btv->crop[0]; /* current = default */
@@ -3800,11 +3800,34 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
                if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
                    (item->vb.queue.next != &btv->capture)) {
                        item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
+                       /* Mike Isely <isely@pobox.com> - Only check
+                        * and set up the bottom field in the logic
+                        * below.  Don't ever do the top field.  This
+                        * of course means that if we set up the
+                        * bottom field in the above code that we'll
+                        * actually skip a field.  But that's OK.
+                        * Having processed only a single buffer this
+                        * time, then the next time around the first
+                        * available buffer should be for a top field.
+                        * That will then cause us here to set up a
+                        * top then a bottom field in the normal way.
+                        * The alternative to this understanding is
+                        * that we set up the second available buffer
+                        * as a top field, but that's out of order
+                        * since this driver always processes the top
+                        * field first - the effect will be the two
+                        * buffers being returned in the wrong order,
+                        * with the second buffer also being delayed
+                        * by one field time (owing to the fifo nature
+                        * of videobuf).  Worse still, we'll be stuck
+                        * doing fields out of order now every time
+                        * until something else causes a field to be
+                        * dropped.  By effectively forcing a field to
+                        * drop this way then we always get back into
+                        * sync within a single frame time.  (Out of
+                        * order fields can screw up deinterlacing
+                        * algorithms.) */
                        if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
-                               if (NULL == set->top &&
-                                   V4L2_FIELD_TOP == item->vb.field) {
-                                       set->top = item;
-                               }
                                if (NULL == set->bottom &&
                                    V4L2_FIELD_BOTTOM == item->vb.field) {
                                        set->bottom = item;
index 7bd8a70..ac947ae 100644 (file)
@@ -383,6 +383,11 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
 
 static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
 {
+       struct em28xx *dev = snd_pcm_substream_chip(substream);
+
+       dev->adev.hwptr_done_capture = 0;
+       dev->adev.capture_transfer_done = 0;
+
        return 0;
 }
 
index 59400e8..a27afeb 100644 (file)
@@ -35,12 +35,25 @@ static
     const
        struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
        {
+               .ident = "BRUNEINIT",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "BRUNENIT"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "BRUNENIT"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "00030D0000000001")
+               }
+       }, {
                .ident = "Fujitsu-Siemens Amilo Xa 2528",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
                }
        }, {
+               .ident = "Fujitsu-Siemens Amilo Xi 2528",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2528")
+               }
+       }, {
                .ident = "Fujitsu-Siemens Amilo Xi 2550",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -57,6 +70,13 @@ static
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
+                       DMI_MATCH(DMI_BIOS_DATE, "12/02/2008")
+               }
+       }, {
+               .ident = "MSI GX700",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
                        DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
                }
        }, {
index 140c8f3..f8328b9 100644 (file)
@@ -483,7 +483,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
                data[3] = 0x2c;                    /* reg 2, H size/8 */
                data[4] = 0x48;                    /* reg 3, V size/4 */
                data[6] = 0x06;                    /* reg 5, H start  */
-               data[8] = 0x06 + sd->sensor_type;  /* reg 7, V start  */
+               data[8] = 0x06 - sd->sensor_type;  /* reg 7, V start  */
                break;
        }
        err_code = mr_write(gspca_dev, 11);
index 2f6e135..a5c190e 100644 (file)
@@ -2919,7 +2919,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
        /* A false positive here is likely, until OVT gives me
         * the definitive SOF/EOF format */
        if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
-               gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+               frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
                gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
                sd->packet_nr = 0;
        }
index 65489d6..bfae63f 100644 (file)
@@ -394,7 +394,8 @@ frame_data:
                        PDEBUG(D_PACK, "End of frame detected");
 
                        /* Complete the last frame (if any) */
-                       gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+                       frame = gspca_frame_add(gspca_dev, LAST_PACKET,
+                                               frame, data, 0);
 
                        if (chunk_len)
                                PDEBUG(D_ERR, "Chunk length is "
index 6952e96..51b683c 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -1432,7 +1433,9 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
                icd->sense = &sense;
 
        cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
-       ret = v4l2_subdev_call(sd, video, s_fmt, f);
+       ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
+       cam_f.fmt.pix.pixelformat = pix->pixelformat;
+       *pix = cam_f.fmt.pix;
 
        icd->sense = NULL;
 
index 9e3262c..2c0bb06 100644 (file)
@@ -598,11 +598,6 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
        buf = list_entry(dma_q->active.next,
                         struct s2255_buffer, vb.queue);
 
-       if (!waitqueue_active(&buf->vb.done)) {
-               /* no one active */
-               rc = -1;
-               goto unlock;
-       }
        list_del(&buf->vb.queue);
        do_gettimeofday(&buf->vb.ts);
        dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
index 71145bf..0901322 100644 (file)
@@ -3428,6 +3428,7 @@ struct saa7134_board saa7134_boards[] = {
                .tuner_config   = 3,
                .mpeg           = SAA7134_MPEG_DVB,
                .ts_type        = SAA7134_MPEG_TS_SERIAL,
+               .ts_force_val   = 1,
                .gpiomask       = 0x0800100, /* GPIO 21 is an INPUT */
                .inputs         = {{
                        .name = name_tv,
index 3fa6522..03488ba 100644 (file)
@@ -262,11 +262,13 @@ int saa7134_ts_start(struct saa7134_dev *dev)
        switch (saa7134_boards[dev->board].ts_type) {
        case SAA7134_MPEG_TS_PARALLEL:
                saa_writeb(SAA7134_TS_SERIAL0, 0x40);
-               saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+               saa_writeb(SAA7134_TS_PARALLEL, 0xec |
+                       (saa7134_boards[dev->board].ts_force_val << 4));
                break;
        case SAA7134_MPEG_TS_SERIAL:
                saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
-               saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+               saa_writeb(SAA7134_TS_PARALLEL, 0x6c |
+                       (saa7134_boards[dev->board].ts_force_val << 4));
                saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
                saa_writeb(SAA7134_TS_SERIAL1, 0x02);
                break;
index 6ee3e9b..f8697d4 100644 (file)
@@ -360,6 +360,7 @@ struct saa7134_board {
        enum saa7134_mpeg_type  mpeg;
        enum saa7134_mpeg_ts_type ts_type;
        unsigned int            vid_port_opts;
+       unsigned int            ts_force_val:1;
 };
 
 #define card_has_radio(dev)   (NULL != saa7134_boards[dev->board].radio.name)
index c45966e..9c1d3ac 100644 (file)
@@ -347,7 +347,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
 
        /* Prepare some basic command/response structures */
        memset(&command_t, 0, sizeof(command_t));
-       memset(&response_t, 0, sizeof(&response_t));
+       memset(&response_t, 0, sizeof(response_t));
        pcommand_t = &command_t;
        presponse_t = &response_t;
        command_t.id = id;
index 65ac474..2f78b4f 100644 (file)
@@ -1173,8 +1173,8 @@ static int get_scales(struct soc_camera_device *icd,
        width_in = scale_up(cam->ceu_rect.width, *scale_h);
        height_in = scale_up(cam->ceu_rect.height, *scale_v);
 
-       *scale_h = calc_generic_scale(cam->ceu_rect.width, icd->user_width);
-       *scale_v = calc_generic_scale(cam->ceu_rect.height, icd->user_height);
+       *scale_h = calc_generic_scale(width_in, icd->user_width);
+       *scale_v = calc_generic_scale(height_in, icd->user_height);
 
        return 0;
 }
index 59aa7a3..36e617b 100644 (file)
@@ -1160,13 +1160,15 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
                if (icd->iface == ici->nr) {
                        /* The bus->remove will be called */
                        device_unregister(&icd->dev);
-                       /* Not before device_unregister(), .remove
-                        * needs parent to call ici->ops->remove() */
-                       icd->dev.parent = NULL;
-
-                       /* If the host module is loaded again, device_register()
-                        * would complain "already initialised" */
-                       memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
+                       /*
+                        * Not before device_unregister(), .remove
+                        * needs parent to call ici->ops->remove().
+                        * If the host module is loaded again, device_register()
+                        * would complain "already initialised," since 2.6.32
+                        * this is also needed to prevent use-after-free of the
+                        * device private data.
+                        */
+                       memset(&icd->dev, 0, sizeof(icd->dev));
                }
        }
 
index c3225a5..1b89735 100644 (file)
@@ -348,7 +348,7 @@ static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
        __s32 value, __u8 *data)
 {
        data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
-       data[2] = min(abs(value), 0xff);
+       data[2] = min((int)abs(value), 0xff);
 }
 
 static struct uvc_control_mapping uvc_ctrl_mappings[] = {
index f960e8e..a6e41d1 100644 (file)
@@ -90,7 +90,8 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
                ctrl->dwMaxVideoFrameSize =
                        frame->dwMaxVideoFrameBufferSize;
 
-       if (stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+       if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
+           stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
            stream->intf->num_altsetting > 1) {
                u32 interval;
                u32 bandwidth;
index ccd4408..3f2375c 100644 (file)
@@ -161,14 +161,15 @@ static int options_show(struct seq_file *s, void *p)
 static ssize_t options_write(struct file *file, const char __user *userbuf,
                             size_t count, loff_t *data)
 {
-       unsigned long val;
-       char buf[80];
+       char buf[20];
 
-       if (strncpy_from_user(buf, userbuf, sizeof(buf) - 1) < 0)
+       if (count >= sizeof(buf))
+               return -EINVAL;
+       if (copy_from_user(buf, userbuf, count))
                return -EFAULT;
-       buf[count - 1] = '\0';
-       if (!strict_strtoul(buf, 10, &val))
-               gru_options = val;
+       buf[count] = '\0';
+       if (strict_strtoul(buf, 0, &gru_options))
+               return -EINVAL;
 
        return count;
 }
index 841e085..14be075 100644 (file)
@@ -486,6 +486,7 @@ config MTD_BFIN_ASYNC
 
 config MTD_GPIO_ADDR
        tristate "GPIO-assisted Flash Chip Support"
+       depends on GENERIC_GPIO || GPIOLIB
        depends on MTD_COMPLEX_MAPPINGS
        select MTD_PARTITIONS
        help
index 1d5cf86..ae2f6db 100644 (file)
@@ -58,4 +58,6 @@ obj-$(CONFIG_MTD_PLATRAM)     += plat-ram.o
 obj-$(CONFIG_MTD_OMAP_NOR)     += omap_nor.o
 obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
 obj-$(CONFIG_MTD_BFIN_ASYNC)   += bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939)     += rbtx4939-flash.o
+obj-$(CONFIG_MTD_VMU)          += vmu-flash.o
 obj-$(CONFIG_MTD_GPIO_ADDR)    += gpio-addr-flash.o
index 44ef9a4..1ad5caf 100644 (file)
@@ -13,7 +13,9 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
@@ -23,9 +25,6 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 
-#include <asm/gpio.h>
-#include <asm/io.h>
-
 #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
 
 #define DRIVER_NAME "gpio-addr-flash"
index 2211386..2957cc7 100644 (file)
@@ -761,6 +761,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  *
  * Not for syndrome calculating ecc controllers, which use a special oob layout
  */
@@ -777,6 +778,7 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
@@ -818,6 +820,7 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *c
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  */
 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int page)
@@ -939,6 +942,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  *
  * Not for syndrome calculating ecc controllers which need a special oob layout
  */
@@ -983,6 +987,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  *
  * Hardware ECC for large page chips, require OOB to be read first.
  * For this ECC mode, the write_page method is re-used from ECC_HW.
@@ -1031,6 +1036,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @page:      page number to read
  *
  * The hw generator calculates the error syndrome automatically. Therefor
  * we need a special oob layout and handling.
index a80da0e..3b79a22 100644 (file)
@@ -259,6 +259,8 @@ struct be_adapter {
        u32 port_num;
        bool promiscuous;
        u32 cap;
+       u32 rx_fc;              /* Rx flow control */
+       u32 tx_fc;              /* Tx flow control */
 };
 
 extern const struct ethtool_ops be_ethtool_ops;
index 4995378..e5f9676 100644 (file)
@@ -68,7 +68,7 @@ enum {
 #define CQE_STATUS_COMPL_MASK          0xFFFF
 #define CQE_STATUS_COMPL_SHIFT         0       /* bits 0 - 15 */
 #define CQE_STATUS_EXTD_MASK           0xFFFF
-#define CQE_STATUS_EXTD_SHIFT          0       /* bits 0 - 15 */
+#define CQE_STATUS_EXTD_SHIFT          16      /* bits 16 - 31 */
 
 struct be_mcc_compl {
        u32 status;             /* dword 0 */
index cda5bf2..f0fd95b 100644 (file)
@@ -323,10 +323,12 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 
        if (ecmd->autoneg != 0)
                return -EINVAL;
+       adapter->tx_fc = ecmd->tx_pause;
+       adapter->rx_fc = ecmd->rx_pause;
 
-       status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
-                       ecmd->rx_pause);
-       if (!status)
+       status = be_cmd_set_flow_control(adapter,
+                                       adapter->tx_fc, adapter->rx_fc);
+       if (status)
                dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
 
        return status;
index 1f941f0..876b357 100644 (file)
@@ -1610,11 +1610,21 @@ static int be_open(struct net_device *netdev)
 
        status = be_cmd_link_status_query(adapter, &link_up);
        if (status)
-               return status;
+               goto ret_sts;
        be_link_status_update(adapter, link_up);
 
+       status = be_vid_config(adapter);
+       if (status)
+               goto ret_sts;
+
+       status = be_cmd_set_flow_control(adapter,
+                                       adapter->tx_fc, adapter->rx_fc);
+       if (status)
+               goto ret_sts;
+
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
-       return 0;
+ret_sts:
+       return status;
 }
 
 static int be_setup(struct be_adapter *adapter)
@@ -1648,17 +1658,8 @@ static int be_setup(struct be_adapter *adapter)
        if (status != 0)
                goto rx_qs_destroy;
 
-       status = be_vid_config(adapter);
-       if (status != 0)
-               goto mccqs_destroy;
-
-       status = be_cmd_set_flow_control(adapter, true, true);
-       if (status != 0)
-               goto mccqs_destroy;
        return 0;
 
-mccqs_destroy:
-       be_mcc_queues_destroy(adapter);
 rx_qs_destroy:
        be_rx_queues_destroy(adapter);
 tx_qs_destroy:
@@ -1909,6 +1910,10 @@ static void be_netdev_init(struct net_device *netdev)
 
        adapter->rx_csum = true;
 
+       /* Default settings for Rx and Tx flow control */
+       adapter->rx_fc = true;
+       adapter->tx_fc = true;
+
        netif_set_gso_max_size(netdev, 65535);
 
        BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
@@ -2171,6 +2176,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
                be_close(netdev);
                rtnl_unlock();
        }
+       be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc);
        be_clear(adapter);
 
        pci_save_state(pdev);
index f0b9a1e..564e31c 100644 (file)
@@ -589,6 +589,22 @@ static int can_changelink(struct net_device *dev,
        return 0;
 }
 
+static size_t can_get_size(const struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       size_t size;
+
+       size = nla_total_size(sizeof(u32));   /* IFLA_CAN_STATE */
+       size += sizeof(struct can_ctrlmode);  /* IFLA_CAN_CTRLMODE */
+       size += nla_total_size(sizeof(u32));  /* IFLA_CAN_RESTART_MS */
+       size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
+       size += sizeof(struct can_clock);     /* IFLA_CAN_CLOCK */
+       if (priv->bittiming_const)            /* IFLA_CAN_BITTIMING_CONST */
+               size += sizeof(struct can_bittiming_const);
+
+       return size;
+}
+
 static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
        struct can_priv *priv = netdev_priv(dev);
@@ -639,6 +655,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
        .setup          = can_setup,
        .newlink        = can_newlink,
        .changelink     = can_changelink,
+       .get_size       = can_get_size,
        .fill_info      = can_fill_info,
        .fill_xstats    = can_fill_xstats,
 };
index 9012e0a..abdbd9c 100644 (file)
@@ -319,7 +319,7 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
 
        cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
 
-       cf->can_id = msg->msg.can_msg.id;
+       cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
        cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
 
        if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME
@@ -813,6 +813,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
                msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
        }
 
+       /* Respect byte order */
+       msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
+
        for (i = 0; i < MAX_TX_URBS; i++) {
                if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
                        context = &dev->tx_contexts[i];
index 05916aa..f857afe 100644 (file)
@@ -4342,11 +4342,11 @@ static int cas_open(struct net_device *dev)
                cas_unlock_all_restore(cp, flags);
        }
 
+       err = -ENOMEM;
        if (cas_tx_tiny_alloc(cp) < 0)
-               return -ENOMEM;
+               goto err_unlock;
 
        /* alloc rx descriptors */
-       err = -ENOMEM;
        if (cas_alloc_rxds(cp) < 0)
                goto err_tx_tiny;
 
@@ -4386,6 +4386,7 @@ err_spare:
        cas_free_rxds(cp);
 err_tx_tiny:
        cas_tx_tiny_free(cp);
+err_unlock:
        mutex_unlock(&cp->pm_mutex);
        return err;
 }
index f72c56d..3179521 100644 (file)
@@ -2221,7 +2221,7 @@ void emac_poll_controller(struct net_device *ndev)
        struct emac_priv *priv = netdev_priv(ndev);
 
        emac_int_disable(priv);
-       emac_irq(ndev->irq, priv);
+       emac_irq(ndev->irq, ndev);
        emac_int_enable(priv);
 }
 #endif
index 6ac4648..efbf676 100644 (file)
@@ -427,3 +427,4 @@ void fsl_pq_mdio_exit(void)
        of_unregister_platform_driver(&fsl_pq_mdio_driver);
 }
 module_exit(fsl_pq_mdio_exit);
+MODULE_LICENSE("GPL");
index cbb143c..5bd9e6b 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "ixgbe.h"
 #include "ixgbe_common.h"
+#include "ixgbe_dcb_82599.h"
 
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
@@ -226,6 +227,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
        /* tx_buffer_info must be completely set up in the transmit path */
 }
 
+/**
+ * ixgbe_tx_is_paused - check if the tx ring is paused
+ * @adapter: the ixgbe adapter
+ * @tx_ring: the corresponding tx_ring
+ *
+ * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
+ * corresponding TC of this tx_ring when checking TFCS.
+ *
+ * Returns : true if paused
+ */
+static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
+                                      struct ixgbe_ring *tx_ring)
+{
+       int tc;
+       u32 txoff = IXGBE_TFCS_TXOFF;
+
+#ifdef CONFIG_IXGBE_DCB
+       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+               int reg_idx = tx_ring->reg_idx;
+               int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+
+               if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+                       tc = reg_idx >> 2;
+                       txoff = IXGBE_TFCS_TXOFF0;
+               } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+                       tc = 0;
+                       txoff = IXGBE_TFCS_TXOFF;
+                       if (dcb_i == 8) {
+                               /* TC0, TC1 */
+                               tc = reg_idx >> 5;
+                               if (tc == 2) /* TC2, TC3 */
+                                       tc += (reg_idx - 64) >> 4;
+                               else if (tc == 3) /* TC4, TC5, TC6, TC7 */
+                                       tc += 1 + ((reg_idx - 96) >> 3);
+                       } else if (dcb_i == 4) {
+                               /* TC0, TC1 */
+                               tc = reg_idx >> 6;
+                               if (tc == 1) {
+                                       tc += (reg_idx - 64) >> 5;
+                                       if (tc == 2) /* TC2, TC3 */
+                                               tc += (reg_idx - 96) >> 4;
+                               }
+                       }
+               }
+               txoff <<= tc;
+       }
+#endif
+       return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
+}
+
 static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
                                        struct ixgbe_ring *tx_ring,
                                        unsigned int eop)
@@ -237,7 +288,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
        adapter->detect_tx_hung = false;
        if (tx_ring->tx_buffer_info[eop].time_stamp &&
            time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
-           !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
+           !ixgbe_tx_is_paused(adapter, tx_ring)) {
                /* detected Tx unit hang */
                union ixgbe_adv_tx_desc *tx_desc;
                tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
@@ -412,19 +463,23 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
        u32 txctrl;
        int cpu = get_cpu();
        int q = tx_ring - adapter->tx_ring;
+       struct ixgbe_hw *hw = &adapter->hw;
 
        if (tx_ring->cpu != cpu) {
-               txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
                if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q));
                        txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
                        txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+                       txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl);
                } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+                       txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
                        txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
                        txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
-                                  IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+                                 IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+                       txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
+                       IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
                }
-               txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
                tx_ring->cpu = cpu;
        }
        put_cpu();
@@ -1913,11 +1968,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
                        break;
                }
        }
+
        if (hw->mac.type == ixgbe_mac_82599EB) {
+               u32 rttdcs;
+
+               /* disable the arbiter while setting MTQC */
+               rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+               rttdcs |= IXGBE_RTTDCS_ARBDIS;
+               IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+
                /* We enable 8 traffic classes, DCB only */
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
                        IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
                                        IXGBE_MTQC_8TC_8TQ));
+               else
+                       IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+
+               /* re-eable the arbiter */
+               rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
+               IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
        }
 }
 
@@ -2471,7 +2540,10 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
        ixgbe_restore_vlan(adapter);
 #ifdef CONFIG_IXGBE_DCB
        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-               netif_set_gso_max_size(netdev, 32768);
+               if (hw->mac.type == ixgbe_mac_82598EB)
+                       netif_set_gso_max_size(netdev, 32768);
+               else
+                       netif_set_gso_max_size(netdev, 65536);
                ixgbe_configure_dcb(adapter);
        } else {
                netif_set_gso_max_size(netdev, 65536);
index 61eabca..b3d7d8d 100644 (file)
@@ -223,69 +223,73 @@ static int __devinit macsonic_init(struct net_device *dev)
        return 0;
 }
 
-static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
+#define INVALID_MAC(mac) (memcmp(mac, "\x08\x00\x07", 3) && \
+                          memcmp(mac, "\x00\xA0\x40", 3) && \
+                          memcmp(mac, "\x00\x80\x19", 3) && \
+                          memcmp(mac, "\x00\x05\x02", 3))
+
+static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
 {
        struct sonic_local *lp = netdev_priv(dev);
        const int prom_addr = ONBOARD_SONIC_PROM_BASE;
-       int i;
+       unsigned short val;
 
-       /* On NuBus boards we can sometimes look in the ROM resources.
-          No such luck for comm-slot/onboard. */
-       for(i = 0; i < 6; i++)
-               dev->dev_addr[i] = SONIC_READ_PROM(i);
+       /*
+        * On NuBus boards we can sometimes look in the ROM resources.
+        * No such luck for comm-slot/onboard.
+        * On the PowerBook 520, the PROM base address is a mystery.
+        */
+       if (hwreg_present((void *)prom_addr)) {
+               int i;
+
+               for (i = 0; i < 6; i++)
+                       dev->dev_addr[i] = SONIC_READ_PROM(i);
+               if (!INVALID_MAC(dev->dev_addr))
+                       return;
 
-       /* Most of the time, the address is bit-reversed.  The NetBSD
-          source has a rather long and detailed historical account of
-          why this is so. */
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
+               /*
+                * Most of the time, the address is bit-reversed. The NetBSD
+                * source has a rather long and detailed historical account of
+                * why this is so.
+                */
                bit_reverse_addr(dev->dev_addr);
-       else
-               return 0;
-
-       /* If we still have what seems to be a bogus address, we'll
-           look in the CAM.  The top entry should be ours. */
-       /* Danger! This only works if MacOS has already initialized
-           the card... */
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
-       {
-               unsigned short val;
-
-               printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n");
-
-               SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
-               SONIC_WRITE(SONIC_CEP, 15);
-
-               val = SONIC_READ(SONIC_CAP2);
-               dev->dev_addr[5] = val >> 8;
-               dev->dev_addr[4] = val & 0xff;
-               val = SONIC_READ(SONIC_CAP1);
-               dev->dev_addr[3] = val >> 8;
-               dev->dev_addr[2] = val & 0xff;
-               val = SONIC_READ(SONIC_CAP0);
-               dev->dev_addr[1] = val >> 8;
-               dev->dev_addr[0] = val & 0xff;
-
-               printk(KERN_INFO "HW Address from CAM 15: %pM\n",
-                      dev->dev_addr);
-       } else return 0;
-
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
-       {
+               if (!INVALID_MAC(dev->dev_addr))
+                       return;
+
                /*
-                * Still nonsense ... messed up someplace!
+                * If we still have what seems to be a bogus address, we'll
+                * look in the CAM. The top entry should be ours.
                 */
-               printk(KERN_ERR "macsonic: ERROR (INVALID MAC)\n");
-               return -EIO;
-       } else return 0;
+               printk(KERN_WARNING "macsonic: MAC address in PROM seems "
+                                   "to be invalid, trying CAM\n");
+       } else {
+               printk(KERN_WARNING "macsonic: cannot read MAC address from "
+                                   "PROM, trying CAM\n");
+       }
+
+       /* This only works if MacOS has already initialized the card. */
+
+       SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
+       SONIC_WRITE(SONIC_CEP, 15);
+
+       val = SONIC_READ(SONIC_CAP2);
+       dev->dev_addr[5] = val >> 8;
+       dev->dev_addr[4] = val & 0xff;
+       val = SONIC_READ(SONIC_CAP1);
+       dev->dev_addr[3] = val >> 8;
+       dev->dev_addr[2] = val & 0xff;
+       val = SONIC_READ(SONIC_CAP0);
+       dev->dev_addr[1] = val >> 8;
+       dev->dev_addr[0] = val & 0xff;
+
+       if (!INVALID_MAC(dev->dev_addr))
+               return;
+
+       /* Still nonsense ... messed up someplace! */
+
+       printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 "
+                           "seems invalid, will use a random MAC\n");
+       random_ether_addr(dev->dev_addr);
 }
 
 static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
@@ -402,8 +406,7 @@ static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
        SONIC_WRITE(SONIC_ISR, 0x7fff);
 
        /* Now look for the MAC address. */
-       if (mac_onboard_sonic_ethernet_addr(dev) != 0)
-               return -ENODEV;
+       mac_onboard_sonic_ethernet_addr(dev);
 
        /* Shared init code */
        return macsonic_init(dev);
index cea7531..a2fc70a 100644 (file)
@@ -3916,6 +3916,8 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                goto err_out;
        }
 
+       /* Set PCIe reset type for EEH to fundamental. */
+       pdev->needs_freset = 1;
        pci_save_state(pdev);
        qdev->reg_base =
            ioremap_nocache(pci_resource_start(pdev, 1),
index bcf13c9..aec05f2 100644 (file)
@@ -499,7 +499,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
                /* Wait for the interrupt to come in. */
                status = ql_wait_mbx_cmd_cmplt(qdev);
                if (status)
-                       goto end;
+                       continue;
 
                /* Process the event.  If it's an AEN, it
                 * will be handled in-line or a worker
index cee00ad..49eb91b 100644 (file)
@@ -188,7 +188,7 @@ static int sfn4111t_reset(struct efx_nic *efx)
        efx_oword_t reg;
 
        /* GPIO 3 and the GPIO register are shared with I2C, so block that */
-       mutex_lock(&efx->i2c_adap.bus_lock);
+       i2c_lock_adapter(&efx->i2c_adap);
 
        /* Pull RST_N (GPIO 2) low then let it up again, setting the
         * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
@@ -204,7 +204,7 @@ static int sfn4111t_reset(struct efx_nic *efx)
        falcon_write(efx, &reg, GPIO_CTL_REG_KER);
        msleep(1);
 
-       mutex_unlock(&efx->i2c_adap.bus_lock);
+       i2c_unlock_adapter(&efx->i2c_adap);
 
        ssleep(1);
        return 0;
index c47237c..32d9356 100644 (file)
@@ -174,7 +174,7 @@ config USB_NET_CDCETHER
            * Ericsson Mobile Broadband Module (all variants)
            * Motorola (DM100 and SB4100)
            * Broadcom Cable Modem (reference design)
-           * Toshiba (PCX1100U and F3507g)
+           * Toshiba (PCX1100U and F3507g/F3607gw)
            * ...
 
          This driver creates an interface named "ethX", where X depends on
index 4a6aff5..21e1ba1 100644 (file)
@@ -544,20 +544,60 @@ static const struct usb_device_id products [] = {
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
 }, {
-       /* Ericsson F3307 */
+       /* Ericsson F3607gw ver 2 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Ericsson F3607gw ver 3 */
        USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
 }, {
+       /* Ericsson F3307 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Ericsson F3307 ver 2 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Ericsson C3607w */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
        /* Toshiba F3507g */
        USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
 }, {
+       /* Toshiba F3607gw */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Toshiba F3607gw ver 2 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
        /* Dell F3507g */
        USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Dell F3607gw */
+       USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Dell F3607gw ver 2 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
 },
        { },            // END
 };
index 05630f2..b9e002f 100644 (file)
@@ -998,7 +998,7 @@ static unsigned int features[] = {
        VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 };
 
-static struct virtio_driver virtio_net = {
+static struct virtio_driver virtio_net_driver = {
        .feature_table = features,
        .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,
@@ -1011,12 +1011,12 @@ static struct virtio_driver virtio_net = {
 
 static int __init init(void)
 {
-       return register_virtio_driver(&virtio_net);
+       return register_virtio_driver(&virtio_net_driver);
 }
 
 static void __exit fini(void)
 {
-       unregister_virtio_driver(&virtio_net);
+       unregister_virtio_driver(&virtio_net_driver);
 }
 module_init(init);
 module_exit(fini);
index a741d37..240cff1 100644 (file)
@@ -6325,10 +6325,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 
       fail:
        if (dev) {
-               if (registered) {
-                       unregister_ieee80211(priv->ieee);
+               if (registered)
                        unregister_netdev(dev);
-               }
 
                ipw2100_hw_stop_adapter(priv);
 
@@ -6385,7 +6383,6 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
                /* Unregister the device first - this results in close()
                 * being called if the device is open.  If we free storage
                 * first, then close() will crash. */
-               unregister_ieee80211(priv->ieee);
                unregister_netdev(dev);
 
                /* ipw2100_down will ensure that there is no more pending work
index 9b0f2c0..827824d 100644 (file)
@@ -11822,7 +11822,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
                if (err) {
                        IPW_ERROR("Failed to register promiscuous network "
                                  "device (error %d).\n", err);
-                       unregister_ieee80211(priv->ieee);
                        unregister_netdev(priv->net_dev);
                        goto out_remove_sysfs;
                }
@@ -11873,7 +11872,6 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
 
        mutex_unlock(&priv->mutex);
 
-       unregister_ieee80211(priv->ieee);
        unregister_netdev(priv->net_dev);
 
        if (priv->rxq) {
index f42ade6..bf45391 100644 (file)
@@ -1020,7 +1020,6 @@ static inline int libipw_is_cck_rate(u8 rate)
 /* ieee80211.c */
 extern void free_ieee80211(struct net_device *dev, int monitor);
 extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
-extern void unregister_ieee80211(struct libipw_device *ieee);
 extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
 
 extern void libipw_networks_age(struct libipw_device *ieee,
index be5b809..a0e9f6a 100644 (file)
@@ -235,19 +235,16 @@ void free_ieee80211(struct net_device *dev, int monitor)
        libipw_networks_free(ieee);
 
        /* free cfg80211 resources */
-       if (!monitor)
+       if (!monitor) {
+               wiphy_unregister(ieee->wdev.wiphy);
+               kfree(ieee->a_band.channels);
+               kfree(ieee->bg_band.channels);
                wiphy_free(ieee->wdev.wiphy);
+       }
 
        free_netdev(dev);
 }
 
-void unregister_ieee80211(struct libipw_device *ieee)
-{
-       wiphy_unregister(ieee->wdev.wiphy);
-       kfree(ieee->a_band.channels);
-       kfree(ieee->bg_band.channels);
-}
-
 #ifdef CONFIG_LIBIPW_DEBUG
 
 static int debug = 0;
@@ -333,4 +330,3 @@ module_init(libipw_init);
 
 EXPORT_SYMBOL(alloc_ieee80211);
 EXPORT_SYMBOL(free_ieee80211);
-EXPORT_SYMBOL(unregister_ieee80211);
index 71761b3..73bbec5 100644 (file)
@@ -815,6 +815,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 
        mutex_init(&rt2x00dev->csr_mutex);
 
+       set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+
        /*
         * Make room for rt2x00_intf inside the per-interface
         * structure ieee80211_vif.
@@ -871,8 +873,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
        rt2x00leds_register(rt2x00dev);
        rt2x00debug_register(rt2x00dev);
 
-       set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
-
        return 0;
 
 exit:
index c64db0b..c708d0b 100644 (file)
@@ -362,8 +362,9 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
 
        rt2x00link_reset_tuner(rt2x00dev, false);
 
-       ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                    &link->work, LINK_TUNE_INTERVAL);
+       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               ieee80211_queue_delayed_work(rt2x00dev->hw,
+                                            &link->work, LINK_TUNE_INTERVAL);
 }
 
 void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
@@ -469,8 +470,10 @@ static void rt2x00link_tuner(struct work_struct *work)
         * Increase tuner counter, and reschedule the next link tuner run.
         */
        link->count++;
-       ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                    &link->work, LINK_TUNE_INTERVAL);
+
+       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               ieee80211_queue_delayed_work(rt2x00dev->hw,
+                                            &link->work, LINK_TUNE_INTERVAL);
 }
 
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
index 5015448..f02b48a 100644 (file)
@@ -47,6 +47,8 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
            (requesttype == USB_VENDOR_REQUEST_IN) ?
            usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
 
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return -ENODEV;
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                status = usb_control_msg(usb_dev, pipe, request, requesttype,
@@ -60,8 +62,10 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
                 * -ENODEV: Device has disappeared, no point continuing.
                 * All other errors: Try again.
                 */
-               else if (status == -ENODEV)
+               else if (status == -ENODEV) {
+                       clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
                        break;
+               }
        }
 
        ERROR(rt2x00dev,
@@ -161,6 +165,9 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
 {
        unsigned int i;
 
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return -ENODEV;
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2x00usb_register_read_lock(rt2x00dev, offset, reg);
                if (!rt2x00_get_field32(*reg, field))
index a1c670f..cf8a4a4 100644 (file)
@@ -210,10 +210,10 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
 
        /* turn the LED off before exiting */
        ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
-       cancel_delayed_work_sync(&priv->led_off);
-       cancel_delayed_work_sync(&priv->led_on);
        rtl8187_unregister_led(&priv->led_rx);
        rtl8187_unregister_led(&priv->led_tx);
+       cancel_delayed_work_sync(&priv->led_off);
+       cancel_delayed_work_sync(&priv->led_on);
 }
 #endif /* def CONFIG_RTL8187_LED */
 
index d379e74..4226e53 100644 (file)
@@ -150,8 +150,6 @@ struct eeepc_hotk {
 /* The actual device the driver binds to */
 static struct eeepc_hotk *ehotk;
 
-static void eeepc_rfkill_hotplug(bool real);
-
 /* Platform device/driver */
 static int eeepc_hotk_thaw(struct device *device);
 static int eeepc_hotk_restore(struct device *device);
@@ -345,16 +343,7 @@ static bool eeepc_wlan_rfkill_blocked(void)
 static int eeepc_rfkill_set(void *data, bool blocked)
 {
        unsigned long asl = (unsigned long)data;
-       int ret;
-
-       if (asl != CM_ASL_WLAN)
-               return set_acpi(asl, !blocked);
-
-       /* hack to avoid panic with rt2860sta */
-       if (blocked)
-               eeepc_rfkill_hotplug(false);
-       ret = set_acpi(asl, !blocked);
-       return ret;
+       return set_acpi(asl, !blocked);
 }
 
 static const struct rfkill_ops eeepc_rfkill_ops = {
@@ -367,7 +356,8 @@ static void __devinit eeepc_enable_camera(void)
         * If the following call to set_acpi() fails, it's because there's no
         * camera so we can ignore the error.
         */
-       set_acpi(CM_ASL_CAMERA, 1);
+       if (get_acpi(CM_ASL_CAMERA) == 0)
+               set_acpi(CM_ASL_CAMERA, 1);
 }
 
 /*
@@ -654,13 +644,13 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
        return 0;
 }
 
-static void eeepc_rfkill_hotplug(bool real)
+static void eeepc_rfkill_hotplug(void)
 {
        struct pci_dev *dev;
        struct pci_bus *bus;
-       bool blocked = real ? eeepc_wlan_rfkill_blocked() : true;
+       bool blocked = eeepc_wlan_rfkill_blocked();
 
-       if (real && ehotk->wlan_rfkill)
+       if (ehotk->wlan_rfkill)
                rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
 
        mutex_lock(&ehotk->hotplug_lock);
@@ -703,7 +693,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
        if (event != ACPI_NOTIFY_BUS_CHECK)
                return;
 
-       eeepc_rfkill_hotplug(true);
+       eeepc_rfkill_hotplug();
 }
 
 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
@@ -861,7 +851,7 @@ static int eeepc_hotk_restore(struct device *device)
 {
        /* Refresh both wlan rfkill state and pci hotplug */
        if (ehotk->wlan_rfkill)
-               eeepc_rfkill_hotplug(true);
+               eeepc_rfkill_hotplug();
 
        if (ehotk->bluetooth_rfkill)
                rfkill_set_sw_state(ehotk->bluetooth_rfkill,
@@ -1004,7 +994,7 @@ static void eeepc_rfkill_exit(void)
         * Refresh pci hotplug in case the rfkill state was changed after
         * eeepc_unregister_rfkill_notifier()
         */
-       eeepc_rfkill_hotplug(true);
+       eeepc_rfkill_hotplug();
        if (ehotk->hotplug_slot)
                pci_hp_deregister(ehotk->hotplug_slot);
 
@@ -1120,7 +1110,7 @@ static int eeepc_rfkill_init(struct device *dev)
         * Refresh pci hotplug in case the rfkill state was changed during
         * setup.
         */
-       eeepc_rfkill_hotplug(true);
+       eeepc_rfkill_hotplug();
 
 exit:
        if (result && result != -ENODEV)
index 85119fb..6498bd1 100644 (file)
@@ -1143,7 +1143,7 @@ static void serial_console_write(struct console *co, const char *s,
        while ((sci_in(port, SCxSR) & bits) != bits)
                cpu_relax();
 
-       if (sci_port->disable);
+       if (sci_port->disable)
                sci_port->disable(port);
 }
 
index 4e83c29..6f8d8f9 100644 (file)
@@ -180,15 +180,15 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
 
        switch (type) {
        case THERMAL_TRIP_CRITICAL:
-               return sprintf(buf, "critical");
+               return sprintf(buf, "critical\n");
        case THERMAL_TRIP_HOT:
-               return sprintf(buf, "hot");
+               return sprintf(buf, "hot\n");
        case THERMAL_TRIP_PASSIVE:
-               return sprintf(buf, "passive");
+               return sprintf(buf, "passive\n");
        case THERMAL_TRIP_ACTIVE:
-               return sprintf(buf, "active");
+               return sprintf(buf, "active\n");
        default:
-               return sprintf(buf, "unknown");
+               return sprintf(buf, "unknown\n");
        }
 }
 
index 852ca19..91430a8 100644 (file)
@@ -227,7 +227,7 @@ static int __init fitpc2_wdt_init(void)
        }
 
        err = misc_register(&fitpc2_wdt_miscdev);
-       if (!err) {
+       if (err) {
                pr_err("cannot register miscdev on minor=%d (err=%d)\n",
                                                        WATCHDOG_MINOR, err);
                goto err_margin;
index 2126078..64d44ef 100644 (file)
@@ -135,7 +135,7 @@ config TMPFS_POSIX_ACL
 
 config HUGETLBFS
        bool "HugeTLB file system support"
-       depends on X86 || IA64 || PPC_BOOK3S_64 || SPARC64 || (S390 && 64BIT) || \
+       depends on X86 || IA64 || SPARC64 || (S390 && 64BIT) || \
                   SYS_SUPPORTS_HUGETLBFS || BROKEN
        help
          hugetlbfs is a filesystem backing for HugeTLB pages, based on
index 6928c24..5646727 100644 (file)
@@ -388,4 +388,5 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
                const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
                        const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
+extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
 #endif                 /* _CIFSPROTO_H */
index b090980..63ea83f 100644 (file)
@@ -2220,16 +2220,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon,
                   struct cifs_sb_info *cifs_sb, const char *full_path)
 {
        int rc;
-       __u64 inode_num;
        FILE_ALL_INFO *pfile_info;
 
-       rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num,
-                                  cifs_sb->local_nls,
-                                  cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
-       if (rc != -EOPNOTSUPP)
-               return rc;
-
        pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
        if (pfile_info == NULL)
                return -ENOMEM;
index 5e24925..cababd8 100644 (file)
@@ -512,13 +512,10 @@ int cifs_get_inode_info(struct inode **pinode,
                                        cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       if (rc1) {
+                       if (rc1 || !fattr.cf_uniqueid) {
                                cFYI(1, ("GetSrvInodeNum rc %d", rc1));
                                fattr.cf_uniqueid = iunique(sb, ROOT_I);
-                               /* disable serverino if call not supported */
-                               if (rc1 == -EINVAL)
-                                       cifs_sb->mnt_cifs_flags &=
-                                                       ~CIFS_MOUNT_SERVER_INUM;
+                               cifs_autodisable_serverino(cifs_sb);
                        }
                } else {
                        fattr.cf_uniqueid = iunique(sb, ROOT_I);
index 0241b25..1e25efc 100644 (file)
@@ -715,3 +715,17 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
 ctoUCS_out:
        return i;
 }
+
+void
+cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
+{
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
+               cifs_sb->mnt_cifs_flags &= CIFS_MOUNT_SERVER_INUM;
+               cERROR(1, ("Autodisabling the use of server inode numbers on "
+                          "%s. This server doesn't seem to support them "
+                          "properly. Hardlinks will not be recognized on this "
+                          "mount. Consider mounting with the \"noserverino\" "
+                          "option to silence this message.",
+                          cifs_sb->tcon->treeName));
+       }
+}
index 1f098ca..f84062f 100644 (file)
@@ -727,11 +727,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
                cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
                                        pfindEntry, cifs_sb);
 
-       /* FIXME: make _to_fattr functions fill this out */
-       if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
+       if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
                fattr.cf_uniqueid = inum;
-       else
+       } else {
                fattr.cf_uniqueid = iunique(sb, ROOT_I);
+               cifs_autodisable_serverino(cifs_sb);
+       }
 
        ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
        tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
index d576b55..6c19040 100644 (file)
@@ -1532,6 +1532,8 @@ int compat_do_execve(char * filename,
        if (retval < 0)
                goto out;
 
+       current->stack_start = current->mm->start_stack;
+
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
index 00d153f..8825515 100644 (file)
@@ -322,6 +322,7 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
 #define EXT4_STATE_NO_EXPAND           0x00000008 /* No space for expansion */
 #define EXT4_STATE_DA_ALLOC_CLOSE      0x00000010 /* Alloc DA blks on close */
 #define EXT4_STATE_EXT_MIGRATE         0x00000020 /* Inode is migrating */
+#define EXT4_STATE_DIO_UNWRITTEN       0x00000040 /* need convert on dio done*/
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext4_new_group_input {
index 10539e3..715264b 100644 (file)
@@ -2807,6 +2807,8 @@ fix_extent_len:
  * into three uninitialized extent(at most). After IO complete, the part
  * being filled will be convert to initialized by the end_io callback function
  * via ext4_convert_unwritten_extents().
+ *
+ * Returns the size of uninitialized extent to be written on success.
  */
 static int ext4_split_unwritten_extents(handle_t *handle,
                                        struct inode *inode,
@@ -2824,7 +2826,6 @@ static int ext4_split_unwritten_extents(handle_t *handle,
        unsigned int allocated, ee_len, depth;
        ext4_fsblk_t newblock;
        int err = 0;
-       int ret = 0;
 
        ext_debug("ext4_split_unwritten_extents: inode %lu,"
                  "iblock %llu, max_blocks %u\n", inode->i_ino,
@@ -2842,12 +2843,12 @@ static int ext4_split_unwritten_extents(handle_t *handle,
        ext4_ext_store_pblock(&orig_ex, ext_pblock(ex));
 
        /*
-        * if the entire unintialized extent length less than
-        * the size of extent to write, there is no need to split
-        * uninitialized extent
+        * If the uninitialized extent begins at the same logical
+        * block where the write begins, and the write completely
+        * covers the extent, then we don't need to split it.
         */
-       if (allocated <= max_blocks)
-               return ret;
+       if ((iblock == ee_block) && (allocated <= max_blocks))
+               return allocated;
 
        err = ext4_ext_get_access(handle, inode, path + depth);
        if (err)
@@ -3048,12 +3049,18 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
                ret = ext4_split_unwritten_extents(handle,
                                                inode, path, iblock,
                                                max_blocks, flags);
-               /* flag the io_end struct that we need convert when IO done */
+               /*
+                * Flag the inode(non aio case) or end_io struct (aio case)
+                * that this IO needs to convertion to written when IO is
+                * completed
+                */
                if (io)
                        io->flag = DIO_AIO_UNWRITTEN;
+               else
+                       EXT4_I(inode)->i_state |= EXT4_STATE_DIO_UNWRITTEN;
                goto out;
        }
-       /* DIO end_io complete, convert the filled extent to written */
+       /* async DIO end_io complete, convert the filled extent to written */
        if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
                ret = ext4_convert_unwritten_extents_dio(handle, inode,
                                                        path);
@@ -3295,10 +3302,16 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                 * To avoid unecessary convertion for every aio dio rewrite
                 * to the mid of file, here we flag the IO that is really
                 * need the convertion.
-                *
+                * For non asycn direct IO case, flag the inode state
+                * that we need to perform convertion when IO is done.
                 */
-               if (io && flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT)
-                       io->flag = DIO_AIO_UNWRITTEN;
+               if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
+                       if (io)
+                               io->flag = DIO_AIO_UNWRITTEN;
+                       else
+                               EXT4_I(inode)->i_state |=
+                                       EXT4_STATE_DIO_UNWRITTEN;;
+               }
        }
        err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
        if (err) {
@@ -3519,6 +3532,7 @@ retry:
  *
  * This function is called from the direct IO end io call back
  * function, to convert the fallocated extents after IO is completed.
+ * Returns 0 on success.
  */
 int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
                                    loff_t len)
index 5c5bc5d..2c8caa5 100644 (file)
@@ -193,7 +193,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
  * so before we call here everything must be consistently dirtied against
  * this transaction.
  */
- int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
+int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
                                 int nblocks)
 {
        int ret;
@@ -209,6 +209,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
        up_write(&EXT4_I(inode)->i_data_sem);
        ret = ext4_journal_restart(handle, blocks_for_truncate(inode));
        down_write(&EXT4_I(inode)->i_data_sem);
+       ext4_discard_preallocations(inode);
 
        return ret;
 }
@@ -3445,8 +3446,6 @@ out:
        return ret;
 }
 
-/* Maximum number of blocks we map for direct IO at once. */
-
 static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,
                   struct buffer_head *bh_result, int create)
 {
@@ -3654,13 +3653,14 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
         ext4_io_end_t *io_end = iocb->private;
        struct workqueue_struct *wq;
 
+       /* if not async direct IO or dio with 0 bytes write, just return */
+       if (!io_end || !size)
+               return;
+
        ext_debug("ext4_end_io_dio(): io_end 0x%p"
                  "for inode %lu, iocb 0x%p, offset %llu, size %llu\n",
                  iocb->private, io_end->inode->i_ino, iocb, offset,
                  size);
-       /* if not async direct IO or dio with 0 bytes write, just return */
-       if (!io_end || !size)
-               return;
 
        /* if not aio dio with unwritten extents, just free io and return */
        if (io_end->flag != DIO_AIO_UNWRITTEN){
@@ -3771,13 +3771,19 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {
                        ext4_free_io_end(iocb->private);
                        iocb->private = NULL;
-               } else if (ret > 0)
+               } else if (ret > 0 && (EXT4_I(inode)->i_state &
+                                      EXT4_STATE_DIO_UNWRITTEN)) {
+                       int err;
                        /*
                         * for non AIO case, since the IO is already
                         * completed, we could do the convertion right here
                         */
-                       ret = ext4_convert_unwritten_extents(inode,
-                                                               offset, ret);
+                       err = ext4_convert_unwritten_extents(inode,
+                                                            offset, ret);
+                       if (err < 0)
+                               ret = err;
+                       EXT4_I(inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN;
+               }
                return ret;
        }
 
index 7c8fe80..6d2c1b8 100644 (file)
@@ -1518,12 +1518,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
                        return retval;
 
                if (blocks == 1 && !dx_fallback &&
-                   EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
-                       retval = make_indexed_dir(handle, dentry, inode, bh);
-                       if (retval == -ENOSPC)
-                               brelse(bh);
-                       return retval;
-               }
+                   EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
+                       return make_indexed_dir(handle, dentry, inode, bh);
                brelse(bh);
        }
        bh = ext4_append(handle, dir, &block, &retval);
@@ -1532,10 +1528,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
        de = (struct ext4_dir_entry_2 *) bh->b_data;
        de->inode = 0;
        de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
-       retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
-       if (retval == -ENOSPC)
-               brelse(bh);
-       return retval;
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
 
 /*
@@ -1664,8 +1657,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
        if (!de)
                goto cleanup;
        err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-       if (err != -ENOSPC)
-               bh = NULL;
+       bh = NULL;
        goto cleanup;
 
 journal_error:
index 992f6c9..8ada78a 100644 (file)
@@ -712,8 +712,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
                        fuse_invalidate_attr(newdir);
 
                /* newent will end up negative */
-               if (newent->d_inode)
+               if (newent->d_inode) {
+                       fuse_invalidate_attr(newent->d_inode);
                        fuse_invalidate_entry_cache(newent);
+               }
        } else if (err == -EINTR) {
                /* If request was interrupted, DEITY only knows if the
                   rename actually took place.  If the invalidation
index a3492f7..c18913a 100644 (file)
@@ -1063,7 +1063,8 @@ ssize_t fuse_direct_io(struct file *file, const char __user *buf,
                                break;
                }
        }
-       fuse_put_request(fc, req);
+       if (!IS_ERR(req))
+               fuse_put_request(fc, req);
        if (res > 0)
                *ppos = pos;
 
@@ -1599,7 +1600,7 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
                        kaddr += copy;
                }
 
-               kunmap(map);
+               kunmap(page);
        }
 
        return 0;
index 6572ea4..d24057d 100644 (file)
@@ -297,7 +297,18 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
                               (unsigned long long)vdesc->vd_vblocknr);
                return ret;
        }
-       bh->b_private = vdesc;
+       if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
+               printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
+                      "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
+                      __func__, vdesc->vd_flags ? "node" : "data",
+                      (unsigned long long)vdesc->vd_ino,
+                      (unsigned long long)vdesc->vd_cno,
+                      (unsigned long long)vdesc->vd_offset,
+                      (unsigned long long)vdesc->vd_blocknr,
+                      (unsigned long long)vdesc->vd_vblocknr);
+               brelse(bh);
+               return -EEXIST;
+       }
        list_add_tail(&bh->b_assoc_buffers, buffers);
        return 0;
 }
@@ -335,24 +346,10 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
        list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
                ret = nilfs_gccache_wait_and_mark_dirty(bh);
                if (unlikely(ret < 0)) {
-                       if (ret == -EEXIST) {
-                               vdesc = bh->b_private;
-                               printk(KERN_CRIT
-                                      "%s: conflicting %s buffer: "
-                                      "ino=%llu, cno=%llu, offset=%llu, "
-                                      "blocknr=%llu, vblocknr=%llu\n",
-                                      __func__,
-                                      vdesc->vd_flags ? "node" : "data",
-                                      (unsigned long long)vdesc->vd_ino,
-                                      (unsigned long long)vdesc->vd_cno,
-                                      (unsigned long long)vdesc->vd_offset,
-                                      (unsigned long long)vdesc->vd_blocknr,
-                                      (unsigned long long)vdesc->vd_vblocknr);
-                       }
+                       WARN_ON(ret == -EEXIST);
                        goto failed;
                }
                list_del_init(&bh->b_assoc_buffers);
-               bh->b_private = NULL;
                brelse(bh);
        }
        return nmembs;
@@ -360,7 +357,6 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
  failed:
        list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
                list_del_init(&bh->b_assoc_buffers);
-               bh->b_private = NULL;
                brelse(bh);
        }
        return ret;
@@ -471,7 +467,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
        return 0;
 
  failed:
-       nilfs_remove_all_gcinode(nilfs);
        printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
               msg, ret);
        return ret;
@@ -560,6 +555,8 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
        else
                ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
 
+       if (ret < 0)
+               nilfs_remove_all_gcinode(nilfs);
        clear_nilfs_gc_running(nilfs);
 
  out_free:
index 5fad489..e020183 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/completion.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/security.h>
 #include "sysfs.h"
 
 DEFINE_MUTEX(sysfs_mutex);
@@ -285,6 +286,9 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
                sysfs_put(sd->s_symlink.target_sd);
        if (sysfs_type(sd) & SYSFS_COPY_NAME)
                kfree(sd->s_name);
+       if (sd->s_iattr && sd->s_iattr->ia_secdata)
+               security_release_secctx(sd->s_iattr->ia_secdata,
+                                       sd->s_iattr->ia_secdata_len);
        kfree(sd->s_iattr);
        sysfs_free_ino(sd->s_ino);
        kmem_cache_free(sysfs_dir_cachep, sd);
index 57d41b0..7b40cda 100644 (file)
@@ -361,6 +361,24 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
        dev_set_drvdata(&dev->dev, data);
 }
 
+/**
+ * i2c_lock_adapter - Prevent access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
+{
+       mutex_lock(&adapter->bus_lock);
+}
+
+/**
+ * i2c_unlock_adapter - Reauthorize access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
+{
+       mutex_unlock(&adapter->bus_lock);
+}
+
 /*flags for the client struct: */
 #define I2C_CLIENT_PEC 0x04            /* Use Packet Error Checking */
 #define I2C_CLIENT_TEN 0x10            /* we have a ten bit chip address */
index b0f0f38..9ceb392 100644 (file)
 #define PCI_DEVICE_ID_AMD_8131_BRIDGE  0x7450
 #define PCI_DEVICE_ID_AMD_8131_APIC    0x7451
 #define PCI_DEVICE_ID_AMD_8132_BRIDGE  0x7458
-#define PCI_DEVICE_ID_AMD_SB900_SMBUS  0x780b
+#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS        0x780b
 #define PCI_DEVICE_ID_AMD_CS5535_IDE    0x208F
 #define PCI_DEVICE_ID_AMD_CS5536_ISA    0x2090
 #define PCI_DEVICE_ID_AMD_CS5536_FLASH  0x2091
index cbdd628..5cf7270 100644 (file)
@@ -255,11 +255,9 @@ static inline bool nf_ct_kill(struct nf_conn *ct)
 }
 
 /* These are for NAT.  Icky. */
-/* Update TCP window tracking data when NAT mangles the packet */
-extern void nf_conntrack_tcp_update(const struct sk_buff *skb,
-                                   unsigned int dataoff,
-                                   struct nf_conn *ct, int dir,
-                                   s16 offset);
+extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
+                              enum ip_conntrack_dir dir,
+                              u32 seq);
 
 /* Fake conntrack entry for untracked connections */
 extern struct nf_conn nf_conntrack_untracked;
index 237a961..4222220 100644 (file)
@@ -32,4 +32,8 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
  * to port ct->master->saved_proto. */
 extern void nf_nat_follow_master(struct nf_conn *ct,
                                 struct nf_conntrack_expect *this);
+
+extern s16 nf_nat_get_offset(const struct nf_conn *ct,
+                            enum ip_conntrack_dir dir,
+                            u32 seq);
 #endif
index f515864..9e03ef8 100644 (file)
@@ -937,7 +937,7 @@ config PERF_EVENTS
          Enable kernel support for various performance events provided
          by software and hardware.
 
-         Software events are supported either build-in or via the
+         Software events are supported either built-in or via the
          use of generic tracepoints.
 
          Most modern CPUs support performance events via performance
@@ -949,7 +949,7 @@ config PERF_EVENTS
          used to profile the code that runs on that CPU.
 
          The Linux Performance Event subsystem provides an abstraction of
-         these software and hardware cevent apabilities, available via a
+         these software and hardware event capabilities, available via a
          system call and used by the "perf" utility in tools/perf/. It
          provides per task and per CPU counters, and it provides event
          capabilities on top of those.
index 114e704..bd7273e 100644 (file)
@@ -121,7 +121,9 @@ static void poll_all_shared_irqs(void)
                if (!(status & IRQ_SPURIOUS_DISABLED))
                        continue;
 
+               local_irq_disable();
                try_one_irq(i, desc);
+               local_irq_enable();
        }
 }
 
index 5fe7099..ab7ae57 100644 (file)
@@ -150,29 +150,6 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
 EXPORT_SYMBOL(kthread_create);
 
 /**
- * kthread_bind - bind a just-created kthread to a cpu.
- * @k: thread created by kthread_create().
- * @cpu: cpu (might not be online, must be possible) for @k to run on.
- *
- * Description: This function is equivalent to set_cpus_allowed(),
- * except that @cpu doesn't need to be online, and the thread must be
- * stopped (i.e., just returned from kthread_create()).
- */
-void kthread_bind(struct task_struct *k, unsigned int cpu)
-{
-       /* Must have done schedule() in kthread() before we set_task_cpu */
-       if (!wait_task_inactive(k, TASK_UNINTERRUPTIBLE)) {
-               WARN_ON(1);
-               return;
-       }
-       set_task_cpu(k, cpu);
-       k->cpus_allowed = cpumask_of_cpu(cpu);
-       k->rt.nr_cpus_allowed = 1;
-       k->flags |= PF_THREAD_BOUND;
-}
-EXPORT_SYMBOL(kthread_bind);
-
-/**
  * kthread_stop - stop a thread created by kthread_create().
  * @k: thread created by kthread_create().
  *
index 0536125..f3077c0 100644 (file)
@@ -59,7 +59,7 @@
                NUM_RCU_LVL_2, \
                NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \
        }, \
-       .signaled = RCU_SIGNAL_INIT, \
+       .signaled = RCU_GP_IDLE, \
        .gpnum = -300, \
        .completed = -300, \
        .onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \
@@ -657,14 +657,17 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
         * irqs disabled.
         */
        rcu_for_each_node_breadth_first(rsp, rnp) {
-               spin_lock(&rnp->lock);  /* irqs already disabled. */
+               spin_lock(&rnp->lock);          /* irqs already disabled. */
                rcu_preempt_check_blocked_tasks(rnp);
                rnp->qsmask = rnp->qsmaskinit;
                rnp->gpnum = rsp->gpnum;
-               spin_unlock(&rnp->lock);        /* irqs already disabled. */
+               spin_unlock(&rnp->lock);        /* irqs remain disabled. */
        }
 
+       rnp = rcu_get_root(rsp);
+       spin_lock(&rnp->lock);                  /* irqs already disabled. */
        rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */
+       spin_unlock(&rnp->lock);                /* irqs remain disabled. */
        spin_unlock_irqrestore(&rsp->onofflock, flags);
 }
 
@@ -706,6 +709,7 @@ static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
 {
        WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
        rsp->completed = rsp->gpnum;
+       rsp->signaled = RCU_GP_IDLE;
        rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
        rcu_start_gp(rsp, flags);  /* releases root node's rnp->lock. */
 }
@@ -1162,9 +1166,10 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
        }
        spin_unlock(&rnp->lock);
        switch (signaled) {
+       case RCU_GP_IDLE:
        case RCU_GP_INIT:
 
-               break; /* grace period still initializing, ignore. */
+               break; /* grace period idle or initializing, ignore. */
 
        case RCU_SAVE_DYNTICK:
 
@@ -1178,7 +1183,8 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
 
                /* Update state, record completion counter. */
                spin_lock(&rnp->lock);
-               if (lastcomp == rsp->completed) {
+               if (lastcomp == rsp->completed &&
+                   rsp->signaled == RCU_SAVE_DYNTICK) {
                        rsp->signaled = RCU_FORCE_QS;
                        dyntick_record_completed(rsp, lastcomp);
                }
index 1823c6e..1899023 100644 (file)
@@ -201,9 +201,10 @@ struct rcu_data {
 };
 
 /* Values for signaled field in struct rcu_state. */
-#define RCU_GP_INIT            0       /* Grace period being initialized. */
-#define RCU_SAVE_DYNTICK       1       /* Need to scan dyntick state. */
-#define RCU_FORCE_QS           2       /* Need to force quiescent state. */
+#define RCU_GP_IDLE            0       /* No grace period in progress. */
+#define RCU_GP_INIT            1       /* Grace period being initialized. */
+#define RCU_SAVE_DYNTICK       2       /* Need to scan dyntick state. */
+#define RCU_FORCE_QS           3       /* Need to force quiescent state. */
 #ifdef CONFIG_NO_HZ
 #define RCU_SIGNAL_INIT                RCU_SAVE_DYNTICK
 #else /* #ifdef CONFIG_NO_HZ */
index a455dca..3c11ae0 100644 (file)
@@ -309,6 +309,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rt_rq, init_rt_rq);
  */
 static DEFINE_SPINLOCK(task_group_lock);
 
+#ifdef CONFIG_FAIR_GROUP_SCHED
+
 #ifdef CONFIG_SMP
 static int root_task_group_empty(void)
 {
@@ -316,7 +318,6 @@ static int root_task_group_empty(void)
 }
 #endif
 
-#ifdef CONFIG_FAIR_GROUP_SCHED
 #ifdef CONFIG_USER_SCHED
 # define INIT_TASK_GROUP_LOAD  (2*NICE_0_LOAD)
 #else /* !CONFIG_USER_SCHED */
@@ -1992,6 +1993,38 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
                p->sched_class->prio_changed(rq, p, oldprio, running);
 }
 
+/**
+ * kthread_bind - bind a just-created kthread to a cpu.
+ * @p: thread created by kthread_create().
+ * @cpu: cpu (might not be online, must be possible) for @k to run on.
+ *
+ * Description: This function is equivalent to set_cpus_allowed(),
+ * except that @cpu doesn't need to be online, and the thread must be
+ * stopped (i.e., just returned from kthread_create()).
+ *
+ * Function lives here instead of kthread.c because it messes with
+ * scheduler internals which require locking.
+ */
+void kthread_bind(struct task_struct *p, unsigned int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       /* Must have done schedule() in kthread() before we set_task_cpu */
+       if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
+               WARN_ON(1);
+               return;
+       }
+
+       spin_lock_irqsave(&rq->lock, flags);
+       set_task_cpu(p, cpu);
+       p->cpus_allowed = cpumask_of_cpu(cpu);
+       p->rt.nr_cpus_allowed = 1;
+       p->flags |= PF_THREAD_BOUND;
+       spin_unlock_irqrestore(&rq->lock, flags);
+}
+EXPORT_SYMBOL(kthread_bind);
+
 #ifdef CONFIG_SMP
 /*
  * Is this task likely cache-hot:
@@ -2004,7 +2037,7 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
        /*
         * Buddy candidates are cache hot:
         */
-       if (sched_feat(CACHE_HOT_BUDDY) &&
+       if (sched_feat(CACHE_HOT_BUDDY) && this_rq()->nr_running &&
                        (&p->se == cfs_rq_of(&p->se)->next ||
                         &p->se == cfs_rq_of(&p->se)->last))
                return 1;
@@ -9532,13 +9565,13 @@ void __init sched_init(void)
        current->sched_class = &fair_sched_class;
 
        /* Allocate the nohz_cpu_mask if CONFIG_CPUMASK_OFFSTACK */
-       alloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_NO_HZ
-       alloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
        alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT);
 #endif
-       alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
+       zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
 #endif /* SMP */
 
        perf_event_init();
index c32c3e6..37087a7 100644 (file)
@@ -822,6 +822,26 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
                 * re-elected due to buddy favours.
                 */
                clear_buddies(cfs_rq, curr);
+               return;
+       }
+
+       /*
+        * Ensure that a task that missed wakeup preemption by a
+        * narrow margin doesn't have to wait for a full slice.
+        * This also mitigates buddy induced latencies under load.
+        */
+       if (!sched_feat(WAKEUP_PREEMPT))
+               return;
+
+       if (delta_exec < sysctl_sched_min_granularity)
+               return;
+
+       if (cfs_rq->nr_running > 1) {
+               struct sched_entity *se = __pick_next_entity(cfs_rq);
+               s64 delta = curr->vruntime - se->vruntime;
+
+               if (delta > ideal_runtime)
+                       resched_task(rq_of(cfs_rq)->curr);
        }
 }
 
@@ -861,21 +881,18 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
 static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
 {
        struct sched_entity *se = __pick_next_entity(cfs_rq);
-       struct sched_entity *buddy;
+       struct sched_entity *left = se;
 
-       if (cfs_rq->next) {
-               buddy = cfs_rq->next;
-               cfs_rq->next = NULL;
-               if (wakeup_preempt_entity(buddy, se) < 1)
-                       return buddy;
-       }
+       if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1)
+               se = cfs_rq->next;
 
-       if (cfs_rq->last) {
-               buddy = cfs_rq->last;
-               cfs_rq->last = NULL;
-               if (wakeup_preempt_entity(buddy, se) < 1)
-                       return buddy;
-       }
+       /*
+        * Prefer last buddy, try to return the CPU to a preempted task.
+        */
+       if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, left) < 1)
+               se = cfs_rq->last;
+
+       clear_buddies(cfs_rq, se);
 
        return se;
 }
@@ -1577,6 +1594,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        struct sched_entity *se = &curr->se, *pse = &p->se;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
        int sync = wake_flags & WF_SYNC;
+       int scale = cfs_rq->nr_running >= sched_nr_latency;
 
        update_curr(cfs_rq);
 
@@ -1591,18 +1609,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        if (unlikely(se == pse))
                return;
 
-       /*
-        * Only set the backward buddy when the current task is still on the
-        * rq. This can happen when a wakeup gets interleaved with schedule on
-        * the ->pre_schedule() or idle_balance() point, either of which can
-        * drop the rq lock.
-        *
-        * Also, during early boot the idle thread is in the fair class, for
-        * obvious reasons its a bad idea to schedule back to the idle thread.
-        */
-       if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
-               set_last_buddy(se);
-       if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK))
+       if (sched_feat(NEXT_BUDDY) && scale && !(wake_flags & WF_FORK))
                set_next_buddy(pse);
 
        /*
@@ -1648,8 +1655,22 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
 
        BUG_ON(!pse);
 
-       if (wakeup_preempt_entity(se, pse) == 1)
+       if (wakeup_preempt_entity(se, pse) == 1) {
                resched_task(curr);
+               /*
+                * Only set the backward buddy when the current task is still
+                * on the rq. This can happen when a wakeup gets interleaved
+                * with schedule on the ->pre_schedule() or idle_balance()
+                * point, either of which can * drop the rq lock.
+                *
+                * Also, during early boot the idle thread is in the fair class,
+                * for obvious reasons its a bad idea to schedule back to it.
+                */
+               if (unlikely(!se->on_rq || curr == rq->idle))
+                       return;
+               if (sched_feat(LAST_BUDDY) && scale && entity_is_task(se))
+                       set_last_buddy(se);
+       }
 }
 
 static struct task_struct *pick_next_task_fair(struct rq *rq)
index 9c451a1..6dc4e5e 100644 (file)
@@ -2222,15 +2222,15 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
                ret = ftrace_process_regex(parser->buffer,
                                           parser->idx, enable);
                if (ret)
-                       goto out;
+                       goto out_unlock;
 
                trace_parser_clear(parser);
        }
 
        ret = read;
-
+out_unlock:
        mutex_unlock(&ftrace_regex_lock);
-out:
+
        return ret;
 }
 
index 3ffa502..5dd017f 100644 (file)
@@ -1193,6 +1193,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
        atomic_inc(&cpu_buffer->record_disabled);
        synchronize_sched();
 
+       spin_lock_irq(&cpu_buffer->reader_lock);
        rb_head_page_deactivate(cpu_buffer);
 
        for (i = 0; i < nr_pages; i++) {
@@ -1207,6 +1208,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
                return;
 
        rb_reset_cpu(cpu_buffer);
+       spin_unlock_irq(&cpu_buffer->reader_lock);
 
        rb_check_pages(cpu_buffer);
 
index 2c000e7..46d0165 100644 (file)
@@ -330,9 +330,9 @@ done:
  */
 static void free_user(struct user_struct *up, unsigned long flags)
 {
-       spin_unlock_irqrestore(&uidhash_lock, flags);
        INIT_DELAYED_WORK(&up->work, cleanup_user_struct);
        schedule_delayed_work(&up->work, msecs_to_jiffies(1000));
+       spin_unlock_irqrestore(&uidhash_lock, flags);
 }
 
 #else  /* CONFIG_USER_SCHED && CONFIG_SYSFS */
index 58a9f9f..ce6b7ea 100644 (file)
@@ -819,9 +819,11 @@ static void check_unmap(struct dma_debug_entry *ref)
                err_printk(ref->dev, entry, "DMA-API: device driver frees "
                           "DMA memory with different CPU address "
                           "[device address=0x%016llx] [size=%llu bytes] "
-                          "[cpu alloc address=%p] [cpu free address=%p]",
+                          "[cpu alloc address=0x%016llx] "
+                          "[cpu free address=0x%016llx]",
                           ref->dev_addr, ref->size,
-                          (void *)entry->paddr, (void *)ref->paddr);
+                          (unsigned long long)entry->paddr,
+                          (unsigned long long)ref->paddr);
        }
 
        if (ref->sg_call_ents && ref->type == dma_debug_sg &&
index 25878cc..9c1e627 100644 (file)
@@ -426,16 +426,21 @@ void __init page_address_init(void)
 
 void debug_kmap_atomic(enum km_type type)
 {
-       static unsigned warn_count = 10;
+       static int warn_count = 10;
 
-       if (unlikely(warn_count == 0))
+       if (unlikely(warn_count < 0))
                return;
 
        if (unlikely(in_interrupt())) {
-               if (in_irq()) {
+               if (in_nmi()) {
+                       if (type != KM_NMI && type != KM_NMI_PTE) {
+                               WARN_ON(1);
+                               warn_count--;
+                       }
+               } else if (in_irq()) {
                        if (type != KM_IRQ0 && type != KM_IRQ1 &&
                            type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
-                           type != KM_BOUNCE_READ) {
+                           type != KM_BOUNCE_READ && type != KM_IRQ_PTE) {
                                WARN_ON(1);
                                warn_count--;
                        }
@@ -452,7 +457,9 @@ void debug_kmap_atomic(enum km_type type)
        }
 
        if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
-                       type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
+                       type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ ||
+                       type == KM_IRQ_PTE || type == KM_NMI ||
+                       type == KM_NMI_PTE ) {
                if (!irqs_disabled()) {
                        WARN_ON(1);
                        warn_count--;
index bef1af4..5575f86 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1012,6 +1012,7 @@ static struct rmap_item *unstable_tree_search_insert(struct page *page,
                struct rmap_item *tree_rmap_item;
                int ret;
 
+               cond_resched();
                tree_rmap_item = rb_entry(*new, struct rmap_item, node);
                page2[0] = get_mergeable_page(tree_rmap_item);
                if (!page2[0])
index b1b3b0f..4a9f527 100644 (file)
@@ -377,12 +377,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
        struct net_bridge_port *p;
        int err = 0;
 
-       if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
+       /* Don't allow bridging non-ethernet like devices */
+       if ((dev->flags & IFF_LOOPBACK) ||
+           dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN)
                return -EINVAL;
 
+       /* No bridging of bridges */
        if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit)
                return -ELOOP;
 
+       /* Device is already being bridged */
        if (dev->br_port != NULL)
                return -EBUSY;
 
index 597da4f..e8d58f3 100644 (file)
@@ -132,23 +132,27 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk)
 /*
  * procfs functions
  */
-static char *bcm_proc_getifname(int ifindex)
+static char *bcm_proc_getifname(char *result, int ifindex)
 {
        struct net_device *dev;
 
        if (!ifindex)
                return "any";
 
-       /* no usage counting */
+       read_lock(&dev_base_lock);
        dev = __dev_get_by_index(&init_net, ifindex);
        if (dev)
-               return dev->name;
+               strcpy(result, dev->name);
+       else
+               strcpy(result, "???");
+       read_unlock(&dev_base_lock);
 
-       return "???";
+       return result;
 }
 
 static int bcm_proc_show(struct seq_file *m, void *v)
 {
+       char ifname[IFNAMSIZ];
        struct sock *sk = (struct sock *)m->private;
        struct bcm_sock *bo = bcm_sk(sk);
        struct bcm_op *op;
@@ -157,7 +161,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
        seq_printf(m, " / sk %p", sk);
        seq_printf(m, " / bo %p", bo);
        seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
-       seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex));
+       seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex));
        seq_printf(m, " <<<\n");
 
        list_for_each_entry(op, &bo->rx_ops, list) {
@@ -169,7 +173,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
                        continue;
 
                seq_printf(m, "rx_op: %03X %-5s ",
-                               op->can_id, bcm_proc_getifname(op->ifindex));
+                               op->can_id, bcm_proc_getifname(ifname, op->ifindex));
                seq_printf(m, "[%d]%c ", op->nframes,
                                (op->flags & RX_CHECK_DLC)?'d':' ');
                if (op->kt_ival1.tv64)
@@ -194,7 +198,8 @@ static int bcm_proc_show(struct seq_file *m, void *v)
        list_for_each_entry(op, &bo->tx_ops, list) {
 
                seq_printf(m, "tx_op: %03X %s [%d] ",
-                               op->can_id, bcm_proc_getifname(op->ifindex),
+                               op->can_id,
+                               bcm_proc_getifname(ifname, op->ifindex),
                                op->nframes);
 
                if (op->kt_ival1.tv64)
index 26b0ab1..2036568 100644 (file)
@@ -263,11 +263,10 @@ static int dn_def_dev_strategy(ctl_table *table,
                        return -ENODEV;
 
                rv = -ENODEV;
-               if (dev->dn_ptr != NULL) {
+               if (dev->dn_ptr != NULL)
                        rv = dn_dev_set_default(dev, 1);
-                       if (rv)
-                               dev_put(dev);
-               }
+               if (rv)
+                       dev_put(dev);
        }
 
        return rv;
index 08ccd34..ae40ed1 100644 (file)
@@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                goto tx_error;
        }
 
-       if (tiph->frag_off)
+       df |= old_iph->frag_off & htons(IP_DF);
+
+       if (df) {
                mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
-       else
-               mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
-       if (mtu < 68) {
-               stats->collisions++;
-               ip_rt_put(rt);
-               goto tx_error;
-       }
-       if (skb_dst(skb))
-               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
+               if (mtu < 68) {
+                       stats->collisions++;
+                       ip_rt_put(rt);
+                       goto tx_error;
+               }
 
-       df |= (old_iph->frag_off&htons(IP_DF));
+               if (skb_dst(skb))
+                       skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
-       if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
-               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
-               ip_rt_put(rt);
-               goto tx_error;
+               if ((old_iph->frag_off & htons(IP_DF)) &&
+                   mtu < ntohs(old_iph->tot_len)) {
+                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                                 htonl(mtu));
+                       ip_rt_put(rt);
+                       goto tx_error;
+               }
        }
 
        if (tunnel->err_count > 0) {
index 68afc6e..fe1a644 100644 (file)
@@ -750,6 +750,8 @@ static int __init nf_nat_init(void)
        BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
        rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
                           nfnetlink_parse_nat_setup);
+       BUG_ON(nf_ct_nat_offset != NULL);
+       rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset);
        return 0;
 
  cleanup_extend:
@@ -764,6 +766,7 @@ static void __exit nf_nat_cleanup(void)
        nf_ct_extend_unregister(&nat_extend);
        rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
        rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
+       rcu_assign_pointer(nf_ct_nat_offset, NULL);
        synchronize_net();
 }
 
index 09172a6..f9520fa 100644 (file)
@@ -73,6 +73,28 @@ adjust_tcp_sequence(u32 seq,
        DUMP_OFFSET(this_way);
 }
 
+/* Get the offset value, for conntrack */
+s16 nf_nat_get_offset(const struct nf_conn *ct,
+                     enum ip_conntrack_dir dir,
+                     u32 seq)
+{
+       struct nf_conn_nat *nat = nfct_nat(ct);
+       struct nf_nat_seq *this_way;
+       s16 offset;
+
+       if (!nat)
+               return 0;
+
+       this_way = &nat->seq[dir];
+       spin_lock_bh(&nf_nat_seqofs_lock);
+       offset = after(seq, this_way->correction_pos)
+                ? this_way->offset_after : this_way->offset_before;
+       spin_unlock_bh(&nf_nat_seqofs_lock);
+
+       return offset;
+}
+EXPORT_SYMBOL_GPL(nf_nat_get_offset);
+
 /* Frobs data inside this packet, which is linear. */
 static void mangle_contents(struct sk_buff *skb,
                            unsigned int dataoff,
@@ -189,11 +211,6 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
                adjust_tcp_sequence(ntohl(tcph->seq),
                                    (int)rep_len - (int)match_len,
                                    ct, ctinfo);
-               /* Tell TCP window tracking about seq change */
-               nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
-                                       ct, CTINFO2DIR(ctinfo),
-                                       (int)rep_len - (int)match_len);
-
                nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
        }
        return 1;
@@ -415,12 +432,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
        tcph->seq = newseq;
        tcph->ack_seq = newack;
 
-       if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo))
-               return 0;
-
-       nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff);
-
-       return 1;
+       return nf_nat_sack_adjust(skb, tcph, ct, ctinfo);
 }
 
 /* Setup NAT on this expected conntrack so it follows master. */
index ca6e68d..b9168c1 100644 (file)
@@ -1351,6 +1351,11 @@ err_stat:
        return ret;
 }
 
+s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
+                       enum ip_conntrack_dir dir,
+                       u32 seq);
+EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
+
 int nf_conntrack_init(struct net *net)
 {
        int ret;
@@ -1368,6 +1373,9 @@ int nf_conntrack_init(struct net *net)
                /* For use by REJECT target */
                rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
                rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
+
+               /* Howto get NAT offsets */
+               rcu_assign_pointer(nf_ct_nat_offset, NULL);
        }
        return 0;
 
index 97a82ba..ba2b769 100644 (file)
@@ -492,6 +492,21 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
        }
 }
 
+#ifdef CONFIG_NF_NAT_NEEDED
+static inline s16 nat_offset(const struct nf_conn *ct,
+                            enum ip_conntrack_dir dir,
+                            u32 seq)
+{
+       typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset);
+
+       return get_offset != NULL ? get_offset(ct, dir, seq) : 0;
+}
+#define NAT_OFFSET(pf, ct, dir, seq) \
+       (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0)
+#else
+#define NAT_OFFSET(pf, ct, dir, seq)   0
+#endif
+
 static bool tcp_in_window(const struct nf_conn *ct,
                          struct ip_ct_tcp *state,
                          enum ip_conntrack_dir dir,
@@ -506,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
        struct ip_ct_tcp_state *receiver = &state->seen[!dir];
        const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
        __u32 seq, ack, sack, end, win, swin;
+       s16 receiver_offset;
        bool res;
 
        /*
@@ -519,11 +535,16 @@ static bool tcp_in_window(const struct nf_conn *ct,
        if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
                tcp_sack(skb, dataoff, tcph, &sack);
 
+       /* Take into account NAT sequence number mangling */
+       receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1);
+       ack -= receiver_offset;
+       sack -= receiver_offset;
+
        pr_debug("tcp_in_window: START\n");
        pr_debug("tcp_in_window: ");
        nf_ct_dump_tuple(tuple);
-       pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
-                seq, ack, sack, win, end);
+       pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
+                seq, ack, receiver_offset, sack, receiver_offset, win, end);
        pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
                 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
                 sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -613,8 +634,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
 
        pr_debug("tcp_in_window: ");
        nf_ct_dump_tuple(tuple);
-       pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
-                seq, ack, sack, win, end);
+       pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
+                seq, ack, receiver_offset, sack, receiver_offset, win, end);
        pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
                 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
                 sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -700,7 +721,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
                        before(seq, sender->td_maxend + 1) ?
                        after(end, sender->td_end - receiver->td_maxwin - 1) ?
                        before(sack, receiver->td_end + 1) ?
-                       after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
+                       after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
                        : "ACK is under the lower bound (possible overly delayed ACK)"
                        : "ACK is over the upper bound (ACKed data not seen yet)"
                        : "SEQ is under the lower bound (already ACKed data retransmitted)"
@@ -715,39 +736,6 @@ static bool tcp_in_window(const struct nf_conn *ct,
        return res;
 }
 
-#ifdef CONFIG_NF_NAT_NEEDED
-/* Update sender->td_end after NAT successfully mangled the packet */
-/* Caller must linearize skb at tcp header. */
-void nf_conntrack_tcp_update(const struct sk_buff *skb,
-                            unsigned int dataoff,
-                            struct nf_conn *ct, int dir,
-                            s16 offset)
-{
-       const struct tcphdr *tcph = (const void *)skb->data + dataoff;
-       const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
-       const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir];
-       __u32 end;
-
-       end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
-
-       spin_lock_bh(&ct->lock);
-       /*
-        * We have to worry for the ack in the reply packet only...
-        */
-       if (ct->proto.tcp.seen[dir].td_end + offset == end)
-               ct->proto.tcp.seen[dir].td_end = end;
-       ct->proto.tcp.last_end = end;
-       spin_unlock_bh(&ct->lock);
-       pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
-                "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-                sender->td_end, sender->td_maxend, sender->td_maxwin,
-                sender->td_scale,
-                receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-                receiver->td_scale);
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
-#endif
-
 #define        TH_FIN  0x01
 #define        TH_SYN  0x02
 #define        TH_RST  0x04
index 6809809..38f03f7 100644 (file)
@@ -103,7 +103,7 @@ static int count_them(struct xt_connlimit_data *data,
                      const struct nf_conntrack_tuple *tuple,
                      const union nf_inet_addr *addr,
                      const union nf_inet_addr *mask,
-                     const struct xt_match *match)
+                     u_int8_t family)
 {
        const struct nf_conntrack_tuple_hash *found;
        struct xt_connlimit_conn *conn;
@@ -113,8 +113,7 @@ static int count_them(struct xt_connlimit_data *data,
        bool addit = true;
        int matches = 0;
 
-
-       if (match->family == NFPROTO_IPV6)
+       if (family == NFPROTO_IPV6)
                hash = &data->iphash[connlimit_iphash6(addr, mask)];
        else
                hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
@@ -157,8 +156,7 @@ static int count_them(struct xt_connlimit_data *data,
                        continue;
                }
 
-               if (same_source_net(addr, mask, &conn->tuple.src.u3,
-                   match->family))
+               if (same_source_net(addr, mask, &conn->tuple.src.u3, family))
                        /* same source network -> be counted! */
                        ++matches;
                nf_ct_put(found_ct);
@@ -207,7 +205,7 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 
        spin_lock_bh(&info->data->lock);
        connections = count_them(info->data, tuple_ptr, &addr,
-                                &info->mask, par->match);
+                                &info->mask, par->family);
        spin_unlock_bh(&info->data->lock);
 
        if (connections < 0) {
index 9478d9b..f3e2198 100644 (file)
@@ -578,18 +578,18 @@ static int rose_clear_routes(void)
 
 /*
  *     Check that the device given is a valid AX.25 interface that is "up".
+ *     called whith RTNL
  */
-static struct net_device *rose_ax25_dev_get(char *devname)
+static struct net_device *rose_ax25_dev_find(char *devname)
 {
        struct net_device *dev;
 
-       if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
+       if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
                return NULL;
 
        if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
                return dev;
 
-       dev_put(dev);
        return NULL;
 }
 
@@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
        case SIOCADDRT:
                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
                        return -EFAULT;
-               if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+               if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
                        return -EINVAL;
-               if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */
-                       dev_put(dev);
+               if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
                        return -EINVAL;
-               }
                if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
                        return -EINVAL;
                if (rose_route.ndigis > AX25_MAX_DIGIS)
                        return -EINVAL;
                err = rose_add_node(&rose_route, dev);
-               dev_put(dev);
                return err;
 
        case SIOCDELRT:
                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
                        return -EFAULT;
-               if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+               if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
                        return -EINVAL;
                err = rose_del_node(&rose_route, dev);
-               dev_put(dev);
                return err;
 
        case SIOCRSCLRRT:
index 793b7f4..3f3c3f7 100644 (file)
@@ -219,7 +219,9 @@ static int shared_resources_initialised;
      *  Mid level stuff
      */
 
-struct sound_settings dmasound = { .lock = SPIN_LOCK_UNLOCKED };
+struct sound_settings dmasound = {
+       .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
+};
 
 static inline void sound_silence(void)
 {
index 77d0e5e..ce4db49 100644 (file)
@@ -157,7 +157,7 @@ static void sb_intr (sb_devc *devc)
                                break;
 
                        default:
-                               /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */
+                               /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
                                ;
                }
        }
@@ -177,7 +177,7 @@ static void sb_intr (sb_devc *devc)
                                break;
 
                        default:
-                               /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */
+                               /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
                                ;
                }
        }
index 180e95c..51a3d38 100644 (file)
@@ -782,7 +782,7 @@ printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
                        break;
 
                default:;
-                       /* printk(KERN_WARN "ESS: Unexpected interrupt\n"); */
+                       /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
        }
 }
 
index e340792..6517f58 100644 (file)
@@ -722,9 +722,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
                   chip->last_cmd[addr]);
        chip->single_cmd = 1;
        bus->response_reset = 0;
-       /* re-initialize CORB/RIRB */
+       /* release CORB/RIRB */
        azx_free_cmd_io(chip);
-       azx_init_cmd_io(chip);
+       /* disable unsolicited responses */
+       azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
        return -1;
 }
 
@@ -865,7 +866,9 @@ static int azx_reset(struct azx *chip)
        }
 
        /* Accept unsolicited responses */
-       azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);
+       if (!chip->single_cmd)
+               azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
+                          ICH6_GCTL_UNSOL);
 
        /* detect codecs */
        if (!chip->codec_mask) {
@@ -980,7 +983,8 @@ static void azx_init_chip(struct azx *chip)
        azx_int_enable(chip);
 
        /* initialize the codec command I/O */
-       azx_init_cmd_io(chip);
+       if (!chip->single_cmd)
+               azx_init_cmd_io(chip);
 
        /* program the position buffer */
        azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
index 3fbbc8c..6479e65 100644 (file)
@@ -2325,6 +2325,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
                      CXT5066_LAPTOP),
        SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
                      CXT5066_DELL_LAPTOP),
+       SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        {}
 };
 
index 66c0876..8eb6508 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/dmi.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
 #include <sound/jack.h>
@@ -1693,6 +1694,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                      "DFI LanParty", STAC_92HD71BXX_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
                      "HP dv4-1222nr", STAC_HP_DV4_1222NR),
+       SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
+                         "HP", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
@@ -4665,6 +4668,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
        }
 }
 
+static int hp_bseries_system(u32 subsystem_id)
+{
+       switch (subsystem_id) {
+       case 0x103c307e:
+       case 0x103c307f:
+       case 0x103c3080:
+       case 0x103c3081:
+       case 0x103c1722:
+       case 0x103c1723:
+       case 0x103c1724:
+       case 0x103c1725:
+       case 0x103c1726:
+       case 0x103c1727:
+       case 0x103c1728:
+       case 0x103c1729:
+               return 1;
+       }
+       return 0;
+}
+
 #ifdef CONFIG_PROC_FS
 static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
                               struct hda_codec *codec, hda_nid_t nid)
@@ -4754,6 +4777,11 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
                else
                        spec->gpio_data |= spec->gpio_led; /* white */
 
+               if (hp_bseries_system(codec->subsystem_id)) {
+                       /* LED state is inverted on these systems */
+                       spec->gpio_data ^= spec->gpio_led;
+               }
+
                stac_gpio_set(codec, spec->gpio_mask,
                              spec->gpio_dir,
                              spec->gpio_data);
@@ -5243,6 +5271,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec;
        struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
+       unsigned int pin_cfg;
        int err = 0;
 
        spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5426,6 +5455,45 @@ again:
                break;
        }
 
+       if (hp_bseries_system(codec->subsystem_id)) {
+               pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
+               if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
+                       get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER  ||
+                       get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
+                       /* It was changed in the BIOS to just satisfy MS DTM.
+                        * Lets turn it back into slaved HP
+                        */
+                       pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
+                                       | (AC_JACK_HP_OUT <<
+                                               AC_DEFCFG_DEVICE_SHIFT);
+                       pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
+                                                       | AC_DEFCFG_SEQUENCE)))
+                                                               | 0x1f;
+                       snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
+               }
+       }
+
+       if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
+               const struct dmi_device *dev = NULL;
+               while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
+                                             NULL, dev))) {
+                       if (strcmp(dev->name, "HP_Mute_LED_1")) {
+                               switch (codec->vendor_id) {
+                               case 0x111d7608:
+                                       spec->gpio_led = 0x01;
+                                       break;
+                               case 0x111d7600:
+                               case 0x111d7601:
+                               case 0x111d7602:
+                               case 0x111d7603:
+                                       spec->gpio_led = 0x08;
+                                       break;
+                               }
+                               break;
+                       }
+               }
+       }
+
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (spec->gpio_led) {
                spec->gpio_mask |= spec->gpio_led;
index 754867e..aac20fb 100644 (file)
@@ -1950,6 +1950,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
        },
        {
                .subvendor = 0x104d,
+               .subdevice = 0x8144,
+               .name = "Sony",
+               .type = AC97_TUNE_INV_EAPD
+       },
+       {
+               .subvendor = 0x104d,
                .subdevice = 0x8197,
                .name = "Sony S1XP",
                .type = AC97_TUNE_INV_EAPD
index 583a369..a0df401 100644 (file)
@@ -49,6 +49,7 @@ MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
 MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}");
+MODULE_FIRMWARE("aica_firmware.bin");
 
 /* module parameters */
 #define CARD_NAME "AICA"
index 5735945..6a829ee 100644 (file)
@@ -195,8 +195,12 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
        else
                omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
 
-       omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
-       omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
+       if (!(cpu_class_is_omap1())) {
+               omap_set_dma_src_burst_mode(prtd->dma_ch,
+                                               OMAP_DMA_DATA_BURST_16);
+               omap_set_dma_dest_burst_mode(prtd->dma_ch,
+                                               OMAP_DMA_DATA_BURST_16);
+       }
 
        return 0;
 }
index 3c06c40..105a77e 100644 (file)
@@ -220,6 +220,8 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
                goto err;
        }
 
+       clk_enable(i2s->iis_cclk);
+
        ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
        if (ret)
                goto err_clk;
index 8e7f789..e9a3a9d 100644 (file)
@@ -210,7 +210,7 @@ struct snd_usb_midi_endpoint_info {
 /*
  */
 
-#define combine_word(s)    ((*s) | ((unsigned int)(s)[1] << 8))
+#define combine_word(s)    ((*(s)) | ((unsigned int)(s)[1] << 8))
 #define combine_triple(s)  (combine_word(s) | ((unsigned int)(s)[2] << 16))
 #define combine_quad(s)    (combine_triple(s) | ((unsigned int)(s)[3] << 24))
 
index 3eeef33..a4be453 100644 (file)
@@ -426,7 +426,7 @@ try_again:
        if (fd[nr_cpu][counter] < 0) {
                int err = errno;
 
-               if (err == EPERM)
+               if (err == EPERM || err == EACCES)
                        die("Permission error - are you root?\n");
                else if (err ==  ENODEV && profile_cpu != -1)
                        die("No such device - did you specify an out-of-range profile CPU?\n");
index a1b1d10..e23bc74 100644 (file)
@@ -1027,7 +1027,7 @@ try_again:
        if (fd[i][counter] < 0) {
                int err = errno;
 
-               if (err == EPERM)
+               if (err == EPERM || err == EACCES)
                        die("No permission - are you root?\n");
                /*
                 * If it's cycles then fall back to hrtimer