Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 May 2012 18:27:00 +0000 (11:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 May 2012 18:27:00 +0000 (11:27 -0700)
Pull ARM: SoC fixes from Olof Johansson:
 "Things have slowed down a lot for us, but we have five more fixes for
  omap and kirkwood below.  Three are for boards setup issues, two are
  SoC-level fixes."

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  ARM: OMAP: igep0020: fix smsc911x dummy regulator id
  ARM: orion5x: Fix GPIO enable bits for MPP9
  ARM: kirkwood: add missing kexec.h include
  ARM: OMAP: Revert "ARM: OMAP: ctrl: Fix CONTROL_DSIPHY register fields"
  ARM: OMAP1: Amstrad Delta: Fix wrong IRQ base in FIQ handler

27 files changed:
arch/arm/kernel/ptrace.c
arch/arm/kernel/smp.c
arch/arm/kernel/sys_arm.c
arch/ia64/kvm/kvm-ia64.c
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/traps.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c
arch/x86/kernel/kvm.c
arch/x86/kernel/process_64.c
arch/x86/kernel/setup_percpu.c
arch/x86/kvm/x86.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
drivers/base/regmap/regmap.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_i2c.h
drivers/regulator/core.c
drivers/regulator/max8997.c
drivers/video/xen-fbfront.c
drivers/xen/Kconfig
mm/percpu.c

index 80abafb9bf3374d5f6d86b67ee0f1b1260b7e9fc..9650c143afc115fe82c2ccd5fdecad6ef02116e0 100644 (file)
@@ -906,27 +906,14 @@ long arch_ptrace(struct task_struct *child, long request,
        return ret;
 }
 
-#ifdef __ARMEB__
-#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB
-#else
-#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
-#endif
-
 asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 {
        unsigned long ip;
 
-       /*
-        * Save IP.  IP is used to denote syscall entry/exit:
-        *  IP = 0 -> entry, = 1 -> exit
-        */
-       ip = regs->ARM_ip;
-       regs->ARM_ip = why;
-
-       if (!ip)
+       if (why)
                audit_syscall_exit(regs);
        else
-               audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0,
+               audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,
                                    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
 
        if (!test_thread_flag(TIF_SYSCALL_TRACE))
@@ -936,6 +923,13 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 
        current_thread_info()->syscall = scno;
 
+       /*
+        * IP is used to denote syscall entry/exit:
+        * IP = 0 -> entry, =1 -> exit
+        */
+       ip = regs->ARM_ip;
+       regs->ARM_ip = why;
+
        /* the 0x80 provides a way for the tracing parent to distinguish
           between a syscall stop and SIGTRAP delivery */
        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
index f6a4d32b0421a9dd35fa1ca2884e8980374a76a3..8f4644659777ebbefd8ba2de8b366b8a5d7de8fa 100644 (file)
@@ -251,8 +251,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
        struct mm_struct *mm = &init_mm;
        unsigned int cpu = smp_processor_id();
 
-       printk("CPU%u: Booted secondary processor\n", cpu);
-
        /*
         * All kernel threads share the same mm context; grab a
         * reference and switch to it.
@@ -264,6 +262,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
        enter_lazy_tlb(mm, current);
        local_flush_tlb_all();
 
+       printk("CPU%u: Booted secondary processor\n", cpu);
+
        cpu_init();
        preempt_disable();
        trace_hardirqs_off();
index d2b177905cdb4c46def1de346ec7296425e1e315..76cbb055dd05ee2e8620bc1a3f1dc322f1333aeb 100644 (file)
@@ -115,7 +115,7 @@ int kernel_execve(const char *filename,
                  "Ir" (THREAD_START_SP - sizeof(regs)),
                  "r" (&regs),
                  "Ir" (sizeof(regs))
-               : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
+               : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
 
  out:
        return ret;
index f5104b7c52cd369b0150f9884133922ba6defe03..463fb3bbe11ee13dbd903f65359864bd8f45b452 100644 (file)
@@ -1174,7 +1174,7 @@ out:
 
 bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
 {
-       return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL);
+       return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL);
 }
 
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
index 548da3aa0a303a3f2065127d079b280c6264d14f..d58fc4e4149cb11c69abf8cb462c7e7021cf822a 100644 (file)
@@ -288,13 +288,6 @@ label##_hv:                                                                \
 /* Exception addition: Hard disable interrupts */
 #define DISABLE_INTS   SOFT_DISABLE_INTS(r10,r11)
 
-/* Exception addition: Keep interrupt state */
-#define ENABLE_INTS                            \
-       ld      r11,PACAKMSR(r13);              \
-       ld      r12,_MSR(r1);                   \
-       rlwimi  r11,r12,0,MSR_EE;               \
-       mtmsrd  r11,1
-
 #define ADD_NVGPRS                             \
        bl      .save_nvgprs
 
index f8a7a1a1a9f4480ac1881f907da771a474606998..fc6015027a86cc40c74406702ff7d32907b2ebe7 100644 (file)
@@ -767,16 +767,6 @@ do_work:
        SOFT_DISABLE_INTS(r3,r4)
 1:     bl      .preempt_schedule_irq
 
-       /* Hard-disable interrupts again (and update PACA) */
-#ifdef CONFIG_PPC_BOOK3E
-       wrteei  0
-#else
-       ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
-       mtmsrd  r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-       li      r0,PACA_IRQ_HARD_DIS
-       stb     r0,PACAIRQHAPPENED(r13)
-
        /* Re-test flags and eventually loop */
        clrrdi  r9,r1,THREAD_SHIFT
        ld      r4,TI_FLAGS(r9)
@@ -787,14 +777,6 @@ do_work:
 user_work:
 #endif /* CONFIG_PREEMPT */
 
-       /* Enable interrupts */
-#ifdef CONFIG_PPC_BOOK3E
-       wrteei  1
-#else
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-
        andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
        bl      .restore_interrupts
index cb705fdbb4583b6b162c9c2cb8991be43525eea4..8f880bc77c56a2a8cd811ca19a21677778856130 100644 (file)
@@ -768,8 +768,8 @@ alignment_common:
        std     r3,_DAR(r1)
        std     r4,_DSISR(r1)
        bl      .save_nvgprs
+       DISABLE_INTS
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
        bl      .alignment_exception
        b       .ret_from_except
 
index 43eb74fcedde2806da8dd0c5193f3df4c91433dc..c6c6f3b7f8cd0a91df68cb14ba476cbf0f5f5ac1 100644 (file)
@@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore);
  * if they are currently disabled. This is typically called before
  * schedule() or do_signal() when returning to userspace. We do it
  * in C to avoid the burden of dealing with lockdep etc...
+ *
+ * NOTE: This is called with interrupts hard disabled but not marked
+ * as such in paca->irq_happened, so we need to resync this.
  */
 void restore_interrupts(void)
 {
-       if (irqs_disabled())
+       if (irqs_disabled()) {
+               local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
                local_irq_enable();
+       } else
+               __hard_irq_enable();
 }
 
 #endif /* CONFIG_PPC64 */
index 6aa0c663e247fe1417a1bef2eb2479204082ce09..158972341a2d7a66da48c32878fdc0842b2a4feb 100644 (file)
@@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
                                   addr, regs->nip, regs->link, code);
        }
 
