]> Git Repo - linux.git/commitdiff
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <[email protected]>
Fri, 22 Oct 2010 04:19:54 +0000 (21:19 -0700)
committerLinus Torvalds <[email protected]>
Fri, 22 Oct 2010 04:19:54 +0000 (21:19 -0700)
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (71 commits)
  powerpc/44x: Update ppc44x_defconfig
  powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
  fsl_rio: Add comments for sRIO registers.
  powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
  powerpc/fsl-booke: Add p5020 DS board support
  powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
  powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
  powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
  powerpc/85xx: add cache-sram support
  powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
  powerpc: Fix compile error with paca code on ppc64e
  powerpc/fsl-booke: Add p3041 DS board support
  oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
  powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
  powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
  powerpc/fsl_booke: Add support to boot from core other than 0
  powerpc/p1022: Add probing for individual DMA channels
  powerpc/fsl_soc: Search all global-utilities nodes for rstccr
  powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
  powerpc/mpc83xx: Support for MPC8308 P1M board
  ...

Fix up conflict with the generic irq_work changes in arch/powerpc/kernel/time.c

12 files changed:
1  2 
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/system.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/time.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/fsl_msi.c
include/linux/pci_ids.h

index 9b287fdd8ea335352cb7034a600225b6161d6a30,6af6c1613409c3cd568c804ac3ec8f1a21929786..ec57540cd7af639b6d111f01bc2ae1f8d98c1a46
@@@ -85,6 -85,8 +85,8 @@@ struct paca_struct 
        u8 kexec_state;         /* set when kexec down has irqs off */
  #ifdef CONFIG_PPC_STD_MMU_64
        struct slb_shadow *slb_shadow_ptr;
+       struct dtl_entry *dispatch_log;
+       struct dtl_entry *dispatch_log_end;
  
        /*
         * Now, starting in cacheline 2, the exception save areas
        u8 soft_enabled;                /* irq soft-enable flag */
        u8 hard_enabled;                /* set if irqs are enabled in MSR */
        u8 io_sync;                     /* writel() needs spin_unlock sync */
 -      u8 perf_event_pending;          /* PM interrupt while soft-disabled */
 +      u8 irq_work_pending;            /* IRQ_WORK interrupt while soft-disable */
  
        /* Stuff for accurate time accounting */
        u64 user_time;                  /* accumulated usermode TB ticks */
        u64 system_time;                /* accumulated system TB ticks */
-       u64 startpurr;                  /* PURR/TB value snapshot */
+       u64 user_time_scaled;           /* accumulated usermode SPURR ticks */
+       u64 starttime;                  /* TB value snapshot */
+       u64 starttime_user;             /* TB value on exit to usermode */
        u64 startspurr;                 /* SPURR value snapshot */
+       u64 utime_sspurr;               /* ->user_time when ->startspurr set */
+       u64 stolen_time;                /* TB ticks taken by hypervisor */
+       u64 dtl_ridx;                   /* read index in dispatch log */
+       struct dtl_entry *dtl_curr;     /* pointer corresponding to dtl_ridx */
  
  #ifdef CONFIG_KVM_BOOK3S_HANDLER
        /* We use this to store guest state in */
index 9c3d160670b4ed928da2b92bdbfd60dad8a214ae,0b3fe78be71beb9d1aad0c2d698b72bf3e65a37c..5e474ddd227382350fc82ae0e2ca80352d1fd070
@@@ -154,8 -154,8 +154,8 @@@ extern void enable_kernel_spe(void)
  extern void giveup_spe(struct task_struct *);
  extern void load_up_spe(struct task_struct *);
  extern int fix_alignment(struct pt_regs *);
- extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
- extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+ extern void cvt_fd(float *from, double *to);
+ extern void cvt_df(double *from, float *to);
  
  #ifndef CONFIG_SMP
  extern void discard_lazy_cpu_state(void);
@@@ -542,6 -542,10 +542,6 @@@ extern void reloc_got2(unsigned long)
  
  #define PTRRELOC(x)   ((typeof(x)) add_reloc_offset((unsigned long)(x)))
  
 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING
 -extern void account_system_vtime(struct task_struct *);
 -#endif
 -
  extern struct dentry *powerpc_debugfs_root;
  
  #endif /* __KERNEL__ */
