Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jul 2011 20:51:32 +0000 (13:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jul 2011 20:51:32 +0000 (13:51 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (21 commits)
  slip: fix wrong SLIP6 ifdef-endif placing
  natsemi: fix another dma-debug report
  sctp: ABORT if receive, reassmbly, or reodering queue is not empty while closing socket
  net: Fix default in docs for tcp_orphan_retries.
  hso: fix a use after free condition
  net/natsemi: Fix module parameter permissions
  XFRM: Fix memory leak in xfrm_state_update
  sctp: Enforce retransmission limit during shutdown
  mac80211: fix TKIP replay vulnerability
  mac80211: fix ie memory allocation for scheduled scans
  ssb: fix init regression of hostmode PCI core
  rtlwifi: rtl8192cu: Add new USB ID for Netgear WNA1000M
  ath9k: Fix tx throughput drops for AR9003 chips with AES encryption
  carl9170: add NEC WL300NU-AG usbid
  cfg80211: fix deadlock with rfkill/sched_scan by adding new mutex
  ath5k: fix incorrect use of drvdata in PCI suspend/resume code
  ath5k: fix incorrect use of drvdata in sysfs code
  Bluetooth: Fix memory leak under page timeouts
  Bluetooth: Fix regression with incoming L2CAP connections
  Bluetooth: Fix hidp disconnect deadlocks and lost wakeup
  ...

123 files changed:
Documentation/Changes
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
Documentation/laptops/thinkpad-acpi.txt
Documentation/spinlocks.txt
MAINTAINERS
Makefile
arch/arm/common/dmabounce.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/setup.c
arch/arm/kernel/smp_twd.c
arch/arm/mach-davinci/irq.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-exynos4/cpu.c
arch/arm/mach-exynos4/dev-audio.c
arch/arm/mach-exynos4/headsmp.S
arch/arm/mach-exynos4/mach-smdkv310.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/gpio15xx.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-s3c2440/mach-mini2440.c
arch/arm/mach-s3c64xx/dev-spi.c
arch/arm/mach-s5p64x0/dev-spi.c
arch/arm/mach-s5pc100/dev-spi.c
arch/arm/mach-s5pv210/dev-spi.c
arch/arm/mach-vt8500/irq.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/mmu.c
arch/arm/mm/nommu.c
arch/arm/plat-orion/gpio.c
arch/arm/plat-pxa/gpio.c
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s5p/irq-gpioint.c
arch/arm/plat-s5p/s5p-time.c
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
arch/arm/plat-samsung/irq-uart.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/x86/mm/init_64.c
drivers/base/memory.c
drivers/base/syscore.c
drivers/cpufreq/acpi-cpufreq.c
drivers/firewire/ohci.c
drivers/gpio/langwell_gpio.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/rv770.c
drivers/hwmon/lm95241.c
drivers/hwmon/pmbus.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-tegra.c
drivers/leds/leds-pca9532.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cx18/cx18-ioctl.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/msp3400-driver.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/tuner-core.c
drivers/media/video/v4l2-ioctl.c
drivers/mfd/asic3.c
drivers/mfd/htc-pasic3.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/net/wireless/ath/ath5k/desc.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/setup-bus.c
drivers/pcmcia/pxa2xx_vpac270.c
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/compal-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/intel_oaktrail.c
drivers/platform/x86/thinkpad_acpi.c
drivers/regulator/db8500-prcmu.c
drivers/regulator/max8952.c
drivers/regulator/max8997.c
drivers/spi/spi_s3c64xx.c
drivers/usb/core/message.c
drivers/w1/masters/ds1wm.c
fs/btrfs/ctree.h
fs/btrfs/inode.c
fs/btrfs/super.c
fs/btrfs/volumes.c
fs/cifs/cifsfs.c
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_trans.c
include/linux/irq.h
include/linux/memory.h
include/linux/mfd/ds1wm.h
include/media/v4l2-subdev.h
kernel/irq/generic-chip.c
mm/memcontrol.c
mm/memory.c
mm/nommu.c
mm/vmscan.c
sound/pci/hda/patch_realtek.c
sound/soc/blackfin/bf5xx-i2s-pcm.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8994.c
sound/soc/soc-core.c
sound/soc/tegra/tegra_i2s.c

index 5f4828a..b175808 100644 (file)
@@ -2,13 +2,7 @@ Intro
 =====
 
 This document is designed to provide a list of the minimum levels of
-software necessary to run the 2.6 kernels, as well as provide brief
-instructions regarding any other "Gotchas" users may encounter when
-trying life on the Bleeding Edge.  If upgrading from a pre-2.4.x
-kernel, please consult the Changes file included with 2.4.x kernels for
-additional information; most of that information will not be repeated
-here.  Basically, this document assumes that your system is already
-functional and running at least 2.4.x kernels.
+software necessary to run the 3.0 kernels.
 
 This document is originally based on my "Changes" file for 2.0.x kernels
 and therefore owes credit to the same people as that file (Jared Mauch,
@@ -22,11 +16,10 @@ Upgrade to at *least* these software revisions before thinking you've
 encountered a bug!  If you're unsure what version you're currently
 running, the suggested command should tell you.
 
-Again, keep in mind that this list assumes you are already
-functionally running a Linux 2.4 kernel.  Also, not all tools are
-necessary on all systems; obviously, if you don't have any ISDN
-hardware, for example, you probably needn't concern yourself with
-isdn4k-utils.
+Again, keep in mind that this list assumes you are already functionally
+running a Linux kernel.  Also, not all tools are necessary on all
+systems; obviously, if you don't have any ISDN hardware, for example,
+you probably needn't concern yourself with isdn4k-utils.
 
 o  Gnu C                  3.2                     # gcc --version
 o  Gnu make               3.80                    # make --version
@@ -114,12 +107,12 @@ Ksymoops
 
 If the unthinkable happens and your kernel oopses, you may need the
 ksymoops tool to decode it, but in most cases you don't.
-In the 2.6 kernel it is generally preferred to build the kernel with
-CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is
-(this also produces better output than ksymoops).
-If for some reason your kernel is not build with CONFIG_KALLSYMS and
-you have no way to rebuild and reproduce the Oops with that option, then
-you can still decode that Oops with ksymoops.
+It is generally preferred to build the kernel with CONFIG_KALLSYMS so
+that it produces readable dumps that can be used as-is (this also
+produces better output than ksymoops).  If for some reason your kernel
+is not build with CONFIG_KALLSYMS and you have no way to rebuild and
+reproduce the Oops with that option, then you can still decode that Oops
+with ksymoops.
 
 Module-Init-Tools
 -----------------
@@ -261,8 +254,8 @@ needs to be recompiled or (preferably) upgraded.
 NFS-utils
 ---------
 
-In 2.4 and earlier kernels, the nfs server needed to know about any
-client that expected to be able to access files via NFS.  This
+In ancient (2.4 and earlier) kernels, the nfs server needed to know
+about any client that expected to be able to access files via NFS.  This
 information would be given to the kernel by "mountd" when the client
 mounted the filesystem, or by "exportfs" at system startup.  exportfs
 would take information about active clients from /var/lib/nfs/rmtab.
@@ -272,11 +265,11 @@ which is not always easy, particularly when trying to implement
 fail-over.  Even when the system is working well, rmtab suffers from
 getting lots of old entries that never get removed.
 
-With 2.6 we have the option of having the kernel tell mountd when it
-gets a request from an unknown host, and mountd can give appropriate
-export information to the kernel.  This removes the dependency on
-rmtab and means that the kernel only needs to know about currently
-active clients.
+With modern kernels we have the option of having the kernel tell mountd
+when it gets a request from an unknown host, and mountd can give
+appropriate export information to the kernel.  This removes the
+dependency on rmtab and means that the kernel only needs to know about
+currently active clients.
 
 To enable this new functionality, you need to:
 
index 72e2384..b1c921c 100644 (file)
@@ -583,3 +583,25 @@ Why:       Superseded by the UVCIOC_CTRL_QUERY ioctl.
 Who:   Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 
 ----------------------------
+
+What:  For VIDIOC_S_FREQUENCY the type field must match the device node's type.
+       If not, return -EINVAL.
+When:  3.2
+Why:   It makes no sense to switch the tuner to radio mode by calling
+       VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by
+       calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a
+       move to more consistent handling of tv and radio tuners.
+Who:   Hans Verkuil <hans.verkuil@cisco.com>
+
+----------------------------
+
+What:  Opening a radio device node will no longer automatically switch the
+       tuner mode from tv to radio.
+When:  3.3
+Why:   Just opening a V4L device should not change the state of the hardware
+       like that. It's very unexpected and against the V4L spec. Instead, you
+       switch to radio mode by calling VIDIOC_S_FREQUENCY. This is the second
+       and last step of the move to consistent handling of tv and radio tuners.
+Who:   Hans Verkuil <hans.verkuil@cisco.com>
+
+----------------------------
index fd248a3..aa47be7 100644 (file)
@@ -2015,6 +2015,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                                the default.
                                off: Turn ECRC off
                                on: Turn ECRC on.
+               realloc         reallocate PCI resources if allocations done by BIOS
+                               are erroneous.
 
        pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
                        Management.
index 1565eef..6181548 100644 (file)
@@ -534,6 +534,8 @@ Events that are never propagated by the driver:
 0x2404         System is waking up from hibernation to undock
 0x2405         System is waking up from hibernation to eject bay
 0x5010         Brightness level changed/control event
+0x6000         KEYBOARD: Numlock key pressed
+0x6005         KEYBOARD: Fn key pressed (TO BE VERIFIED)
 
 Events that are propagated by the driver to userspace:
 
@@ -545,6 +547,8 @@ Events that are propagated by the driver to userspace:
 0x3006         Bay hotplug request (hint to power up SATA link when
                the optical drive tray is ejected)
 0x4003         Undocked (see 0x2x04), can sleep again
+0x4010         Docked into hotplug port replicator (non-ACPI dock)
+0x4011         Undocked from hotplug port replicator (non-ACPI dock)
 0x500B         Tablet pen inserted into its storage bay
 0x500C         Tablet pen removed from its storage bay
 0x6011         ALARM: battery is too hot
@@ -552,6 +556,7 @@ Events that are propagated by the driver to userspace:
 0x6021         ALARM: a sensor is too hot
 0x6022         ALARM: a sensor is extremely hot
 0x6030         System thermal table changed
+0x6040         Nvidia Optimus/AC adapter related (TO BE VERIFIED)
 
 Battery nearly empty alarms are a last resort attempt to get the
 operating system to hibernate or shutdown cleanly (0x2313), or shutdown
index 2e3c64b..9dbe885 100644 (file)
@@ -13,18 +13,8 @@ static DEFINE_SPINLOCK(xxx_lock);
 The above is always safe. It will disable interrupts _locally_, but the
 spinlock itself will guarantee the global lock, so it will guarantee that
 there is only one thread-of-control within the region(s) protected by that
-lock. This works well even under UP. The above sequence under UP
-essentially is just the same as doing
-
-       unsigned long flags;
-
-       save_flags(flags); cli();
-        ... critical section ...
-       restore_flags(flags);
-
-so the code does _not_ need to worry about UP vs SMP issues: the spinlocks
-work correctly under both (and spinlocks are actually more efficient on
-architectures that allow doing the "save_flags + cli" in one operation).
+lock. This works well even under UP also, so the code does _not_ need to
+worry about UP vs SMP issues: the spinlocks work correctly under both.
 
    NOTE! Implications of spin_locks for memory are further described in:
 
@@ -36,27 +26,7 @@ The above is usually pretty simple (you usually need and want only one
 spinlock for most things - using more than one spinlock can make things a
 lot more complex and even slower and is usually worth it only for
 sequences that you _know_ need to be split up: avoid it at all cost if you
-aren't sure). HOWEVER, it _does_ mean that if you have some code that does
-
-       cli();
-       .. critical section ..
-       sti();
-
-and another sequence that does
-
-       spin_lock_irqsave(flags);
-       .. critical section ..
-       spin_unlock_irqrestore(flags);
-
-then they are NOT mutually exclusive, and the critical regions can happen
-at the same time on two different CPU's. That's fine per se, but the
-critical regions had better be critical for different things (ie they
-can't stomp on each other).
-
-The above is a problem mainly if you end up mixing code - for example the
-routines in ll_rw_block() tend to use cli/sti to protect the atomicity of
-their actions, and if a driver uses spinlocks instead then you should
-think about issues like the above.
+aren't sure).
 
 This is really the only really hard part about spinlocks: once you start
 using spinlocks they tend to expand to areas you might not have noticed
@@ -120,11 +90,10 @@ Lesson 3: spinlocks revisited.
 
 The single spin-lock primitives above are by no means the only ones. They
 are the most safe ones, and the ones that work under all circumstances,
-but partly _because_ they are safe they are also fairly slow. They are
-much faster than a generic global cli/sti pair, but slower than they'd
-need to be, because they do have to disable interrupts (which is just a
-single instruction on a x86, but it's an expensive one - and on other
-architectures it can be worse).
+but partly _because_ they are safe they are also fairly slow. They are slower
+than they'd need to be, because they do have to disable interrupts
+(which is just a single instruction on a x86, but it's an expensive one -
+and on other architectures it can be worse).
 
 If you have a case where you have to protect a data structure across
 several CPU's and you want to use spinlocks you can potentially use
index 9820e89..187282d 100644 (file)
@@ -594,6 +594,16 @@ S: Maintained
 F:     arch/arm/lib/floppydma.S
 F:     arch/arm/include/asm/floppy.h
 
+ARM PMU PROFILING AND DEBUGGING
+M:     Will Deacon <will.deacon@arm.com>
+S:     Maintained
+F:     arch/arm/kernel/perf_event*
+F:     arch/arm/oprofile/common.c
+F:     arch/arm/kernel/pmu.c
+F:     arch/arm/include/asm/pmu.h
+F:     arch/arm/kernel/hw_breakpoint.c
+F:     arch/arm/include/asm/hw_breakpoint.h
+
 ARM PORT
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -4982,7 +4992,7 @@ F:        drivers/power/power_supply*
 
 PNP SUPPORT
 M:     Adam Belay <abelay@mit.edu>
-M:     Bjorn Helgaas <bjorn.helgaas@hp.com>
+M:     Bjorn Helgaas <bhelgaas@google.com>
 S:     Maintained
 F:     drivers/pnp/
 
index 86f47a0..60d91f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Sneaky Weasel
 
 # *DOCUMENTATION*
index e568163..841df7d 100644 (file)
@@ -255,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
                if (buf == 0) {
                        dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
                               __func__, ptr);
-                       return 0;
+                       return ~0;
                }
 
                dev_dbg(dev,
index d53c0ab..2b5b142 100644 (file)
@@ -583,7 +583,7 @@ static int armpmu_event_init(struct perf_event *event)
 static void armpmu_enable(struct pmu *pmu)
 {
        /* Enable all of the perf events on hardware. */
-       int idx;
+       int idx, enabled = 0;
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
        if (!armpmu)
@@ -596,9 +596,11 @@ static void armpmu_enable(struct pmu *pmu)
                        continue;
 
                armpmu->enable(&event->hw, idx);
+               enabled = 1;
        }
 
-       armpmu->start();
+       if (enabled)
+               armpmu->start();
 }
 
 static void armpmu_disable(struct pmu *pmu)
index ed11fb0..acbb447 100644 (file)
@@ -73,6 +73,7 @@ __setup("fpe=", fpe_setup);
 #endif
 
 extern void paging_init(struct machine_desc *desc);
+extern void sanity_check_meminfo(void);
 extern void reboot_setup(char *str);
 
 unsigned int processor_id;
@@ -900,6 +901,7 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+       sanity_check_meminfo();
        arm_memblock_init(&meminfo, mdesc);
 
        paging_init(mdesc);
index 60636f4..2c277d4 100644 (file)
@@ -115,7 +115,7 @@ static void __cpuinit twd_calibrate_rate(void)
                twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
 
                printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
-                       (twd_timer_rate / 1000000) % 100);
+                       (twd_timer_rate / 10000) % 100);
        }
 }
 
index bfe68ec..d8c1af0 100644 (file)
@@ -53,7 +53,7 @@ davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
 
        gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
        ct = gc->chip_types;
-       ct->chip.irq_ack = irq_gc_ack;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
        ct->chip.irq_mask = irq_gc_mask_clr_bit;
        ct->chip.irq_unmask = irq_gc_mask_set_bit;
 
index 1d4b65f..6659a0d 100644 (file)
@@ -251,9 +251,9 @@ static void ep93xx_uart_set_mctrl(struct amba_device *dev,
        unsigned int mcr;
 
        mcr = 0;
-       if (!(mctrl & TIOCM_RTS))
+       if (mctrl & TIOCM_RTS)
                mcr |= 2;
-       if (!(mctrl & TIOCM_DTR))
+       if (mctrl & TIOCM_DTR)
                mcr |= 1;
 
        __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
index 9babe44..bfd6214 100644 (file)
@@ -23,6 +23,7 @@
 #include <plat/sdhci.h>
 #include <plat/devs.h>
 #include <plat/fimc-core.h>
+#include <plat/iic-core.h>
 
 #include <mach/regs-irq.h>
 
@@ -132,6 +133,11 @@ void __init exynos4_map_io(void)
        s3c_fimc_setname(1, "exynos4-fimc");
        s3c_fimc_setname(2, "exynos4-fimc");
        s3c_fimc_setname(3, "exynos4-fimc");
+
+       /* The I2C bus controllers are directly compatible with s3c2440 */
+       s3c_i2c0_setname("s3c2440-i2c");
+       s3c_i2c1_setname("s3c2440-i2c");
+       s3c_i2c2_setname("s3c2440-i2c");
 }
 
 void __init exynos4_init_clocks(int xtal)