-       if (!arch_irq_disabled_regs(regs))
+       if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
                local_irq_enable();
 
        memset(&info, 0, sizeof(info));
@@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs)
                return;
        }
 
-       local_irq_enable();
+       /* We restore the interrupt state now */
+       if (!arch_irq_disabled_regs(regs))
+               local_irq_enable();
 
 #ifdef CONFIG_MATH_EMULATION
        /* (reason & REASON_ILLEGAL) would be the obvious thing here,
@@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
 {
        int sig, code, fixed = 0;
 
+       /* We restore the interrupt state now */
+       if (!arch_irq_disabled_regs(regs))
+               local_irq_enable();
+
        /* we don't implement logging of alignment exceptions */
        if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
                fixed = fix_alignment(regs);
index ddc485a529f2d7f7c59e22729fd55372eac9be03..c3beaeef3f60b41013c723197b2b898cf47f3d1b 100644 (file)
@@ -258,6 +258,8 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn,
                            !(memslot->userspace_addr & (s - 1))) {
                                start &= ~(s - 1);
                                pgsize = s;
+                               get_page(hpage);
+                               put_page(page);
                                page = hpage;
                        }
                }
@@ -281,11 +283,8 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn,
        err = 0;
 
  out:
-       if (got) {
-               if (PageHuge(page))
-                       page = compound_head(page);
+       if (got)
                put_page(page);
-       }
        return err;
 
  up_err:
@@ -678,8 +677,15 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                SetPageDirty(page);
 
  out_put:
-       if (page)
-               put_page(page);
+       if (page) {
+               /*
+                * We drop pages[0] here, not page because page might
+                * have been set to the head page of a compound, but
+                * we have to drop the reference on the correct tail
+                * page to match the get inside gup()
+                */
+               put_page(pages[0]);
+       }
        return ret;
 
  out_unlock:
@@ -979,6 +985,7 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa,
                        pa = *physp;
                }
                page = pfn_to_page(pa >> PAGE_SHIFT);
+               get_page(page);
        } else {
                hva = gfn_to_hva_memslot(memslot, gfn);
                npages = get_user_pages_fast(hva, 1, 1, pages);
@@ -991,8 +998,6 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa,
                page = compound_head(page);
                psize <<= compound_order(page);
        }
-       if (!kvm->arch.using_mmu_notifiers)
-               get_page(page);
        offset = gpa & (psize - 1);
        if (nb_ret)
                *nb_ret = psize - offset;
@@ -1003,7 +1008,6 @@ void kvmppc_unpin_guest_page(struct kvm *kvm, void *va)
 {
        struct page *page = virt_to_page(va);
 
-       page = compound_head(page);
        put_page(page);
 }
 
index 01294a5099dda77b3528cfce18eef9dc78ff13ab..108d1f580177b5e0b860c02b221ef888d1c63676 100644 (file)
@@ -1192,8 +1192,6 @@ static void unpin_slot(struct kvm *kvm, int slot_id)
                                continue;
                        pfn = physp[j] >> PAGE_SHIFT;
                        page = pfn_to_page(pfn);
-                       if (PageHuge(page))
-                               page = compound_head(page);
                        SetPageDirty(page);
                        put_page(page);
                }