index 1903290f5469e0cab341e9c0f6db06b8b4ca286a,4002b48fd607f07aa84b8c9e845fedac652a9ecd..ce557f6f00fcf2817c38ad8821a2e7fc8c8394a4
@@@ -116,7 -116,7 +116,7 @@@ static inline notrace void set_soft_ena
        : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
  }
  
 -notrace void raw_local_irq_restore(unsigned long en)
 +notrace void arch_local_irq_restore(unsigned long en)
  {
        /*
         * get_paca()->soft_enabled = en;
  
        __hard_irq_enable();
  }
 -EXPORT_SYMBOL(raw_local_irq_restore);
 +EXPORT_SYMBOL(arch_local_irq_restore);
  #endif /* CONFIG_PPC64 */
  
  static int show_other_interrupts(struct seq_file *p, int prec)
@@@ -587,8 -587,10 +587,10 @@@ struct irq_host *irq_alloc_host(struct 
                         * this will be fixed once slab is made available early
                         * instead of the current cruft
                         */
-                       if (mem_init_done)
+                       if (mem_init_done) {
+                               of_node_put(host->of_node);
                                kfree(host);
+                       }
                        return NULL;
                }
                irq_map[0].host = host;
@@@ -1143,7 -1145,7 +1145,7 @@@ static int virq_debug_show(struct seq_f
        unsigned long flags;
        struct irq_desc *desc;
        const char *p;
-       char none[] = "none";
+       static const char none[] = "none";
        int i;
  
        seq_printf(m, "%-5s  %-7s  %-15s  %s\n", "virq", "hwirq",
index a4e72159234f4c93213458b82f9d11cf2b5d95ce,cefc0df8f1e5694dcf769ad5b913fb54423826c1..ebf9846f3c3b30b7cf2d61d48a8a96c37b702c1c
@@@ -26,6 -26,20 +26,20 @@@ extern unsigned long __toc_start
  
  #ifdef CONFIG_PPC_BOOK3S
  
+ /*
+  * We only have to have statically allocated lppaca structs on
+  * legacy iSeries, which supports at most 64 cpus.
+  */
+ #ifdef CONFIG_PPC_ISERIES
+ #if NR_CPUS < 64
+ #define NR_LPPACAS    NR_CPUS
+ #else
+ #define NR_LPPACAS    64
+ #endif
+ #else /* not iSeries */
+ #define NR_LPPACAS    1
+ #endif
  /*
   * The structure which the hypervisor knows about - this structure
   * should not cross a page boundary.  The vpa_init/register_vpa call
@@@ -36,7 -50,7 +50,7 @@@
   * will suffice to ensure that it doesn't cross a page boundary.
   */
  struct lppaca lppaca[] = {
-       [0 ... (NR_CPUS-1)] = {
+       [0 ... (NR_LPPACAS-1)] = {
                .desc = 0xd397d781,     /* "LpPa" */
                .size = sizeof(struct lppaca),
                .dyn_proc_status = 2,
        },
  };
  
+ static struct lppaca *extra_lppacas;
+ static long __initdata lppaca_size;
+ static void allocate_lppacas(int nr_cpus, unsigned long limit)
+ {
+       if (nr_cpus <= NR_LPPACAS)
+               return;
+       lppaca_size = PAGE_ALIGN(sizeof(struct lppaca) *
+                                (nr_cpus - NR_LPPACAS));
+       extra_lppacas = __va(memblock_alloc_base(lppaca_size,
+                                                PAGE_SIZE, limit));
+ }
+ static struct lppaca *new_lppaca(int cpu)
+ {
+       struct lppaca *lp;
+       if (cpu < NR_LPPACAS)
+               return &lppaca[cpu];
+       lp = extra_lppacas + (cpu - NR_LPPACAS);
+       *lp = lppaca[0];
+       return lp;
+ }
+ static void free_lppacas(void)
+ {
+       long new_size = 0, nr;
+       if (!lppaca_size)
+               return;
+       nr = num_possible_cpus() - NR_LPPACAS;
+       if (nr > 0)
+               new_size = PAGE_ALIGN(nr * sizeof(struct lppaca));
+       if (new_size >= lppaca_size)
+               return;
+       memblock_free(__pa(extra_lppacas) + new_size, lppaca_size - new_size);
+       lppaca_size = new_size;
+ }
+ #else
+ static inline void allocate_lppacas(int nr_cpus, unsigned long limit) { }
+ static inline void free_lppacas(void) { }
  #endif /* CONFIG_PPC_BOOK3S */
  
  #ifdef CONFIG_PPC_STD_MMU_64
@@@ -88,7 -150,7 +150,7 @@@ void __init initialise_paca(struct paca
        unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
  
  #ifdef CONFIG_PPC_BOOK3S
-       new_paca->lppaca_ptr = &lppaca[cpu];
+       new_paca->lppaca_ptr = new_lppaca(cpu);
  #else
        new_paca->kernel_pgd = swapper_pg_dir;
  #endif
@@@ -127,7 -189,7 +189,7 @@@ void __init allocate_pacas(void
         * the first segment. On iSeries they must be within the area mapped
         * by the HV, which is HvPagesToMap * HVPAGESIZE bytes.
         */
 -      limit = min(0x10000000ULL, memblock.rmo_size);
 +      limit = min(0x10000000ULL, ppc64_rma_size);
        if (firmware_has_feature(FW_FEATURE_ISERIES))
                limit = min(limit, HvPagesToMap * HVPAGESIZE);
  
        printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
                paca_size, nr_cpus, paca);
  
+       allocate_lppacas(nr_cpus, limit);
        /* Can't use for_each_*_cpu, as they aren't functional yet */
        for (cpu = 0; cpu < nr_cpus; cpu++)
                initialise_paca(&paca[cpu], cpu);
@@@ -164,4 -228,6 +228,6 @@@ void __init free_unused_pacas(void
                paca_size - new_size);
  
        paca_size = new_size;
+       free_lppacas();
  }
index 7333fdbf857b73592496d63b70a2f735915066b3,dc67ea46465e62846b73f8ec862f2bdf7e3f502c..8fe8bc61c10a5543a2cd1553fbe613a096054586
@@@ -805,7 -805,7 +805,7 @@@ static void rtas_percpu_suspend_me(voi
        __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
  }
  
static int rtas_ibm_suspend_me(struct rtas_args *args)
+ int rtas_ibm_suspend_me(struct rtas_args *args)
  {
        long state;
        long rc;
        return atomic_read(&data.error);
  }
  #else /* CONFIG_PPC_PSERIES */
static int rtas_ibm_suspend_me(struct rtas_args *args)
+ int rtas_ibm_suspend_me(struct rtas_args *args)
  {
        return -ENOSYS;
  }
@@@ -969,7 -969,7 +969,7 @@@ void __init rtas_initialize(void
         */
  #ifdef CONFIG_PPC64
        if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
 -              rtas_region = min(memblock.rmo_size, RTAS_INSTANTIATE_MAX);
 +              rtas_region = min(ppc64_rma_size, RTAS_INSTANTIATE_MAX);
                ibm_suspend_me_token = rtas_token("ibm,suspend-me");
        }
  #endif
index b86111fe9257c1ad892dcfd99f04f33d73e6b45c,8da1632f9fe743eb02d01afa60435c75cec41d90..1d2fbc905303401c50bbd410da0118338cb05eb7
@@@ -46,7 -46,7 +46,7 @@@
  
  extern void bootx_init(unsigned long r4, unsigned long phys);
  
- int boot_cpuid;
+ int boot_cpuid = -1;
  EXPORT_SYMBOL_GPL(boot_cpuid);
  int boot_cpuid_phys;
  
@@@ -246,7 -246,7 +246,7 @@@ static void __init irqstack_early_init(
        unsigned int i;
  
        /* interrupt stacks must be in lowmem, we get that for free on ppc32
 -       * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
 +       * as the memblock is limited to lowmem by default */
        for_each_possible_cpu(i) {
                softirq_ctx[i] = (struct thread_info *)
                        __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
index 54888eb10c3b4686f5b3d29a7166afc87bc76da0,644f9188d8e7c33edca56caa2eb54bd2042c41cc..010406958d974a4d0275be31bbba90af2de5035a
@@@ -53,7 -53,7 +53,7 @@@
  #include <linux/posix-timers.h>
  #include <linux/irq.h>
  #include <linux/delay.h>
 -#include <linux/perf_event.h>
 +#include <linux/irq_work.h>
  #include <asm/trace.h>
  
  #include <asm/io.h>
@@@ -161,10 -161,9 +161,9 @@@ extern struct timezone sys_tz
  static long timezone_offset;
  
  unsigned long ppc_proc_freq;
- EXPORT_SYMBOL(ppc_proc_freq);
+ EXPORT_SYMBOL_GPL(ppc_proc_freq);
  unsigned long ppc_tb_freq;
- static DEFINE_PER_CPU(u64, last_jiffy);
+ EXPORT_SYMBOL_GPL(ppc_tb_freq);
  
  #ifdef CONFIG_VIRT_CPU_ACCOUNTING
  /*
@@@ -185,6 -184,8 +184,8 @@@ DEFINE_PER_CPU(unsigned long, cputime_s
  
  cputime_t cputime_one_jiffy;
  
+ void (*dtl_consumer)(struct dtl_entry *, u64);
  static void calc_cputime_factors(void)
  {
        struct div_result res;
  }
  
  /*
-  * Read the PURR on systems that have it, otherwise the timebase.
+  * Read the SPURR on systems that have it, otherwise the PURR,
+  * or if that doesn't exist return the timebase value passed in.
   */
- static u64 read_purr(void)
+ static u64 read_spurr(u64 tb)
  {
+       if (cpu_has_feature(CPU_FTR_SPURR))
+               return mfspr(SPRN_SPURR);
        if (cpu_has_feature(CPU_FTR_PURR))
                return mfspr(SPRN_PURR);
-       return mftb();
+       return tb;
  }
  
+ #ifdef CONFIG_PPC_SPLPAR
  /*
-  * Read the SPURR on systems that have it, otherwise the purr
+  * Scan the dispatch trace log and count up the stolen time.
+  * Should be called with interrupts disabled.
   */
- static u64 read_spurr(u64 purr)
+ static u64 scan_dispatch_log(u64 stop_tb)
  {
-       /*
-        * cpus without PURR won't have a SPURR
-        * We already know the former when we use this, so tell gcc
-        */
-       if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
-               return mfspr(SPRN_SPURR);
-       return purr;
+       u64 i = local_paca->dtl_ridx;
+       struct dtl_entry *dtl = local_paca->dtl_curr;
+       struct dtl_entry *dtl_end = local_paca->dispatch_log_end;
+       struct lppaca *vpa = local_paca->lppaca_ptr;
+       u64 tb_delta;
+       u64 stolen = 0;
+       u64 dtb;
+       if (i == vpa->dtl_idx)
+               return 0;
+       while (i < vpa->dtl_idx) {
+               if (dtl_consumer)
+                       dtl_consumer(dtl, i);
+               dtb = dtl->timebase;
+               tb_delta = dtl->enqueue_to_dispatch_time +
+                       dtl->ready_to_enqueue_time;
+               barrier();
+               if (i + N_DISPATCH_LOG < vpa->dtl_idx) {
+                       /* buffer has overflowed */
+                       i = vpa->dtl_idx - N_DISPATCH_LOG;
+                       dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG);
+                       continue;
+               }
+               if (dtb > stop_tb)
+                       break;
+               stolen += tb_delta;
+               ++i;
+               ++dtl;
+               if (dtl == dtl_end)
+                       dtl = local_paca->dispatch_log;
+       }
+       local_paca->dtl_ridx = i;
+       local_paca->dtl_curr = dtl;
+       return stolen;
  }
  
+ /*
+  * Accumulate stolen time by scanning the dispatch trace log.
+  * Called on entry from user mode.
+  */
+ void accumulate_stolen_time(void)
+ {
+       u64 sst, ust;
+       sst = scan_dispatch_log(get_paca()->starttime_user);
+       ust = scan_dispatch_log(get_paca()->starttime);
+       get_paca()->system_time -= sst;
+       get_paca()->user_time -= ust;
+       get_paca()->stolen_time += ust + sst;
+ }
+ static inline u64 calculate_stolen_time(u64 stop_tb)
+ {
+       u64 stolen = 0;
+       if (get_paca()->dtl_ridx != get_paca()->lppaca_ptr->dtl_idx) {
+               stolen = scan_dispatch_log(stop_tb);
+               get_paca()->system_time -= stolen;
+       }
+       stolen += get_paca()->stolen_time;
+       get_paca()->stolen_time = 0;
+       return stolen;
+ }
+ #else /* CONFIG_PPC_SPLPAR */
+ static inline u64 calculate_stolen_time(u64 stop_tb)
+ {
+       return 0;
+ }
+ #endif /* CONFIG_PPC_SPLPAR */
  /*
   * Account time for a transition between system, hard irq
   * or soft irq state.
   */
  void account_system_vtime(struct task_struct *tsk)
  {
-       u64 now, nowscaled, delta, deltascaled, sys_time;
+       u64 now, nowscaled, delta, deltascaled;
        unsigned long flags;
+       u64 stolen, udelta, sys_scaled, user_scaled;
  
        local_irq_save(flags);
-       now = read_purr();
+       now = mftb();
        nowscaled = read_spurr(now);
-       delta = now - get_paca()->startpurr;
+       get_paca()->system_time += now - get_paca()->starttime;
+       get_paca()->starttime = now;
        deltascaled = nowscaled - get_paca()->startspurr;
-       get_paca()->startpurr = now;
        get_paca()->startspurr = nowscaled;
-       if (!in_interrupt()) {
-               /* deltascaled includes both user and system time.
-                * Hence scale it based on the purr ratio to estimate
-                * the system time */
-               sys_time = get_paca()->system_time;
-               if (get_paca()->user_time)
-                       deltascaled = deltascaled * sys_time /
-                            (sys_time + get_paca()->user_time);
-               delta += sys_time;
-               get_paca()->system_time = 0;
+       stolen = calculate_stolen_time(now);
+       delta = get_paca()->system_time;
+       get_paca()->system_time = 0;
+       udelta = get_paca()->user_time - get_paca()->utime_sspurr;
+       get_paca()->utime_sspurr = get_paca()->user_time;
+       /*
+        * Because we don't read the SPURR on every kernel entry/exit,
+        * deltascaled includes both user and system SPURR ticks.
+        * Apportion these ticks to system SPURR ticks and user
+        * SPURR ticks in the same ratio as the system time (delta)
+        * and user time (udelta) values obtained from the timebase
+        * over the same interval.  The system ticks get accounted here;
+        * the user ticks get saved up in paca->user_time_scaled to be
+        * used by account_process_tick.
+        */
+       sys_scaled = delta;
+       user_scaled = udelta;
+       if (deltascaled != delta + udelta) {
+               if (udelta) {
+                       sys_scaled = deltascaled * delta / (delta + udelta);
+                       user_scaled = deltascaled - sys_scaled;
+               } else {
+                       sys_scaled = deltascaled;
+               }
+       }
+       get_paca()->user_time_scaled += user_scaled;
+       if (in_irq() || idle_task(smp_processor_id()) != tsk) {
+               account_system_time(tsk, 0, delta, sys_scaled);
+               if (stolen)
+                       account_steal_time(stolen);
+       } else {
+               account_idle_time(delta + stolen);
        }
-       if (in_irq() || idle_task(smp_processor_id()) != tsk)
-               account_system_time(tsk, 0, delta, deltascaled);
-       else
-               account_idle_time(delta);
-       __get_cpu_var(cputime_last_delta) = delta;
-       __get_cpu_var(cputime_scaled_last_delta) = deltascaled;
        local_irq_restore(flags);
  }
  EXPORT_SYMBOL_GPL(account_system_vtime);
   * by the exception entry and exit code to the generic process
   * user and system time records.
   * Must be called with interrupts disabled.
+  * Assumes that account_system_vtime() has been called recently
+  * (i.e. since the last entry from usermode) so that
+  * get_paca()->user_time_scaled is up to date.
   */
  void account_process_tick(struct task_struct *tsk, int user_tick)
  {
        cputime_t utime, utimescaled;
  
        utime = get_paca()->user_time;
+       utimescaled = get_paca()->user_time_scaled;
        get_paca()->user_time = 0;
-       utimescaled = cputime_to_scaled(utime);
+       get_paca()->user_time_scaled = 0;
+       get_paca()->utime_sspurr = 0;
        account_user_time(tsk, utime, utimescaled);
  }
  
- /*
-  * Stuff for accounting stolen time.
-  */
- struct cpu_purr_data {
-       int     initialized;                    /* thread is running */
-       u64     tb;                     /* last TB value read */
-       u64     purr;                   /* last PURR value read */
-       u64     spurr;                  /* last SPURR value read */
- };
- /*
-  * Each entry in the cpu_purr_data array is manipulated only by its
-  * "owner" cpu -- usually in the timer interrupt but also occasionally
-  * in process context for cpu online.  As long as cpus do not touch
-  * each others' cpu_purr_data, disabling local interrupts is
-  * sufficient to serialize accesses.
-  */
- static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
- static void snapshot_tb_and_purr(void *data)
- {
-       unsigned long flags;
-       struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
-       local_irq_save(flags);
-       p->tb = get_tb_or_rtc();
-       p->purr = mfspr(SPRN_PURR);
-       wmb();
-       p->initialized = 1;
-       local_irq_restore(flags);
- }
- /*
-  * Called during boot when all cpus have come up.
-  */
- void snapshot_timebases(void)
- {
-       if (!cpu_has_feature(CPU_FTR_PURR))
-               return;
-       on_each_cpu(snapshot_tb_and_purr, NULL, 1);
- }
- /*
-  * Must be called with interrupts disabled.
-  */
- void calculate_steal_time(void)
- {
-       u64 tb, purr;
-       s64 stolen;
-       struct cpu_purr_data *pme;
-       pme = &__get_cpu_var(cpu_purr_data);
-       if (!pme->initialized)
-               return;         /* !CPU_FTR_PURR or early in early boot */
-       tb = mftb();
-       purr = mfspr(SPRN_PURR);
-       stolen = (tb - pme->tb) - (purr - pme->purr);
-       if (stolen > 0) {
-               if (idle_task(smp_processor_id()) != current)
-                       account_steal_time(stolen);
-               else
-                       account_idle_time(stolen);
-       }
-       pme->tb = tb;
-       pme->purr = purr;
- }
- #ifdef CONFIG_PPC_SPLPAR
- /*
-  * Must be called before the cpu is added to the online map when
-  * a cpu is being brought up at runtime.
-  */
- static void snapshot_purr(void)
- {
-       struct cpu_purr_data *pme;
-       unsigned long flags;
-       if (!cpu_has_feature(CPU_FTR_PURR))
-               return;
-       local_irq_save(flags);
-       pme = &__get_cpu_var(cpu_purr_data);
-       pme->tb = mftb();
-       pme->purr = mfspr(SPRN_PURR);
-       pme->initialized = 1;
-       local_irq_restore(flags);
- }
- #endif /* CONFIG_PPC_SPLPAR */
  #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
  #define calc_cputime_factors()
- #define calculate_steal_time()                do { } while (0)
  #endif
  
- #if !(defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR))
- #define snapshot_purr()                       do { } while (0)
- #endif
- /*
-  * Called when a cpu comes up after the system has finished booting,
-  * i.e. as a result of a hotplug cpu action.
-  */
- void snapshot_timebase(void)
- {
-       __get_cpu_var(last_jiffy) = get_tb_or_rtc();
-       snapshot_purr();
- }
  void __delay(unsigned long loops)
  {
        unsigned long start;
@@@ -493,60 -486,60 +486,60 @@@ void __init iSeries_time_init_early(voi
  }
  #endif /* CONFIG_PPC_ISERIES */
  
 -#ifdef CONFIG_PERF_EVENTS
 +#ifdef CONFIG_IRQ_WORK
  
  /*
   * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
   */
  #ifdef CONFIG_PPC64
 -static inline unsigned long test_perf_event_pending(void)
 +static inline unsigned long test_irq_work_pending(void)
  {
        unsigned long x;
  
        asm volatile("lbz %0,%1(13)"
                : "=r" (x)
 -              : "i" (offsetof(struct paca_struct, perf_event_pending)));
 +              : "i" (offsetof(struct paca_struct, irq_work_pending)));
        return x;
  }
  
 -static inline void set_perf_event_pending_flag(void)
 +static inline void set_irq_work_pending_flag(void)
  {
        asm volatile("stb %0,%1(13)" : :
                "r" (1),
 -              "i" (offsetof(struct paca_struct, perf_event_pending)));
 +              "i" (offsetof(struct paca_struct, irq_work_pending)));
  }
  
 -static inline void clear_perf_event_pending(void)
 +static inline void clear_irq_work_pending(void)
  {
        asm volatile("stb %0,%1(13)" : :
                "r" (0),
 -              "i" (offsetof(struct paca_struct, perf_event_pending)));
 +              "i" (offsetof(struct paca_struct, irq_work_pending)));
  }
  
  #else /* 32-bit */
  
 -DEFINE_PER_CPU(u8, perf_event_pending);
 +DEFINE_PER_CPU(u8, irq_work_pending);
  
 -#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
 -#define test_perf_event_pending()     __get_cpu_var(perf_event_pending)
 -#define clear_perf_event_pending()    __get_cpu_var(perf_event_pending) = 0
 +#define set_irq_work_pending_flag()   __get_cpu_var(irq_work_pending) = 1
 +#define test_irq_work_pending()               __get_cpu_var(irq_work_pending)
 +#define clear_irq_work_pending()      __get_cpu_var(irq_work_pending) = 0
  
  #endif /* 32 vs 64 bit */
  
 -void set_perf_event_pending(void)
 +void set_irq_work_pending(void)
  {
        preempt_disable();
 -      set_perf_event_pending_flag();
 +      set_irq_work_pending_flag();
        set_dec(1);
        preempt_enable();
  }
  
 -#else  /* CONFIG_PERF_EVENTS */
 +#else  /* CONFIG_IRQ_WORK */
  
 -#define test_perf_event_pending()     0
 -#define clear_perf_event_pending()
 +#define test_irq_work_pending()       0
 +#define clear_irq_work_pending()
  
 -#endif /* CONFIG_PERF_EVENTS */
 +#endif /* CONFIG_IRQ_WORK */
  
  /*
   * For iSeries shared processors, we have to let the hypervisor
@@@ -585,11 -578,9 +578,9 @@@ void timer_interrupt(struct pt_regs * r
        old_regs = set_irq_regs(regs);
        irq_enter();
  
-       calculate_steal_time();
 -      if (test_perf_event_pending()) {
 -              clear_perf_event_pending();
 -              perf_event_do_pending();
 +      if (test_irq_work_pending()) {
 +              clear_irq_work_pending();
 +              irq_work_run();
        }
  
  #ifdef CONFIG_PPC_ISERIES
index cde270847e7c10f5b405d5e2640b72354b0e6d1f,67bc8a7c7e0be37c2b8951b2c4d76a5e417ec248..f7802c8bba0a6b31be879ecf1446f474c00d52b8
@@@ -40,7 -40,6 +40,7 @@@
  #include <linux/init.h>
  #include <linux/delay.h>
  #include <linux/highmem.h>
 +#include <linux/memblock.h>
  
  #include <asm/pgalloc.h>
  #include <asm/prom.h>
  
  unsigned int tlbcam_index;
  
- #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
- #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
- #endif
  #define NUM_TLBCAMS   (64)
  struct tlbcam TLBCAM[NUM_TLBCAMS];
  
@@@ -138,7 -132,8 +133,8 @@@ static void settlbcam(int index, unsign
        if (mmu_has_feature(MMU_FTR_BIG_PHYS))
                TLBCAM[index].MAS7 = (u64)phys >> 32;
  
-       if (flags & _PAGE_USER) {
+       /* Below is unlikely -- only for large user pages or similar */
+       if (pte_user(flags)) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }
@@@ -185,6 -180,12 +181,12 @@@ unsigned long map_mem_in_cams(unsigned 
        return amount_mapped;
  }
  
+ #ifdef CONFIG_PPC32
+ #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
+ #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
+ #endif
  unsigned long __init mmu_mapin_ram(unsigned long top)
  {
        return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
@@@ -214,14 -215,6 +216,15 @@@ void __init adjust_total_lowmem(void
        pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
                (unsigned int)((total_lowmem - __max_low_memory) >> 20));
  
 -      __initial_memory_limit_addr = memstart_addr + __max_low_memory;
 +      memblock_set_current_limit(memstart_addr + __max_low_memory);
 +}
 +
 +void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 +                              phys_addr_t first_memblock_size)
 +{
 +      phys_addr_t limit = first_memblock_base + first_memblock_size;
 +
 +      /* 64M mapped initially according to head_fsl_booke.S */
 +      memblock_set_current_limit(min_t(u64, limit, 0x04000000));
  }
+ #endif
index 6a0f20c25469f58e41b6f3b2b88f339a29dc3d81,61fe32a256dad634cd472cbc72a63b9edc1386e8..36c0c449a89993659c60d1b4c4b772fb5aa5f94c
@@@ -349,11 -349,47 +349,47 @@@ void tlb_flush_pgtable(struct mmu_gathe
  
  static void setup_page_sizes(void)
  {
-       unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG);
-       unsigned int tlb0ps = mfspr(SPRN_TLB0PS);
-       unsigned int eptcfg = mfspr(SPRN_EPTCFG);
+       unsigned int tlb0cfg;
+       unsigned int tlb0ps;
+       unsigned int eptcfg;
        int i, psize;
  
+ #ifdef CONFIG_PPC_FSL_BOOK3E
+       unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+       if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) &&
+               (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) {
+               unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+               unsigned int min_pg, max_pg;
+               min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+               max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+               for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+                       struct mmu_psize_def *def;
+                       unsigned int shift;
+                       def = &mmu_psize_defs[psize];
+                       shift = def->shift;
+                       if (shift == 0)
+                               continue;
+                       /* adjust to be in terms of 4^shift Kb */
+                       shift = (shift - 10) >> 1;
+                       if ((shift >= min_pg) && (shift <= max_pg))
+                               def->flags |= MMU_PAGE_SIZE_DIRECT;
+               }
+               goto no_indirect;
+       }
+ #endif
+       tlb0cfg = mfspr(SPRN_TLB0CFG);
+       tlb0ps = mfspr(SPRN_TLB0PS);
+       eptcfg = mfspr(SPRN_EPTCFG);
        /* Look for supported direct sizes */
        for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
                struct mmu_psize_def *def = &mmu_psize_defs[psize];
@@@ -505,12 -541,24 +541,26 @@@ static void __early_init_mmu(int boot_c
         */
        linear_map_top = memblock_end_of_DRAM();
  
+ #ifdef CONFIG_PPC_FSL_BOOK3E
+       if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+               unsigned int num_cams;
+               /* use a quarter of the TLBCAM for bolted linear map */
+               num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+               linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
+               /* limit memory so we dont have linear faults */
+               memblock_enforce_memory_limit(linear_map_top);
+               memblock_analyze();
+       }
+ #endif
        /* A sync won't hurt us after mucking around with
         * the MMU configuration
         */
        mb();
 +
 +      memblock_set_current_limit(linear_map_top);
  }
  
  void __init early_init_mmu(void)