index 1eed5f9..983069a 100644 (file)
@@ -330,7 +330,7 @@ struct platform_device exynos4_device_ac97 = {
 
 static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(3));
+       s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
 
        return 0;
 }
index 6c6cfc5..3cdeb36 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-       __INIT
+       __CPUINIT
 
 /*
  * exynos4 specific entry point for secondary CPUs.  This provides
index 1526764..edd8141 100644 (file)
@@ -78,9 +78,7 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
 };
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPK0(2),
-       .ext_cd_gpio_invert     = 1,
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
        .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
        .max_width              = 8,
@@ -96,9 +94,7 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
 };
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPK2(2),
-       .ext_cd_gpio_invert     = 1,
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
        .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
        .max_width              = 8,
index 72b4e76..ab9f999 100644 (file)
@@ -79,7 +79,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
 static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
 static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
 
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(lcd, LCD, 0x7f, 312000000);
 
 /* device and clock bindings */
index 8f92ccd..1464607 100644 (file)
@@ -110,7 +110,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
 static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
 
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(u2o, USB, 0x1b, 480000000);
 
 /* device and clock bindings */
index de88c92..f49ce85 100644 (file)
@@ -215,7 +215,7 @@ static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
        .delay          = 9,
 };
 
-static struct platform_device ams_delta_kp_device __initdata = {
+static struct platform_device ams_delta_kp_device = {
        .name           = "omap-keypad",
        .id             = -1,
        .dev            = {
@@ -225,12 +225,12 @@ static struct platform_device ams_delta_kp_device __initdata = {
        .resource       = ams_delta_kp_resources,
 };
 
-static struct platform_device ams_delta_lcd_device __initdata = {
+static struct platform_device ams_delta_lcd_device = {
        .name   = "lcd_ams_delta",
        .id     = -1,
 };
 
-static struct platform_device ams_delta_led_device __initdata = {
+static struct platform_device ams_delta_led_device = {
        .name   = "ams-delta-led",
        .id     = -1
 };
@@ -267,7 +267,7 @@ static struct soc_camera_link ams_delta_iclink = {
        .power          = ams_delta_camera_power,
 };
 
-static struct platform_device ams_delta_camera_device __initdata = {
+static struct platform_device ams_delta_camera_device = {
        .name   = "soc-camera-pdrv",
        .id     = 0,
        .dev    = {
index 04c4b04..364137c 100644 (file)
@@ -41,7 +41,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
        .bank_stride            = 1,
 };
 
-static struct __initdata platform_device omap15xx_mpu_gpio = {
+static struct platform_device omap15xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -70,7 +70,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap15xx_gpio = {
+static struct platform_device omap15xx_gpio = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
index 5dd0d4c..293a246 100644 (file)
@@ -44,7 +44,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
        .bank_stride            = 1,
 };
 
-static struct __initdata platform_device omap16xx_mpu_gpio = {
+static struct platform_device omap16xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -73,7 +73,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio1 = {
+static struct platform_device omap16xx_gpio1 = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
@@ -102,7 +102,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio2 = {
+static struct platform_device omap16xx_gpio2 = {
        .name           = "omap_gpio",
        .id             = 2,
        .dev            = {
@@ -131,7 +131,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio3 = {
+static struct platform_device omap16xx_gpio3 = {
        .name           = "omap_gpio",
        .id             = 3,
        .dev            = {
@@ -160,7 +160,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio4 = {
+static struct platform_device omap16xx_gpio4 = {
        .name           = "omap_gpio",
        .id             = 4,
        .dev            = {
index 1204c8b..c6ad248 100644 (file)
@@ -46,7 +46,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
        .bank_stride            = 2,
 };
 
-static struct __initdata platform_device omap7xx_mpu_gpio = {
+static struct platform_device omap7xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -75,7 +75,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio1 = {
+static struct platform_device omap7xx_gpio1 = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
@@ -104,7 +104,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio2 = {
+static struct platform_device omap7xx_gpio2 = {
        .name           = "omap_gpio",
        .id             = 2,
        .dev            = {
@@ -133,7 +133,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio3 = {
+static struct platform_device omap7xx_gpio3 = {
        .name           = "omap_gpio",
        .id             = 3,
        .dev            = {
@@ -162,7 +162,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio4 = {
+static struct platform_device omap7xx_gpio4 = {
        .name           = "omap_gpio",
        .id             = 4,
        .dev            = {
@@ -191,7 +191,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio5 = {
+static struct platform_device omap7xx_gpio5 = {
        .name           = "omap_gpio",
        .id             = 5,
        .dev            = {
@@ -220,7 +220,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio6 = {
+static struct platform_device omap7xx_gpio6 = {
        .name           = "omap_gpio",
        .id             = 6,
        .dev            = {
index 9903667..88bd6f7 100644 (file)
@@ -558,7 +558,7 @@ static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module =
        .subdev_board_info = &rx51_si4713_board_info,
 };
 
-static struct platform_device rx51_si4713_dev __initdata_or_module = {
+static struct platform_device rx51_si4713_dev = {
        .name   = "radio-si4713",
        .id     = -1,
        .dev    = {
index 87ae312..b27544b 100644 (file)
@@ -347,9 +347,9 @@ static int pxa2xx_mfp_suspend(void)
                if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
                    (GPDR(i) & GPIO_bit(i))) {
                        if (GPLR(i) & GPIO_bit(i))
-                               PGSR(i) |= GPIO_bit(i);
+                               PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
                        else
-                               PGSR(i) &= ~GPIO_bit(i);
+                               PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
                }
        }
 
index d130f77..2f37d43 100644 (file)
@@ -573,10 +573,10 @@ static struct pxafb_mode_info sharp_lq043t3dx02_mode = {
        .xres           = 480,
        .yres           = 272,
        .bpp            = 16,
-       .hsync_len      = 4,
+       .hsync_len      = 41,
        .left_margin    = 2,
        .right_margin   = 1,
-       .vsync_len      = 1,
+       .vsync_len      = 10,
        .upper_margin   = 3,
        .lower_margin   = 1,
        .sync           = 0,
@@ -596,29 +596,31 @@ static void __init raumfeld_lcd_init(void)
 {
        int ret;
 
-       pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
-
-       /* Earlier devices had the backlight regulator controlled
-        * via PWM, later versions use another controller for that */
-       if ((system_rev & 0xff) < 2) {
-               mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
-               pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
-               platform_device_register(&raumfeld_pwm_backlight_device);
-       } else
-               platform_device_register(&raumfeld_lt3593_device);
-
        ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable");
        if (ret < 0)
                pr_warning("Unable to request GPIO_TFT_VA_EN\n");
        else
                gpio_direction_output(GPIO_TFT_VA_EN, 1);
 
+       msleep(100);
+
        ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable");
        if (ret < 0)
                pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n");
        else
                gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
 
+       /* Hardware revision 2 has the backlight regulator controlled
+        * by an LT3593, earlier and later devices use PWM for that. */
+       if ((system_rev & 0xff) == 2) {
+               platform_device_register(&raumfeld_lt3593_device);
+       } else {
+               mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
+               pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+               platform_device_register(&raumfeld_pwm_backlight_device);
+       }
+
+       pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
        platform_device_register(&pxa3xx_device_gcu);
 }
 
@@ -657,10 +659,10 @@ static struct lis3lv02d_platform_data lis3_pdata = {
 
 #define SPI_AK4104     \
 {                      \
-       .modalias       = "ak4104",     \
-       .max_speed_hz   = 10000,        \
-       .bus_num        = 0,            \
-       .chip_select    = 0,            \
+       .modalias       = "ak4104-codec",       \
+       .max_speed_hz   = 10000,                \
+       .bus_num        = 0,                    \
+       .chip_select    = 0,                    \
        .controller_data = (void *) GPIO_SPDIF_CS,      \
 }
 
index dd3120d..fc2dc0b 100644 (file)
@@ -552,7 +552,7 @@ struct mini2440_features_t {
        struct platform_device *optional[8];
 };
 
-static void mini2440_parse_features(
+static void __init mini2440_parse_features(
                struct mini2440_features_t * features,
                const char * features_str )
 {
index 82db072..5e6b420 100644 (file)
@@ -88,6 +88,7 @@ static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
        .cfg_gpio = s3c64xx_spi_cfg_gpio,
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 13,
+       .tx_st_done = 21,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -132,6 +133,7 @@ static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
        .cfg_gpio = s3c64xx_spi_cfg_gpio,
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 13,
+       .tx_st_done = 21,
 };
 
 struct platform_device s3c64xx_device_spi1 = {
index e78ee18..ac825e8 100644 (file)
@@ -112,12 +112,14 @@ static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
        .cfg_gpio       = s5p6440_spi_cfg_gpio,
        .fifo_lvl_mask  = 0x1ff,
        .rx_lvl_offset  = 15,
+       .tx_st_done     = 25,
 };
 
 static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
        .cfg_gpio       = s5p6450_spi_cfg_gpio,
        .fifo_lvl_mask  = 0x1ff,
        .rx_lvl_offset  = 15,
+       .tx_st_done     = 25,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -160,12 +162,14 @@ static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
        .cfg_gpio       = s5p6440_spi_cfg_gpio,
        .fifo_lvl_mask  = 0x7f,
        .rx_lvl_offset  = 15,
+       .tx_st_done     = 25,
 };
 
 static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
        .cfg_gpio       = s5p6450_spi_cfg_gpio,
        .fifo_lvl_mask  = 0x7f,
        .rx_lvl_offset  = 15,
+       .tx_st_done     = 25,
 };
 
 struct platform_device s5p64x0_device_spi1 = {
index 57b1979..e5d6c4d 100644 (file)
@@ -15,6 +15,7 @@
 #include <mach/dma.h>
 #include <mach/map.h>
 #include <mach/spi-clocks.h>
+#include <mach/irqs.h>
 
 #include <plat/s3c64xx-spi.h>
 #include <plat/gpio-cfg.h>
@@ -90,6 +91,7 @@ static struct s3c64xx_spi_info s5pc100_spi0_pdata = {
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 13,
        .high_speed = 1,
+       .tx_st_done = 21,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -134,6 +136,7 @@ static struct s3c64xx_spi_info s5pc100_spi1_pdata = {
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 13,
        .high_speed = 1,
+       .tx_st_done = 21,
 };
 
 struct platform_device s5pc100_device_spi1 = {
@@ -176,6 +179,7 @@ static struct s3c64xx_spi_info s5pc100_spi2_pdata = {
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 13,
        .high_speed = 1,
+       .tx_st_done = 21,
 };
 
 struct platform_device s5pc100_device_spi2 = {
index e3249a4..eaf9a7b 100644 (file)
@@ -85,6 +85,7 @@ static struct s3c64xx_spi_info s5pv210_spi0_pdata = {
        .fifo_lvl_mask = 0x1ff,
        .rx_lvl_offset = 15,
        .high_speed = 1,
+       .tx_st_done = 25,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -129,6 +130,7 @@ static struct s3c64xx_spi_info s5pv210_spi1_pdata = {
        .fifo_lvl_mask = 0x7f,
        .rx_lvl_offset = 15,
        .high_speed = 1,
+       .tx_st_done = 25,
 };
 
 struct platform_device s5pv210_device_spi1 = {
index 245140c..642de04 100644 (file)
 static void __iomem *ic_regbase;
 static void __iomem *sic_regbase;
 
-static void vt8500_irq_mask(unsigned int irq)
+static void vt8500_irq_mask(struct irq_data *d)
 {
        void __iomem *base = ic_regbase;
+       unsigned irq = d->irq;
        u8 edge;
 
        if (irq >= 64) {
@@ -64,9 +65,10 @@ static void vt8500_irq_mask(unsigned int irq)
        }
 }
 
-static void vt8500_irq_unmask(unsigned int irq)
+static void vt8500_irq_unmask(struct irq_data *d)
 {
        void __iomem *base = ic_regbase;
+       unsigned irq = d->irq;
        u8 dctr;
 
        if (irq >= 64) {
@@ -78,10 +80,11 @@ static void vt8500_irq_unmask(unsigned int irq)
        writeb(dctr, base + VT8500_IC_DCTR + irq);
 }
 
-static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
        void __iomem *base = ic_regbase;
-       unsigned int orig_irq = irq;
+       unsigned irq = d->irq;
+       unsigned orig_irq = irq;
        u8 dctr;
 
        if (irq >= 64) {
@@ -114,11 +117,11 @@ static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
 }
 
 static struct irq_chip vt8500_irq_chip = {
-       .name      = "vt8500",
-       .ack       = vt8500_irq_mask,
-       .mask      = vt8500_irq_mask,
-       .unmask    = vt8500_irq_unmask,
-       .set_type  = vt8500_irq_set_type,
+       .name = "vt8500",
+       .irq_ack = vt8500_irq_mask,
+       .irq_mask = vt8500_irq_mask,
+       .irq_unmask = vt8500_irq_unmask,
+       .irq_set_type = vt8500_irq_set_type,
 };
 
 void __init vt8500_init_irq(void)
index ef59099..44c0867 100644 (file)
@@ -120,17 +120,22 @@ static void l2x0_cache_sync(void)
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_flush_all(void)
+static void __l2x0_flush_all(void)
 {
-       unsigned long flags;
-
-       /* clean all ways */
-       spin_lock_irqsave(&l2x0_lock, flags);
        debug_writel(0x03);
        writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
        cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
        cache_sync();
        debug_writel(0x00);
+}
+
+static void l2x0_flush_all(void)
+{
+       unsigned long flags;
+
+       /* clean all ways */
+       spin_lock_irqsave(&l2x0_lock, flags);
+       __l2x0_flush_all();
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
@@ -266,7 +271,9 @@ static void l2x0_disable(void)
        unsigned long flags;
 
        spin_lock_irqsave(&l2x0_lock, flags);
-       writel(0, l2x0_base + L2X0_CTRL);
+       __l2x0_flush_all();
+       writel_relaxed(0, l2x0_base + L2X0_CTRL);
+       dsb();
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
index 9d9e736..594d677 100644 (file)
@@ -759,7 +759,7 @@ early_param("vmalloc", early_vmalloc);
 
 static phys_addr_t lowmem_limit __initdata = 0;
 
-static void __init sanity_check_meminfo(void)
+void __init sanity_check_meminfo(void)
 {
        int i, j, highmem = 0;
 
@@ -1032,8 +1032,9 @@ void __init paging_init(struct machine_desc *mdesc)
 {
        void *zero_page;
 
+       memblock_set_current_limit(lowmem_limit);
+
        build_mem_type_table();
-       sanity_check_meminfo();
        prepare_page_table();
        map_lowmem();
        devicemaps_init(mdesc);
index 687d023..941a98c 100644 (file)
@@ -27,6 +27,10 @@ void __init arm_mm_memblock_reserve(void)
        memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
+void __init sanity_check_meminfo(void)
+{
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
index 5b4fffa..41ab97e 100644 (file)
@@ -432,7 +432,7 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
        ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF;
        ct->regs.ack = GPIO_EDGE_CAUSE_OFF;
        ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
-       ct->chip.irq_ack = irq_gc_ack;
+       ct->chip.irq_ack = irq_gc_ack_clr_bit;
        ct->chip.irq_mask = irq_gc_mask_clr_bit;
        ct->chip.irq_unmask = irq_gc_mask_set_bit;
        ct->chip.irq_set_type = gpio_irq_set_type;
index 48ebb94..a11dc36 100644 (file)
@@ -50,7 +50,7 @@ static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
        return container_of(c, struct pxa_gpio_chip, chip)->regbase;
 }
 
-static inline struct pxa_gpio_chip *gpio_to_chip(unsigned gpio)
+static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
 {
        return &pxa_gpio_chips[gpio_to_bank(gpio)];
 }
@@ -161,7 +161,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
        int gpio = irq_to_gpio(d->irq);
        unsigned long gpdr, mask = GPIO_bit(gpio);
 
-       c = gpio_to_chip(gpio);
+       c = gpio_to_pxachip(gpio);
 
        if (type == IRQ_TYPE_PROBE) {
                /* Don't mess with enabled GPIOs using preconfigured edges or
@@ -230,7 +230,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 static void pxa_ack_muxed_gpio(struct irq_data *d)
 {
        int gpio = irq_to_gpio(d->irq);
-       struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+       struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 
        __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
 }
@@ -238,7 +238,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d)
 static void pxa_mask_muxed_gpio(struct irq_data *d)
 {
        int gpio = irq_to_gpio(d->irq);
-       struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+       struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
        uint32_t grer, gfer;
 
        c->irq_mask &= ~GPIO_bit(gpio);
@@ -252,7 +252,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
 static void pxa_unmask_muxed_gpio(struct irq_data *d)
 {
        int gpio = irq_to_gpio(d->irq);
-       struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+       struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
 
        c->irq_mask |= GPIO_bit(gpio);
        update_edge_detect(c);
index 2abf966..a79a8cc 100644 (file)
@@ -1027,17 +1027,13 @@ int s3c2410_dma_config(unsigned int channel,
        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
        unsigned int dcon;
 
-       pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
-                __func__, channel, xferunit, dcon);
+       pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
 
        if (chan == NULL)
                return -EINVAL;
 
-       pr_debug("%s: Initial dcon is %08x\n", __func__, dcon);
-
        dcon = chan->dcon & dma_sel.dcon_mask;
-
-       pr_debug("%s: New dcon is %08x\n", __func__, dcon);
+       pr_debug("%s: dcon is %08x\n", __func__, dcon);
 
        switch (chan->req_ch) {
        case DMACH_I2S_IN:
@@ -1235,7 +1231,7 @@ static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
        /* restore channel's hardware configuration */
 
        if (!cp->in_use)
-               return 0;
+               return;
 
        printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
 
@@ -1246,8 +1242,6 @@ static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
 
        if (cp->map != NULL)
                dma_sel.select(cp, cp->map);
-
-       return 0;
 }
 
 static void s3c2410_dma_resume(void)
index 135abda..327ab9f 100644 (file)
@@ -152,7 +152,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
        if (!gc)
                return -ENOMEM;
        ct = gc->chip_types;
-       ct->chip.irq_ack = irq_gc_ack;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
        ct->chip.irq_mask = irq_gc_mask_set_bit;
        ct->chip.irq_unmask = irq_gc_mask_clr_bit;
        ct->chip.irq_set_type = s5p_gpioint_set_type,
index 899a8cc..612934c 100644 (file)
@@ -370,11 +370,11 @@ static void __init s5p_clocksource_init(void)
 
        clock_rate = clk_get_rate(tin_source);
 
-       init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
-
        s5p_time_setup(timer_source.source_id, TCNT_MAX);
        s5p_time_start(timer_source.source_id, PERIODIC);
 
+       init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
+
        if (clocksource_register_hz(&time_clocksource, clock_rate))
                panic("%s: can't register clocksource\n", time_clocksource.name);
 }
index 4af108f..e3b31c2 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
+
+#ifndef __PLAT_DEVS_H
+#define __PLAT_DEVS_H __FILE__
+
 #include <linux/platform_device.h>
 
 struct s3c24xx_uart_resources {
@@ -159,3 +163,5 @@ extern struct platform_device s3c_device_ac97;
  */
 extern void *s3c_set_platdata(void *pd, size_t pdsize,
                              struct platform_device *pdev);
+
+#endif /* __PLAT_DEVS_H */
index 0ffe34a..4c16fa3 100644 (file)
@@ -39,6 +39,7 @@ struct s3c64xx_spi_csinfo {
  * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
  * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
  * @high_speed: If the controller supports HIGH_SPEED_EN bit
+ * @tx_st_done: Depends on tx fifo_lvl field
  */
 struct s3c64xx_spi_info {
        int src_clk_nr;
@@ -53,6 +54,7 @@ struct s3c64xx_spi_info {
        int fifo_lvl_mask;
        int rx_lvl_offset;
        int high_speed;
+       int tx_st_done;
 };
 
 /**
index 32582c0..0e46588 100644 (file)
@@ -55,7 +55,7 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
        gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base,
                                    handle_level_irq);
        ct = gc->chip_types;
-       ct->chip.irq_ack = irq_gc_ack;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
        ct->chip.irq_mask = irq_gc_mask_set_bit;
        ct->chip.irq_unmask = irq_gc_mask_clr_bit;
        ct->regs.ack = S3C64XX_UINTP;
index 33867ec..9d6a8ef 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/of.h>
 #include <linux/memblock.h>
 #include <linux/vmalloc.h>
+#include <linux/memory.h>
+
 #include <asm/firmware.h>
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
 static unsigned long get_memblock_size(void)
 {
        struct device_node *np;
-       unsigned int memblock_size = 0;
+       unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE;
+       struct resource r;
 
        np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
        if (np) {
-               const unsigned long *size;
+               const __be64 *size;
 
                size = of_get_property(np, "ibm,lmb-size", NULL);
-               memblock_size = size ? *size : 0;
-
+               if (size)
+                       memblock_size = be64_to_cpup(size);
                of_node_put(np);
-       } else {
+       } else  if (machine_is(pseries)) {
+               /* This fallback really only applies to pseries */
                unsigned int memzero_size = 0;
-               const unsigned int *regs;
 
                np = of_find_node_by_path("/memory@0");
                if (np) {
-                       regs = of_get_property(np, "reg", NULL);
-                       memzero_size = regs ? regs[3] : 0;
+                       if (!of_address_to_resource(np, 0, &r))
+                               memzero_size = resource_size(&r);
                        of_node_put(np);
                }
 
@@ -50,16 +53,21 @@ static unsigned long get_memblock_size(void)
                        sprintf(buf, "/memory@%x", memzero_size);
                        np = of_find_node_by_path(buf);
                        if (np) {
-                               regs = of_get_property(np, "reg", NULL);
-                               memblock_size = regs ? regs[3] : 0;
+                               if (!of_address_to_resource(np, 0, &r))
+                                       memblock_size = resource_size(&r);
                                of_node_put(np);
                        }
                }
        }
-
        return memblock_size;
 }
 
+/* WARNING: This is going to override the generic definition whenever
+ * pseries is built-in regardless of what platform is active at boot
+ * time. This is fine for now as this is the only "option" and it
+ * should work everywhere. If not, we'll have to turn this into a
+ * ppc_md. callback
+ */
 unsigned long memory_block_size_bytes(void)
 {
        return get_memblock_size();
index d865c4a..bbaaa00 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/poison.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
+#include <linux/memory.h>
 #include <linux/memory_hotplug.h>
 #include <linux/nmi.h>
 #include <linux/gfp.h>
@@ -895,8 +896,6 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 }
 
 #ifdef CONFIG_X86_UV
-#define MIN_MEMORY_BLOCK_SIZE   (1 << SECTION_SIZE_BITS)
-
 unsigned long memory_block_size_bytes(void)
 {
        if (is_uv_system()) {
index 9f9b235..45d7c8f 100644 (file)
@@ -30,7 +30,6 @@
 static DEFINE_MUTEX(mem_sysfs_mutex);
 
 #define MEMORY_CLASS_NAME      "memory"
-#define MIN_MEMORY_BLOCK_SIZE  (1 << SECTION_SIZE_BITS)
 
 static int sections_per_block;
 
index c126db3..e8d11b6 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 
 static LIST_HEAD(syscore_ops_list);
 static DEFINE_MUTEX(syscore_ops_lock);
@@ -48,6 +49,13 @@ int syscore_suspend(void)
        struct syscore_ops *ops;
        int ret = 0;
 
+       pr_debug("Checking wakeup interrupts\n");
+
+       /* Return error code if there are any wakeup interrupts pending. */
+       ret = check_wakeup_irqs();
+       if (ret)
+               return ret;
+
        WARN_ONCE(!irqs_disabled(),
                "Interrupts enabled before system core suspend.\n");
 
index 4e04e12..596d5dd 100644 (file)
@@ -759,7 +759,7 @@ static void __exit acpi_cpufreq_exit(void)
 
        cpufreq_unregister_driver(&acpi_cpufreq_driver);
 
-       free_percpu(acpi_perf_data);
+       free_acpi_perf_data();
 }
 
 module_param(acpi_pstate_strict, uint, 0644);
index 438e6c8..ebb8973 100644 (file)
@@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 #define PCI_DEVICE_ID_AGERE_FW643      0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
 
 #define QUIRK_CYCLE_TIMER              1
 #define QUIRK_RESET_PACKET             2
@@ -3190,6 +3191,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
        int i, err;
        size_t size;
 
+       if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
+               dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
+               return -ENOSYS;
+       }
+
        ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
        if (ohci == NULL) {
                err = -ENOMEM;
index bd6571e..644ba12 100644 (file)
@@ -223,7 +223,7 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
                gedr = gpio_reg(&lnw->chip, base, GEDR);
                pending = readl(gedr);
                while (pending) {
-                       gpio = __ffs(pending) - 1;
+                       gpio = __ffs(pending);
                        mask = BIT(gpio);
                        pending &= ~mask;
                        /* Clear before handling so we can't lose an edge */
index 21058e6..82db185 100644 (file)
@@ -886,9 +886,6 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
        total_objects += dev->mode_config.num_connector;
        total_objects += dev->mode_config.num_encoder;
 
-       if (total_objects == 0)
-               return -EINVAL;
-
        group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
        if (!group->id_list)
                return -ENOMEM;
index e178702..296fbd6 100644 (file)
@@ -1943,7 +1943,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (!dev_priv->mm.gtt) {
                DRM_ERROR("Failed to initialize GTT\n");
                ret = -ENODEV;
-               goto out_iomapfree;
+               goto out_rmmap;
        }
 
        agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
@@ -1987,7 +1987,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (dev_priv->wq == NULL) {
                DRM_ERROR("Failed to create our workqueue.\n");
                ret = -ENOMEM;
-               goto out_iomapfree;
+               goto out_mtrrfree;
        }
 
        /* enable GEM by default */
@@ -2074,13 +2074,21 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        return 0;
 
 out_gem_unload:
+       if (dev_priv->mm.inactive_shrinker.shrink)
+               unregister_shrinker(&dev_priv->mm.inactive_shrinker);
+
        if (dev->pdev->msi_enabled)
                pci_disable_msi(dev->pdev);
 
        intel_teardown_gmbus(dev);
        intel_teardown_mchbar(dev);
        destroy_workqueue(dev_priv->wq);
-out_iomapfree:
+out_mtrrfree:
+       if (dev_priv->mm.gtt_mtrr >= 0) {
+               mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
+                        dev->agp->agp_info.aper_size * 1024 * 1024);
+               dev_priv->mm.gtt_mtrr = -1;
+       }
        io_mapping_free(dev_priv->mm.gtt_mapping);
 out_rmmap:
        pci_iounmap(dev->pdev, dev_priv->regs);
index 013d304..eb91e2d 100644 (file)
@@ -52,7 +52,7 @@ module_param_named(powersave, i915_powersave, int, 0600);
 unsigned int i915_semaphores = 0;
 module_param_named(semaphores, i915_semaphores, int, 0600);
 
-unsigned int i915_enable_rc6 = 1;
+unsigned int i915_enable_rc6 = 0;
 module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
 
 unsigned int i915_enable_fbc = 0;
@@ -577,6 +577,7 @@ int i915_reset(struct drm_device *dev, u8 flags)
        if (get_seconds() - dev_priv->last_gpu_reset < 5) {
                DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
        } else switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                ret = gen6_do_reset(dev, flags);
                /* If reset with a user forcewake, try to restore */
index 391b55f..e2aced6 100644 (file)
@@ -50,7 +50,6 @@ struct intel_dp {
        bool has_audio;
        int force_audio;
        uint32_t color_range;
-       int dpms_mode;
        uint8_t link_bw;
        uint8_t lane_count;
        uint8_t dpcd[4];
@@ -138,8 +137,8 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
        int max_lane_count = 4;
 
-       if (intel_dp->dpcd[0] >= 0x11) {
-               max_lane_count = intel_dp->dpcd[2] & 0x1f;
+       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
+               max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
                switch (max_lane_count) {
                case 1: case 2: case 4:
                        break;
@@ -153,7 +152,7 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp)
 static int
 intel_dp_max_link_bw(struct intel_dp *intel_dp)
 {
-       int max_link_bw = intel_dp->dpcd[1];
+       int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
 
        switch (max_link_bw) {
        case DP_LINK_BW_1_62:
@@ -774,7 +773,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        /*
         * Check for DPCD version > 1.1 and enhanced framing support
         */
-       if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
+       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+           (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
                intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
                intel_dp->DP |= DP_ENHANCED_FRAMING;
        }
@@ -942,11 +942,44 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder)
        udelay(200);
 }
 
+/* If the sink supports it, try to set the power state appropriately */
+static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
+{
+       int ret, i;
+
+       /* Should have a valid DPCD by this point */
+       if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+               return;
+
+       if (mode != DRM_MODE_DPMS_ON) {
+               ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER,
+                                                 DP_SET_POWER_D3);
+               if (ret != 1)
+                       DRM_DEBUG_DRIVER("failed to write sink power state\n");
+       } else {
+               /*
+                * When turning on, we need to retry for 1ms to give the sink
+                * time to wake up.
+                */
+               for (i = 0; i < 3; i++) {
+                       ret = intel_dp_aux_native_write_1(intel_dp,
+                                                         DP_SET_POWER,
+                                                         DP_SET_POWER_D0);
+                       if (ret == 1)
+                               break;
+                       msleep(1);
+               }
+       }
+}
+
 static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        struct drm_device *dev = encoder->dev;
 
+       /* Wake up the sink first */
+       intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+
        if (is_edp(intel_dp)) {
                ironlake_edp_backlight_off(dev);
                ironlake_edp_panel_off(dev);
@@ -990,6 +1023,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        if (mode != DRM_MODE_DPMS_ON) {
                if (is_edp(intel_dp))
                        ironlake_edp_backlight_off(dev);
+               intel_dp_sink_dpms(intel_dp, mode);
                intel_dp_link_down(intel_dp);
                if (is_edp(intel_dp))
                        ironlake_edp_panel_off(dev);
@@ -998,6 +1032,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        } else {
                if (is_edp(intel_dp))
                        ironlake_edp_panel_vdd_on(intel_dp);
+               intel_dp_sink_dpms(intel_dp, mode);
                if (!(dp_reg & DP_PORT_EN)) {
                        intel_dp_start_link_train(intel_dp);
                        if (is_edp(intel_dp)) {
@@ -1009,7 +1044,31 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
                if (is_edp(intel_dp))
                        ironlake_edp_backlight_on(dev);
        }
-       intel_dp->dpms_mode = mode;
+}
+
+/*
+ * Native read with retry for link status and receiver capability reads for
+ * cases where the sink may still be asleep.
+ */
+static bool
+intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
+                              uint8_t *recv, int recv_bytes)
+{
+       int ret, i;
+
+       /*
+        * Sinks are *supposed* to come up within 1ms from an off state,
+        * but we're also supposed to retry 3 times per the spec.
+        */
+       for (i = 0; i < 3; i++) {
+               ret = intel_dp_aux_native_read(intel_dp, address, recv,
+                                              recv_bytes);
+               if (ret == recv_bytes)
+                       return true;
+               msleep(1);
+       }
+
+       return false;
 }
 
 /*
@@ -1019,14 +1078,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
 static bool
 intel_dp_get_link_status(struct intel_dp *intel_dp)
 {
-       int ret;
-
-       ret = intel_dp_aux_native_read(intel_dp,
-                                      DP_LANE0_1_STATUS,
-                                      intel_dp->link_status, DP_LINK_STATUS_SIZE);
-       if (ret != DP_LINK_STATUS_SIZE)
-               return false;
-       return true;
+       return intel_dp_aux_native_read_retry(intel_dp,
+                                             DP_LANE0_1_STATUS,
+                                             intel_dp->link_status,
+                                             DP_LINK_STATUS_SIZE);
 }
 
 static uint8_t
@@ -1515,6 +1570,8 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
+       int ret;
+
        if (!intel_dp->base.base.crtc)
                return;
 
@@ -1523,6 +1580,15 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                return;
        }
 
+       /* Try to read receiver status if the link appears to be up */
+       ret = intel_dp_aux_native_read(intel_dp,
+                                      0x000, intel_dp->dpcd,
+                                      sizeof (intel_dp->dpcd));
+       if (ret != sizeof(intel_dp->dpcd)) {
+               intel_dp_link_down(intel_dp);
+               return;
+       }
+
        if (!intel_channel_eq_ok(intel_dp)) {
                intel_dp_start_link_train(intel_dp);
                intel_dp_complete_link_train(intel_dp);
@@ -1533,6 +1599,7 @@ static enum drm_connector_status
 ironlake_dp_detect(struct intel_dp *intel_dp)
 {
        enum drm_connector_status status;
+       bool ret;
 
        /* Can't disconnect eDP, but you can close the lid... */
        if (is_edp(intel_dp)) {
@@ -1543,13 +1610,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
        }
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_dp,
-                                    0x000, intel_dp->dpcd,
-                                    sizeof (intel_dp->dpcd))
-           == sizeof(intel_dp->dpcd)) {
-               if (intel_dp->dpcd[0] != 0)
-                       status = connector_status_connected;
-       }
+       ret = intel_dp_aux_native_read_retry(intel_dp,
+                                            0x000, intel_dp->dpcd,
+                                            sizeof (intel_dp->dpcd));
+       if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0)
+               status = connector_status_connected;
        DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
                      intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
        return status;
@@ -1586,7 +1651,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
        if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd,
                                     sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
        {
-               if (intel_dp->dpcd[0] != 0)
+               if (intel_dp->dpcd[DP_DPCD_REV] != 0)
                        status = connector_status_connected;
        }
 
@@ -1790,8 +1855,7 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
        struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
 
-       if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON)
-               intel_dp_check_link_status(intel_dp);
+       intel_dp_check_link_status(intel_dp);
 }
 
 /* Return which DP Port should be selected for Transcoder DP control */
@@ -1859,7 +1923,6 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                return;
 
        intel_dp->output_reg = output_reg;
-       intel_dp->dpms_mode = -1;
 
        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
        if (!intel_connector) {
@@ -1954,8 +2017,9 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                                               sizeof(intel_dp->dpcd));
                ironlake_edp_panel_vdd_off(intel_dp);
                if (ret == sizeof(intel_dp->dpcd)) {
-                       if (intel_dp->dpcd[0] >= 0x11)
-                               dev_priv->no_aux_handshake = intel_dp->dpcd[3] &
+                       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
+                               dev_priv->no_aux_handshake =
+                                       intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
                                        DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
                } else {
                        /* if this fails, presume the device is a ghost */
index c0e0ee6..39ac2b6 100644 (file)
@@ -165,7 +165,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring);
 int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n);
 static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring)
 {
-       return intel_wait_ring_buffer(ring, ring->space - 8);
+       return intel_wait_ring_buffer(ring, ring->size - 8);
 }
 
 int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n);
index e8a5ffb..660f964 100644 (file)
@@ -985,17 +985,19 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
 {
        save->vga_control[0] = RREG32(D1VGA_CONTROL);
        save->vga_control[1] = RREG32(D2VGA_CONTROL);
-       save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
-       save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
-       save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
-       save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
        save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
        save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
        save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
        save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
+               save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
+               save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
                save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
                save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+       }
+       if (rdev->num_crtc >= 6) {
+               save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
+               save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
                save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
                save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
        }
@@ -1004,35 +1006,45 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
        WREG32(VGA_RENDER_CONTROL, 0);
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
        }
        WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
 
        WREG32(D1VGA_CONTROL, 0);
        WREG32(D2VGA_CONTROL, 0);
-       WREG32(EVERGREEN_D3VGA_CONTROL, 0);
-       WREG32(EVERGREEN_D4VGA_CONTROL, 0);
-       WREG32(EVERGREEN_D5VGA_CONTROL, 0);
-       WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+       if (rdev->num_crtc >= 4) {
+               WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+               WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+       }
+       if (rdev->num_crtc >= 6) {
+               WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+               WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+       }
 }
 
 void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1055,7 +1067,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
               (u32)rdev->mc.vram_start);
 
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
                       upper_32_bits(rdev->mc.vram_start));
                WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
@@ -1073,7 +1085,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
                       (u32)rdev->mc.vram_start);
                WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
                       (u32)rdev->mc.vram_start);
-
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
                       upper_32_bits(rdev->mc.vram_start));
                WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
@@ -1101,31 +1114,41 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
        /* Restore video state */
        WREG32(D1VGA_CONTROL, save->vga_control[0]);
        WREG32(D2VGA_CONTROL, save->vga_control[1]);
-       WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
-       WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
-       WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
-       WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+       if (rdev->num_crtc >= 4) {
+               WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
+               WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
+       }
+       if (rdev->num_crtc >= 6) {
+               WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
+               WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+       }
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
        }
        WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
        WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
                WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
        }
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
                WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
@@ -2417,18 +2440,22 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
        WREG32(GRBM_INT_CNTL, 0);
        WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
                WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
 
        WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
@@ -2547,19 +2574,25 @@ int evergreen_irq_set(struct radeon_device *rdev)
 
        WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
        WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (rdev->num_crtc >= 4) {
                WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
                WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
+       }
+       if (rdev->num_crtc >= 6) {
                WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
                WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
        }
 
        WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
        WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+       if (rdev->num_crtc >= 4) {
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
+       }
+       if (rdev->num_crtc >= 6) {
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+       }
 
        WREG32(DC_HPD1_INT_CONTROL, hpd1);
        WREG32(DC_HPD2_INT_CONTROL, hpd2);
@@ -2583,53 +2616,57 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev)
        rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
        rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
        rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
-       rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
-       rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
-       rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
-       rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+       if (rdev->num_crtc >= 4) {
+               rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+               rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+       }
+       if (rdev->num_crtc >= 6) {
+               rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+               rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+       }
 
        if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
                WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
        if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
                WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-       if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
-               WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-       if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
-               WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-       if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
-               WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-       if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
-               WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-
        if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
                WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
        if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
                WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
-
        if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
                WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
        if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)
                WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
 
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
-               WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
-               WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
-
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
-               WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
-               WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
-
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
-               WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
-               WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
-
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
-               WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
-       if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
-               WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+       if (rdev->num_crtc >= 4) {
+               if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
+                       WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+               if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
+                       WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+                       WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+                       WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
+                       WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
+                       WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
+       }
+
+       if (rdev->num_crtc >= 6) {
+               if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
+                       WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+               if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
+                       WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+                       WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+                       WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
+                       WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
+               if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
+                       WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+       }
 
        if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
                tmp = RREG32(DC_HPD1_INT_CONTROL);
@@ -3237,6 +3274,7 @@ void evergreen_fini(struct radeon_device *rdev)
        r700_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        evergreen_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
index 1636e34..b7b2714 100644 (file)
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
 #       define LB_D5_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD5_INTERRUPT                        (1 << 17)
 #       define DC_HPD5_RX_INTERRUPT                     (1 << 18)
-#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6050
+#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6150
 #       define LB_D6_VLINE_INTERRUPT                    (1 << 2)
 #       define LB_D6_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD6_INTERRUPT                        (1 << 17)
index 16caafe..559dbd4 100644 (file)
@@ -1581,6 +1581,7 @@ void cayman_fini(struct radeon_device *rdev)
        cayman_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        cayman_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
index f79d2cc..bc54b26 100644 (file)
@@ -2628,6 +2628,7 @@ void r600_fini(struct radeon_device *rdev)
        r600_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        r600_pcie_gart_fini(rdev);
        radeon_agp_fini(rdev);
index f140a0d..0245ae6 100644 (file)
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
index 8bb347d..4de5189 100644 (file)
@@ -1368,6 +1368,7 @@ void rv770_fini(struct radeon_device *rdev)
        r700_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        rv770_pcie_gart_fini(rdev);
        rv770_vram_scratch_fini(rdev);
index 1a6dfb6..d3b464b 100644 (file)
@@ -98,11 +98,16 @@ struct lm95241_data {
 };
 
 /* Conversions */
-static int TempFromReg(u8 val_h, u8 val_l)
+static int temp_from_reg_signed(u8 val_h, u8 val_l)
 {
-       if (val_h & 0x80)
-               return val_h - 0x100;
-       return val_h * 1000 + val_l * 1000 / 256;
+       s16 val_hl = (val_h << 8) | val_l;
+       return val_hl * 1000 / 256;
+}
+
+static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
+{
+       u16 val_hl = (val_h << 8) | val_l;
+       return val_hl * 1000 / 256;
 }
 
 static struct lm95241_data *lm95241_update_device(struct device *dev)
@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
        struct lm95241_data *data = lm95241_update_device(dev);
+       int index = to_sensor_dev_attr(attr)->index;
 
        return snprintf(buf, PAGE_SIZE - 1, "%d\n",
-               TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
-                           data->temp[to_sensor_dev_attr(attr)->index + 1]));
+                       index == 0 || (data->config & (1 << (index / 2))) ?
+               temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
+               temp_from_reg_unsigned(data->temp[index],
+                                      data->temp[index + 1]));
 }
 
 static ssize_t show_type(struct device *dev, struct device_attribute *attr,
@@ -339,7 +347,7 @@ static int lm95241_detect(struct i2c_client *new_client,
        if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
             == MANUFACTURER_ID)
            && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-               >= DEFAULT_REVISION)) {
+               == DEFAULT_REVISION)) {
                name = DEVNAME;
        } else {
                dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
index 931d940..9b1f0c3 100644 (file)
@@ -59,16 +59,17 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
                if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
                        info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
        }
-       if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
+       if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
                info->func[0] |= PMBUS_HAVE_TEMP;
-               if (pmbus_check_byte_register(client, 0,
-                                             PMBUS_STATUS_TEMPERATURE))
-                       info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
-       }
        if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
                info->func[0] |= PMBUS_HAVE_TEMP2;
        if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
                info->func[0] |= PMBUS_HAVE_TEMP3;
+       if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
+                            | PMBUS_HAVE_TEMP3)
+           && pmbus_check_byte_register(client, 0,
+                                        PMBUS_STATUS_TEMPERATURE))
+                       info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
 
        /* Sensors detected on all pages */
        for (page = 0; page < info->pages; page++) {
index 52b545a..cbc98ae 100644 (file)
@@ -193,7 +193,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
                return;
        }
        if (twi_int_status & MCOMP) {
-               if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+               if ((read_MASTER_CTL(iface) & MEN) == 0 &&
+                       (iface->cur_mode == TWI_I2C_MODE_REPEAT ||
+                       iface->cur_mode == TWI_I2C_MODE_COMBINED)) {
+                       iface->result = -1;
+                       write_INT_MASK(iface, 0);
+                       write_MASTER_CTL(iface, 0);
+               } else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
                        if (iface->readNum == 0) {
                                /* set the read number to 1 and ask for manual
                                 * stop in block combine mode
index 6c00c10..f84a63c 100644 (file)
@@ -248,12 +248,12 @@ static inline int is_msgend(struct s3c24xx_i2c *i2c)
        return i2c->msg_ptr >= i2c->msg->len;
 }
 
-/* i2s_s3c_irq_nextbyte
+/* i2c_s3c_irq_nextbyte
  *
  * process an interrupt and work out what to do
  */
 
-static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
+static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
 {
        unsigned long tmp;
        unsigned char byte;
@@ -264,7 +264,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
        case STATE_IDLE:
                dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
                goto out;
-               break;
 
        case STATE_STOP:
                dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
@@ -444,7 +443,7 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
        /* pretty much this leaves us with the fact that we've
         * transmitted or received whatever byte we last sent */
 
-       i2s_s3c_irq_nextbyte(i2c, status);
+       i2c_s3c_irq_nextbyte(i2c, status);
 
  out:
        return IRQ_HANDLED;
index 4d93196..fb3b4f8 100644 (file)
 #define I2C_CNFG_NEW_MASTER_FSM                        (1<<11)
 #define I2C_STATUS                             0x01C
 #define I2C_SL_CNFG                            0x020
+#define I2C_SL_CNFG_NACK                       (1<<1)
 #define I2C_SL_CNFG_NEWSL                      (1<<2)
 #define I2C_SL_ADDR1                           0x02c
+#define I2C_SL_ADDR2                           0x030
 #define I2C_TX_FIFO                            0x050
 #define I2C_RX_FIFO                            0x054
 #define I2C_PACKET_TRANSFER_STATUS             0x058
@@ -337,7 +339,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 
        if (!i2c_dev->is_dvc) {
                u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
-               i2c_writel(i2c_dev, sl_cfg | I2C_SL_CNFG_NEWSL, I2C_SL_CNFG);
+               sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
+               i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
+               i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
+               i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
+
        }
 
        val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
index d8d3a1e..a2c8746 100644 (file)
@@ -88,7 +88,7 @@ static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {
 
 static struct i2c_driver pca9532_driver = {
        .driver = {
-               .name = "pca953x",
+               .name = "leds-pca953x",
        },
        .probe = pca9532_probe,
        .remove = pca9532_remove,
index a97cf27..834a483 100644 (file)
@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv,
        if (0 != t->index)
                return -EINVAL;
 
-       bttv_call_all(btv, tuner, g_tuner, t);
+       bttv_call_all(btv, tuner, s_tuner, t);
        return 0;
 }
 
index 1933d4d..e80134f 100644 (file)
@@ -695,14 +695,10 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 
        cx18_call_all(cx, tuner, g_tuner, vt);
 
-       if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
+       if (vt->type == V4L2_TUNER_RADIO)
                strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
-               vt->type = V4L2_TUNER_RADIO;
-       } else {
+       else
                strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
-               vt->type = V4L2_TUNER_ANALOG_TV;
-       }
-
        return 0;
 }
 
index f9e347d..120c7d8 100644 (file)
@@ -1184,14 +1184,10 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 
        ivtv_call_all(itv, tuner, g_tuner, vt);
 
-       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+       if (vt->type == V4L2_TUNER_RADIO)
                strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
-               vt->type = V4L2_TUNER_RADIO;
-       } else {
+       else
                strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
-               vt->type = V4L2_TUNER_ANALOG_TV;
-       }
-
        return 0;
 }
 
index de5d481..c43c81f 100644 (file)
@@ -480,12 +480,14 @@ static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
        struct msp_state *state = to_state(sd);
        struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-       if (state->radio)
+       if (vt->type != V4L2_TUNER_ANALOG_TV)
                return 0;
-       if (state->opmode == OPMODE_AUTOSELECT)
-               msp_detect_stereo(client);
-       vt->audmode    = state->audmode;
-       vt->rxsubchans = state->rxsubchans;
+       if (!state->radio) {
+               if (state->opmode == OPMODE_AUTOSELECT)
+                       msp_detect_stereo(client);
+               vt->rxsubchans = state->rxsubchans;
+       }
+       vt->audmode = state->audmode;
        vt->capability |= V4L2_TUNER_CAP_STEREO |
                V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
        return 0;
index 9d0dd08..e98d382 100644 (file)
@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
        if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
                struct v4l2_tuner vt;
                memset(&vt, 0, sizeof(vt));
+               vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
                vt.audmode = hdw->audiomode_val;
                v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
        }
@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
 {
        struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
        memset(vtp, 0, sizeof(*vtp));
+       vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+               V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        hdw->tuner_signal_stale = 0;
        /* Note: There apparently is no replacement for VIDIOC_CROPCAP
           using v4l2-subdev - therefore we can't support that AT ALL right
index 9363ed9..cfa9f7e 100644 (file)
@@ -724,19 +724,15 @@ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
 }
 
 /**
- * set_mode_freq - Switch tuner to other mode.
- * @client:    struct i2c_client pointer
+ * set_mode - Switch tuner to other mode.
  * @t:         a pointer to the module's internal struct_tuner
  * @mode:      enum v4l2_type (radio or TV)
- * @freq:      frequency to set (0 means to use the previous one)
  *
  * If tuner doesn't support the needed mode (radio or TV), prints a
  * debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the state and sets frequency to the last value, if
- * the tuner can sleep or if it supports both Radio and TV.
+ * Otherwise, changes the mode and returns 0.
  */
-static int set_mode_freq(struct i2c_client *client, struct tuner *t,
-                        enum v4l2_tuner_type mode, unsigned int freq)
+static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
 {
        struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
@@ -752,17 +748,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t,
                t->mode = mode;
                tuner_dbg("Changing to mode %d\n", mode);
        }
+       return 0;
+}
+
+/**
+ * set_freq - Set the tuner to the desired frequency.
+ * @t:         a pointer to the module's internal struct_tuner
+ * @freq:      frequency to set (0 means to use the current frequency)
+ */
+static void set_freq(struct tuner *t, unsigned int freq)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
        if (t->mode == V4L2_TUNER_RADIO) {
-               if (freq)
-                       t->radio_freq = freq;
-               set_radio_freq(client, t->radio_freq);
+               if (!freq)
+                       freq = t->radio_freq;
+               set_radio_freq(client, freq);
        } else {
-               if (freq)
-                       t->tv_freq = freq;
-               set_tv_freq(client, t->tv_freq);
+               if (!freq)
+                       freq = t->tv_freq;
+               set_tv_freq(client, freq);
        }
-
-       return 0;
 }
 
 /*
@@ -817,7 +823,8 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 /**
  * tuner_fixup_std - force a given video standard variant
  *
- * @t: tuner internal struct
+ * @t: tuner internal struct
+ * @std:       TV standard
  *
  * A few devices or drivers have problem to detect some standard variations.
  * On other operational systems, the drivers generally have a per-country
@@ -827,57 +834,39 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
  * to distinguish all video standard variations, a modprobe parameter can
  * be used to force a video standard match.
  */
-static int tuner_fixup_std(struct tuner *t)
+static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std)
 {
-       if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
+       if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) {
                switch (pal[0]) {
                case '6':
-                       tuner_dbg("insmod fixup: PAL => PAL-60\n");
-                       t->std = V4L2_STD_PAL_60;
-                       break;
+                       return V4L2_STD_PAL_60;
                case 'b':
                case 'B':
                case 'g':
                case 'G':
-                       tuner_dbg("insmod fixup: PAL => PAL-BG\n");
-                       t->std = V4L2_STD_PAL_BG;
-                       break;
+                       return V4L2_STD_PAL_BG;
                case 'i':
                case 'I':
-                       tuner_dbg("insmod fixup: PAL => PAL-I\n");
-                       t->std = V4L2_STD_PAL_I;
-                       break;
+                       return V4L2_STD_PAL_I;
                case 'd':
                case 'D':
                case 'k':
                case 'K':
-                       tuner_dbg("insmod fixup: PAL => PAL-DK\n");
-                       t->std = V4L2_STD_PAL_DK;
-                       break;
+                       return V4L2_STD_PAL_DK;
                case 'M':
                case 'm':
-                       tuner_dbg("insmod fixup: PAL => PAL-M\n");
-                       t->std = V4L2_STD_PAL_M;
-                       break;
+                       return V4L2_STD_PAL_M;
                case 'N':
                case 'n':
-                       if (pal[1] == 'c' || pal[1] == 'C') {
-                               tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
-                               t->std = V4L2_STD_PAL_Nc;
-                       } else {
-                               tuner_dbg("insmod fixup: PAL => PAL-N\n");
-                               t->std = V4L2_STD_PAL_N;
-                       }
-                       break;
-               case '-':
-                       /* default parameter, do nothing */
-                       break;
+                       if (pal[1] == 'c' || pal[1] == 'C')
+                               return V4L2_STD_PAL_Nc;
+                       return V4L2_STD_PAL_N;
                default:
                        tuner_warn("pal= argument not recognised\n");
                        break;
                }
        }
-       if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+       if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
                switch (secam[0]) {
                case 'b':
                case 'B':
@@ -885,63 +874,42 @@ static int tuner_fixup_std(struct tuner *t)
                case 'G':
                case 'h':
                case 'H':
-                       tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
-                       t->std = V4L2_STD_SECAM_B |
-                                V4L2_STD_SECAM_G |
-                                V4L2_STD_SECAM_H;
-                       break;
+                       return V4L2_STD_SECAM_B |
+                              V4L2_STD_SECAM_G |
+                              V4L2_STD_SECAM_H;
                case 'd':
                case 'D':
                case 'k':
                case 'K':
-                       tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
-                       t->std = V4L2_STD_SECAM_DK;
-                       break;
+                       return V4L2_STD_SECAM_DK;
                case 'l':
                case 'L':
-                       if ((secam[1] == 'C') || (secam[1] == 'c')) {
-                               tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
-                               t->std = V4L2_STD_SECAM_LC;
-                       } else {
-                               tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
-                               t->std = V4L2_STD_SECAM_L;
-                       }
-                       break;
-               case '-':
-                       /* default parameter, do nothing */
-                       break;
+                       if ((secam[1] == 'C') || (secam[1] == 'c'))
+                               return V4L2_STD_SECAM_LC;
+                       return V4L2_STD_SECAM_L;
                default:
                        tuner_warn("secam= argument not recognised\n");
                        break;
                }
        }
 
-       if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+       if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
                switch (ntsc[0]) {
                case 'm':
                case 'M':
-                       tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
-                       t->std = V4L2_STD_NTSC_M;
-                       break;
+                       return V4L2_STD_NTSC_M;
                case 'j':
                case 'J':
-                       tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
-                       t->std = V4L2_STD_NTSC_M_JP;
-                       break;
+                       return V4L2_STD_NTSC_M_JP;
                case 'k':
                case 'K':
-                       tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
-                       t->std = V4L2_STD_NTSC_M_KR;
-                       break;
-               case '-':
-                       /* default parameter, do nothing */
-                       break;
+                       return V4L2_STD_NTSC_M_KR;
                default:
                        tuner_info("ntsc= argument not recognised\n");
                        break;
                }
        }
-       return 0;
+       return std;
 }
 
 /*
@@ -1058,10 +1026,9 @@ static void tuner_status(struct dvb_frontend *fe)
 static int tuner_s_radio(struct v4l2_subdev *sd)
 {
        struct tuner *t = to_tuner(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-       if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
-               return 0;
+       if (set_mode(t, V4L2_TUNER_RADIO) == 0)
+               set_freq(t, 0);
        return 0;
 }
 
@@ -1072,16 +1039,20 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
 /**
  * tuner_s_power - controls the power state of the tuner
  * @sd: pointer to struct v4l2_subdev
- * @on: a zero value puts the tuner to sleep
+ * @on: a zero value puts the tuner to sleep, non-zero wakes it up
  */
 static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
        struct tuner *t = to_tuner(sd);
        struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
-       /* FIXME: Why this function don't wake the tuner if on != 0 ? */
-       if (on)
+       if (on) {
+               if (t->standby && set_mode(t, t->mode) == 0) {
+                       tuner_dbg("Waking up tuner\n");
+                       set_freq(t, 0);
+               }
                return 0;
+       }
 
        tuner_dbg("Putting tuner to sleep\n");
        t->standby = true;
@@ -1093,28 +1064,36 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
 static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
        struct tuner *t = to_tuner(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-       if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
+       if (set_mode(t, V4L2_TUNER_ANALOG_TV))
                return 0;
 
-       t->std = std;
-       tuner_fixup_std(t);
-
+       t->std = tuner_fixup_std(t, std);
+       if (t->std != std)
+               tuner_dbg("Fixup standard %llx to %llx\n", std, t->std);
+       set_freq(t, 0);
        return 0;
 }
 
 static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 {
        struct tuner *t = to_tuner(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
-               return 0;
 
+       if (set_mode(t, f->type) == 0)
+               set_freq(t, f->frequency);
        return 0;
 }
 
+/**
+ * tuner_g_frequency - Get the tuned frequency for the tuner
+ * @sd: pointer to struct v4l2_subdev
+ * @f: pointer to struct v4l2_frequency
+ *
+ * At return, the structure f will be filled with tuner frequency
+ * if the tuner matches the f->type.
+ * Note: f->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 {
        struct tuner *t = to_tuner(sd);
@@ -1122,8 +1101,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 
        if (check_mode(t, f->type) == -EINVAL)
                return 0;
-       f->type = t->mode;
-       if (fe_tuner_ops->get_frequency && !t->standby) {
+       if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) {
                u32 abs_freq;
 
                fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
@@ -1131,12 +1109,22 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
                        DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
                        DIV_ROUND_CLOSEST(abs_freq, 62500);
        } else {
-               f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
+               f->frequency = (V4L2_TUNER_RADIO == f->type) ?
                        t->radio_freq : t->tv_freq;
        }
        return 0;
 }
 
+/**
+ * tuner_g_tuner - Fill in tuner information
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * At return, the structure vt will be filled with tuner information
+ * if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 {
        struct tuner *t = to_tuner(sd);
@@ -1145,48 +1133,58 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 
        if (check_mode(t, vt->type) == -EINVAL)
                return 0;
-       vt->type = t->mode;
-       if (analog_ops->get_afc)
+       if (vt->type == t->mode && analog_ops->get_afc)
                vt->afc = analog_ops->get_afc(&t->fe);
-       if (t->mode == V4L2_TUNER_ANALOG_TV)
+       if (vt->type == V4L2_TUNER_ANALOG_TV)
                vt->capability |= V4L2_TUNER_CAP_NORM;
-       if (t->mode != V4L2_TUNER_RADIO) {
+       if (vt->type != V4L2_TUNER_RADIO) {
                vt->rangelow = tv_range[0] * 16;
                vt->rangehigh = tv_range[1] * 16;
                return 0;
        }
 
        /* radio mode */
-       vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-       if (fe_tuner_ops->get_status) {
-               u32 tuner_status;
-
-               fe_tuner_ops->get_status(&t->fe, &tuner_status);
-               vt->rxsubchans =
-                       (tuner_status & TUNER_STATUS_STEREO) ?
-                       V4L2_TUNER_SUB_STEREO :
-                       V4L2_TUNER_SUB_MONO;
+       if (vt->type == t->mode) {
+               vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+               if (fe_tuner_ops->get_status) {
+                       u32 tuner_status;
+
+                       fe_tuner_ops->get_status(&t->fe, &tuner_status);
+                       vt->rxsubchans =
+                               (tuner_status & TUNER_STATUS_STEREO) ?
+                               V4L2_TUNER_SUB_STEREO :
+                               V4L2_TUNER_SUB_MONO;
+               }
+               if (analog_ops->has_signal)
+                       vt->signal = analog_ops->has_signal(&t->fe);
+               vt->audmode = t->audmode;
        }
-       if (analog_ops->has_signal)
-               vt->signal = analog_ops->has_signal(&t->fe);
        vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-       vt->audmode = t->audmode;
        vt->rangelow = radio_range[0] * 16000;
        vt->rangehigh = radio_range[1] * 16000;
 
        return 0;
 }
 
+/**
+ * tuner_s_tuner - Set the tuner's audio mode
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * Sets the audio mode if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 {
        struct tuner *t = to_tuner(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-       if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
+       if (set_mode(t, vt->type))
                return 0;
 
        if (t->mode == V4L2_TUNER_RADIO)
                t->audmode = vt->audmode;
+       set_freq(t, 0);
 
        return 0;
 }
@@ -1221,7 +1219,8 @@ static int tuner_resume(struct i2c_client *c)
        tuner_dbg("resume\n");
 
        if (!t->standby)
-               set_mode_freq(c, t, t->type, 0);
+               if (set_mode(t, t->mode) == 0)
+                       set_freq(t, 0);
 
        return 0;
 }
index 506edcc..69e8c6f 100644 (file)
@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file,
                if (!ops->vidioc_g_tuner)
                        break;
 
+               p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
                ret = ops->vidioc_g_tuner(file, fh, p);
                if (!ret)
                        dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file,
 
                if (!ops->vidioc_s_tuner)
                        break;
+               p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
                dbgarg(cmd, "index=%d, name=%s, type=%d, "
                                "capability=0x%x, rangelow=%d, "
                                "rangehigh=%d, signal=%d, afc=%d, "
@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file,
                if (!ops->vidioc_g_frequency)
                        break;
 
+               p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
                ret = ops->vidioc_g_frequency(file, fh, p);
                if (!ret)
                        dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1940,13 +1946,19 @@ static long __video_do_ioctl(struct file *file,
        case VIDIOC_S_HW_FREQ_SEEK:
        {
                struct v4l2_hw_freq_seek *p = arg;
+               enum v4l2_tuner_type type;
 
                if (!ops->vidioc_s_hw_freq_seek)
                        break;
+               type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
                dbgarg(cmd,
-                       "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
-                       p->tuner, p->type, p->seek_upward, p->wrap_around);
-               ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
+                       "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
+                       p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
+               if (p->type != type)
+                       ret = -EINVAL;
+               else
+                       ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
                break;
        }
        case VIDIOC_ENUM_FRAMESIZES:
index c27fd1f..c71ae09 100644 (file)
@@ -619,6 +619,7 @@ static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
 /* MFD cells (SPI, PWM, LED, DS1WM, MMC) */
 static struct ds1wm_driver_data ds1wm_pdata = {
        .active_high = 1,
+       .reset_recover_delay = 1,
 };
 
 static struct resource ds1wm_resources[] = {
index 2808bd1..04c7093 100644 (file)
@@ -99,6 +99,7 @@ static int ds1wm_disable(struct platform_device *pdev)
 
 static struct ds1wm_driver_data ds1wm_pdata = {
        .active_high = 0,
+       .reset_recover_delay = 1,
 };
 
 static struct resource ds1wm_resources[] __initdata = {
index 7721de9..fe14072 100644 (file)
@@ -582,6 +582,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
                        data->error = -EILSEQ;
                } else if (status & MCI_DATATIMEOUT) {
                        data->error = -ETIMEDOUT;
+               } else if (status & MCI_STARTBITERR) {
+                       data->error = -ECOMM;
                } else if (status & MCI_TXUNDERRUN) {
                        data->error = -EIO;
                } else if (status & MCI_RXOVERRUN) {
index bb32e21..2164e8c 100644 (file)
@@ -86,6 +86,7 @@
 #define MCI_CMDRESPEND         (1 << 6)
 #define MCI_CMDSENT            (1 << 7)
 #define MCI_DATAEND            (1 << 8)
+#define MCI_STARTBITERR                (1 << 9)
 #define MCI_DATABLOCKEND       (1 << 10)
 #define MCI_CMDACTIVE          (1 << 11)
 #define MCI_TXACTIVE           (1 << 12)
 #define MCI_CMDRESPENDCLR      (1 << 6)
 #define MCI_CMDSENTCLR         (1 << 7)
 #define MCI_DATAENDCLR         (1 << 8)
+#define MCI_STARTBITERRCLR     (1 << 9)
 #define MCI_DATABLOCKENDCLR    (1 << 10)
 /* Extended status bits for the ST Micro variants */
 #define MCI_ST_SDIOITC         (1 << 22)
 #define MCI_CMDRESPENDMASK     (1 << 6)
 #define MCI_CMDSENTMASK                (1 << 7)
 #define MCI_DATAENDMASK                (1 << 8)
+#define MCI_STARTBITERRMASK    (1 << 9)
 #define MCI_DATABLOCKENDMASK   (1 << 10)
 #define MCI_CMDACTIVEMASK      (1 << 11)
 #define MCI_TXACTIVEMASK       (1 << 12)
 #define MCI_IRQENABLE  \
        (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK|     \
        MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK|       \
-       MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
+       MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK)
 
 /* These interrupts are directed to IRQ1 when two IRQ lines are available */
 #define MCI_IRQ1MASK \
index 62172d5..f82383b 100644 (file)
@@ -107,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
                case AR5K_PKT_TYPE_BEACON:
                case AR5K_PKT_TYPE_PROBE_RESP:
                        frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
+                       break;
                case AR5K_PKT_TYPE_PIFS:
                        frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
+                       break;
                default:
                        frame_type = type;
+                       break;
                }
 
                tx_ctl->tx_control_0 |=
index 2c5b9b9..692671b 100644 (file)
@@ -3483,6 +3483,8 @@ static int __init pci_setup(char *str)
                                pci_no_msi();
                        } else if (!strcmp(str, "noaer")) {
                                pci_no_aer();
+                       } else if (!strncmp(str, "realloc", 7)) {
+                               pci_realloc();
                        } else if (!strcmp(str, "nodomains")) {
                                pci_no_domains();
                        } else if (!strncmp(str, "cbiosize=", 9)) {
index 731e202..3a39bf1 100644 (file)
@@ -146,6 +146,8 @@ static inline void pci_no_msi(void) { }
 static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
 #endif
 
+extern void pci_realloc(void);
+
 static inline int pci_no_d1d2(struct pci_dev *dev)
 {
        unsigned int parent_dstates = 0;
index 1e9e5a5..9995842 100644 (file)
@@ -47,6 +47,13 @@ struct resource_list_x {
        (head)->next = NULL;                            \
 } while (0)
 
+int pci_realloc_enable = 0;
+#define pci_realloc_enabled() pci_realloc_enable
+void pci_realloc(void)
+{
+       pci_realloc_enable = 1;
+}
+
 /**
  * add_to_list() - add a new resource tracker to the list
  * @head:      Head of the list
@@ -1025,6 +1032,7 @@ static int __init pci_get_max_depth(void)
        return depth;
 }
 
+
 /*
  * first try will not touch pci bridge res
  * second  and later try will clear small leaf bridge res
@@ -1068,6 +1076,13 @@ again:
        /* any device complain? */
        if (!head.next)
                goto enable_and_dump;
+
+       /* don't realloc if asked to do so */
+       if (!pci_realloc_enabled()) {
+               free_list(resource_list_x, &head);
+               goto enable_and_dump;
+       }
+
        failed_type = 0;
        for (list = head.next; list;) {
                failed_type |= list->flags;
index 712baab..e956f65 100644 (file)
@@ -76,10 +76,10 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
        if (skt->nr == 0)
-               gpio_request_array(vpac270_pcmcia_gpios,
+               gpio_free_array(vpac270_pcmcia_gpios,
                                        ARRAY_SIZE(vpac270_pcmcia_gpios));
        else
-               gpio_request_array(vpac270_cf_gpios,
+               gpio_free_array(vpac270_cf_gpios,
                                        ARRAY_SIZE(vpac270_cf_gpios));
 }
 
index 005417b..e1c4938 100644 (file)
@@ -1156,9 +1156,9 @@ static acpi_status wmid3_set_device_status(u32 value, u16 device)
        struct wmid3_gds_input_param params = {
                .function_num = 0x1,
                .hotkey_number = 0x01,
-               .devices = ACER_WMID3_GDS_WIRELESS &
-                               ACER_WMID3_GDS_THREEG &
-                               ACER_WMID3_GDS_WIMAX &
+               .devices = ACER_WMID3_GDS_WIRELESS |
+                               ACER_WMID3_GDS_THREEG |
+                               ACER_WMID3_GDS_WIMAX |
                                ACER_WMID3_GDS_BLUETOOTH,
        };
        struct acpi_buffer input = {
@@ -1445,6 +1445,8 @@ static void acer_wmi_notify(u32 value, void *context)
        union acpi_object *obj;
        struct event_return_value return_value;
        acpi_status status;
+       u16 device_state;
+       const struct key_entry *key;
 
        status = wmi_get_event_data(value, &response);
        if (status != AE_OK) {
@@ -1472,23 +1474,32 @@ static void acer_wmi_notify(u32 value, void *context)
 
        switch (return_value.function) {
        case WMID_HOTKEY_EVENT:
-               if (return_value.device_state) {
-                       u16 device_state = return_value.device_state;
-                       pr_debug("device state: 0x%x\n", device_state);
-                       if (has_cap(ACER_CAP_WIRELESS))
-                               rfkill_set_sw_state(wireless_rfkill,
-                               !(device_state & ACER_WMID3_GDS_WIRELESS));
-                       if (has_cap(ACER_CAP_BLUETOOTH))
-                               rfkill_set_sw_state(bluetooth_rfkill,
-                               !(device_state & ACER_WMID3_GDS_BLUETOOTH));
-                       if (has_cap(ACER_CAP_THREEG))
-                               rfkill_set_sw_state(threeg_rfkill,
-                               !(device_state & ACER_WMID3_GDS_THREEG));
-               }
-               if (!sparse_keymap_report_event(acer_wmi_input_dev,
-                               return_value.key_num, 1, true))
+               device_state = return_value.device_state;
+               pr_debug("device state: 0x%x\n", device_state);
+
+               key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
+                                                       return_value.key_num);
+               if (!key) {
                        pr_warn("Unknown key number - 0x%x\n",
                                return_value.key_num);
+               } else {
+                       switch (key->keycode) {
+                       case KEY_WLAN:
+                       case KEY_BLUETOOTH:
+                               if (has_cap(ACER_CAP_WIRELESS))
+                                       rfkill_set_sw_state(wireless_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_WIRELESS));
+                               if (has_cap(ACER_CAP_THREEG))
+                                       rfkill_set_sw_state(threeg_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_THREEG));
+                               if (has_cap(ACER_CAP_BLUETOOTH))
+                                       rfkill_set_sw_state(bluetooth_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_BLUETOOTH));
+                               break;
+                       }
+                       sparse_keymap_report_entry(acer_wmi_input_dev, key,
+                                                  1, true);
+               }
                break;
        default:
                pr_warn("Unknown function number - %d - %d\n",
index 00460cb..3c7857c 100644 (file)
@@ -1025,6 +1025,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
                return power;
 
        memset(&props, 0, sizeof(struct backlight_properties));
+       props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = max;
        bd = backlight_device_register(asus->driver->name,
                                       &asus->platform_device->dev, asus,
index 3f204fd..8877b83 100644 (file)
@@ -1030,8 +1030,10 @@ static int __devinit compal_probe(struct platform_device *pdev)
        initialize_fan_control_data(data);
 
        err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group);
-       if (err)
+       if (err) {
+               kfree(data);
                return err;
+       }
 
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
        if (IS_ERR(data->hwmon_dev)) {
index d3841de..e39ab1d 100644 (file)
@@ -292,12 +292,9 @@ static int dell_rfkill_set(void *data, bool blocked)
        dell_send_request(buffer, 17, 11);
 
        /* If the hardware switch controls this radio, and the hardware
-          switch is disabled, don't allow changing the software state.
-          If the hardware switch is reported as not supported, always
-          fire the SMI to toggle the killswitch. */
+          switch is disabled, don't allow changing the software state */
        if ((hwswitch_state & BIT(hwswitch_bit)) &&
-           !(buffer->output[1] & BIT(16)) &&
-           (buffer->output[1] & BIT(0))) {
+           !(buffer->output[1] & BIT(16))) {
                ret = -EINVAL;
                goto out;
        }
@@ -403,23 +400,6 @@ static const struct file_operations dell_debugfs_fops = {
 
 static void dell_update_rfkill(struct work_struct *ignored)
 {
-       int status;
-
-       get_buffer();
-       dell_send_request(buffer, 17, 11);
-       status = buffer->output[1];
-       release_buffer();
-
-       /* if hardware rfkill is not supported, set it explicitly */
-       if (!(status & BIT(0))) {
-               if (wifi_rfkill)
-                       dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
-               if (bluetooth_rfkill)
-                       dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
-               if (wwan_rfkill)
-                       dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
-       }
-
        if (wifi_rfkill)
                dell_rfkill_query(wifi_rfkill, (void *)1);
        if (bluetooth_rfkill)
@@ -560,11 +540,11 @@ static int dell_get_intensity(struct backlight_device *bd)
        else
                dell_send_request(buffer, 0, 1);
 
+       ret = buffer->output[1];
+
 out:
        release_buffer();
-       if (ret)
-               return ret;
-       return buffer->output[1];
+       return ret;
 }
 
 static const struct backlight_ops dell_ops = {
index f94017b..e2faa3c 100644 (file)
@@ -207,6 +207,7 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
        };
        struct acpi_buffer input = { sizeof(struct bios_args), &args };
        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       u32 rc;
 
        if (WARN_ON(insize > sizeof(args.data)))
                return -EINVAL;
@@ -224,13 +225,13 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
        }
 
        bios_return = (struct bios_return *)obj->buffer.pointer;
+       rc = bios_return->return_code;
 
-       if (bios_return->return_code) {
-               if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE)
-                       pr_warn("query 0x%x returned error 0x%x\n",
-                               query, bios_return->return_code);
+       if (rc) {
+               if (rc != HPWMI_RET_UNKNOWN_CMDTYPE)
+                       pr_warn("query 0x%x returned error 0x%x\n", query, rc);
                kfree(obj);
-               return bios_return->return_code;
+               return rc;
        }
 
        if (!outsize) {
index e936364..7f88c79 100644 (file)
@@ -250,6 +250,7 @@ static int oaktrail_backlight_init(void)
        struct backlight_properties props;
 
        memset(&props, 0, sizeof(struct backlight_properties));
+       props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX;
        bd = backlight_device_register(DRIVER_NAME,
                                       &oaktrail_device->dev, NULL,
index 77f6e70..26c5b11 100644 (file)
@@ -184,6 +184,10 @@ enum tpacpi_hkey_event_t {
 
        /* Misc bay events */
        TP_HKEY_EV_OPTDRV_EJ            = 0x3006, /* opt. drive tray ejected */
+       TP_HKEY_EV_HOTPLUG_DOCK         = 0x4010, /* docked into hotplug dock
+                                                    or port replicator */
+       TP_HKEY_EV_HOTPLUG_UNDOCK       = 0x4011, /* undocked from hotplug
+                                                    dock or port replicator */
 
        /* User-interface events */
        TP_HKEY_EV_LID_CLOSE            = 0x5001, /* laptop lid closed */
@@ -194,6 +198,10 @@ enum tpacpi_hkey_event_t {
        TP_HKEY_EV_PEN_REMOVED          = 0x500c, /* tablet pen removed */
        TP_HKEY_EV_BRGHT_CHANGED        = 0x5010, /* backlight control event */
 
+       /* Key-related user-interface events */
+       TP_HKEY_EV_KEY_NUMLOCK          = 0x6000, /* NumLock key pressed */
+       TP_HKEY_EV_KEY_FN               = 0x6005, /* Fn key pressed? E420 */
+
        /* Thermal events */
        TP_HKEY_EV_ALARM_BAT_HOT        = 0x6011, /* battery too hot */
        TP_HKEY_EV_ALARM_BAT_XHOT       = 0x6012, /* battery critically hot */
@@ -201,6 +209,10 @@ enum tpacpi_hkey_event_t {
        TP_HKEY_EV_ALARM_SENSOR_XHOT    = 0x6022, /* sensor critically hot */
        TP_HKEY_EV_THM_TABLE_CHANGED    = 0x6030, /* thermal table changed */
 
+       TP_HKEY_EV_UNK_6040             = 0x6040, /* Related to AC change?
+                                                    some sort of APM hint,
+                                                    W520 */
+
        /* Misc */
        TP_HKEY_EV_RFKILL_CHANGED       = 0x7000, /* rfkill switch changed */
 };
@@ -3513,6 +3525,34 @@ static bool hotkey_notify_wakeup(const u32 hkey,
        return true;
 }
 
+static bool hotkey_notify_dockevent(const u32 hkey,
+                                bool *send_acpi_ev,
+                                bool *ignore_acpi_ev)
+{
+       /* 0x4000-0x4FFF: dock-related events */
+       *send_acpi_ev = true;
+       *ignore_acpi_ev = false;
+
+       switch (hkey) {
+       case TP_HKEY_EV_UNDOCK_ACK:
+               /* ACPI undock operation completed after wakeup */
+               hotkey_autosleep_ack = 1;
+               pr_info("undocked\n");
+               hotkey_wakeup_hotunplug_complete_notify_change();
+               return true;
+
+       case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */
+               pr_info("docked into hotplug port replicator\n");
+               return true;
+       case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */
+               pr_info("undocked from hotplug port replicator\n");
+               return true;
+
+       default:
+               return false;
+       }
+}
+
 static bool hotkey_notify_usrevent(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
@@ -3547,13 +3587,13 @@ static bool hotkey_notify_usrevent(const u32 hkey,
 
 static void thermal_dump_all_sensors(void);
 
-static bool hotkey_notify_thermal(const u32 hkey,
+static bool hotkey_notify_6xxx(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
 {
        bool known = true;
 
-       /* 0x6000-0x6FFF: thermal alarms */
+       /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */
        *send_acpi_ev = true;
        *ignore_acpi_ev = false;
 
@@ -3582,8 +3622,17 @@ static bool hotkey_notify_thermal(const u32 hkey,
                         "a sensor reports something is extremely hot!\n");
                /* recommended action: immediate sleep/hibernate */
                break;
+
+       case TP_HKEY_EV_KEY_NUMLOCK:
+       case TP_HKEY_EV_KEY_FN:
+               /* key press events, we just ignore them as long as the EC
+                * is still reporting them in the normal keyboard stream */
+               *send_acpi_ev = false;
+               *ignore_acpi_ev = true;
+               return true;
+
        default:
-               pr_alert("THERMAL ALERT: unknown thermal alarm received\n");
+               pr_warn("unknown possible thermal alarm or keyboard event received\n");
                known = false;
        }
 
@@ -3652,15 +3701,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                        }
                        break;
                case 4:
-                       /* 0x4000-0x4FFF: dock-related wakeups */
-                       if (hkey == TP_HKEY_EV_UNDOCK_ACK) {
-                               hotkey_autosleep_ack = 1;
-                               pr_info("undocked\n");
-                               hotkey_wakeup_hotunplug_complete_notify_change();
-                               known_ev = true;
-                       } else {
-                               known_ev = false;
-                       }
+                       /* 0x4000-0x4FFF: dock-related events */
+                       known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev,
+                                               &ignore_acpi_ev);
                        break;
                case 5:
                        /* 0x5000-0x5FFF: human interface helpers */
@@ -3668,8 +3711,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                                                 &ignore_acpi_ev);
                        break;
                case 6:
-                       /* 0x6000-0x6FFF: thermal alarms */
-                       known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
+                       /* 0x6000-0x6FFF: thermal alarms/notices and
+                        *                keyboard events */
+                       known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,
                                                 &ignore_acpi_ev);
                        break;
                case 7:
index e5f7b8f..2bb8f45 100644 (file)
@@ -266,7 +266,7 @@ static struct regulator_ops db8500_regulator_switch_ops = {
  * Regulator information
  */
 static struct db8500_regulator_info
-               db8500_regulator_info[DB8500_NUM_REGULATORS] = {
+db8500_regulator_info[DB8500_NUM_REGULATORS] = {
        [DB8500_REGULATOR_VAPE] = {
                .desc = {
                        .name   = "db8500-vape",
@@ -492,11 +492,9 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
                                info->desc.name, err);
 
                        /* if failing, unregister all earlier regulators */
-                       i--;
-                       while (i >= 0) {
+                       while (--i >= 0) {
                                info = &db8500_regulator_info[i];
                                regulator_unregister(info->rdev);
-                               i--;
                        }
                        return err;
                }
@@ -536,13 +534,7 @@ static struct platform_driver db8500_regulator_driver = {
 
 static int __init db8500_regulator_init(void)
 {
-       int ret;
-
-       ret = platform_driver_register(&db8500_regulator_driver);
-       if (ret < 0)
-               return -ENODEV;
-
-       return 0;
+       return platform_driver_register(&db8500_regulator_driver);
 }
 
 static void __exit db8500_regulator_exit(void)
index daff7fd..486ed81 100644 (file)
@@ -139,7 +139,7 @@ static int max8952_set_voltage(struct regulator_dev *rdev,
        s8 vid = -1, i;
 
        if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
-                       !gpio_is_valid(max8952->pdata->gpio_vid0)) {
+                       !gpio_is_valid(max8952->pdata->gpio_vid1)) {
                /* DVS not supported */
                return -EPERM;
        }
index 10d5a1d..ad6628c 100644 (file)
@@ -39,25 +39,28 @@ struct max8997_data {
        struct regulator_dev **rdev;
        int ramp_delay; /* in mV/us */
 
+       bool buck1_gpiodvs;
+       bool buck2_gpiodvs;
+       bool buck5_gpiodvs;
        u8 buck1_vol[8];
        u8 buck2_vol[8];
        u8 buck5_vol[8];
+       int buck125_gpios[3];
        int buck125_gpioindex;
+       bool ignore_gpiodvs_side_effect;
 
        u8 saved_states[MAX8997_REG_MAX];
 };
 
 static inline void max8997_set_gpio(struct max8997_data *max8997)
 {
-       struct max8997_platform_data *pdata =
-               dev_get_platdata(max8997->iodev->dev);
        int set3 = (max8997->buck125_gpioindex) & 0x1;
        int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
        int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
 
-       gpio_set_value(pdata->buck125_gpios[0], set1);
-       gpio_set_value(pdata->buck125_gpios[1], set2);
-       gpio_set_value(pdata->buck125_gpios[2], set3);
+       gpio_set_value(max8997->buck125_gpios[0], set1);
+       gpio_set_value(max8997->buck125_gpios[1], set2);
+       gpio_set_value(max8997->buck125_gpios[2], set3);
 }
 
 struct voltage_map_desc {
@@ -380,8 +383,6 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
 static int max8997_get_voltage(struct regulator_dev *rdev)
 {
        struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-       struct max8997_platform_data *pdata =
-               dev_get_platdata(max8997->iodev->dev);
        struct i2c_client *i2c = max8997->iodev->i2c;
        int reg, shift, mask, ret;
        int rid = max8997_get_rid(rdev);
@@ -391,9 +392,9 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
        if (ret)
                return ret;
 
-       if ((rid == MAX8997_BUCK1 && pdata->buck1_gpiodvs) ||
-                       (rid == MAX8997_BUCK2 && pdata->buck2_gpiodvs) ||
-                       (rid == MAX8997_BUCK5 && pdata->buck5_gpiodvs))
+       if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) ||
+                       (rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) ||
+                       (rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs))
                reg += max8997->buck125_gpioindex;
 
        ret = max8997_read_reg(i2c, reg, &val);
@@ -543,7 +544,8 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev,
                        rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) {
                /* If the voltage is increasing */
                if (org < i)
-                       udelay(desc->step * (i - org) / max8997->ramp_delay);
+                       udelay(DIV_ROUND_UP(desc->step * (i - org),
+                                               max8997->ramp_delay));
        }
 
        return ret;
@@ -561,8 +563,6 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev,
                u8 new_val, int *best)
 {
        struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-       struct max8997_platform_data *pdata =
-               dev_get_platdata(max8997->iodev->dev);
        int rid = max8997_get_rid(rdev);
        u8 *buckx_val[3];
        bool buckx_gpiodvs[3];
@@ -589,9 +589,9 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev,
        buckx_val[0] = max8997->buck1_vol;
        buckx_val[1] = max8997->buck2_vol;
        buckx_val[2] = max8997->buck5_vol;
-       buckx_gpiodvs[0] = pdata->buck1_gpiodvs;
-       buckx_gpiodvs[1] = pdata->buck2_gpiodvs;
-       buckx_gpiodvs[2] = pdata->buck5_gpiodvs;
+       buckx_gpiodvs[0] = max8997->buck1_gpiodvs;
+       buckx_gpiodvs[1] = max8997->buck2_gpiodvs;
+       buckx_gpiodvs[2] = max8997->buck5_gpiodvs;
 
        for (i = 0; i < 8; i++) {
                int others;
@@ -640,8 +640,6 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
                int min_uV, int max_uV, unsigned *selector)
 {
        struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-       struct max8997_platform_data *pdata =
-               dev_get_platdata(max8997->iodev->dev);
        int rid = max8997_get_rid(rdev);
        const struct voltage_map_desc *desc;
        int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
@@ -653,15 +651,15 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
 
        switch (rid) {
        case MAX8997_BUCK1:
-               if (pdata->buck1_gpiodvs)
+               if (max8997->buck1_gpiodvs)
                        gpio_dvs_mode = true;
                break;
        case MAX8997_BUCK2:
-               if (pdata->buck2_gpiodvs)
+               if (max8997->buck2_gpiodvs)
                        gpio_dvs_mode = true;
                break;
        case MAX8997_BUCK5:
-               if (pdata->buck5_gpiodvs)
+               if (max8997->buck5_gpiodvs)
                        gpio_dvs_mode = true;
                break;
        }
@@ -695,7 +693,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
        new_idx = tmp_idx;
        new_val = tmp_val;
 
-       if (pdata->ignore_gpiodvs_side_effect == false)
+       if (max8997->ignore_gpiodvs_side_effect == false)
                return -EINVAL;
 
        dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:"
@@ -993,6 +991,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
        i2c = max8997->iodev->i2c;
 
        max8997->buck125_gpioindex = pdata->buck125_default_idx;
+       max8997->buck1_gpiodvs = pdata->buck1_gpiodvs;
+       max8997->buck2_gpiodvs = pdata->buck2_gpiodvs;
+       max8997->buck5_gpiodvs = pdata->buck5_gpiodvs;
+       memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3);
+       max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect;
 
        for (i = 0; i < 8; i++) {
                max8997->buck1_vol[i] = ret =
@@ -1124,6 +1127,10 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
                                0x3f);
        }
 
+       /* Misc Settings */
+       max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
+       max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
+
        for (i = 0; i < pdata->num_regulators; i++) {
                const struct voltage_map_desc *desc;
                int id = pdata->regulators[i].id;
@@ -1148,10 +1155,6 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
                }
        }
 
-       /* Misc Settings */
-       max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
-       max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
-
        return 0;
 err:
        for (i = 0; i < max8997->num_regulators; i++)
index 795828b..8945e20 100644 (file)
                                        (((i)->fifo_lvl_mask + 1))) \
                                        ? 1 : 0)
 
-#define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \
-                                       (((i)->fifo_lvl_mask + 1) << 1)) \
-                                       ? 1 : 0)
+#define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & (1 << (i)->tx_st_done)) ? 1 : 0)
 #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask)
 #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask)
 
index e0719b4..0b5ec23 100644 (file)
@@ -1147,6 +1147,14 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
         * any drivers bound to them (a key side effect)
         */
        if (dev->actconfig) {
+               /*
+                * FIXME: In order to avoid self-deadlock involving the
+                * bandwidth_mutex, we have to mark all the interfaces
+                * before unregistering any of them.
+                */
+               for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
+                       dev->actconfig->interface[i]->unregistering = 1;
+
                for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
                        struct usb_interface    *interface;
 
@@ -1156,7 +1164,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                                continue;
                        dev_dbg(&dev->dev, "unregistering interface %s\n",
                                dev_name(&interface->dev));
-                       interface->unregistering = 1;
                        remove_intf_ep_devs(interface);
                        device_del(&interface->dev);
                }
index ad57593..a0c8965 100644 (file)
@@ -109,6 +109,7 @@ struct ds1wm_data {
        /* byte to write that makes all intr disabled, */
        /* considering active_state (IAS) (optimization) */
        u8       int_en_reg_none;
+       unsigned int reset_recover_delay; /* see ds1wm.h */
 };
 
 static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
@@ -187,6 +188,9 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
                return 1;
        }
 
+       if (ds1wm_data->reset_recover_delay)
+               msleep(ds1wm_data->reset_recover_delay);
+
        return 0;
 }
 
@@ -490,6 +494,7 @@ static int ds1wm_probe(struct platform_device *pdev)
        }
        ds1wm_data->irq = res->start;
        ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
+       ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
 
        if (res->flags & IORESOURCE_IRQ_HIGHEDGE)
                irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
index f30ac05..3b859a3 100644 (file)
@@ -1335,6 +1335,11 @@ struct btrfs_ioctl_defrag_range_args {
  */
 #define BTRFS_STRING_ITEM_KEY  253
 
+/*
+ * Flags for mount options.
+ *
+ * Note: don't forget to add new options to btrfs_show_options()
+ */
 #define BTRFS_MOUNT_NODATASUM          (1 << 0)
 #define BTRFS_MOUNT_NODATACOW          (1 << 1)
 #define BTRFS_MOUNT_NOBARRIER          (1 << 2)
index d340f63..3601f0a 100644 (file)
@@ -2678,12 +2678,14 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
        int ret;
 
        /*
-        * If root is tree root, it means this inode is used to
-        * store free space information. And these inodes are updated
-        * when committing the transaction, so they needn't delaye to
-        * be updated, or deadlock will occured.
+        * If the inode is a free space inode, we can deadlock during commit
+        * if we put it into the delayed code.
+        *
+        * The data relocation inode should also be directly updated
+        * without delay
         */
-       if (!is_free_space_inode(root, inode)) {
+       if (!is_free_space_inode(root, inode)
+           && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
                ret = btrfs_delayed_update_inode(trans, root, inode);
                if (!ret)
                        btrfs_set_inode_last_trans(trans, inode);
index 0bb4ebb..15634d4 100644 (file)
@@ -723,6 +723,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
                seq_puts(seq, ",clear_cache");
        if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
                seq_puts(seq, ",user_subvol_rm_allowed");
+       if (btrfs_test_opt(root, ENOSPC_DEBUG))
+               seq_puts(seq, ",enospc_debug");
+       if (btrfs_test_opt(root, AUTO_DEFRAG))
+               seq_puts(seq, ",autodefrag");
+       if (btrfs_test_opt(root, INODE_MAP_CACHE))
+               seq_puts(seq, ",inode_cache");
        return 0;
 }
 
index 1efa56e..19450bc 100644 (file)
@@ -2098,7 +2098,8 @@ int btrfs_balance(struct btrfs_root *dev_root)
                                           chunk_root->root_key.objectid,
                                           found_key.objectid,
                                           found_key.offset);
-               BUG_ON(ret && ret != -ENOSPC);
+               if (ret && ret != -ENOSPC)
+                       goto error;
                key.offset = found_key.offset - 1;
        }
        ret = 0;
index 35f9154..3e29899 100644 (file)
@@ -649,9 +649,9 @@ cifs_do_mount(struct file_system_type *fs_type,
 
        cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
 
-       rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
-       if (rc)
-               return ERR_PTR(rc);
+       volume_info = cifs_get_volume_info((char *)data, dev_name);
+       if (IS_ERR(volume_info))
+               return ERR_CAST(volume_info);
 
        cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
        if (cifs_sb == NULL) {
@@ -713,7 +713,7 @@ cifs_do_mount(struct file_system_type *fs_type,
 out_super:
        deactivate_locked_super(sb);
 out:
-       cifs_cleanup_volume_info(&volume_info);
+       cifs_cleanup_volume_info(volume_info);
        return root;
 
 out_mountdata:
index 257f312..8df28e9 100644 (file)
@@ -154,9 +154,9 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
 extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
                               struct cifs_sb_info *cifs_sb);
 extern int cifs_match_super(struct super_block *, void *);
-extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info);
-extern int cifs_setup_volume_info(struct smb_vol **pvolume_info,
-                                 char *mount_data, const char *devname);
+extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info);
+extern struct smb_vol *cifs_get_volume_info(char *mount_data,
+                                           const char *devname);
 extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
 extern void cifs_umount(struct cifs_sb_info *);
 extern void cifs_dfs_release_automount_timer(void);
index c8cb83e..dbd669c 100644 (file)
@@ -65,6 +65,8 @@ static int ip_connect(struct TCP_Server_Info *server);
 static int generic_ip_connect(struct TCP_Server_Info *server);
 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
 static void cifs_prune_tlinks(struct work_struct *work);
+static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
+                                       const char *devname);
 
 /*
  * cifs tcp session reconnection
@@ -2240,8 +2242,8 @@ cifs_match_super(struct super_block *sb, void *data)
 
        rc = compare_mount_options(sb, mnt_data);
 out:
-       cifs_put_tlink(tlink);
        spin_unlock(&cifs_tcp_ses_lock);
+       cifs_put_tlink(tlink);
        return rc;
 }
 
@@ -2830,15 +2832,9 @@ is_path_accessible(int xid, struct cifs_tcon *tcon,
        return rc;
 }
 
-void
-cifs_cleanup_volume_info(struct smb_vol **pvolume_info)
+static void
+cleanup_volume_info_contents(struct smb_vol *volume_info)
 {
-       struct smb_vol *volume_info;
-
-       if (!pvolume_info || !*pvolume_info)
-               return;
-
-       volume_info = *pvolume_info;
        kfree(volume_info->username);
        kzfree(volume_info->password);
        kfree(volume_info->UNC);
@@ -2846,28 +2842,44 @@ cifs_cleanup_volume_info(struct smb_vol **pvolume_info)
        kfree(volume_info->domainname);
        kfree(volume_info->iocharset);
        kfree(volume_info->prepath);
+}
+
+void
+cifs_cleanup_volume_info(struct smb_vol *volume_info)
+{
+       if (!volume_info)
+               return;
+       cleanup_volume_info_contents(volume_info);
        kfree(volume_info);
-       *pvolume_info = NULL;
-       return;
 }
 
+
 #ifdef CONFIG_CIFS_DFS_UPCALL
 /* build_path_to_root returns full path to root when
  * we do not have an exiting connection (tcon) */
 static char *
-build_unc_path_to_root(const struct smb_vol *volume_info,
+build_unc_path_to_root(const struct smb_vol *vol,
                const struct cifs_sb_info *cifs_sb)
 {
-       char *full_path;
+       char *full_path, *pos;
+       unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0;
+       unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
 
-       int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
-       full_path = kmalloc(unc_len + 1, GFP_KERNEL);
+       full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
        if (full_path == NULL)
                return ERR_PTR(-ENOMEM);
 
-       strncpy(full_path, volume_info->UNC, unc_len);
-       full_path[unc_len] = 0; /* add trailing null */
+       strncpy(full_path, vol->UNC, unc_len);
+       pos = full_path + unc_len;
+
+       if (pplen) {
+               strncpy(pos, vol->prepath, pplen);
+               pos += pplen;
+       }
+
+       *pos = '\0'; /* add trailing null */
        convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
+       cFYI(1, "%s: full_path=%s", __func__, full_path);
        return full_path;
 }
 
@@ -2910,15 +2922,18 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo,
                                                   &fake_devname);
 
                free_dfs_info_array(referrals, num_referrals);
-               kfree(fake_devname);
-
-               if (cifs_sb->mountdata != NULL)
-                       kfree(cifs_sb->mountdata);
 
                if (IS_ERR(mdata)) {
                        rc = PTR_ERR(mdata);
                        mdata = NULL;
+               } else {
+                       cleanup_volume_info_contents(volume_info);
+                       memset(volume_info, '\0', sizeof(*volume_info));
+                       rc = cifs_setup_volume_info(volume_info, mdata,
+                                                       fake_devname);
                }
+               kfree(fake_devname);
+               kfree(cifs_sb->mountdata);
                cifs_sb->mountdata = mdata;
        }
        kfree(full_path);
@@ -2926,33 +2941,20 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo,
 }
 #endif
 
-int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
-                          const char *devname)
+static int
+cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
+                       const char *devname)
 {
-       struct smb_vol *volume_info;
        int rc = 0;
 
-       *pvolume_info = NULL;
-
-       volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
-       if (!volume_info) {
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       if (cifs_parse_mount_options(mount_data, devname,
-                                    volume_info)) {
-               rc = -EINVAL;
-               goto out;
-       }
+       if (cifs_parse_mount_options(mount_data, devname, volume_info))
+               return -EINVAL;
 
        if (volume_info->nullauth) {
                cFYI(1, "null user");
                volume_info->username = kzalloc(1, GFP_KERNEL);
-               if (volume_info->username == NULL) {
-                       rc = -ENOMEM;
-                       goto out;
-               }
+               if (volume_info->username == NULL)
+                       return -ENOMEM;
        } else if (volume_info->username) {
                /* BB fixme parse for domain name here */
                cFYI(1, "Username: %s", volume_info->username);
@@ -2960,8 +2962,7 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
                cifserror("No username specified");
        /* In userspace mount helper we can get user name from alternate
           locations such as env variables and files on disk */
-               rc = -EINVAL;
-               goto out;
+               return -EINVAL;
        }
 
        /* this is needed for ASCII cp to Unicode converts */
@@ -2973,18 +2974,32 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
                if (volume_info->local_nls == NULL) {
                        cERROR(1, "CIFS mount error: iocharset %s not found",
                                 volume_info->iocharset);
-                       rc = -ELIBACC;
-                       goto out;
+                       return -ELIBACC;
                }
        }
 
-       *pvolume_info = volume_info;
-       return rc;
-out:
-       cifs_cleanup_volume_info(&volume_info);
        return rc;
 }
 
+struct smb_vol *
+cifs_get_volume_info(char *mount_data, const char *devname)
+{
+       int rc;
+       struct smb_vol *volume_info;
+
+       volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
+       if (!volume_info)
+               return ERR_PTR(-ENOMEM);
+
+       rc = cifs_setup_volume_info(volume_info, mount_data, devname);
+       if (rc) {
+               cifs_cleanup_volume_info(volume_info);
+               volume_info = ERR_PTR(rc);
+       }
+
+       return volume_info;
+}
+
 int
 cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
 {
@@ -2997,6 +3012,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
        struct tcon_link *tlink;
 #ifdef CONFIG_CIFS_DFS_UPCALL
        int referral_walks_count = 0;
+#endif
 
        rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
        if (rc)
@@ -3004,6 +3020,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
 
        cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
 
+#ifdef CONFIG_CIFS_DFS_UPCALL
 try_mount_again:
        /* cleanup activities if we're chasing a referral */
        if (referral_walks_count) {
@@ -3012,7 +3029,6 @@ try_mount_again:
                else if (pSesInfo)
                        cifs_put_smb_ses(pSesInfo);
 
-               cifs_cleanup_volume_info(&volume_info);
                FreeXid(xid);
        }
 #endif
index 09983a3..b1e88d5 100644 (file)
@@ -681,15 +681,15 @@ xfs_inode_item_unlock(
  * where the cluster buffer may be unpinned before the inode is inserted into
  * the AIL during transaction committed processing. If the buffer is unpinned
  * before the inode item has been committed and inserted, then it is possible
- * for the buffer to be written and IO completions before the inode is inserted
+ * for the buffer to be written and IO completes before the inode is inserted
  * into the AIL. In that case, we'd be inserting a clean, stale inode into the
  * AIL which will never get removed. It will, however, get reclaimed which
  * triggers an assert in xfs_inode_free() complaining about freein an inode
  * still in the AIL.
  *
- * To avoid this, return a lower LSN than the one passed in so that the
- * transaction committed code will not move the inode forward in the AIL but
- * will still unpin it properly.
+ * To avoid this, just unpin the inode directly and return a LSN of -1 so the
+ * transaction committed code knows that it does not need to do any further
+ * processing on the item.
  */
 STATIC xfs_lsn_t
 xfs_inode_item_committed(
@@ -699,8 +699,10 @@ xfs_inode_item_committed(
        struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
 
-       if (xfs_iflags_test(ip, XFS_ISTALE))
-               return lsn - 1;
+       if (xfs_iflags_test(ip, XFS_ISTALE)) {
+               xfs_inode_item_unpin(lip, 0);
+               return -1;
+       }
        return lsn;
 }
 
index 7c7bc2b..c83f63b 100644 (file)
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed(
                lip->li_flags |= XFS_LI_ABORTED;
        item_lsn = IOP_COMMITTED(lip, commit_lsn);
 
-       /* If the committed routine returns -1, item has been freed. */
+       /* item_lsn of -1 means the item needs no further processing */
        if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
                return;
 
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk(
                        lip->li_flags |= XFS_LI_ABORTED;
                item_lsn = IOP_COMMITTED(lip, commit_lsn);
 
-               /* item_lsn of -1 means the item was freed */
+               /* item_lsn of -1 means the item needs no further processing */
                if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
                        continue;
 
index 8b45384..baa397e 100644 (file)
@@ -676,7 +676,8 @@ void irq_gc_mask_disable_reg(struct irq_data *d);
 void irq_gc_mask_set_bit(struct irq_data *d);
 void irq_gc_mask_clr_bit(struct irq_data *d);
 void irq_gc_unmask_enable_reg(struct irq_data *d);
-void irq_gc_ack(struct irq_data *d);
+void irq_gc_ack_set_bit(struct irq_data *d);
+void irq_gc_ack_clr_bit(struct irq_data *d);
 void irq_gc_mask_disable_reg_and_ack(struct irq_data *d);
 void irq_gc_eoi(struct irq_data *d);
 int irq_gc_set_wake(struct irq_data *d, unsigned int on);
index e1e3b2b..935699b 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/compiler.h>
 #include <linux/mutex.h>
 
+#define MIN_MEMORY_BLOCK_SIZE     (1 << SECTION_SIZE_BITS)
+
 struct memory_block {
        unsigned long start_section_nr;
        unsigned long end_section_nr;
index be469a3..38a372a 100644 (file)
@@ -3,4 +3,11 @@
 struct ds1wm_driver_data {
        int active_high;
        int clock_rate;
+       /* in milliseconds, the amount of time to */
+       /* sleep following a reset pulse. Zero    */
+       /* should work if your bus devices recover*/
+       /* time respects the 1-wire spec since the*/
+       /* ds1wm implements the precise timings of*/
+       /* a reset pulse/presence detect sequence.*/
+       unsigned int reset_recover_delay;
 };
index 1562c4f..2884e3e 100644 (file)
@@ -173,16 +173,20 @@ struct v4l2_subdev_core_ops {
                                 struct v4l2_event_subscription *sub);
 };
 
-/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
+/* s_radio: v4l device was opened in radio mode.
 
-   s_radio: v4l device was opened in Radio mode, to be replaced by s_mode.
+   g_frequency: freq->type must be filled in. Normally done by video_ioctl2
+       or the bridge driver.
+
+   g_tuner:
+   s_tuner: vt->type must be filled in. Normally done by video_ioctl2 or the
+       bridge driver.
 
    s_type_addr: sets tuner type and its I2C addr.
 
    s_config: sets tda9887 specific stuff, like port1, port2 and qss
  */
 struct v4l2_subdev_tuner_ops {
-       int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type);
        int (*s_radio)(struct v4l2_subdev *sd);
        int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
        int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
index 31a9db7..3a2cab4 100644 (file)
@@ -101,10 +101,10 @@ void irq_gc_unmask_enable_reg(struct irq_data *d)
 }
 
 /**
- * irq_gc_ack - Ack pending interrupt
+ * irq_gc_ack_set_bit - Ack pending interrupt via setting bit
  * @d: irq_data
  */
-void irq_gc_ack(struct irq_data *d)
+void irq_gc_ack_set_bit(struct irq_data *d)
 {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
        u32 mask = 1 << (d->irq - gc->irq_base);
@@ -114,6 +114,20 @@ void irq_gc_ack(struct irq_data *d)
        irq_gc_unlock(gc);
 }
 
+/**
+ * irq_gc_ack_clr_bit - Ack pending interrupt via clearing bit
+ * @d: irq_data
+ */
+void irq_gc_ack_clr_bit(struct irq_data *d)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       u32 mask = ~(1 << (d->irq - gc->irq_base));
+
+       irq_gc_lock(gc);
+       irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
+       irq_gc_unlock(gc);
+}
+
 /**
  * irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt
  * @d: irq_data
index ddffc74..e013b8e 100644 (file)
@@ -108,10 +108,12 @@ enum mem_cgroup_events_index {
 enum mem_cgroup_events_target {
        MEM_CGROUP_TARGET_THRESH,
        MEM_CGROUP_TARGET_SOFTLIMIT,
+       MEM_CGROUP_TARGET_NUMAINFO,
        MEM_CGROUP_NTARGETS,
 };
 #define THRESHOLDS_EVENTS_TARGET (128)
 #define SOFTLIMIT_EVENTS_TARGET (1024)
+#define NUMAINFO_EVENTS_TARGET (1024)
 
 struct mem_cgroup_stat_cpu {
        long count[MEM_CGROUP_STAT_NSTATS];
@@ -237,7 +239,8 @@ struct mem_cgroup {
        int last_scanned_node;
 #if MAX_NUMNODES > 1
        nodemask_t      scan_nodes;
-       unsigned long   next_scan_node_update;
+       atomic_t        numainfo_events;
+       atomic_t        numainfo_updating;
 #endif
        /*
         * Should the accounting and control be hierarchical, per subtree?
@@ -577,15 +580,6 @@ static long mem_cgroup_read_stat(struct mem_cgroup *mem,
        return val;
 }
 
-static long mem_cgroup_local_usage(struct mem_cgroup *mem)
-{
-       long ret;
-
-       ret = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_RSS);
-       ret += mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_CACHE);
-       return ret;
-}
-
 static void mem_cgroup_swap_statistics(struct mem_cgroup *mem,
                                         bool charge)
 {
@@ -689,6 +683,9 @@ static void __mem_cgroup_target_update(struct mem_cgroup *mem, int target)
        case MEM_CGROUP_TARGET_SOFTLIMIT:
                next = val + SOFTLIMIT_EVENTS_TARGET;
                break;
+       case MEM_CGROUP_TARGET_NUMAINFO:
+               next = val + NUMAINFO_EVENTS_TARGET;
+               break;
        default:
                return;
        }
@@ -707,11 +704,19 @@ static void memcg_check_events(struct mem_cgroup *mem, struct page *page)
                mem_cgroup_threshold(mem);
                __mem_cgroup_target_update(mem, MEM_CGROUP_TARGET_THRESH);
                if (unlikely(__memcg_event_check(mem,
-                       MEM_CGROUP_TARGET_SOFTLIMIT))){
+                            MEM_CGROUP_TARGET_SOFTLIMIT))) {
                        mem_cgroup_update_tree(mem, page);
                        __mem_cgroup_target_update(mem,
-                               MEM_CGROUP_TARGET_SOFTLIMIT);
+                                                  MEM_CGROUP_TARGET_SOFTLIMIT);
+               }
+#if MAX_NUMNODES > 1
+               if (unlikely(__memcg_event_check(mem,
+                       MEM_CGROUP_TARGET_NUMAINFO))) {
+                       atomic_inc(&mem->numainfo_events);
+                       __mem_cgroup_target_update(mem,
+                               MEM_CGROUP_TARGET_NUMAINFO);
                }
+#endif
        }
 }
 
@@ -1129,7 +1134,6 @@ unsigned long mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg,
        return MEM_CGROUP_ZSTAT(mz, lru);
 }
 
-#ifdef CONFIG_NUMA
 static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg,
                                                        int nid)
 {
@@ -1141,6 +1145,17 @@ static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg,
        return ret;
 }
 
+static unsigned long mem_cgroup_node_nr_anon_lru_pages(struct mem_cgroup *memcg,
+                                                       int nid)
+{
+       unsigned long ret;
+
+       ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_ANON) +
+               mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_ANON);
+       return ret;
+}
+
+#if MAX_NUMNODES > 1
 static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg)
 {
        u64 total = 0;
@@ -1152,17 +1167,6 @@ static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg)
        return total;
 }
 
-static unsigned long mem_cgroup_node_nr_anon_lru_pages(struct mem_cgroup *memcg,
-                                                       int nid)
-{
-       unsigned long ret;
-
-       ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_ANON) +
-               mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_ANON);
-
-       return ret;
-}
-
 static unsigned long mem_cgroup_nr_anon_lru_pages(struct mem_cgroup *memcg)
 {
        u64 total = 0;
@@ -1559,6 +1563,28 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem)
        return ret;
 }
 
+/**
+ * test_mem_cgroup_node_reclaimable
+ * @mem: the target memcg
+ * @nid: the node ID to be checked.
+ * @noswap : specify true here if the user wants flle only information.
+ *
+ * This function returns whether the specified memcg contains any
+ * reclaimable pages on a node. Returns true if there are any reclaimable
+ * pages in the node.
+ */
+static bool test_mem_cgroup_node_reclaimable(struct mem_cgroup *mem,
+               int nid, bool noswap)
+{
+       if (mem_cgroup_node_nr_file_lru_pages(mem, nid))
+               return true;
+       if (noswap || !total_swap_pages)
+               return false;
+       if (mem_cgroup_node_nr_anon_lru_pages(mem, nid))
+               return true;
+       return false;
+
+}
 #if MAX_NUMNODES > 1
 
 /*
@@ -1570,26 +1596,26 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem)
 static void mem_cgroup_may_update_nodemask(struct mem_cgroup *mem)
 {
        int nid;
-
-       if (time_after(mem->next_scan_node_update, jiffies))
+       /*
+        * numainfo_events > 0 means there was at least NUMAINFO_EVENTS_TARGET
+        * pagein/pageout changes since the last update.
+        */
+       if (!atomic_read(&mem->numainfo_events))
+               return;
+       if (atomic_inc_return(&mem->numainfo_updating) > 1)
                return;
 
-       mem->next_scan_node_update = jiffies + 10*HZ;
        /* make a nodemask where this memcg uses memory from */
        mem->scan_nodes = node_states[N_HIGH_MEMORY];
 
        for_each_node_mask(nid, node_states[N_HIGH_MEMORY]) {
 
-               if (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_FILE) ||
-                   mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_FILE))
-                       continue;
-
-               if (total_swap_pages &&
-                   (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_ANON) ||
-                    mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_ANON)))
-                       continue;
-               node_clear(nid, mem->scan_nodes);
+               if (!test_mem_cgroup_node_reclaimable(mem, nid, false))
+                       node_clear(nid, mem->scan_nodes);
        }
+
+       atomic_set(&mem->numainfo_events, 0);
+       atomic_set(&mem->numainfo_updating, 0);
 }
 
 /*
@@ -1627,11 +1653,51 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *mem)
        return node;
 }
 
+/*
+ * Check all nodes whether it contains reclaimable pages or not.
+ * For quick scan, we make use of scan_nodes. This will allow us to skip
+ * unused nodes. But scan_nodes is lazily updated and may not cotain
+ * enough new information. We need to do double check.
+ */
+bool mem_cgroup_reclaimable(struct mem_cgroup *mem, bool noswap)
+{
+       int nid;
+
+       /*
+        * quick check...making use of scan_node.
+        * We can skip unused nodes.
+        */
+       if (!nodes_empty(mem->scan_nodes)) {
+               for (nid = first_node(mem->scan_nodes);
+                    nid < MAX_NUMNODES;
+                    nid = next_node(nid, mem->scan_nodes)) {
+
+                       if (test_mem_cgroup_node_reclaimable(mem, nid, noswap))
+                               return true;
+               }
+       }
+       /*
+        * Check rest of nodes.
+        */
+       for_each_node_state(nid, N_HIGH_MEMORY) {
+               if (node_isset(nid, mem->scan_nodes))
+                       continue;
+               if (test_mem_cgroup_node_reclaimable(mem, nid, noswap))
+                       return true;
+       }
+       return false;
+}
+
 #else
 int mem_cgroup_select_victim_node(struct mem_cgroup *mem)
 {
        return 0;
 }
+
+bool mem_cgroup_reclaimable(struct mem_cgroup *mem, bool noswap)
+{
+       return test_mem_cgroup_node_reclaimable(mem, 0, noswap);
+}
 #endif
 
 /*
@@ -1702,7 +1768,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem,
                                }
                        }
                }
-               if (!mem_cgroup_local_usage(victim)) {
+               if (!mem_cgroup_reclaimable(victim, noswap)) {
                        /* this cgroup's local usage == 0 */
                        css_put(&victim->css);
                        continue;
index 40b7531..9b8a01d 100644 (file)
@@ -305,6 +305,7 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
        if (batch->nr == batch->max) {
                if (!tlb_next_batch(tlb))
                        return 0;
+               batch = tlb->active;
        }
        VM_BUG_ON(batch->nr > batch->max);
 
index 1fd0c51..9edc897 100644 (file)
@@ -1813,10 +1813,13 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
        return NULL;
 }
 
-int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-               unsigned long to, unsigned long size, pgprot_t prot)
+int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
+               unsigned long pfn, unsigned long size, pgprot_t prot)
 {
-       vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
+       if (addr != (pfn << PAGE_SHIFT))
+               return -EINVAL;
+
+       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
        return 0;
 }
 EXPORT_SYMBOL(remap_pfn_range);
index 4f49535..5ed24b9 100644 (file)
@@ -2326,7 +2326,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
                return true;
 
        /* Check the watermark levels */
-       for (i = 0; i < pgdat->nr_zones; i++) {
+       for (i = 0; i <= classzone_idx; i++) {
                struct zone *zone = pgdat->node_zones + i;
 
                if (!populated_zone(zone))
@@ -2344,7 +2344,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
                }
 
                if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
-                                                       classzone_idx, 0))
+                                                       i, 0))
                        all_zones_ok = false;
                else
                        balanced += zone->present_pages;
@@ -2451,7 +2451,6 @@ loop_again:
                        if (!zone_watermark_ok_safe(zone, order,
                                        high_wmark_pages(zone), 0, 0)) {
                                end_zone = i;
-                               *classzone_idx = i;
                                break;
                        }
                }
@@ -2510,18 +2509,18 @@ loop_again:
                                KSWAPD_ZONE_BALANCE_GAP_RATIO);
                        if (!zone_watermark_ok_safe(zone, order,
                                        high_wmark_pages(zone) + balance_gap,
-                                       end_zone, 0))
+                                       end_zone, 0)) {
                                shrink_zone(priority, zone, &sc);
-                       reclaim_state->reclaimed_slab = 0;
-                       nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages);
-                       sc.nr_reclaimed += reclaim_state->reclaimed_slab;
-                       total_scanned += sc.nr_scanned;
 
-                       if (zone->all_unreclaimable)
-                               continue;
-                       if (nr_slab == 0 &&
-                           !zone_reclaimable(zone))
-                               zone->all_unreclaimable = 1;
+                               reclaim_state->reclaimed_slab = 0;
+                               nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages);
+                               sc.nr_reclaimed += reclaim_state->reclaimed_slab;
+                               total_scanned += sc.nr_scanned;
+
+                               if (nr_slab == 0 && !zone_reclaimable(zone))
+                                       zone->all_unreclaimable = 1;
+                       }
+
                        /*
                         * If we've done a decent amount of scanning and
                         * the reclaim ratio is low, start doing writepage
@@ -2531,6 +2530,12 @@ loop_again:
                            total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
                                sc.may_writepage = 1;
 
+                       if (zone->all_unreclaimable) {
+                               if (end_zone && end_zone == i)
+                                       end_zone--;
+                               continue;
+                       }
+
                        if (!zone_watermark_ok_safe(zone, order,
                                        high_wmark_pages(zone), end_zone, 0)) {
                                all_zones_ok = 0;
@@ -2709,8 +2714,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
  */
 static int kswapd(void *p)
 {
-       unsigned long order;
-       int classzone_idx;
+       unsigned long order, new_order;
+       int classzone_idx, new_classzone_idx;
        pg_data_t *pgdat = (pg_data_t*)p;
        struct task_struct *tsk = current;
 
@@ -2740,17 +2745,23 @@ static int kswapd(void *p)
        tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
        set_freezable();
 
-       order = 0;
-       classzone_idx = MAX_NR_ZONES - 1;
+       order = new_order = 0;
+       classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
        for ( ; ; ) {
-               unsigned long new_order;
-               int new_classzone_idx;
                int ret;
 
-               new_order = pgdat->kswapd_max_order;
-               new_classzone_idx = pgdat->classzone_idx;
-               pgdat->kswapd_max_order = 0;
-               pgdat->classzone_idx = MAX_NR_ZONES - 1;
+               /*
+                * If the last balance_pgdat was unsuccessful it's unlikely a
+                * new request of a similar or harder type will succeed soon
+                * so consider going to sleep on the basis we reclaimed at
+                */
+               if (classzone_idx >= new_classzone_idx && order == new_order) {
+                       new_order = pgdat->kswapd_max_order;
+                       new_classzone_idx = pgdat->classzone_idx;
+                       pgdat->kswapd_max_order =  0;
+                       pgdat->classzone_idx = pgdat->nr_zones - 1;
+               }
+
                if (order < new_order || classzone_idx > new_classzone_idx) {
                        /*
                         * Don't sleep if someone wants a larger 'order'
@@ -2763,7 +2774,7 @@ static int kswapd(void *p)
                        order = pgdat->kswapd_max_order;
                        classzone_idx = pgdat->classzone_idx;
                        pgdat->kswapd_max_order = 0;
-                       pgdat->classzone_idx = MAX_NR_ZONES - 1;
+                       pgdat->classzone_idx = pgdat->nr_zones - 1;
                }
 
                ret = try_to_freeze();
index d21191d..b48fb43 100644 (file)
@@ -2715,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
 
 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol,
-                                getput_call_t func)
+                                getput_call_t func, bool check_adc_switch)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
-       unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-       int err;
+       int i, err = 0;
 
        mutex_lock(&codec->control_mutex);
-       kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
-                                                     3, 0, HDA_INPUT);
-       err = func(kcontrol, ucontrol);
+       if (check_adc_switch && spec->dual_adc_switch) {
+               for (i = 0; i < spec->num_adc_nids; i++) {
+                       kcontrol->private_value =
+                               HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
+                                                   3, 0, HDA_INPUT);
+                       err = func(kcontrol, ucontrol);
+                       if (err < 0)
+                               goto error;
+               }
+       } else {
+               i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+               kcontrol->private_value =
+                       HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
+                                           3, 0, HDA_INPUT);
+               err = func(kcontrol, ucontrol);
+       }
+ error:
        mutex_unlock(&codec->control_mutex);
        return err;
 }
@@ -2734,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
        return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_volume_get);
+                                    snd_hda_mixer_amp_volume_get, false);
 }
 
 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
        return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_volume_put);
+                                    snd_hda_mixer_amp_volume_put, true);
 }
 
 /* capture mixer elements */
@@ -2751,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
        return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_switch_get);
+                                    snd_hda_mixer_amp_switch_get, false);
 }
 
 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
        return alc_cap_getput_caller(kcontrol, ucontrol,
-                                    snd_hda_mixer_amp_switch_put);
+                                    snd_hda_mixer_amp_switch_put, true);
 }
 
 #define _DEFINE_CAPMIX(num) \
index b5101ef..f1fd95b 100644 (file)
@@ -138,11 +138,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
        pr_debug("%s enter\n", __func__);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                diff = sport_curr_offset_tx(sport);
-               frames = bytes_to_frames(substream->runtime, diff);
        } else {
                diff = sport_curr_offset_rx(sport);
-               frames = bytes_to_frames(substream->runtime, diff);
        }