index b8ba6e4a27e4102bd36a6445ec4b503be990d62d..e554e5ad2fe8b46b8739386c564a4594621d0f61 100644 (file)
@@ -79,7 +79,6 @@ struct kvm_task_sleep_node {
        u32 token;
        int cpu;
        bool halted;
-       struct mm_struct *mm;
 };
 
 static struct kvm_task_sleep_head {
@@ -126,9 +125,7 @@ void kvm_async_pf_task_wait(u32 token)
 
        n.token = token;
        n.cpu = smp_processor_id();
-       n.mm = current->active_mm;
        n.halted = idle || preempt_count() > 1;
-       atomic_inc(&n.mm->mm_count);
        init_waitqueue_head(&n.wq);
        hlist_add_head(&n.link, &b->list);
        spin_unlock(&b->lock);
@@ -161,9 +158,6 @@ EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait);
 static void apf_task_wake_one(struct kvm_task_sleep_node *n)
 {
        hlist_del_init(&n->link);
-       if (!n->mm)
-               return;
-       mmdrop(n->mm);
        if (n->halted)
                smp_send_reschedule(n->cpu);
        else if (waitqueue_active(&n->wq))
@@ -207,7 +201,7 @@ again:
                 * async PF was not yet handled.
                 * Add dummy entry for the token.
                 */
-               n = kmalloc(sizeof(*n), GFP_ATOMIC);
+               n = kzalloc(sizeof(*n), GFP_ATOMIC);
                if (!n) {
                        /*
                         * Allocation failed! Busy wait while other cpu
@@ -219,7 +213,6 @@ again:
                }
                n->token = token;
                n->cpu = smp_processor_id();
-               n->mm = NULL;
                init_waitqueue_head(&n->wq);
                hlist_add_head(&n->link, &b->list);
        } else
index 733ca39f367ebcc222eaca07b87eb170f2831e1e..43d8b48b23e61dc20afb3ddc0aed3308e7d92f2b 100644 (file)
@@ -423,6 +423,7 @@ void set_personality_ia32(bool x32)
                current_thread_info()->status |= TS_COMPAT;
        }
 }
+EXPORT_SYMBOL_GPL(set_personality_ia32);
 
 unsigned long get_wchan(struct task_struct *p)
 {
index 71f4727da3735ffc93c2346a2b7712208df9a020..5a98aa27218417737c631cbf4c43e3e50cf69540 100644 (file)
@@ -185,10 +185,22 @@ void __init setup_per_cpu_areas(void)
 #endif
        rc = -EINVAL;
        if (pcpu_chosen_fc != PCPU_FC_PAGE) {
-               const size_t atom_size = cpu_has_pse ? PMD_SIZE : PAGE_SIZE;
                const size_t dyn_size = PERCPU_MODULE_RESERVE +
                        PERCPU_DYNAMIC_RESERVE - PERCPU_FIRST_CHUNK_RESERVE;
+               size_t atom_size;
 
+               /*
+                * On 64bit, use PMD_SIZE for atom_size so that embedded
+                * percpu areas are aligned to PMD.  This, in the future,
+                * can also allow using PMD mappings in vmalloc area.  Use
+                * PAGE_SIZE on 32bit as vmalloc space is highly contended
+                * and large vmalloc area allocs can easily fail.
+                */
+#ifdef CONFIG_X86_64
+               atom_size = PMD_SIZE;
+#else
+               atom_size = PAGE_SIZE;
+#endif
                rc = pcpu_embed_first_chunk(PERCPU_FIRST_CHUNK_RESERVE,
                                            dyn_size, atom_size,
                                            pcpu_cpu_distance,
index 91a5e989abcfe86f60df7bcb2a2919e25f87df6a..185a2b823a2dbbceedab23b4dcfd8db4395ceda9 100644 (file)
@@ -6581,6 +6581,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
                kvm_inject_page_fault(vcpu, &fault);
        }
        vcpu->arch.apf.halted = false;
+       vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 }
 
 bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
index a8f8844b8d32690b8a189bc37d12cd3f286a81cd..95dccce8e97909dd0e6d4c9b250f2613e87c4bf6 100644 (file)
@@ -63,6 +63,7 @@
 #include <asm/stackprotector.h>
 #include <asm/hypervisor.h>
 #include <asm/mwait.h>
+#include <asm/pci_x86.h>
 
 #ifdef CONFIG_ACPI
 #include <linux/acpi.h>
@@ -809,9 +810,40 @@ static void xen_io_delay(void)
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
+static unsigned long xen_set_apic_id(unsigned int x)
+{
+       WARN_ON(1);
+       return x;
+}
+static unsigned int xen_get_apic_id(unsigned long x)
+{
+       return ((x)>>24) & 0xFFu;
+}
 static u32 xen_apic_read(u32 reg)
 {
-       return 0;
+       struct xen_platform_op op = {
+               .cmd = XENPF_get_cpuinfo,
+               .interface_version = XENPF_INTERFACE_VERSION,
+               .u.pcpu_info.xen_cpuid = 0,
+       };
+       int ret = 0;
+
+       /* Shouldn't need this as APIC is turned off for PV, and we only
+        * get called on the bootup processor. But just in case. */
+       if (!xen_initial_domain() || smp_processor_id())
+               return 0;
+
+       if (reg == APIC_LVR)
+               return 0x10;
+
+       if (reg != APIC_ID)
+               return 0;
+
+       ret = HYPERVISOR_dom0_op(&op);
+       if (ret)
+               return 0;
+
+       return op.u.pcpu_info.apic_id << 24;
 }
 
 static void xen_apic_write(u32 reg, u32 val)
@@ -849,6 +881,8 @@ static void set_xen_basic_apic_ops(void)
        apic->icr_write = xen_apic_icr_write;
        apic->wait_icr_idle = xen_apic_wait_icr_idle;
        apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
+       apic->set_apic_id = xen_set_apic_id;
+       apic->get_apic_id = xen_get_apic_id;
 }
 
 #endif
@@ -1365,8 +1399,10 @@ asmlinkage void __init xen_start_kernel(void)
                /* Make sure ACS will be enabled */
                pci_request_acs();
        }
