Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Feb 2013 01:09:55 +0000 (17:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Feb 2013 01:09:55 +0000 (17:09 -0800)
Pull powerpc updates from Benjamin Herrenschmidt:
 "So from the depth of frozen Minnesota, here's the powerpc pull request
  for 3.9.  It has a few interesting highlights, in addition to the
  usual bunch of bug fixes, minor updates, embedded device tree updates
  and new boards:

   - Hand tuned asm implementation of SHA1 (by Paulus & Michael
     Ellerman)

   - Support for Doorbell interrupts on Power8 (kind of fast
     thread-thread IPIs) by Ian Munsie

   - Long overdue cleanup of the way we handle relocation of our open
     firmware trampoline (prom_init.c) on 64-bit by Anton Blanchard

   - Support for saving/restoring & context switching the PPR (Processor
     Priority Register) on server processors that support it.  This
     allows the kernel to preserve thread priorities established by
     userspace.  By Haren Myneni.

   - DAWR (new watchpoint facility) support on Power8 by Michael Neuling

   - Ability to change the DSCR (Data Stream Control Register) which
     controls cache prefetching on a running process via ptrace by
     Alexey Kardashevskiy

   - Support for context switching the TAR register on Power8 (new
     branch target register meant to be used by some new specific
     userspace perf event interrupt facility which is yet to be enabled)
     by Ian Munsie.

   - Improve preservation of the CFAR register (which captures the
     origin of a branch) on various exception conditions by Paulus.

   - Move the Bestcomm DMA driver from arch powerpc to drivers/dma where
     it belongs by Philippe De Muyter

   - Support for Transactional Memory on Power8 by Michael Neuling
     (based on original work by Matt Evans).  For those curious about
     the feature, the patch contains a pretty good description."

(See commit db8ff907027b: "powerpc: Documentation for transactional
memory on powerpc" for the mentioned description added to the file
Documentation/powerpc/transactional_memory.txt)

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (140 commits)
  powerpc/kexec: Disable hard IRQ before kexec
  powerpc/85xx: l2sram - Add compatible string for BSC9131 platform
  powerpc/85xx: bsc9131 - Correct typo in SDHC device node
  powerpc/e500/qemu-e500: enable coreint
  powerpc/mpic: allow coreint to be determined by MPIC version
  powerpc/fsl_pci: Store the pci ctlr device ptr in the pci ctlr struct
  powerpc/85xx: Board support for ppa8548
  powerpc/fsl: remove extraneous DIU platform functions
  arch/powerpc/platforms/85xx/p1022_ds.c: adjust duplicate test
  powerpc: Documentation for transactional memory on powerpc
  powerpc: Add transactional memory to pseries and ppc64 defconfigs
  powerpc: Add config option for transactional memory
  powerpc: Add transactional memory to POWER8 cpu features
  powerpc: Add new transactional memory state to the signal context
  powerpc: Hook in new transactional memory code
  powerpc: Routines for FP/VSX/VMX unavailable during a transaction
  powerpc: Add transactional memory unavaliable execption handler
  powerpc: Add reclaim and recheckpoint functions for context switching transactional memory processes
  powerpc: Add FP/VSX and VMX register load functions for transactional memory
  powerpc: Add helper functions for transactional memory context switching
  ...

13 files changed:
1  2 
arch/powerpc/Kconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/include/asm/perf_event_server.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/pseries/setup.c
crypto/Kconfig
drivers/Makefile
drivers/dma/bestcomm/bestcomm.c
drivers/net/ethernet/freescale/fec_mpc52xx.c

diff --combined arch/powerpc/Kconfig
index e7fb8edb629b4b2c96dee92383fedf9dc5809a40,85ff3a0803609588f5a5453538391a99aa042e00..a5255f242be91424ab745bf039e6ae87a3b779af
@@@ -118,12 -118,14 +118,12 @@@ config PP
        select HAVE_SYSCALL_WRAPPERS if PPC64
        select GENERIC_ATOMIC64 if PPC32
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 -      select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
        select HAVE_GENERIC_HARDIRQS
        select ARCH_WANT_IPC_PARSE_VERSION
        select SPARSE_IRQ
 -      select IRQ_PER_CPU
        select IRQ_DOMAIN
        select GENERIC_IRQ_SHOW
        select GENERIC_IRQ_SHOW_LEVEL
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
        select CLONE_BACKWARDS
+       select ARCH_USE_BUILTIN_BSWAP
  
  config EARLY_PRINTK
        bool
@@@ -273,6 -276,10 +274,10 @@@ config PPC_ADV_DEBUG_DAC_RANG
        depends on PPC_ADV_DEBUG_REGS && 44x
        default y
  
+ config PPC_EMULATE_SSTEP
+       bool
+       default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT
  source "init/Kconfig"
  
  source "kernel/Kconfig.freezer"
@@@ -306,6 -313,14 +311,14 @@@ config MATH_EMULATIO
          unit, which will allow programs that use floating-point
          instructions to run.
  
+ config PPC_TRANSACTIONAL_MEM
+        bool "Transactional Memory support for POWERPC"
+        depends on PPC_BOOK3S_64
+        depends on SMP
+        default n
+        ---help---
+          Support user-mode Transactional Memory on POWERPC.
  config 8XX_MINIMAL_FPEMU
        bool "Minimal math emulation for 8xx"
        depends on 8xx && !MATH_EMULATION
@@@ -332,7 -347,7 +345,7 @@@ config SWIOTL
  
  config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
 -      depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
 +      depends on SMP && HOTPLUG && (PPC_PSERIES || \
        PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
        ---help---
          Say Y here to be able to disable and re-enable individual
@@@ -354,8 -369,8 +367,8 @@@ config ARCH_ENABLE_MEMORY_HOTREMOV
        def_bool y
  
  config KEXEC
 -      bool "kexec system call (EXPERIMENTAL)"
 -      depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) && EXPERIMENTAL
 +      bool "kexec system call"
 +      depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP))
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
@@@ -850,8 -865,8 +863,8 @@@ config LOWMEM_CAM_NU
        default 3
  
  config DYNAMIC_MEMSTART
 -      bool "Enable page aligned dynamic load address for kernel (EXPERIMENTAL)"
 -      depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && (FSL_BOOKE || 44x)
 +      bool "Enable page aligned dynamic load address for kernel"
 +      depends on ADVANCED_OPTIONS && FLATMEM && (FSL_BOOKE || 44x)
        select NONSTATIC_KERNEL
        help
          This option enables the kernel to be loaded at any page aligned
          This option is overridden by CONFIG_RELOCATABLE
  
  config RELOCATABLE
 -      bool "Build a relocatable kernel (EXPERIMENTAL)"
 -      depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && 44x
 +      bool "Build a relocatable kernel"
 +      depends on ADVANCED_OPTIONS && FLATMEM && 44x
        select NONSTATIC_KERNEL
        help
          This builds a kernel image that is capable of running at the
index f7df8362911fc80644b03badd8c639538ff59afd,7375961f017b3a4a46e64213322ba912c9371404..3d139fa04050364f4d4d5a76a0d5f27cfa8938ce
@@@ -1,6 -1,6 +1,6 @@@
  CONFIG_PPC64=y
  CONFIG_PPC_BOOK3E_64=y
 -# CONFIG_VIRT_CPU_ACCOUNTING is not set
 +# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
  CONFIG_SMP=y
  CONFIG_NR_CPUS=2
  CONFIG_EXPERIMENTAL=y
@@@ -26,7 -26,6 +26,6 @@@ CONFIG_P5020_DS=
  CONFIG_P5040_DS=y
  # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
  CONFIG_BINFMT_MISC=m
- CONFIG_IRQ_ALL_CPUS=y
  CONFIG_PCIEPORTBUS=y
  CONFIG_PCI_MSI=y
  CONFIG_RAPIDIO=y
index 136bba62efa48775bd8b4738f675e8796b0ee0b2,d3e97487c72c80da90c7590b949888edc99f5e77..d0aec72722e945f5ac00c82047cef4a7257622bc
@@@ -11,7 -11,6 +11,7 @@@
  
  #include <linux/types.h>
  #include <asm/hw_irq.h>
 +#include <linux/device.h>
  
  #define MAX_HWEVENTS          8
  #define MAX_EVENT_ALTERNATIVES        8