+
+       /*
+        * TX at least can report one frame beyond the end of the
+        * buffer if we hit the wraparound case - clamp to within the
+        * buffer as the ALSA APIs require.
+        */
+       if (diff == snd_pcm_lib_buffer_bytes(substream))
+               diff = 0;
+
+       frames = bytes_to_frames(substream->runtime, diff);
+
        return frames;
 }
 
index 4be0570..65f4604 100644 (file)
@@ -357,7 +357,7 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PW_MGMT2, MS, data);
+       snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
        snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
 
        /* format type */
index e2a7608..7859bdc 100644 (file)
@@ -161,10 +161,18 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
                dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
        }
 
-       /* Configure PLL */
+       /**
+        * Configure PLL
+        * fsref = (mclk * PLLM) / 2048
+        * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal)
+        */
        pval = 1;
-       jval = (fsref == 44100) ? 7 : 8;
-       dval = (fsref == 44100) ? 5264 : 1920;
+       /* compute J portion of multiplier */
+       jval = fsref / (aic26->mclk / 2048);
+       /* compute fractional DDDD component of multiplier */
+       dval = fsref - (jval * (aic26->mclk / 2048));
+       dval = (10000 * dval) / (aic26->mclk / 2048);
+       dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
        qval = 0;
        reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
        aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