-               
-
+#ifdef CONFIG_PCI
+       /* PCI BIOS service won't work from a PV guest. */
+       pci_probe &= ~PCI_PROBE_BIOS;
+#endif
        xen_raw_console_write("about to get started...\n");
 
        xen_setup_runstate_info(0);
index b8e279479a6b31984a7e715c52eec4283e38e007..69f5857660ac7d04322f81ad8314bb7239dc68f3 100644 (file)
@@ -353,8 +353,13 @@ static pteval_t pte_mfn_to_pfn(pteval_t val)
 {
        if (val & _PAGE_PRESENT) {
                unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
+               unsigned long pfn = mfn_to_pfn(mfn);
+
                pteval_t flags = val & PTE_FLAGS_MASK;
-               val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags;
+               if (unlikely(pfn == ~0))
+                       val = flags & ~_PAGE_PRESENT;
+               else
+                       val = ((pteval_t)pfn << PAGE_SHIFT) | flags;
        }
 
        return val;
index 7a3f535e481c69ac31254b84bc6111e0d9793814..bb80853ff27a9d25e1003a25edec0d21cbe8c2ad 100644 (file)
@@ -775,9 +775,11 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
                        map->format.parse_val(val + i);
        } else {
                for (i = 0; i < val_count; i++) {
-                       ret = regmap_read(map, reg + i, val + (i * val_bytes));
+                       unsigned int ival;
+                       ret = regmap_read(map, reg + i, &ival);
                        if (ret != 0)
                                return ret;
+                       memcpy(val + (i * val_bytes), &ival, val_bytes);
                }
        }
 
index 80fce51e2f439d9bf4825fffadf05051fb6531b9..62892a826edec6df73de3d2b49edfc893d6e01a5 100644 (file)
@@ -398,10 +398,8 @@ static int init_render_ring(struct intel_ring_buffer *ring)
                        return ret;
        }
 