@@@ -523,18 -571,4 +573,18 @@@ void __cpuinit early_init_mmu_secondary
        __early_init_mmu(0);
  }
  
 +void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 +                              phys_addr_t first_memblock_size)
 +{
 +      /* On Embedded 64-bit, we adjust the RMA size to match
 +       * the bolted TLB entry. We know for now that only 1G
 +       * entries are supported though that may eventually
 +       * change. We crop it to the size of the first MEMBLOCK to
 +       * avoid going over total available memory just in case...
 +       */
 +      ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
 +
 +      /* Finally limit subsequent allocations */
 +      memblock_set_current_limit(ppc64_memblock_base + ppc64_rma_size);
 +}
  #endif /* CONFIG_PPC64 */
index 67e2c4bdac8fd7de4e3ca277439a93fc2600a7eb,7c1e3426888b7e17c4bc00ea9dad6a642d554cd3..7b96e5a270ce7b768ad13a8f4de2de3d84f4c692
@@@ -178,7 -178,7 +178,7 @@@ static int get_irq_server(unsigned int 
        if (!distribute_irqs)
                return default_server;
  
-       if (!cpumask_equal(cpumask, cpu_all_mask)) {
+       if (!cpumask_subset(cpu_possible_mask, cpumask)) {
                int server = cpumask_first_and(cpu_online_mask, cpumask);
  
                if (server < nr_cpu_ids)
@@@ -243,7 -243,7 +243,7 @@@ static unsigned int xics_startup(unsign
         * at that level, so we do it here by hand.
         */
        if (irq_to_desc(virq)->msi_desc)
 -              unmask_msi_irq(virq);
 +              unmask_msi_irq(irq_get_irq_data(virq));
  
        /* unmask it */
        xics_unmask_irq(virq);
index bdbd896c89d81195bf7c77ed67d0761dbaa4f496,20cdcd2b0eedabbe7af2d9ab717c1c5e27d836a1..108d76fa8f1c997f566a1a3448402ce9e55d3bae
@@@ -24,6 -24,7 +24,7 @@@
  #include <asm/ppc-pci.h>
  #include <asm/mpic.h>
  #include "fsl_msi.h"
+ #include "fsl_pci.h"
  
  LIST_HEAD(msi_head);
  
@@@ -51,8 -52,8 +52,8 @@@ static void fsl_msi_end_irq(unsigned in
  }
  
  static struct irq_chip fsl_msi_chip = {
 -      .mask           = mask_msi_irq,
 -      .unmask         = unmask_msi_irq,
 +      .irq_mask       = mask_msi_irq,
 +      .irq_unmask     = unmask_msi_irq,
        .ack            = fsl_msi_end_irq,
        .name           = "FSL-MSI",
  };
@@@ -125,13 -126,11 +126,11 @@@ static void fsl_compose_msi_msg(struct 
  {
        struct fsl_msi *msi_data = fsl_msi_data;
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-       u32 base = 0;
+       u64 base = fsl_pci_immrbar_base(hose);
  
-       pci_bus_read_config_dword(hose->bus,
-               PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+       msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
+       msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
  
-       msg->address_lo = msi_data->msi_addr_lo + base;
-       msg->address_hi = msi_data->msi_addr_hi;
        msg->data = hwirq;
  
        pr_debug("%s: allocated srs: %d, ibs: %d\n",
diff --combined include/linux/pci_ids.h
index 2615c37c8fe507c0126174dfa8572e6b5e78651c,f69dfe5e01ef3eda1440f77979a0434996a9ca38..dad30734432ac3a0a0ee4523d443c9e29880bc4c
  #define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302
  #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303
  #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304
 +#define PCI_DEVICE_ID_AMD_15H_NB_MISC 0x1603
  #define PCI_DEVICE_ID_AMD_LANCE               0x2000
  #define PCI_DEVICE_ID_AMD_LANCE_HOME  0x2001
  #define PCI_DEVICE_ID_AMD_SCSI                0x2020
  #define PCI_DEVICE_ID_P4080           0x0401
  #define PCI_DEVICE_ID_P4040E          0x0408
  #define PCI_DEVICE_ID_P4040           0x0409
+ #define PCI_DEVICE_ID_P2040E          0x0410
+ #define PCI_DEVICE_ID_P2040           0x0411
+ #define PCI_DEVICE_ID_P3041E          0x041E
+ #define PCI_DEVICE_ID_P3041           0x041F
+ #define PCI_DEVICE_ID_P5020E          0x0420
+ #define PCI_DEVICE_ID_P5020           0x0421
+ #define PCI_DEVICE_ID_P5010E          0x0428
+ #define PCI_DEVICE_ID_P5010           0x0429
  #define PCI_DEVICE_ID_MPC8641         0x7010
  #define PCI_DEVICE_ID_MPC8641D                0x7011
  #define PCI_DEVICE_ID_MPC8610         0x7018
This page took 0.195885 seconds and 4 git commands to generate.