@@@ -36,7 -35,6 +36,7 @@@ struct power_pmu 
        void            (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
        int             (*limited_pmc_event)(u64 event_id);
        u32             flags;
 +      const struct attribute_group    **attr_groups;
        int             n_generic;
        int             *generic_events;
        int             (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
  /*
   * Values for power_pmu.flags
   */
- #define PPMU_LIMITED_PMC5_6   1       /* PMC5/6 have limited function */
- #define PPMU_ALT_SIPR         2       /* uses alternate posn for SIPR/HV */
- #define PPMU_NO_SIPR          4       /* no SIPR/HV in MMCRA at all */
- #define PPMU_NO_CONT_SAMPLING 8       /* no continuous sampling */
- #define PPMU_SIAR_VALID               16      /* Processor has SIAR Valid bit */
+ #define PPMU_LIMITED_PMC5_6   0x00000001 /* PMC5/6 have limited function */
+ #define PPMU_ALT_SIPR         0x00000002 /* uses alternate posn for SIPR/HV */
+ #define PPMU_NO_SIPR          0x00000004 /* no SIPR/HV in MMCRA at all */
+ #define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */
+ #define PPMU_SIAR_VALID               0x00000010 /* Processor has SIAR Valid bit */
  
  /*
   * Values for flags to get_alternatives()
@@@ -111,27 -109,3 +111,27 @@@ extern unsigned long perf_instruction_p
   * If an event_id is not subject to the constraint expressed by a particular
   * field, then it will have 0 in both the mask and value for that field.
   */
 +
 +extern ssize_t power_events_sysfs_show(struct device *dev,
 +                              struct device_attribute *attr, char *page);
 +
 +/*
 + * EVENT_VAR() is same as PMU_EVENT_VAR with a suffix.
 + *
 + * Having a suffix allows us to have aliases in sysfs - eg: the generic
 + * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and
 + * 'PM_CYC' where the latter is the name by which the event is known in
 + * POWER CPU specification.
 + */
 +#define       EVENT_VAR(_id, _suffix)         event_attr_##_id##_suffix
 +#define       EVENT_PTR(_id, _suffix)         &EVENT_VAR(_id, _suffix).attr.attr
 +
 +#define       EVENT_ATTR(_name, _id, _suffix)                                 \
 +      PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_PM_##_id,    \
 +                      power_events_sysfs_show)
 +
 +#define       GENERIC_EVENT_ATTR(_name, _id)  EVENT_ATTR(_name, _id, _g)
 +#define       GENERIC_EVENT_PTR(_id)          EVENT_PTR(_id, _g)
 +
 +#define       POWER_EVENT_ATTR(_name, _id)    EVENT_ATTR(PM_##_name, _id, _p)
 +#define       POWER_EVENT_PTR(_id)            EVENT_PTR(_id, _p)
index 2d0e1f5d83394a60544cc3a3fa003973c868596b,54219cea9e88bbdce78518e74dcc022e1779c2be..cea8496091ffbd1cb2437061cb1f7772f3b8bbc3
   * user_time and system_time fields in the paca.
   */
  
 -#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
  #define ACCOUNT_CPU_USER_ENTRY(ra, rb)
  #define ACCOUNT_CPU_USER_EXIT(ra, rb)
  #define ACCOUNT_STOLEN_TIME
  #else
  #define ACCOUNT_CPU_USER_ENTRY(ra, rb)                                        \
-       beq     2f;                     /* if from kernel mode */       \
        MFTB(ra);                       /* get timebase */              \
        ld      rb,PACA_STARTTIME_USER(r13);                            \
        std     ra,PACA_STARTTIME(r13);                                 \
@@@ -38,7 -37,6 +37,6 @@@
        ld      ra,PACA_USER_TIME(r13);                                 \
        add     ra,ra,rb;               /* add on to user time */       \
        std     ra,PACA_USER_TIME(r13);                                 \
- 2:
  
  #define ACCOUNT_CPU_USER_EXIT(ra, rb)                                 \
        MFTB(ra);                       /* get timebase */              \
@@@ -70,7 -68,7 +68,7 @@@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPL
  
  #endif /* CONFIG_PPC_SPLPAR */
  
 -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
 +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
  
  /*
   * Macros for storing registers into and loading registers from
  #define REST_16VRS(n,b,base)  REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
  #define REST_32VRS(n,b,base)  REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
  
+ /* Save/restore FPRs, VRs and VSRs from their checkpointed backups in
+  * thread_struct:
+  */
+ #define SAVE_FPR_TRANSACT(n, base)    stfd n,THREAD_TRANSACT_FPR0+    \
+                                       8*TS_FPRWIDTH*(n)(base)
+ #define SAVE_2FPRS_TRANSACT(n, base)  SAVE_FPR_TRANSACT(n, base);     \
+                                       SAVE_FPR_TRANSACT(n+1, base)
+ #define SAVE_4FPRS_TRANSACT(n, base)  SAVE_2FPRS_TRANSACT(n, base);   \
+                                       SAVE_2FPRS_TRANSACT(n+2, base)
+ #define SAVE_8FPRS_TRANSACT(n, base)  SAVE_4FPRS_TRANSACT(n, base);   \
+                                       SAVE_4FPRS_TRANSACT(n+4, base)
+ #define SAVE_16FPRS_TRANSACT(n, base) SAVE_8FPRS_TRANSACT(n, base);   \
+                                       SAVE_8FPRS_TRANSACT(n+8, base)
+ #define SAVE_32FPRS_TRANSACT(n, base) SAVE_16FPRS_TRANSACT(n, base);  \
+                                       SAVE_16FPRS_TRANSACT(n+16, base)
+ #define REST_FPR_TRANSACT(n, base)    lfd     n,THREAD_TRANSACT_FPR0+ \
+                                       8*TS_FPRWIDTH*(n)(base)
+ #define REST_2FPRS_TRANSACT(n, base)  REST_FPR_TRANSACT(n, base);     \
+                                       REST_FPR_TRANSACT(n+1, base)
+ #define REST_4FPRS_TRANSACT(n, base)  REST_2FPRS_TRANSACT(n, base);   \
+                                       REST_2FPRS_TRANSACT(n+2, base)
+ #define REST_8FPRS_TRANSACT(n, base)  REST_4FPRS_TRANSACT(n, base);   \
+                                       REST_4FPRS_TRANSACT(n+4, base)
+ #define REST_16FPRS_TRANSACT(n, base) REST_8FPRS_TRANSACT(n, base);   \
+                                       REST_8FPRS_TRANSACT(n+8, base)
+ #define REST_32FPRS_TRANSACT(n, base) REST_16FPRS_TRANSACT(n, base);  \
+                                       REST_16FPRS_TRANSACT(n+16, base)
+ #define SAVE_VR_TRANSACT(n,b,base)    li b,THREAD_TRANSACT_VR0+(16*(n)); \
+                                       stvx n,b,base
+ #define SAVE_2VRS_TRANSACT(n,b,base)  SAVE_VR_TRANSACT(n,b,base);     \
+                                       SAVE_VR_TRANSACT(n+1,b,base)
+ #define SAVE_4VRS_TRANSACT(n,b,base)  SAVE_2VRS_TRANSACT(n,b,base);   \
+                                       SAVE_2VRS_TRANSACT(n+2,b,base)
+ #define SAVE_8VRS_TRANSACT(n,b,base)  SAVE_4VRS_TRANSACT(n,b,base);   \
+                                       SAVE_4VRS_TRANSACT(n+4,b,base)
+ #define SAVE_16VRS_TRANSACT(n,b,base) SAVE_8VRS_TRANSACT(n,b,base);   \
+                                       SAVE_8VRS_TRANSACT(n+8,b,base)
+ #define SAVE_32VRS_TRANSACT(n,b,base) SAVE_16VRS_TRANSACT(n,b,base);  \
+                                       SAVE_16VRS_TRANSACT(n+16,b,base)
+ #define REST_VR_TRANSACT(n,b,base)    li b,THREAD_TRANSACT_VR0+(16*(n)); \
+                                       lvx n,b,base
+ #define REST_2VRS_TRANSACT(n,b,base)  REST_VR_TRANSACT(n,b,base);     \
+                                       REST_VR_TRANSACT(n+1,b,base)
+ #define REST_4VRS_TRANSACT(n,b,base)  REST_2VRS_TRANSACT(n,b,base);   \
+                                       REST_2VRS_TRANSACT(n+2,b,base)
+ #define REST_8VRS_TRANSACT(n,b,base)  REST_4VRS_TRANSACT(n,b,base);   \
+                                       REST_4VRS_TRANSACT(n+4,b,base)
+ #define REST_16VRS_TRANSACT(n,b,base) REST_8VRS_TRANSACT(n,b,base);   \
+                                       REST_8VRS_TRANSACT(n+8,b,base)
+ #define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base);  \
+                                       REST_16VRS_TRANSACT(n+16,b,base)
+ #define SAVE_VSR_TRANSACT(n,b,base)   li b,THREAD_TRANSACT_VSR0+(16*(n)); \
+                                       STXVD2X(n,R##base,R##b)
+ #define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base);    \
+                                       SAVE_VSR_TRANSACT(n+1,b,base)
+ #define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base);  \
+                                       SAVE_2VSRS_TRANSACT(n+2,b,base)
+ #define SAVE_8VSRS_TRANSACT(n,b,base) SAVE_4VSRS_TRANSACT(n,b,base);  \
+                                       SAVE_4VSRS_TRANSACT(n+4,b,base)
+ #define SAVE_16VSRS_TRANSACT(n,b,base)        SAVE_8VSRS_TRANSACT(n,b,base);  \
+                                       SAVE_8VSRS_TRANSACT(n+8,b,base)
+ #define SAVE_32VSRS_TRANSACT(n,b,base)        SAVE_16VSRS_TRANSACT(n,b,base); \
+                                       SAVE_16VSRS_TRANSACT(n+16,b,base)
+ #define REST_VSR_TRANSACT(n,b,base)   li b,THREAD_TRANSACT_VSR0+(16*(n)); \
+                                       LXVD2X(n,R##base,R##b)
+ #define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base);    \
+                                       REST_VSR_TRANSACT(n+1,b,base)
+ #define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base);  \
+                                       REST_2VSRS_TRANSACT(n+2,b,base)
+ #define REST_8VSRS_TRANSACT(n,b,base) REST_4VSRS_TRANSACT(n,b,base);  \
+                                       REST_4VSRS_TRANSACT(n+4,b,base)
+ #define REST_16VSRS_TRANSACT(n,b,base)        REST_8VSRS_TRANSACT(n,b,base);  \
+                                       REST_8VSRS_TRANSACT(n+8,b,base)
+ #define REST_32VSRS_TRANSACT(n,b,base)        REST_16VSRS_TRANSACT(n,b,base); \
+                                       REST_16VSRS_TRANSACT(n+16,b,base)
  /* Save the lower 32 VSRs in the thread VSR region */
  #define SAVE_VSR(n,b,base)    li b,THREAD_VSR0+(16*(n));  STXVD2X(n,R##base,R##b)
  #define SAVE_2VSRS(n,b,base)  SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
@@@ -391,6 -472,31 +472,31 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_601
        FTR_SECTION_ELSE_NESTED(848);   \
        mtocrf (FXM), RS;               \
        ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848)
+ /*
+  * PPR restore macros used in entry_64.S
+  * Used for P7 or later processors
+  */
+ #define HMT_MEDIUM_LOW_HAS_PPR                                                \
+ BEGIN_FTR_SECTION_NESTED(944)                                         \
+       HMT_MEDIUM_LOW;                                                 \
+ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,944)
+ #define SET_DEFAULT_THREAD_PPR(ra, rb)                                        \
+ BEGIN_FTR_SECTION_NESTED(945)                                         \
+       lis     ra,INIT_PPR@highest;    /* default ppr=3 */             \
+       ld      rb,PACACURRENT(r13);                                    \
+       sldi    ra,ra,32;       /* 11- 13 bits are used for ppr */      \
+       std     ra,TASKTHREADPPR(rb);                                   \
+ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
+ #define RESTORE_PPR(ra, rb)                                           \
+ BEGIN_FTR_SECTION_NESTED(946)                                         \
+       ld      ra,PACACURRENT(r13);                                    \
+       ld      rb,TASKTHREADPPR(ra);                                   \
+       mtspr   SPRN_PPR,rb;    /* Restore PPR */                       \
+ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
  #endif
  
  /*
index ac057013f9fdaa5c0c64323df0a68c271de49a2f,612ea130c5d26e6e21c00e48d08bd04dc47c7ad4..256c5bf0adb7a87cb0429bc02c435f3cfecbd3b5
@@@ -62,8 -62,9 +62,9 @@@ system_call_common
        std     r12,_MSR(r1)
        std     r0,GPR0(r1)
        std     r10,GPR1(r1)
+       beq     2f                      /* if from kernel mode */
        ACCOUNT_CPU_USER_ENTRY(r10, r11)
      std     r2,GPR2(r1)
2:    std     r2,GPR2(r1)
        std     r3,GPR3(r1)
        mfcr    r2
        std     r4,GPR4(r1)
@@@ -94,7 -95,7 +95,7 @@@
        addi    r9,r1,STACK_FRAME_OVERHEAD
        ld      r11,exception_marker@toc(r2)
        std     r11,-16(r9)             /* "regshere" marker */
 -#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR)
 +#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR)
  BEGIN_FW_FTR_SECTION
        beq     33f
        /* if from user, see if there are any DTL entries to process */
        addi    r9,r1,STACK_FRAME_OVERHEAD
  33:
  END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
 -#endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */
 +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */
  
        /*
         * A syscall should always be called with interrupts enabled
@@@ -226,6 -227,7 +227,7 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHEC
  
        beq-    1f
        ACCOUNT_CPU_USER_EXIT(r11, r12)
+       HMT_MEDIUM_LOW_HAS_PPR
        ld      r13,GPR13(r1)   /* only restore r13 if returning to usermode */
  1:    ld      r2,GPR2(r1)
        ld      r1,GPR1(r1)
@@@ -302,6 -304,7 +304,7 @@@ syscall_exit_work
        subi    r12,r12,TI_FLAGS
  
  4:    /* Anything else left to do? */
+       SET_DEFAULT_THREAD_PPR(r3, r9)          /* Set thread.ppr = 3 */
        andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
        beq     .ret_from_except_lite
  
@@@ -445,6 -448,19 +448,19 @@@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR
        std     r23,_CCR(r1)
        std     r1,KSP(r3)      /* Set old stack pointer */
  
+ #ifdef CONFIG_PPC_BOOK3S_64
+ BEGIN_FTR_SECTION
+       /*
+        * Back up the TAR across context switches.  Note that the TAR is not
+        * available for use in the kernel.  (To provide this, the TAR should
+        * be backed up/restored on exception entry/exit instead, and be in
+        * pt_regs.  FIXME, this should be in pt_regs anyway (for debug).)
+        */
+       mfspr   r0,SPRN_TAR
+       std     r0,THREAD_TAR(r3)
+ END_FTR_SECTION_IFSET(CPU_FTR_BCTAR)
+ #endif
  #ifdef CONFIG_SMP
        /* We need a sync somewhere here to make sure that if the
         * previous task gets rescheduled on another CPU, it sees all
@@@ -527,6 -543,13 +543,13 @@@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SE
        mr      r1,r8           /* start using new stack pointer */
        std     r7,PACAKSAVE(r13)
  
+ #ifdef CONFIG_PPC_BOOK3S_64
+ BEGIN_FTR_SECTION
+       ld      r0,THREAD_TAR(r4)
+       mtspr   SPRN_TAR,r0
+ END_FTR_SECTION_IFSET(CPU_FTR_BCTAR)
+ #endif
  #ifdef CONFIG_ALTIVEC
  BEGIN_FTR_SECTION
        ld      r0,THREAD_VRSAVE(r4)
@@@ -762,6 -785,10 +785,10 @@@ fast_exception_return
        andc    r4,r4,r0         /* r0 contains MSR_RI here */
        mtmsrd  r4,1
  
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       /* TM debug */
+       std     r3, PACATMSCRATCH(r13) /* Stash returned-to MSR */
+ #endif
        /*
         * r13 is our per cpu area, only restore it if we are returning to
         * userspace the value stored in the stack frame may belong to
        andi.   r0,r3,MSR_PR
        beq     1f
        ACCOUNT_CPU_USER_EXIT(r2, r4)
+       RESTORE_PPR(r2, r4)
        REST_GPR(13, r1)
  1:
        mtspr   SPRN_SRR1,r3
@@@ -849,13 -877,22 +877,22 @@@ restore_check_irq_replay
        addi    r3,r1,STACK_FRAME_OVERHEAD;
        bl      .timer_interrupt
        b       .ret_from_except
+ #ifdef CONFIG_PPC_DOORBELL
+ 1:
  #ifdef CONFIG_PPC_BOOK3E
- 1:    cmpwi   cr0,r3,0x280
+       cmpwi   cr0,r3,0x280
+ #else
+       BEGIN_FTR_SECTION
+               cmpwi   cr0,r3,0xe80
+       FTR_SECTION_ELSE
+               cmpwi   cr0,r3,0xa00
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+ #endif /* CONFIG_PPC_BOOK3E */
        bne     1f
        addi    r3,r1,STACK_FRAME_OVERHEAD;
        bl      .doorbell_exception
        b       .ret_from_except
- #endif /* CONFIG_PPC_BOOK3E */
+ #endif /* CONFIG_PPC_DOORBELL */
  1:    b       .ret_from_except /* What else to do here ? */
   
  unrecov_restore:
index fa476d50791f28f690d77a236defafbe17896526,069f92b319927defe72cb703a12691695420d3b7..65362e98eb263cdf84ad61bb7f154598c9c5e3a4
@@@ -880,8 -880,16 +880,16 @@@ static int power_pmu_add(struct perf_ev
        cpuhw->events[n0] = event->hw.config;
        cpuhw->flags[n0] = event->hw.event_base;
  
+       /*
+        * This event may have been disabled/stopped in record_and_restart()
+        * because we exceeded the ->event_limit. If re-starting the event,
+        * clear the ->hw.state (STOPPED and UPTODATE flags), so the user
+        * notification is re-enabled.
+        */
        if (!(ef_flags & PERF_EF_START))
                event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+       else
+               event->hw.state = 0;
  
        /*
         * If group events scheduling transaction was started,
@@@ -1305,16 -1313,6 +1313,16 @@@ static int power_pmu_event_idx(struct p
        return event->hw.idx;
  }
  
 +ssize_t power_events_sysfs_show(struct device *dev,
 +                              struct device_attribute *attr, char *page)
 +{
 +      struct perf_pmu_events_attr *pmu_attr;
 +
 +      pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
 +
 +      return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
 +}
 +
  struct pmu power_pmu = {
        .pmu_enable     = power_pmu_enable,
        .pmu_disable    = power_pmu_disable,
@@@ -1359,6 -1357,8 +1367,8 @@@ static void record_and_restart(struct p
         */
        val = 0;
        left = local64_read(&event->hw.period_left) - delta;
+       if (delta == 0)
+               left++;
        if (period) {
                if (left <= 0) {
                        left += period;
@@@ -1422,11 -1422,8 +1432,8 @@@ unsigned long perf_instruction_pointer(
                return regs->nip;
  }
  
- static bool pmc_overflow(unsigned long val)
+ static bool pmc_overflow_power7(unsigned long val)
  {
-       if ((int)val < 0)
-               return true;
        /*
         * Events on POWER7 can roll back if a speculative event doesn't
         * eventually complete. Unfortunately in some rare cases they will
         * PMCs because a user might set a period of less than 256 and we
         * don't want to mistakenly reset them.
         */
-       if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256))
+       if ((0x80000000 - val) <= 256)
+               return true;
+       return false;
+ }
+ static bool pmc_overflow(unsigned long val)
+ {
+       if ((int)val < 0)
                return true;
  
        return false;
   */
  static void perf_event_interrupt(struct pt_regs *regs)
  {
-       int i;
+       int i, j;
        struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
        struct perf_event *event;
-       unsigned long val;
-       int found = 0;
+       unsigned long val[8];
+       int found, active;
        int nmi;
  
        if (cpuhw->n_limited)
        else
                irq_enter();
  
-       for (i = 0; i < cpuhw->n_events; ++i) {
-               event = cpuhw->event[i];
-               if (!event->hw.idx || is_limited_pmc(event->hw.idx))
+       /* Read all the PMCs since we'll need them a bunch of times */
+       for (i = 0; i < ppmu->n_counter; ++i)
+               val[i] = read_pmc(i + 1);
+       /* Try to find what caused the IRQ */
+       found = 0;
+       for (i = 0; i < ppmu->n_counter; ++i) {
+               if (!pmc_overflow(val[i]))
                        continue;
-               val = read_pmc(event->hw.idx);
-               if ((int)val < 0) {
-                       /* event has overflowed */
-                       found = 1;
-                       record_and_restart(event, val, regs);
+               if (is_limited_pmc(i + 1))
+                       continue; /* these won't generate IRQs */
+               /*
+                * We've found one that's overflowed.  For active
+                * counters we need to log this.  For inactive
+                * counters, we need to reset it anyway
+                */
+               found = 1;
+               active = 0;
+               for (j = 0; j < cpuhw->n_events; ++j) {
+                       event = cpuhw->event[j];
+                       if (event->hw.idx == (i + 1)) {
+                               active = 1;
+                               record_and_restart(event, val[i], regs);
+                               break;
+                       }
                }
+               if (!active)
+                       /* reset non active counters that have overflowed */
+                       write_pmc(i + 1, 0);
        }
-       /*
-        * In case we didn't find and reset the event that caused
-        * the interrupt, scan all events and reset any that are
-        * negative, to avoid getting continual interrupts.
-        * Any that we processed in the previous loop will not be negative.
-        */
-       if (!found) {
-               for (i = 0; i < ppmu->n_counter; ++i) {
-                       if (is_limited_pmc(i + 1))
+       if (!found && pvr_version_is(PVR_POWER7)) {
+               /* check active counters for special buggy p7 overflow */
+               for (i = 0; i < cpuhw->n_events; ++i) {
+                       event = cpuhw->event[i];
+                       if (!event->hw.idx || is_limited_pmc(event->hw.idx))
                                continue;
-                       val = read_pmc(i + 1);
-                       if (pmc_overflow(val))
-                               write_pmc(i + 1, 0);
+                       if (pmc_overflow_power7(val[event->hw.idx - 1])) {
+                               /* event has overflowed in a buggy way*/
+                               found = 1;
+                               record_and_restart(event,
+                                                  val[event->hw.idx - 1],
+                                                  regs);
+                       }
                }
        }
+       if ((!found) && printk_ratelimit())
+               printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
  
        /*
         * Reset MMCR0 to its normal value.  This will set PMXE and
@@@ -1547,8 -1572,6 +1582,8 @@@ int __cpuinit register_power_pmu(struc
        pr_info("%s performance monitor hardware support registered\n",
                pmu->name);
  
 +      power_pmu.attr_groups = ppmu->attr_groups;
 +
  #ifdef MSR_HV
        /*
         * Use FCHV to ignore kernel events if MSR.HV is set.
index 92ab60a62711d22b8c1ad2b347f165331405eded,bcc53aa09bf7d5873e6796094fe437b3e187e26c..a0dcd577fb0d4bba51a1f472411a6e71c4f03ce8
@@@ -191,6 -191,13 +191,13 @@@ config SBC854
        help
          This option enables support for the Wind River SBC8548 board
  
+ config PPA8548
+       bool "Prodrive PPA8548"
+       help
+         This option enables support for the Prodrive PPA8548 board.
+       select DEFAULT_UIMAGE
+       select HAS_RAPIDIO
  config GE_IMP3A
        bool "GE Intelligent Platforms IMP3A"
        select DEFAULT_UIMAGE
@@@ -245,6 -252,14 +252,14 @@@ config P4080_D
        help
          This option enables support for the P4080 DS board
  
+ config SGY_CTS1000
+       tristate "Servergy CTS-1000 support"
+       select GPIOLIB
+       select OF_GPIO
+       depends on P4080_DS
+       help
+         Enable this to support functionality in Servergy's CTS-1000 systems.
  endif # PPC32
  
  config P5020_DS
@@@ -277,6 -292,7 +292,6 @@@ config P5040_D
  
  config PPC_QEMU_E500
        bool "QEMU generic e500 platform"
 -      depends on EXPERIMENTAL
        select DEFAULT_UIMAGE
        help
          This option enables support for running as a QEMU guest using
index e346edf7f157dfd180128c84bf7522499246fe15,c3e47144d0e4a84344a5eff1fa727793470e8b3b..e611e79f23ce68053d0c4190adf2b2104862e6a9
        (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
        (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
  
- /**
-  * p1022ds_get_pixel_format: return the Area Descriptor for a given pixel depth
-  *
-  * The Area Descriptor is a 32-bit value that determine which bits in each
-  * pixel are to be used for each color.
-  */
- static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port,
-                                   unsigned int bits_per_pixel)
- {
-       switch (bits_per_pixel) {
-       case 32:
-               /* 0x88883316 */
-               return MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8);
-       case 24:
-               /* 0x88082219 */
-               return MAKE_AD(4, 0, 1, 2, 2, 0, 8, 8, 8);
-       case 16:
-               /* 0x65053118 */
-               return MAKE_AD(4, 2, 1, 0, 1, 5, 6, 5, 0);
-       default:
-               pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel);
-               return 0;
-       }
- }
- /**
-  * p1022ds_set_gamma_table: update the gamma table, if necessary
-  *
-  * On some boards, the gamma table for some ports may need to be modified.
-  * This is not the case on the P1022DS, so we do nothing.
- */
- static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
-                                   char *gamma_table_base)
- {
- }
  struct fsl_law {
        u32     lawbar;
        u32     reserved1;
@@@ -215,13 -179,13 +179,13 @@@ static void p1022ds_set_monitor_port(en
        /* Map the global utilities registers. */
        guts_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
        if (!guts_node) {
 -              pr_err("p1022ds: missing global utilties device node\n");
 +              pr_err("p1022ds: missing global utilities device node\n");
                return;
        }
  
        guts = of_iomap(guts_node, 0);
        if (!guts) {
 -              pr_err("p1022ds: could not map global utilties device\n");
 +              pr_err("p1022ds: could not map global utilities device\n");
                goto exit;
        }
  
                goto exit;
        }
        cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
-       if (!cs0_addr) {
+       if (!cs1_addr) {
                pr_err("p1022ds: could not determine physical address for CS1"
                       " (BR1=%08x)\n", br1);
                goto exit;
@@@ -416,14 -380,14 +380,14 @@@ void p1022ds_set_pixel_clock(unsigned i
        /* Map the global utilities registers. */
        guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
        if (!guts_np) {
 -              pr_err("p1022ds: missing global utilties device node\n");
 +              pr_err("p1022ds: missing global utilities device node\n");
                return;
        }
  
        guts = of_iomap(guts_np, 0);
        of_node_put(guts_np);
        if (!guts) {
 -              pr_err("p1022ds: could not map global utilties device\n");
 +              pr_err("p1022ds: could not map global utilities device\n");
                return;
        }
  
@@@ -510,8 -474,6 +474,6 @@@ static void __init p1022_ds_setup_arch(
                ppc_md.progress("p1022_ds_setup_arch()", 0);
  
  #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-       diu_ops.get_pixel_format        = p1022ds_get_pixel_format;
-       diu_ops.set_gamma_table         = p1022ds_set_gamma_table;
        diu_ops.set_monitor_port        = p1022ds_set_monitor_port;
        diu_ops.set_pixel_clock         = p1022ds_set_pixel_clock;
        diu_ops.valid_monitor_port      = p1022ds_valid_monitor_port;
index 527e12c9573be178757b8eb7920b94654224e589,b1f60d162bb617618d56654855b63598380d7f8c..8bcc9ca6682f66a15e96ea4d4f6deb4c14ff1f61
@@@ -65,6 -65,7 +65,7 @@@
  #include <asm/smp.h>
  #include <asm/firmware.h>
  #include <asm/eeh.h>
+ #include <asm/reg.h>
  
  #include "plpar_wrappers.h"
  #include "pseries.h"
@@@ -281,7 -282,7 +282,7 @@@ static struct notifier_block pci_dn_rec
  
  struct kmem_cache *dtl_cache;
  
 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING
 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
  /*
   * Allocate space for the dispatch trace log for all possible cpus
   * and register the buffers with the hypervisor.  This is used for
@@@ -332,12 -333,12 +333,12 @@@ static int alloc_dispatch_logs(void
  
        return 0;
  }
 -#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
 +#else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
  static inline int alloc_dispatch_logs(void)
  {
        return 0;
  }
 -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
 +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
  
  static int alloc_dispatch_log_kmem_cache(void)
  {
@@@ -375,7 -376,7 +376,7 @@@ static void pSeries_idle(void
   * to ever be a problem in practice we can move this into a kernel thread to
   * finish off the process later in boot.
   */
static int __init pSeries_enable_reloc_on_exc(void)
long pSeries_enable_reloc_on_exc(void)
  {
        long rc;
        unsigned int delay, total_delay = 0;
                mdelay(delay);
        }
  }
+ EXPORT_SYMBOL(pSeries_enable_reloc_on_exc);
  
- #ifdef CONFIG_KEXEC
- static long pSeries_disable_reloc_on_exc(void)
+ long pSeries_disable_reloc_on_exc(void)
  {
        long rc;
  
                mdelay(get_longbusy_msecs(rc));
        }
  }
+ EXPORT_SYMBOL(pSeries_disable_reloc_on_exc);
  
+ #ifdef CONFIG_KEXEC
  static void pSeries_machine_kexec(struct kimage *image)
  {
        long rc;
@@@ -498,6 -501,14 +501,14 @@@ static int pseries_set_xdabr(unsigned l
        return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx);
  }
  
+ static int pseries_set_dawr(unsigned long dawr, unsigned long dawrx)
+ {
+       /* PAPR says we can't set HYP */
+       dawrx &= ~DAWRX_HYP;
+       return  plapr_set_watchpoint0(dawr, dawrx);
+ }
  #define CMO_CHARACTERISTICS_TOKEN 44
  #define CMO_MAXLENGTH 1026
  
@@@ -604,6 -615,9 +615,9 @@@ static void __init pSeries_init_early(v
        else if (firmware_has_feature(FW_FEATURE_DABR))
                ppc_md.set_dabr = pseries_set_dabr;
  
+       if (firmware_has_feature(FW_FEATURE_SET_MODE))
+               ppc_md.set_dawr = pseries_set_dawr;
        pSeries_cmo_feature_init();
        iommu_init_early_pSeries();
  
diff --combined crypto/Kconfig
index 3f37520035ddcc9c71e9ee11c6c2666e84ac6c4a,8e6ae5ed837930c31fb74a6e0dacf7bec22f5a23..0880a14834aa7c6d7a08a0a316557135d4c362e3
@@@ -134,8 -134,8 +134,8 @@@ config CRYPTO_NUL
          These are 'Null' algorithms, used by IPsec, which do nothing.
  
  config CRYPTO_PCRYPT
 -      tristate "Parallel crypto engine (EXPERIMENTAL)"
 -      depends on SMP && EXPERIMENTAL
 +      tristate "Parallel crypto engine"
 +      depends on SMP
        select PADATA
        select CRYPTO_MANAGER
        select CRYPTO_AEAD
@@@ -292,6 -292,7 +292,6 @@@ config CRYPTO_HMA
  
  config CRYPTO_XCBC
        tristate "XCBC support"
 -      depends on EXPERIMENTAL
        select CRYPTO_HASH
        select CRYPTO_MANAGER
        help
  
  config CRYPTO_VMAC
        tristate "VMAC support"
 -      depends on EXPERIMENTAL
        select CRYPTO_HASH
        select CRYPTO_MANAGER
        help
@@@ -477,6 -479,13 +477,13 @@@ config CRYPTO_SHA1_AR
          SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
          using optimized ARM assembler.
  
+ config CRYPTO_SHA1_PPC
+       tristate "SHA1 digest algorithm (powerpc)"
+       depends on PPC
+       help
+         This is the powerpc hardware accelerated implementation of the
+         SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
  config CRYPTO_SHA256
        tristate "SHA224 and SHA256 digest algorithm"
        select CRYPTO_HASH
@@@ -930,7 -939,8 +937,7 @@@ config CRYPTO_KHAZA
          <http://www.larc.usp.br/~pbarreto/KhazadPage.html>
  
  config CRYPTO_SALSA20
 -      tristate "Salsa20 stream cipher algorithm (EXPERIMENTAL)"
 -      depends on EXPERIMENTAL
 +      tristate "Salsa20 stream cipher algorithm"
        select CRYPTO_BLKCIPHER
        help
          Salsa20 stream cipher algorithm.
          Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  
  config CRYPTO_SALSA20_586
 -      tristate "Salsa20 stream cipher algorithm (i586) (EXPERIMENTAL)"
 +      tristate "Salsa20 stream cipher algorithm (i586)"
        depends on (X86 || UML_X86) && !64BIT
 -      depends on EXPERIMENTAL
        select CRYPTO_BLKCIPHER
        help
          Salsa20 stream cipher algorithm.
          Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  
  config CRYPTO_SALSA20_X86_64
 -      tristate "Salsa20 stream cipher algorithm (x86_64) (EXPERIMENTAL)"
 +      tristate "Salsa20 stream cipher algorithm (x86_64)"
        depends on (X86 || UML_X86) && 64BIT
 -      depends on EXPERIMENTAL
        select CRYPTO_BLKCIPHER
        help
          Salsa20 stream cipher algorithm.
diff --combined drivers/Makefile
index b359948fc02b87eae1f140453d617442bcdf02ae,d8372ab2e4cf5614f448226ec423b13d167aa270..dce39a95fa71ee028285ebaa6d3a105eca1b4b97
@@@ -29,7 -29,7 +29,7 @@@ obj-$(CONFIG_PNP)             += pnp
  obj-y                         += amba/
  # Many drivers will want to use DMA so this has to be made available
  # really early.
- obj-$(CONFIG_DMA_ENGINE)      += dma/
+ obj-$(CONFIG_DMADEVICES)      += dma/
  
  obj-$(CONFIG_VIRTIO)          += virtio/
  obj-$(CONFIG_XEN)             += xen/
@@@ -130,7 -130,6 +130,7 @@@ obj-y                              += platform
  #common clk code
  obj-y                         += clk/
  
 +obj-$(CONFIG_MAILBOX)         += mailbox/
  obj-$(CONFIG_HWSPINLOCK)      += hwspinlock/
  obj-$(CONFIG_NFC)             += nfc/
  obj-$(CONFIG_IOMMU_SUPPORT)   += iommu/
@@@ -147,4 -146,3 +147,4 @@@ obj-$(CONFIG_MEMORY)               += memory
  obj-$(CONFIG_IIO)             += iio/
  obj-$(CONFIG_VME_BUS)         += vme/
  obj-$(CONFIG_IPACK_BUS)               += ipack/
 +obj-$(CONFIG_NTB)             += ntb/
index 0000000000000000000000000000000000000000,3a189460328226d9d0acab9ad5bc6a24afe28f22..a8c2e2994d2eb9dba9a64ec8107dcfed0dc28d50
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,531 +1,531 @@@
 -      if (!request_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma),
+ /*
+  * Driver for MPC52xx processor BestComm peripheral controller
+  *
+  *
+  * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
+  * Copyright (C) 2005      Varma Electronics Oy,
+  *                         ( by Andrey Volkov <avolkov@varma-el.com> )
+  * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+  *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+  *
+  * This file is licensed under the terms of the GNU General Public License
+  * version 2. This program is licensed "as is" without any warranty of any
+  * kind, whether express or implied.
+  */
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/mpc52xx.h>
+ #include <linux/fsl/bestcomm/sram.h>
+ #include <linux/fsl/bestcomm/bestcomm_priv.h>
+ #include "linux/fsl/bestcomm/bestcomm.h"
+ #define DRIVER_NAME "bestcomm-core"
+ /* MPC5200 device tree match tables */
+ static struct of_device_id mpc52xx_sram_ids[] = {
+       { .compatible = "fsl,mpc5200-sram", },
+       { .compatible = "mpc5200-sram", },
+       {}
+ };
+ struct bcom_engine *bcom_eng = NULL;
+ EXPORT_SYMBOL_GPL(bcom_eng);  /* needed for inline functions */
+ /* ======================================================================== */
+ /* Public and private API                                                   */
+ /* ======================================================================== */
+ /* Private API */
+ struct bcom_task *
+ bcom_task_alloc(int bd_count, int bd_size, int priv_size)
+ {
+       int i, tasknum = -1;
+       struct bcom_task *tsk;
+       /* Don't try to do anything if bestcomm init failed */
+       if (!bcom_eng)
+               return NULL;
+       /* Get and reserve a task num */
+       spin_lock(&bcom_eng->lock);
+       for (i=0; i<BCOM_MAX_TASKS; i++)
+               if (!bcom_eng->tdt[i].stop) {   /* we use stop as a marker */
+                       bcom_eng->tdt[i].stop = 0xfffffffful; /* dummy addr */
+                       tasknum = i;
+                       break;
+               }
+       spin_unlock(&bcom_eng->lock);
+       if (tasknum < 0)
+               return NULL;
+       /* Allocate our structure */
+       tsk = kzalloc(sizeof(struct bcom_task) + priv_size, GFP_KERNEL);
+       if (!tsk)
+               goto error;
+       tsk->tasknum = tasknum;
+       if (priv_size)
+               tsk->priv = (void*)tsk + sizeof(struct bcom_task);
+       /* Get IRQ of that task */
+       tsk->irq = irq_of_parse_and_map(bcom_eng->ofnode, tsk->tasknum);
+       if (tsk->irq == NO_IRQ)
+               goto error;
+       /* Init the BDs, if needed */
+       if (bd_count) {
+               tsk->cookie = kmalloc(sizeof(void*) * bd_count, GFP_KERNEL);
+               if (!tsk->cookie)
+                       goto error;
+               tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa);
+               if (!tsk->bd)
+                       goto error;
+               memset(tsk->bd, 0x00, bd_count * bd_size);
+               tsk->num_bd = bd_count;
+               tsk->bd_size = bd_size;
+       }
+       return tsk;
+ error:
+       if (tsk) {
+               if (tsk->irq != NO_IRQ)
+                       irq_dispose_mapping(tsk->irq);
+               bcom_sram_free(tsk->bd);
+               kfree(tsk->cookie);
+               kfree(tsk);
+       }
+       bcom_eng->tdt[tasknum].stop = 0;
+       return NULL;
+ }
+ EXPORT_SYMBOL_GPL(bcom_task_alloc);
+ void
+ bcom_task_free(struct bcom_task *tsk)
+ {
+       /* Stop the task */
+       bcom_disable_task(tsk->tasknum);
+       /* Clear TDT */
+       bcom_eng->tdt[tsk->tasknum].start = 0;
+       bcom_eng->tdt[tsk->tasknum].stop  = 0;
+       /* Free everything */
+       irq_dispose_mapping(tsk->irq);
+       bcom_sram_free(tsk->bd);
+       kfree(tsk->cookie);
+       kfree(tsk);
+ }
+ EXPORT_SYMBOL_GPL(bcom_task_free);
+ int
+ bcom_load_image(int task, u32 *task_image)
+ {
+       struct bcom_task_header *hdr = (struct bcom_task_header *)task_image;
+       struct bcom_tdt *tdt;
+       u32 *desc, *var, *inc;
+       u32 *desc_src, *var_src, *inc_src;
+       /* Safety checks */
+       if (hdr->magic != BCOM_TASK_MAGIC) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": Trying to load invalid microcode\n");
+               return -EINVAL;
+       }
+       if ((task < 0) || (task >= BCOM_MAX_TASKS)) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": Trying to load invalid task %d\n", task);
+               return -EINVAL;
+       }
+       /* Initial load or reload */
+       tdt = &bcom_eng->tdt[task];
+       if (tdt->start) {
+               desc = bcom_task_desc(task);
+               if (hdr->desc_size != bcom_task_num_descs(task)) {
+                       printk(KERN_ERR DRIVER_NAME
+                               ": Trying to reload wrong task image "
+                               "(%d size %d/%d)!\n",
+                               task,
+                               hdr->desc_size,
+                               bcom_task_num_descs(task));
+                       return -EINVAL;
+               }
+       } else {
+               phys_addr_t start_pa;
+               desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa);
+               if (!desc)
+                       return -ENOMEM;
+               tdt->start = start_pa;
+               tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32));
+       }
+       var = bcom_task_var(task);
+       inc = bcom_task_inc(task);
+       /* Clear & copy */
+       memset(var, 0x00, BCOM_VAR_SIZE);
+       memset(inc, 0x00, BCOM_INC_SIZE);
+       desc_src = (u32 *)(hdr + 1);
+       var_src = desc_src + hdr->desc_size;
+       inc_src = var_src + hdr->var_size;
+       memcpy(desc, desc_src, hdr->desc_size * sizeof(u32));
+       memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32));
+       memcpy(inc, inc_src, hdr->inc_size * sizeof(u32));
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(bcom_load_image);
+ void
+ bcom_set_initiator(int task, int initiator)
+ {
+       int i;
+       int num_descs;
+       u32 *desc;
+       int next_drd_has_initiator;
+       bcom_set_tcr_initiator(task, initiator);
+       /* Just setting tcr is apparently not enough due to some problem */
+       /* with it. So we just go thru all the microcode and replace in  */
+       /* the DRD directly */
+       desc = bcom_task_desc(task);
+       next_drd_has_initiator = 1;
+       num_descs = bcom_task_num_descs(task);
+       for (i=0; i<num_descs; i++, desc++) {
+               if (!bcom_desc_is_drd(*desc))
+                       continue;
+               if (next_drd_has_initiator)
+                       if (bcom_desc_initiator(*desc) != BCOM_INITIATOR_ALWAYS)
+                               bcom_set_desc_initiator(desc, initiator);
+               next_drd_has_initiator = !bcom_drd_is_extended(*desc);
+       }
+ }
+ EXPORT_SYMBOL_GPL(bcom_set_initiator);
+ /* Public API */
+ void
+ bcom_enable(struct bcom_task *tsk)
+ {
+       bcom_enable_task(tsk->tasknum);
+ }
+ EXPORT_SYMBOL_GPL(bcom_enable);
+ void
+ bcom_disable(struct bcom_task *tsk)
+ {
+       bcom_disable_task(tsk->tasknum);
+ }
+ EXPORT_SYMBOL_GPL(bcom_disable);
+ /* ======================================================================== */
+ /* Engine init/cleanup                                                      */
+ /* ======================================================================== */
+ /* Function Descriptor table */
+ /* this will need to be updated if Freescale changes their task code FDT */
+ static u32 fdt_ops[] = {
+       0xa0045670,     /* FDT[48] - load_acc()   */
+       0x80045670,     /* FDT[49] - unload_acc() */
+       0x21800000,     /* FDT[50] - and()        */
+       0x21e00000,     /* FDT[51] - or()         */
+       0x21500000,     /* FDT[52] - xor()        */
+       0x21400000,     /* FDT[53] - andn()       */
+       0x21500000,     /* FDT[54] - not()        */
+       0x20400000,     /* FDT[55] - add()        */
+       0x20500000,     /* FDT[56] - sub()        */
+       0x20800000,     /* FDT[57] - lsh()        */
+       0x20a00000,     /* FDT[58] - rsh()        */
+       0xc0170000,     /* FDT[59] - crc8()       */
+       0xc0145670,     /* FDT[60] - crc16()      */
+       0xc0345670,     /* FDT[61] - crc32()      */
+       0xa0076540,     /* FDT[62] - endian32()   */
+       0xa0000760,     /* FDT[63] - endian16()   */
+ };
+ static int bcom_engine_init(void)
+ {
+       int task;
+       phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
+       unsigned int tdt_size, ctx_size, var_size, fdt_size;
+       /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
+       tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
+       ctx_size = BCOM_MAX_TASKS * BCOM_CTX_SIZE;
+       var_size = BCOM_MAX_TASKS * (BCOM_VAR_SIZE + BCOM_INC_SIZE);
+       fdt_size = BCOM_FDT_SIZE;
+       bcom_eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
+       bcom_eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
+       bcom_eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
+       bcom_eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
+       if (!bcom_eng->tdt || !bcom_eng->ctx || !bcom_eng->var || !bcom_eng->fdt) {
+               printk(KERN_ERR "DMA: SRAM alloc failed in engine init !\n");
+               bcom_sram_free(bcom_eng->tdt);
+               bcom_sram_free(bcom_eng->ctx);
+               bcom_sram_free(bcom_eng->var);
+               bcom_sram_free(bcom_eng->fdt);
+               return -ENOMEM;
+       }
+       memset(bcom_eng->tdt, 0x00, tdt_size);
+       memset(bcom_eng->ctx, 0x00, ctx_size);
+       memset(bcom_eng->var, 0x00, var_size);
+       memset(bcom_eng->fdt, 0x00, fdt_size);
+       /* Copy the FDT for the EU#3 */
+       memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
+       /* Initialize Task base structure */
+       for (task=0; task<BCOM_MAX_TASKS; task++)
+       {
+               out_be16(&bcom_eng->regs->tcr[task], 0);
+               out_8(&bcom_eng->regs->ipr[task], 0);
+               bcom_eng->tdt[task].context     = ctx_pa;
+               bcom_eng->tdt[task].var = var_pa;
+               bcom_eng->tdt[task].fdt = fdt_pa;
+               var_pa += BCOM_VAR_SIZE + BCOM_INC_SIZE;
+               ctx_pa += BCOM_CTX_SIZE;
+       }
+       out_be32(&bcom_eng->regs->taskBar, tdt_pa);
+       /* Init 'always' initiator */
+       out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
+       /* Disable COMM Bus Prefetch on the original 5200; it's broken */
+       if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
+               bcom_disable_prefetch();
+       /* Init lock */
+       spin_lock_init(&bcom_eng->lock);
+       return 0;
+ }
+ static void
+ bcom_engine_cleanup(void)
+ {
+       int task;
+       /* Stop all tasks */
+       for (task=0; task<BCOM_MAX_TASKS; task++)
+       {
+               out_be16(&bcom_eng->regs->tcr[task], 0);
+               out_8(&bcom_eng->regs->ipr[task], 0);
+       }
+       out_be32(&bcom_eng->regs->taskBar, 0ul);
+       /* Release the SRAM zones */
+       bcom_sram_free(bcom_eng->tdt);
+       bcom_sram_free(bcom_eng->ctx);
+       bcom_sram_free(bcom_eng->var);
+       bcom_sram_free(bcom_eng->fdt);
+ }
+ /* ======================================================================== */
+ /* OF platform driver                                                       */
+ /* ======================================================================== */
+ static int mpc52xx_bcom_probe(struct platform_device *op)
+ {
+       struct device_node *ofn_sram;
+       struct resource res_bcom;
+       int rv;
+       /* Inform user we're ok so far */
+       printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
+       /* Get the bestcomm node */
+       of_node_get(op->dev.of_node);
+       /* Prepare SRAM */
+       ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids);
+       if (!ofn_sram) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "No SRAM found in device tree\n");
+               rv = -ENODEV;
+               goto error_ofput;
+       }
+       rv = bcom_sram_init(ofn_sram, DRIVER_NAME);
+       of_node_put(ofn_sram);
+       if (rv) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "Error in SRAM init\n");
+               goto error_ofput;
+       }
+       /* Get a clean struct */
+       bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL);
+       if (!bcom_eng) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "Can't allocate state structure\n");
+               rv = -ENOMEM;
+               goto error_sramclean;
+       }
+       /* Save the node */
+       bcom_eng->ofnode = op->dev.of_node;
+       /* Get, reserve & map io */
+       if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "Can't get resource\n");
+               rv = -EINVAL;
+               goto error_sramclean;
+       }
++      if (!request_mem_region(res_bcom.start, resource_size(&res_bcom),
+                               DRIVER_NAME)) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "Can't request registers region\n");
+               rv = -EBUSY;
+               goto error_sramclean;
+       }
+       bcom_eng->regs_base = res_bcom.start;
+       bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma));
+       if (!bcom_eng->regs) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                       "Can't map registers\n");
+               rv = -ENOMEM;
+               goto error_release;
+       }
+       /* Now, do the real init */
+       rv = bcom_engine_init();
+       if (rv)
+               goto error_unmap;
+       /* Done ! */
+       printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n",
+               (long)bcom_eng->regs_base);
+       return 0;
+       /* Error path */
+ error_unmap:
+       iounmap(bcom_eng->regs);
+ error_release:
+       release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma));
+ error_sramclean:
+       kfree(bcom_eng);
+       bcom_sram_cleanup();
+ error_ofput:
+       of_node_put(op->dev.of_node);
+       printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n");
+       return rv;
+ }
+ static int mpc52xx_bcom_remove(struct platform_device *op)
+ {
+       /* Clean up the engine */
+       bcom_engine_cleanup();
+       /* Cleanup SRAM */
+       bcom_sram_cleanup();
+       /* Release regs */
+       iounmap(bcom_eng->regs);
+       release_mem_region(bcom_eng->regs_base, sizeof(struct mpc52xx_sdma));
+       /* Release the node */
+       of_node_put(bcom_eng->ofnode);
+       /* Release memory */
+       kfree(bcom_eng);
+       bcom_eng = NULL;
+       return 0;
+ }
+ static struct of_device_id mpc52xx_bcom_of_match[] = {
+       { .compatible = "fsl,mpc5200-bestcomm", },
+       { .compatible = "mpc5200-bestcomm", },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match);
+ static struct platform_driver mpc52xx_bcom_of_platform_driver = {
+       .probe          = mpc52xx_bcom_probe,
+       .remove         = mpc52xx_bcom_remove,
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = mpc52xx_bcom_of_match,
+       },
+ };
+ /* ======================================================================== */
+ /* Module                                                                   */
+ /* ======================================================================== */
+ static int __init
+ mpc52xx_bcom_init(void)
+ {
+       return platform_driver_register(&mpc52xx_bcom_of_platform_driver);
+ }
+ static void __exit
+ mpc52xx_bcom_exit(void)
+ {
+       platform_driver_unregister(&mpc52xx_bcom_of_platform_driver);
+ }
+ /* If we're not a module, we must make sure everything is setup before  */
+ /* anyone tries to use us ... that's why we use subsys_initcall instead */
+ /* of module_init. */
+ subsys_initcall(mpc52xx_bcom_init);
+ module_exit(mpc52xx_bcom_exit);
+ MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
+ MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
+ MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
+ MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
+ MODULE_LICENSE("GPL v2");
index 7f91b0c5c264cb6e946ecf0315d40e020235d86c,85e776d500a6f092fa86fd815e3392371072867f..77943a6a1b8cc4c1ae80e40ba0b76536eac4806d
@@@ -29,7 -29,6 +29,7 @@@
  #include <linux/delay.h>
  #include <linux/of_device.h>
  #include <linux/of_mdio.h>
 +#include <linux/of_net.h>
  #include <linux/of_platform.h>
  
  #include <linux/netdevice.h>