-       if (INTEL_INFO(dev)->gen >= 6) {
-               I915_WRITE(INSTPM,
-                          INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
 
+       if (IS_GEN6(dev)) {
                /* From the Sandybridge PRM, volume 1 part 3, page 24:
                 * "If this bit is set, STCunit will have LRA as replacement
                 *  policy. [...] This bit must be reset.  LRA replacement
@@ -411,6 +409,11 @@ static int init_render_ring(struct intel_ring_buffer *ring)
                           CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);
        }
 
+       if (INTEL_INFO(dev)->gen >= 6) {
+               I915_WRITE(INSTPM,
+                          INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
+       }
+
        return ret;
 }
 
index 232d77d07d8b241b7ea1ec45ee8333463ac63c3a..ae5e748f39bbd0cc9109f1c0994498fc4cf731f3 100644 (file)
@@ -1220,8 +1220,14 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
 
 static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
 {
+       struct drm_device *dev = intel_sdvo->base.base.dev;
        u8 response[2];
 
+       /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
+        * on the line. */
+       if (IS_I945G(dev) || IS_I945GM(dev))
+               return false;
+
        return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
                                    &response, 2) && response[0];
 }
index e2be95af2e52919c6a272009e23e01ea48c4165e..77e564667b5c89d6fec1ad5e58f55ce5082f2c42 100644 (file)
 #include "nouveau_i2c.h"
 #include "nouveau_hw.h"
 
-#define T_TIMEOUT  2200000
-#define T_RISEFALL 1000
-#define T_HOLD     5000
-
 static void
 i2c_drive_scl(void *data, int state)
 {
@@ -113,175 +109,6 @@ i2c_sense_sda(void *data)
        return 0;
 }
 
-static void
-i2c_delay(struct nouveau_i2c_chan *port, u32 nsec)
-{
-       udelay((nsec + 500) / 1000);
-}
-
-static bool
-i2c_raise_scl(struct nouveau_i2c_chan *port)
-{
-       u32 timeout = T_TIMEOUT / T_RISEFALL;
-
-       i2c_drive_scl(port, 1);
-       do {
-               i2c_delay(port, T_RISEFALL);
-       } while (!i2c_sense_scl(port) && --timeout);
-
-       return timeout != 0;
-}
-
-static int
-i2c_start(struct nouveau_i2c_chan *port)
-{
-       int ret = 0;
-
-       port->state  = i2c_sense_scl(port);
-       port->state |= i2c_sense_sda(port) << 1;
-       if (port->state != 3) {
-               i2c_drive_scl(port, 0);
-               i2c_drive_sda(port, 1);
-               if (!i2c_raise_scl(port))
-                       ret = -EBUSY;
-       }
-
-       i2c_drive_sda(port, 0);
-       i2c_delay(port, T_HOLD);
-       i2c_drive_scl(port, 0);
-       i2c_delay(port, T_HOLD);
-       return ret;
-}
-
-static void
-i2c_stop(struct nouveau_i2c_chan *port)
-{
-       i2c_drive_scl(port, 0);
-       i2c_drive_sda(port, 0);
-       i2c_delay(port, T_RISEFALL);
-
-       i2c_drive_scl(port, 1);
-       i2c_delay(port, T_HOLD);
-       i2c_drive_sda(port, 1);
-       i2c_delay(port, T_HOLD);
-}
-
-static int
-i2c_bitw(struct nouveau_i2c_chan *port, int sda)
-{
-       i2c_drive_sda(port, sda);
-       i2c_delay(port, T_RISEFALL);
-
-       if (!i2c_raise_scl(port))
-               return -ETIMEDOUT;
-       i2c_delay(port, T_HOLD);
-
-       i2c_drive_scl(port, 0);
-       i2c_delay(port, T_HOLD);
-       return 0;
-}
-
-static int
-i2c_bitr(struct nouveau_i2c_chan *port)
-{
-       int sda;
-
-       i2c_drive_sda(port, 1);
-       i2c_delay(port, T_RISEFALL);
-
-       if (!i2c_raise_scl(port))
-               return -ETIMEDOUT;
-       i2c_delay(port, T_HOLD);
-
-       sda = i2c_sense_sda(port);
-
-       i2c_drive_scl(port, 0);
-       i2c_delay(port, T_HOLD);
-       return sda;
-}
-
-static int
-i2c_get_byte(struct nouveau_i2c_chan *port, u8 *byte, bool last)
-{
-       int i, bit;
-
-       *byte = 0;
-       for (i = 7; i >= 0; i--) {
-               bit = i2c_bitr(port);
-               if (bit < 0)
-                       return bit;
-               *byte |= bit << i;
-       }
-
-       return i2c_bitw(port, last ? 1 : 0);
-}
-
-static int
-i2c_put_byte(struct nouveau_i2c_chan *port, u8 byte)
-{
-       int i, ret;
-       for (i = 7; i >= 0; i--) {
-               ret = i2c_bitw(port, !!(byte & (1 << i)));
-               if (ret < 0)
-                       return ret;
-       }
-
-       ret = i2c_bitr(port);
-       if (ret == 1) /* nack */
-               ret = -EIO;
-       return ret;
-}
-
-static int
-i2c_addr(struct nouveau_i2c_chan *port, struct i2c_msg *msg)
-{
-       u32 addr = msg->addr << 1;
-       if (msg->flags & I2C_M_RD)
-               addr |= 1;
-       return i2c_put_byte(port, addr);
-}
-
-static int
-i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
-       struct nouveau_i2c_chan *port = (struct nouveau_i2c_chan *)adap;
-       struct i2c_msg *msg = msgs;
-       int ret = 0, mcnt = num;
-
-       while (!ret && mcnt--) {
-               u8 remaining = msg->len;
-               u8 *ptr = msg->buf;
-
-               ret = i2c_start(port);
-               if (ret == 0)
-                       ret = i2c_addr(port, msg);
-
-               if (msg->flags & I2C_M_RD) {
-                       while (!ret && remaining--)
-                               ret = i2c_get_byte(port, ptr++, !remaining);
-               } else {
-                       while (!ret && remaining--)
-                               ret = i2c_put_byte(port, *ptr++);
-               }
-
-               msg++;
-       }
-
-       i2c_stop(port);
-       return (ret < 0) ? ret : num;
-}
-
-static u32
-i2c_bit_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-const struct i2c_algorithm nouveau_i2c_bit_algo = {
-       .master_xfer = i2c_bit_xfer,
-       .functionality = i2c_bit_func
-};
-
 static const uint32_t nv50_i2c_port[] = {
        0x00e138, 0x00e150, 0x00e168, 0x00e180,
        0x00e254, 0x00e274, 0x00e764, 0x00e780,
@@ -384,12 +211,10 @@ nouveau_i2c_init(struct drm_device *dev)
                case 0: /* NV04:NV50 */
                        port->drive = entry[0];
                        port->sense = entry[1];
-                       port->adapter.algo = &nouveau_i2c_bit_algo;
                        break;
                case 4: /* NV4E */
                        port->drive = 0x600800 + entry[1];
                        port->sense = port->drive;
-                       port->adapter.algo = &nouveau_i2c_bit_algo;
                        break;
                case 5: /* NV50- */
                        port->drive = entry[0] & 0x0f;
@@ -402,7 +227,6 @@ nouveau_i2c_init(struct drm_device *dev)
                                port->drive = 0x00d014 + (port->drive * 0x20);
                                port->sense = port->drive;
                        }