index c3d96fc..789453d 100644 (file)
@@ -1114,12 +1114,19 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 
                /* Sync reg_cache with the hardware */
                codec->cache_only = 0;
-               for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++)
+               for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++)
                        snd_soc_write(codec, i, cache[i]);
                if (aic3x->model == AIC3X_MODEL_3007)
                        aic3x_init_3007(codec);
                codec->cache_sync = 0;
        } else {
+               /*
+                * Do soft reset to this codec instance in order to clear
+                * possible VDD leakage currents in case the supply regulators
+                * remain on
+                */
+               snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
+               codec->cache_sync = 1;
                aic3x->power = 0;
                /* HW writes are needless when bias is off */
                codec->cache_only = 1;
index 2dc964b..76b4361 100644 (file)
@@ -175,6 +175,7 @@ static const struct snd_kcontrol_new wm8731_input_mux_controls =
 SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
 
 static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("ACTIVE",WM8731_ACTIVE, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
        &wm8731_output_mixer_controls[0],
@@ -204,6 +205,8 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
 static const struct snd_soc_dapm_route wm8731_intercon[] = {
        {"DAC", NULL, "OSC", wm8731_check_osc},
        {"ADC", NULL, "OSC", wm8731_check_osc},
+       {"DAC", NULL, "ACTIVE"},
+       {"ADC", NULL, "ACTIVE"},
 
        /* output mixer */
        {"Output Mixer", "Line Bypass Switch", "Line Input"},
@@ -315,29 +318,6 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
-                             struct snd_soc_dai *dai)
-{
-       struct snd_soc_codec *codec = dai->codec;
-
-       /* set active */
-       snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
-
-       return 0;
-}
-
-static void wm8731_shutdown(struct snd_pcm_substream *substream,
-                           struct snd_soc_dai *dai)
-{
-       struct snd_soc_codec *codec = dai->codec;
-
-       /* deactivate */
-       if (!codec->active) {
-               udelay(50);
-               snd_soc_write(codec, WM8731_ACTIVE, 0x0);
-       }
-}
-
 static int wm8731_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_codec *codec = dai->codec;
@@ -480,7 +460,6 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
                snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, WM8731_ACTIVE, 0x0);
                snd_soc_write(codec, WM8731_PWR, 0xffff);
                regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
                                       wm8731->supplies);