@@@ -41,8 -40,8 +41,8 @@@
  #include <asm/delay.h>
  #include <asm/mpc52xx.h>
  
- #include <sysdev/bestcomm/bestcomm.h>
- #include <sysdev/bestcomm/fec.h>
+ #include <linux/fsl/bestcomm/bestcomm.h>
+ #include <linux/fsl/bestcomm/fec.h>
  
  #include "fec_mpc52xx.h"
  
@@@ -77,6 -76,10 +77,6 @@@ static void mpc52xx_fec_stop(struct net
  static void mpc52xx_fec_start(struct net_device *dev);
  static void mpc52xx_fec_reset(struct net_device *dev);
  
 -static u8 mpc52xx_fec_mac_addr[6];
 -module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0);
 -MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe");
 -
  #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \
                NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP)
  static int debug = -1;        /* the above default */
@@@ -107,6 -110,15 +107,6 @@@ static void mpc52xx_fec_set_paddr(struc
        out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE);
  }
  
 -static void mpc52xx_fec_get_paddr(struct net_device *dev, u8 *mac)
 -{
 -      struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 -      struct mpc52xx_fec __iomem *fec = priv->fec;
 -
 -      *(u32 *)(&mac[0]) = in_be32(&fec->paddr1);
 -      *(u16 *)(&mac[4]) = in_be32(&fec->paddr2) >> 16;
 -}
 -
  static int mpc52xx_fec_set_mac_address(struct net_device *dev, void *addr)
  {
        struct sockaddr *sock = addr;
@@@ -841,8 -853,6 +841,8 @@@ static int mpc52xx_fec_probe(struct pla
        struct resource mem;
        const u32 *prop;
        int prop_size;
 +      struct device_node *np = op->dev.of_node;
 +      const char *mac_addr;
  
        phys_addr_t rx_fifo;
        phys_addr_t tx_fifo;
        priv->ndev = ndev;
  
        /* Reserve FEC control zone */
 -      rv = of_address_to_resource(op->dev.of_node, 0, &mem);
 +      rv = of_address_to_resource(np, 0, &mem);
        if (rv) {
                printk(KERN_ERR DRIVER_NAME ": "
                                "Error while parsing device node resource\n" );
  
        /* Get the IRQ we need one by one */
                /* Control */
 -      ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0);
 +      ndev->irq = irq_of_parse_and_map(np, 0);
  
                /* RX */
        priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk);
                /* TX */
        priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk);
  
 -      /* MAC address init */
 -      if (!is_zero_ether_addr(mpc52xx_fec_mac_addr))
 -              memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
 -      else
 -              mpc52xx_fec_get_paddr(ndev, ndev->dev_addr);
 +      /*
 +       * MAC address init:
 +       *
 +       * First try to read MAC address from DT
 +       */
 +      mac_addr = of_get_mac_address(np);
 +      if (mac_addr) {
 +              memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
 +      } else {
 +              struct mpc52xx_fec __iomem *fec = priv->fec;
 +
 +              /*
 +               * If the MAC addresse is not provided via DT then read
 +               * it back from the controller regs
 +               */
 +              *(u32 *)(&ndev->dev_addr[0]) = in_be32(&fec->paddr1);
 +              *(u16 *)(&ndev->dev_addr[4]) = in_be32(&fec->paddr2) >> 16;
 +      }
 +
 +      /*
 +       * Check if the MAC address is valid, if not get a random one
 +       */
 +      if (!is_valid_ether_addr(ndev->dev_addr)) {
 +              eth_hw_addr_random(ndev);
 +              dev_warn(&ndev->dev, "using random MAC address %pM\n",
 +                       ndev->dev_addr);
 +      }
  
        priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT);
  
        /* Start with safe defaults for link connection */
        priv->speed = 100;
        priv->duplex = DUPLEX_HALF;
 -      priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->dev.of_node) >> 20) / 5) << 1;
 +      priv->mdio_speed = ((mpc5xxx_get_bus_frequency(np) >> 20) / 5) << 1;
  
        /* The current speed preconfigures the speed of the MII link */
 -      prop = of_get_property(op->dev.of_node, "current-speed", &prop_size);
 +      prop = of_get_property(np, "current-speed", &prop_size);
        if (prop && (prop_size >= sizeof(u32) * 2)) {
                priv->speed = prop[0];
                priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
        }
  
        /* If there is a phy handle, then get the PHY node */
 -      priv->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
 +      priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
  
        /* the 7-wire property means don't use MII mode */
 -      if (of_find_property(op->dev.of_node, "fsl,7-wire-mode", NULL)) {
 +      if (of_find_property(np, "fsl,7-wire-mode", NULL)) {
                priv->seven_wire_mode = 1;
                dev_info(&ndev->dev, "using 7-wire PHY mode\n");
        }
  
        /* We're done ! */
        dev_set_drvdata(&op->dev, ndev);
 +      printk(KERN_INFO "%s: %s MAC %pM\n",
 +             ndev->name, op->dev.of_node->full_name, ndev->dev_addr);
  
        return 0;