-                       port->adapter.algo = &nouveau_i2c_bit_algo;
                        break;
                case 6: /* NV50- DP AUX */
                        port->drive = entry[0];
@@ -413,7 +237,7 @@ nouveau_i2c_init(struct drm_device *dev)
                        break;
                }
 
-               if (!port->adapter.algo) {
+               if (!port->adapter.algo && !port->drive) {
                        NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n",
                                 i, port->type, port->drive, port->sense);
                        kfree(port);
@@ -429,7 +253,26 @@ nouveau_i2c_init(struct drm_device *dev)
                port->dcb = ROM32(entry[0]);
                i2c_set_adapdata(&port->adapter, i2c);
 
-               ret = i2c_add_adapter(&port->adapter);
+               if (port->adapter.algo != &nouveau_dp_i2c_algo) {
+                       port->adapter.algo_data = &port->bit;
+                       port->bit.udelay = 10;
+                       port->bit.timeout = usecs_to_jiffies(2200);
+                       port->bit.data = port;
+                       port->bit.setsda = i2c_drive_sda;
+                       port->bit.setscl = i2c_drive_scl;
+                       port->bit.getsda = i2c_sense_sda;
+                       port->bit.getscl = i2c_sense_scl;
+
+                       i2c_drive_scl(port, 0);
+                       i2c_drive_sda(port, 1);
+                       i2c_drive_scl(port, 1);
+
+                       ret = i2c_bit_add_bus(&port->adapter);
+               } else {
+                       port->adapter.algo = &nouveau_dp_i2c_algo;
+                       ret = i2c_add_adapter(&port->adapter);
+               }
+
                if (ret) {
                        NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret);
                        kfree(port);
index 4d2e4e9031be6dc8f51882c5c95a933c0e763064..1d083893a4d74b29b853a6baf4ba898c4e1a0db4 100644 (file)
@@ -34,6 +34,7 @@
 struct nouveau_i2c_chan {
        struct i2c_adapter adapter;
        struct drm_device *dev;
+       struct i2c_algo_bit_data bit;
        struct list_head head;
        u8  index;
        u8  type;
index e70dd382a009a2db05d78087b6e0e588584e6b6e..046fb1bd86199c46561774a8a2bbd2a6118a52fc 100644 (file)
@@ -1431,7 +1431,10 @@ void devm_regulator_put(struct regulator *regulator)
 
        rc = devres_destroy(regulator->dev, devm_regulator_release,
                            devm_regulator_match, regulator);
-       WARN_ON(rc);
+       if (rc == 0)
+               regulator_put(regulator);
+       else
+               WARN_ON(rc);
 }
 EXPORT_SYMBOL_GPL(devm_regulator_put);
 
index 96579296f04d91aaf2859288f6e34ae806e901e4..17a58c56eebfb4f0c7978afa9b04d2307ccc342e 100644 (file)
@@ -684,7 +684,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
                }
 
                new_val++;
-       } while (desc->min + desc->step + new_val <= desc->max);
+       } while (desc->min + desc->step * new_val <= desc->max);
 
        new_idx = tmp_idx;
        new_val = tmp_val;