@@ -496,9 +475,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
        SNDRV_PCM_FMTBIT_S24_LE)
 
 static struct snd_soc_dai_ops wm8731_dai_ops = {
-       .prepare        = wm8731_pcm_prepare,
        .hw_params      = wm8731_hw_params,
-       .shutdown       = wm8731_shutdown,
        .digital_mute   = wm8731_mute,
        .set_sysclk     = wm8731_set_dai_sysclk,
        .set_fmt        = wm8731_set_dai_fmt,
index 970a95c..c2fc035 100644 (file)
@@ -1713,6 +1713,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
                                    WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
                                    reg);
+
+               msleep(5);
        }
 
        wm8994->fll[id].in = freq_in;
index d75043e..b194be0 100644 (file)
@@ -1929,8 +1929,9 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
                 "%s", card->name);
        snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
                 "%s", card->long_name ? card->long_name : card->name);
-       snprintf(card->snd_card->driver, sizeof(card->snd_card->driver),
-                "%s", card->driver_name ? card->driver_name : card->name);
+       if (card->driver_name)
+               strlcpy(card->snd_card->driver, card->driver_name,
+                       sizeof(card->snd_card->driver));
 
        if (card->late_probe) {
                ret = card->late_probe(card);
index 6b817e2..95f03c1 100644 (file)
@@ -222,12 +222,18 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
        if (i2sclock % (2 * srate))
                reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
 
+       if (!i2s->clk_refs)
+               clk_enable(i2s->clk_i2s);
+
        tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
 
        tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
                TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
                TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
 
+       if (!i2s->clk_refs)
+               clk_disable(i2s->clk_i2s);
+
        return 0;
 }