index cb4529c40d742b93ebe7479b3688e43d4e249233..b7f5173ff9e94214ed40c3c40f4444324e128888 100644 (file)
@@ -365,7 +365,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
        struct fb_info *fb_info;
        int fb_size;
        int val;
-       int ret;
+       int ret = 0;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (info == NULL) {
@@ -458,26 +458,31 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
        xenfb_init_shared_page(info, fb_info);
 
        ret = xenfb_connect_backend(dev, info);
-       if (ret < 0)
-               goto error;
+       if (ret < 0) {
+               xenbus_dev_fatal(dev, ret, "xenfb_connect_backend");
+               goto error_fb;
+       }
 
        ret = register_framebuffer(fb_info);
        if (ret) {
-               fb_deferred_io_cleanup(fb_info);
-               fb_dealloc_cmap(&fb_info->cmap);
-               framebuffer_release(fb_info);
                xenbus_dev_fatal(dev, ret, "register_framebuffer");
-               goto error;
+               goto error_fb;
        }
        info->fb_info = fb_info;
 
        xenfb_make_preferred_console();
        return 0;
 
- error_nomem:
-       ret = -ENOMEM;
-       xenbus_dev_fatal(dev, ret, "allocating device memory");
- error:
+error_fb:
+       fb_deferred_io_cleanup(fb_info);
+       fb_dealloc_cmap(&fb_info->cmap);
+       framebuffer_release(fb_info);
+error_nomem:
+       if (!ret) {
+               ret = -ENOMEM;
+               xenbus_dev_fatal(dev, ret, "allocating device memory");
+       }
+error:
        xenfb_remove(dev);
        return ret;
 }
index 94243136f6bfecf4f3ede4730f4bf7cace270242..ea20c51d24c76420c5c586fc4e9203478094ecda 100644 (file)
@@ -183,15 +183,17 @@ config XEN_ACPI_PROCESSOR
        depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ
        default m
        help
-          This ACPI processor uploads Power Management information to the Xen hypervisor.
-
-         To do that the driver parses the Power Management data and uploads said
-         information to the Xen hypervisor. Then the Xen hypervisor can select the
-          proper Cx and Pxx states. It also registers itslef as the SMM so that
-          other drivers (such as ACPI cpufreq scaling driver) will not load.
-
-          To compile this driver as a module, choose M here: the
-          module will be called xen_acpi_processor  If you do not know what to choose,
-          select M here. If the CPUFREQ drivers are built in, select Y here.
+          This ACPI processor uploads Power Management information to the Xen
+         hypervisor.
+
+         To do that the driver parses the Power Management data and uploads
+         said information to the Xen hypervisor. Then the Xen hypervisor can
+         select the proper Cx and Pxx states. It also registers itslef as the
+         SMM so that other drivers (such as ACPI cpufreq scaling driver) will
+         not load.
+
+          To compile this driver as a module, choose M here: the module will be
+         called xen_acpi_processor  If you do not know what to choose, select
+         M here. If the CPUFREQ drivers are built in, select Y here.
 
 endmenu
index f47af9123af78e84d37c473a11daf72093c1ce50..f921fdfb543021f6c1702648404915df2e999337 100644 (file)
@@ -1132,20 +1132,20 @@ static void pcpu_dump_alloc_info(const char *lvl,
                for (alloc_end += gi->nr_units / upa;
                     alloc < alloc_end; alloc++) {
                        if (!(alloc % apl)) {
-                               printk("\n");
+                               printk(KERN_CONT "\n");
                                printk("%spcpu-alloc: ", lvl);
                        }
-                       printk("[%0*d] ", group_width, group);
+                       printk(KERN_CONT "[%0*d] ", group_width, group);
 
                        for (unit_end += upa; unit < unit_end; unit++)
                                if (gi->cpu_map[unit] != NR_CPUS)
-                                       printk("%0*d ", cpu_width,
+                                       printk(KERN_CONT "%0*d ", cpu_width,
                                               gi->cpu_map[unit]);
                                else
-                                       printk("%s ", empty_str);
+                                       printk(KERN_CONT "%s ", empty_str);
                }
        }
-       printk("\n");
+       printk(KERN_CONT "\n");
 }
 
 /**