Commit d8bfb96a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull more powerpc updates from Michael Ellerman:
 "Some more powerpc updates for 4.9:

  Freescale updates from Scott Wood:
   - qbman support (a prerequisite for datapath drivers such as ethernet)
   - a PCI DMA fix+improvement
   - reset handler changes
   - more 8xx optimizations
   - some cleanups and fixes.'

  Fixes:
   - selftests/powerpc: Add missing binaries to .gitignores (Michael Ellerman)
   - selftests/powerpc: Fix build break caused by EXPORT_SYMBOL changes (Michael Ellerman)
   - powerpc/pseries: Fix stack corruption in htpe code (Laurent Dufour)
   - powerpc/64s: Fix power4_fixup_nap placement (Nicholas Piggin)
   - powerpc/64: Fix incorrect return value from __copy_tofrom_user (Paul Mackerras)
   - powerpc/mm/hash64: Fix might_have_hea() check (Michael Ellerman)

  Other:
   - MAINTAINERS: Remove myself from PA Semi entries (Olof Johansson)
   - MAINTAINERS: Drop separate pseries entry (Michael Ellerman)
   - MAINTAINERS: Update powerpc website & add selftests (Michael Ellerman):

* tag 'powerpc-4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (35 commits)
  powerpc/mm/hash64: Fix might_have_hea() check
  powerpc/64: Fix incorrect return value from __copy_tofrom_user
  powerpc/64s: Fix power4_fixup_nap placement
  powerpc/pseries: Fix stack corruption in htpe code
  selftests/powerpc: Fix build break caused by EXPORT_SYMBOL changes
  MAINTAINERS: Update powerpc website & add selftests
  MAINTAINERS: Drop separate pseries entry
  MAINTAINERS: Remove myself from PA Semi entries
  selftests/powerpc: Add missing binaries to .gitignores
  arch/powerpc: Add CONFIG_FSL_DPAA to corenetXX_smp_defconfig
  soc/qman: Add self-test for QMan driver
  soc/bman: Add self-test for BMan driver
  soc/fsl: Introduce DPAA 1.x QMan device driver
  soc/fsl: Introduce DPAA 1.x BMan device driver
  powerpc/8xx: make user addr DTLB miss the short path
  powerpc/8xx: Move additional DTLBMiss handlers out of exception area
  powerpc/8xx: use r3 to scratch CR in ITLBmiss
  soc/fsl/qe: fix gpio save_regs functions
  powerpc/8xx: add dedicated machine check handler
  powerpc/8xx: add system_reset_exception
  ...
parents 11ed3e0e 08bf75ba
...@@ -7201,17 +7201,11 @@ F: drivers/lightnvm/ ...@@ -7201,17 +7201,11 @@ F: drivers/lightnvm/
F: include/linux/lightnvm.h F: include/linux/lightnvm.h
F: include/uapi/linux/lightnvm.h F: include/uapi/linux/lightnvm.h
LINUX FOR IBM pSERIES (RS/6000)
M: Paul Mackerras <paulus@au.ibm.com>
W: http://www.ibm.com/linux/ltc/projects/ppc
S: Supported
F: arch/powerpc/boot/rs6000.h
LINUX FOR POWERPC (32-BIT AND 64-BIT) LINUX FOR POWERPC (32-BIT AND 64-BIT)
M: Benjamin Herrenschmidt <benh@kernel.crashing.org> M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
M: Paul Mackerras <paulus@samba.org> M: Paul Mackerras <paulus@samba.org>
M: Michael Ellerman <mpe@ellerman.id.au> M: Michael Ellerman <mpe@ellerman.id.au>
W: http://www.penguinppc.org/ W: https://github.com/linuxppc/linux/wiki
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
...@@ -7226,6 +7220,7 @@ F: drivers/net/ethernet/ibm/ibmvnic.* ...@@ -7226,6 +7220,7 @@ F: drivers/net/ethernet/ibm/ibmvnic.*
F: drivers/pci/hotplug/pnv_php.c F: drivers/pci/hotplug/pnv_php.c
F: drivers/pci/hotplug/rpa* F: drivers/pci/hotplug/rpa*
F: drivers/scsi/ibmvscsi/ F: drivers/scsi/ibmvscsi/
F: tools/testing/selftests/powerpc
N: opal N: opal
N: /pmac N: /pmac
N: powermac N: powermac
...@@ -7282,9 +7277,8 @@ F: arch/powerpc/platforms/83xx/ ...@@ -7282,9 +7277,8 @@ F: arch/powerpc/platforms/83xx/
F: arch/powerpc/platforms/85xx/ F: arch/powerpc/platforms/85xx/
LINUX FOR POWERPC PA SEMI PWRFICIENT LINUX FOR POWERPC PA SEMI PWRFICIENT
M: Olof Johansson <olof@lixom.net>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Orphan
F: arch/powerpc/platforms/pasemi/ F: arch/powerpc/platforms/pasemi/
F: drivers/*/*pasemi* F: drivers/*/*pasemi*
F: drivers/*/*/*pasemi* F: drivers/*/*/*pasemi*
...@@ -9019,15 +9013,13 @@ S: Maintained ...@@ -9019,15 +9013,13 @@ S: Maintained
F: drivers/net/wireless/intersil/p54/ F: drivers/net/wireless/intersil/p54/
PA SEMI ETHERNET DRIVER PA SEMI ETHERNET DRIVER
M: Olof Johansson <olof@lixom.net>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Orphan
F: drivers/net/ethernet/pasemi/* F: drivers/net/ethernet/pasemi/*
PA SEMI SMBUS DRIVER PA SEMI SMBUS DRIVER
M: Olof Johansson <olof@lixom.net>
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
S: Maintained S: Orphan
F: drivers/i2c/busses/i2c-pasemi.c F: drivers/i2c/busses/i2c-pasemi.c
PADATA PARALLEL EXECUTION MECHANISM PADATA PARALLEL EXECUTION MECHANISM
......
...@@ -318,12 +318,12 @@ mpc85xx_smp_defconfig: ...@@ -318,12 +318,12 @@ mpc85xx_smp_defconfig:
PHONY += corenet32_smp_defconfig PHONY += corenet32_smp_defconfig
corenet32_smp_defconfig: corenet32_smp_defconfig:
$(call merge_into_defconfig,corenet_basic_defconfig,\ $(call merge_into_defconfig,corenet_basic_defconfig,\
85xx-32bit 85xx-smp 85xx-hw fsl-emb-nonhw) 85xx-32bit 85xx-smp 85xx-hw fsl-emb-nonhw dpaa)
PHONY += corenet64_smp_defconfig PHONY += corenet64_smp_defconfig
corenet64_smp_defconfig: corenet64_smp_defconfig:
$(call merge_into_defconfig,corenet_basic_defconfig,\ $(call merge_into_defconfig,corenet_basic_defconfig,\
85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw dpaa)
PHONY += mpc86xx_defconfig PHONY += mpc86xx_defconfig
mpc86xx_defconfig: mpc86xx_defconfig:
......
...@@ -43,6 +43,7 @@ extern int machine_check_e500mc(struct pt_regs *regs); ...@@ -43,6 +43,7 @@ extern int machine_check_e500mc(struct pt_regs *regs);
extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e500(struct pt_regs *regs);
extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs);
extern int machine_check_47x(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs);
int machine_check_8xx(struct pt_regs *regs);
extern void cpu_down_flush_e500v2(void); extern void cpu_down_flush_e500v2(void);
extern void cpu_down_flush_e500mc(void); extern void cpu_down_flush_e500mc(void);
......
...@@ -155,6 +155,8 @@ static inline unsigned long arch_local_irq_save(void) ...@@ -155,6 +155,8 @@ static inline unsigned long arch_local_irq_save(void)
unsigned long flags = arch_local_save_flags(); unsigned long flags = arch_local_save_flags();
#ifdef CONFIG_BOOKE #ifdef CONFIG_BOOKE
asm volatile("wrteei 0" : : : "memory"); asm volatile("wrteei 0" : : : "memory");
#elif defined(CONFIG_PPC_8xx)
wrtspr(SPRN_EID);
#else #else
SET_MSR_EE(flags & ~MSR_EE); SET_MSR_EE(flags & ~MSR_EE);
#endif #endif
...@@ -165,6 +167,8 @@ static inline void arch_local_irq_disable(void) ...@@ -165,6 +167,8 @@ static inline void arch_local_irq_disable(void)
{ {
#ifdef CONFIG_BOOKE #ifdef CONFIG_BOOKE
asm volatile("wrteei 0" : : : "memory"); asm volatile("wrteei 0" : : : "memory");
#elif defined(CONFIG_PPC_8xx)
wrtspr(SPRN_EID);
#else #else
arch_local_irq_save(); arch_local_irq_save();
#endif #endif
...@@ -174,6 +178,8 @@ static inline void arch_local_irq_enable(void) ...@@ -174,6 +178,8 @@ static inline void arch_local_irq_enable(void)
{ {
#ifdef CONFIG_BOOKE #ifdef CONFIG_BOOKE
asm volatile("wrteei 1" : : : "memory"); asm volatile("wrteei 1" : : : "memory");
#elif defined(CONFIG_PPC_8xx)
wrtspr(SPRN_EIE);
#else #else
unsigned long msr = mfmsr(); unsigned long msr = mfmsr();
SET_MSR_EE(msr | MSR_EE); SET_MSR_EE(msr | MSR_EE);
......
...@@ -152,6 +152,7 @@ ...@@ -152,6 +152,7 @@
#define PPC_INST_LWSYNC 0x7c2004ac #define PPC_INST_LWSYNC 0x7c2004ac
#define PPC_INST_SYNC 0x7c0004ac #define PPC_INST_SYNC 0x7c0004ac
#define PPC_INST_SYNC_MASK 0xfc0007fe #define PPC_INST_SYNC_MASK 0xfc0007fe
#define PPC_INST_ISYNC 0x4c00012c
#define PPC_INST_LXVD2X 0x7c000698 #define PPC_INST_LXVD2X 0x7c000698
#define PPC_INST_MCRXR 0x7c000400 #define PPC_INST_MCRXR 0x7c000400
#define PPC_INST_MCRXR_MASK 0xfc0007fe #define PPC_INST_MCRXR_MASK 0xfc0007fe
......
...@@ -1250,6 +1250,8 @@ static inline void mtmsr_isync(unsigned long val) ...@@ -1250,6 +1250,8 @@ static inline void mtmsr_isync(unsigned long val)
: "r" ((unsigned long)(v)) \ : "r" ((unsigned long)(v)) \
: "memory") : "memory")
#endif #endif
#define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",0" : \
: : "memory")
extern unsigned long msr_check_and_set(unsigned long bits); extern unsigned long msr_check_and_set(unsigned long bits);
extern bool strict_msr_control; extern bool strict_msr_control;
......
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
#define SPRN_MD_RAM0 825 #define SPRN_MD_RAM0 825
#define SPRN_MD_RAM1 826 #define SPRN_MD_RAM1 826
/* Special MSR manipulation registers */
#define SPRN_EIE 80 /* External interrupt enable (EE=1, RI=1) */
#define SPRN_EID 81 /* External interrupt disable (EE=0, RI=1) */
/* Commands. Only the first few are available to the instruction cache. /* Commands. Only the first few are available to the instruction cache.
*/ */
#define IDC_ENABLE 0x02000000 /* Cache enable */ #define IDC_ENABLE 0x02000000 /* Cache enable */
......
...@@ -1248,6 +1248,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1248,6 +1248,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.mmu_features = MMU_FTR_TYPE_8xx, .mmu_features = MMU_FTR_TYPE_8xx,
.icache_bsize = 16, .icache_bsize = 16,
.dcache_bsize = 16, .dcache_bsize = 16,
.machine_check = machine_check_8xx,
.platform = "ppc823", .platform = "ppc823",
}, },
#endif /* CONFIG_8xx */ #endif /* CONFIG_8xx */
......
...@@ -1377,7 +1377,7 @@ __end_interrupts: ...@@ -1377,7 +1377,7 @@ __end_interrupts:
DEFINE_FIXED_SYMBOL(__end_interrupts) DEFINE_FIXED_SYMBOL(__end_interrupts)
#ifdef CONFIG_PPC_970_NAP #ifdef CONFIG_PPC_970_NAP
TRAMP_REAL_BEGIN(power4_fixup_nap) EXC_COMMON_BEGIN(power4_fixup_nap)
andc r9,r9,r10 andc r9,r9,r10
std r9,TI_LOCAL_FLAGS(r11) std r9,TI_LOCAL_FLAGS(r11)
ld r10,_LINK(r1) /* make idle task do the */ ld r10,_LINK(r1) /* make idle task do the */
......
...@@ -226,7 +226,7 @@ i##n: \ ...@@ -226,7 +226,7 @@ i##n: \
ret_from_except) ret_from_except)
/* System reset */ /* System reset */
EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
/* Machine check */ /* Machine check */
. = 0x200 . = 0x200
...@@ -321,7 +321,7 @@ SystemCall: ...@@ -321,7 +321,7 @@ SystemCall:
#endif #endif
InstructionTLBMiss: InstructionTLBMiss:
#ifdef CONFIG_8xx_CPU6 #if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
mtspr SPRN_SPRG_SCRATCH2, r3 mtspr SPRN_SPRG_SCRATCH2, r3
#endif #endif
EXCEPTION_PROLOG_0 EXCEPTION_PROLOG_0
...@@ -329,23 +329,20 @@ InstructionTLBMiss: ...@@ -329,23 +329,20 @@ InstructionTLBMiss:
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
* kernel page tables. * kernel page tables.
*/ */
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) #if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
/* Only modules will cause ITLB Misses as we always /* Only modules will cause ITLB Misses as we always
* pin the first 8MB of kernel memory */ * pin the first 8MB of kernel memory */
mfspr r11, SPRN_SRR0 /* Get effective address of fault */ mfcr r3
INVALIDATE_ADJACENT_PAGES_CPU15(r10, r11) IS_KERNEL(r11, r10)
mfcr r10 #endif
IS_KERNEL(r11, r11)
mfspr r11, SPRN_M_TW /* Get level 1 table */ mfspr r11, SPRN_M_TW /* Get level 1 table */
#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
BRANCH_UNLESS_KERNEL(3f) BRANCH_UNLESS_KERNEL(3f)
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
3: 3:
mtcr r10 mtcr r3
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
#else
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
mfspr r11, SPRN_M_TW /* Get level 1 table base address */
#endif #endif
/* Insert level 1 index */ /* Insert level 1 index */
rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
...@@ -377,58 +374,39 @@ InstructionTLBMiss: ...@@ -377,58 +374,39 @@ InstructionTLBMiss:
MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */ MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */
/* Restore registers */ /* Restore registers */
#ifdef CONFIG_8xx_CPU6 #if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
mfspr r3, SPRN_SPRG_SCRATCH2 mfspr r3, SPRN_SPRG_SCRATCH2
#endif #endif
EXCEPTION_EPILOG_0 EXCEPTION_EPILOG_0
rfi rfi
/*
* Bottom part of DataStoreTLBMiss handler for IMMR area
* not enough space in the DataStoreTLBMiss area
*/
DTLBMissIMMR:
mtcr r10
/* Set 512k byte guarded page and mark it valid */
li r10, MD_PS512K | MD_GUARDED | MD_SVALID
MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
mfspr r10, SPRN_IMMR /* Get current IMMR */
rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT | _PAGE_NO_CACHE
MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
. = 0x1200 . = 0x1200
DataStoreTLBMiss: DataStoreTLBMiss:
mtspr SPRN_SPRG_SCRATCH2, r3
EXCEPTION_PROLOG_0 EXCEPTION_PROLOG_0
mfcr r10 mfcr r3
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
* kernel page tables. * kernel page tables.
*/ */
mfspr r11, SPRN_MD_EPN mfspr r10, SPRN_MD_EPN
rlwinm r11, r11, 16, 0xfff8 rlwinm r10, r10, 16, 0xfff8
cmpli cr0, r10, PAGE_OFFSET@h
mfspr r11, SPRN_M_TW /* Get level 1 table */
blt+ 3f
#ifndef CONFIG_PIN_TLB_IMMR #ifndef CONFIG_PIN_TLB_IMMR
cmpli cr0, r11, VIRT_IMMR_BASE@h cmpli cr0, r10, VIRT_IMMR_BASE@h
#endif #endif
cmpli cr7, r11, PAGE_OFFSET@h _ENTRY(DTLBMiss_cmp)
cmpli cr7, r10, (PAGE_OFFSET + 0x1800000)@h
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
#ifndef CONFIG_PIN_TLB_IMMR #ifndef CONFIG_PIN_TLB_IMMR
_ENTRY(DTLBMiss_jmp) _ENTRY(DTLBMiss_jmp)
beq- DTLBMissIMMR beq- DTLBMissIMMR
#endif #endif
bge- cr7, 4f blt cr7, DTLBMissLinear
mfspr r11, SPRN_M_TW /* Get level 1 table */
3: 3:
mtcr r10 mtcr r3
#ifdef CONFIG_8xx_CPU6
mtspr SPRN_SPRG_SCRATCH2, r3
#endif
mfspr r10, SPRN_MD_EPN mfspr r10, SPRN_MD_EPN
/* Insert level 1 index */ /* Insert level 1 index */
...@@ -481,30 +459,7 @@ _ENTRY(DTLBMiss_jmp) ...@@ -481,30 +459,7 @@ _ENTRY(DTLBMiss_jmp)
MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
/* Restore registers */ /* Restore registers */
#ifdef CONFIG_8xx_CPU6
mfspr r3, SPRN_SPRG_SCRATCH2 mfspr r3, SPRN_SPRG_SCRATCH2
#endif
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
4:
_ENTRY(DTLBMiss_cmp)
cmpli cr0, r11, (PAGE_OFFSET + 0x1800000)@h
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
bge- 3b
mtcr r10
/* Set 8M byte page and mark it valid */
li r10, MD_PS8MEG | MD_SVALID
MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
mfspr r10, SPRN_MD_EPN
rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT
MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
mtspr SPRN_DAR, r11 /* Tag DAR */ mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0 EXCEPTION_EPILOG_0
rfi rfi
...@@ -570,6 +525,43 @@ DARFixed:/* Return from dcbx instruction bug workaround */ ...@@ -570,6 +525,43 @@ DARFixed:/* Return from dcbx instruction bug workaround */
. = 0x2000 . = 0x2000
/*
* Bottom part of DataStoreTLBMiss handlers for IMMR area and linear RAM.
* not enough space in the DataStoreTLBMiss area.
*/
DTLBMissIMMR:
mtcr r3
/* Set 512k byte guarded page and mark it valid */
li r10, MD_PS512K | MD_GUARDED | MD_SVALID
MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
mfspr r10, SPRN_IMMR /* Get current IMMR */
rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT | _PAGE_NO_CACHE
MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r3, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
rfi
DTLBMissLinear:
mtcr r3
/* Set 8M byte page and mark it valid */
li r11, MD_PS8MEG | MD_SVALID
MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
rlwinm r10, r10, 16, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT
MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
mtspr SPRN_DAR, r11 /* Tag DAR */
mfspr r3, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
rfi
/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
* by decoding the registers used by the dcbx instruction and adding them. * by decoding the registers used by the dcbx instruction and adding them.
* DAR is set to the calculated address. * DAR is set to the calculated address.
...@@ -586,7 +578,9 @@ FixupDAR:/* Entry point for dcbx workaround. */ ...@@ -586,7 +578,9 @@ FixupDAR:/* Entry point for dcbx workaround. */
rlwinm r11, r10, 16, 0xfff8 rlwinm r11, r10, 16, 0xfff8
_ENTRY(FixupDAR_cmp) _ENTRY(FixupDAR_cmp)
cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
blt- cr7, 200f /* create physical page address from effective address */
tophys(r11, r10)
blt- cr7, 201f
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
/* Insert level 1 index */ /* Insert level 1 index */
3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
...@@ -616,10 +610,6 @@ _ENTRY(FixupDAR_cmp) ...@@ -616,10 +610,6 @@ _ENTRY(FixupDAR_cmp)
141: mfspr r10,SPRN_SPRG_SCRATCH2 141: mfspr r10,SPRN_SPRG_SCRATCH2
b DARFixed /* Nope, go back to normal TLB processing */ b DARFixed /* Nope, go back to normal TLB processing */
/* create physical page address from effective address */
200: tophys(r11, r10)
b 201b
144: mfspr r10, SPRN_DSISR 144: mfspr r10, SPRN_DSISR
rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
mtspr SPRN_DSISR, r10 mtspr SPRN_DSISR, r10
......
...@@ -131,15 +131,26 @@ void machine_shutdown(void) ...@@ -131,15 +131,26 @@ void machine_shutdown(void)
ppc_md.machine_shutdown(); ppc_md.machine_shutdown();
} }
static void machine_hang(void)
{
pr_emerg("System Halted, OK to turn off power\n");
local_irq_disable();
while (1)
;
}
void machine_restart(char *cmd) void machine_restart(char *cmd)
{ {
machine_shutdown(); machine_shutdown();
if (ppc_md.restart) if (ppc_md.restart)
ppc_md.restart(cmd); ppc_md.restart(cmd);
smp_send_stop(); smp_send_stop();
printk(KERN_EMERG "System Halted, OK to turn off power\n");
local_irq_disable(); do_kernel_restart(cmd);
while (1) ; mdelay(1000);
machine_hang();
} }
void machine_power_off(void) void machine_power_off(void)
...@@ -147,10 +158,9 @@ void machine_power_off(void) ...@@ -147,10 +158,9 @@ void machine_power_off(void)
machine_shutdown(); machine_shutdown();
if (pm_power_off) if (pm_power_off)
pm_power_off(); pm_power_off();
smp_send_stop(); smp_send_stop();
printk(KERN_EMERG "System Halted, OK to turn off power\n"); machine_hang();
local_irq_disable();
while (1) ;
} }
/* Used by the G5 thermal driver */ /* Used by the G5 thermal driver */
EXPORT_SYMBOL_GPL(machine_power_off); EXPORT_SYMBOL_GPL(machine_power_off);
...@@ -163,10 +173,9 @@ void machine_halt(void) ...@@ -163,10 +173,9 @@ void machine_halt(void)
machine_shutdown(); machine_shutdown();
if (ppc_md.halt) if (ppc_md.halt)
ppc_md.halt(); ppc_md.halt();
smp_send_stop(); smp_send_stop();
printk(KERN_EMERG "System Halted, OK to turn off power\n"); machine_hang();
local_irq_disable();
while (1) ;
} }
......
...@@ -273,7 +273,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) ...@@ -273,7 +273,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
force_sig_info(signr, &info, current); force_sig_info(signr, &info, current);
} }
#ifdef CONFIG_PPC64
void system_reset_exception(struct pt_regs *regs) void system_reset_exception(struct pt_regs *regs)
{ {
/* See if any machine dependent calls */ /* See if any machine dependent calls */
...@@ -291,6 +290,7 @@ void system_reset_exception(struct pt_regs *regs) ...@@ -291,6 +290,7 @@ void system_reset_exception(struct pt_regs *regs)
/* What should we do here? We could issue a shutdown or hard reset. */ /* What should we do here? We could issue a shutdown or hard reset. */
} }
#ifdef CONFIG_PPC64
/* /*
* This function is called in real mode. Strictly no printk's please. * This function is called in real mode. Strictly no printk's please.
* *
...@@ -352,12 +352,11 @@ static inline int check_io_access(struct pt_regs *regs) ...@@ -352,12 +352,11 @@ static inline int check_io_access(struct pt_regs *regs)
* For the debug message, we look at the preceding * For the debug message, we look at the preceding
* load or store. * load or store.
*/ */
if (*nip == 0x60000000) /* nop */ if (*nip == PPC_INST_NOP)
nip -= 2; nip -= 2;
else if (*nip == 0x4c00012c) /* isync */ else if (*nip == PPC_INST_ISYNC)
--nip; --nip;
if (*nip == 0x7c0004ac || (*nip >> 26) == 3) { if (*nip == PPC_INST_SYNC || (*nip >> 26) == OP_TRAP) {
/* sync or twi */
unsigned int rb; unsigned int rb;
--nip; --nip;
...@@ -668,6 +667,31 @@ int machine_check_e200(struct pt_regs *regs) ...@@ -668,6 +667,31 @@ int machine_check_e200(struct pt_regs *regs)
return 0; return 0;
} }
#elif defined(CONFIG_PPC_8xx)
int machine_check_8xx(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
pr_err("Machine check in kernel mode.\n");
pr_err("Caused by (from SRR1=%lx): ", reason);
if (reason & 0x40000000)
pr_err("Fetch error at address %lx\n", regs->nip);
else
pr_err("Data access error at address %lx\n", regs->dar);
#ifdef CONFIG_PCI
/* the qspan pci read routines can cause machine checks -- Cort
*
* yuck !!! that totally needs to go away ! There are better ways
* to deal with that than having a wart in the mcheck handler.
* -- BenH
*/
bad_page_fault(regs, regs->dar, SIGBUS);
return 1;
#else
return 0;
#endif
}
#else #else
int machine_check_generic(struct pt_regs *regs) int machine_check_generic(struct pt_regs *regs)
{ {
...@@ -727,17 +751,6 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -727,17 +751,6 @@ void machine_check_exception(struct pt_regs *regs)
if (recover > 0) if (recover > 0)
goto bail; goto bail;
#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort
*
* yuck !!! that totally needs to go away ! There are better ways
* to deal with that than having a wart in the mcheck handler.
* -- BenH
*/
bad_page_fault(regs, regs->dar, SIGBUS);
goto bail;
#endif
if (debugger_fault_handler(regs)) if (debugger_fault_handler(regs))
goto bail; goto bail;
......
...@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) ...@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
addi r3,r3,8 addi r3,r3,8
171: 171:
177: 177:
179:
addi r3,r3,8 addi r3,r3,8
370: 370:
372: 372:
...@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) ...@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
173: 173:
174: 174:
175: 175:
179:
181: 181:
184: 184:
186: 186:
......
...@@ -529,7 +529,7 @@ static bool might_have_hea(void) ...@@ -529,7 +529,7 @@ static bool might_have_hea(void)
*/ */
#ifdef CONFIG_IBMEBUS #ifdef CONFIG_IBMEBUS
return !cpu_has_feature(CPU_FTR_ARCH_207S) && return !cpu_has_feature(CPU_FTR_ARCH_207S) &&
!firmware_has_feature(FW_FEATURE_SPLPAR); firmware_has_feature(FW_FEATURE_SPLPAR);
#else #else
return false; return false;
#endif #endif
......
...@@ -30,8 +30,8 @@ config EP8248E ...@@ -30,8 +30,8 @@ config EP8248E
select 8272 select 8272
select 8260 select 8260
select FSL_SOC select FSL_SOC
select PHYLIB select PHYLIB if NETDEVICES
select MDIO_BITBANG select MDIO_BITBANG if PHYLIB
help help
This enables support for the Embedded Planet EP8248E board. This enables support for the Embedded Planet EP8248E board.
......
...@@ -298,6 +298,8 @@ static const struct of_device_id of_bus_ids[] __initconst = { ...@@ -298,6 +298,8 @@ static const struct of_device_id of_bus_ids[] __initconst = {
static int __init declare_of_platform_devices(void) static int __init declare_of_platform_devices(void)
{ {
of_platform_bus_probe(NULL, of_bus_ids, NULL); of_platform_bus_probe(NULL, of_bus_ids, NULL);
if (IS_ENABLED(CONFIG_MDIO_BITBANG))
platform_driver_register(&ep8248e_mdio_driver); platform_driver_register(&ep8248e_mdio_driver);
return 0; return 0;
......
...@@ -30,9 +30,7 @@ ...@@ -30,9 +30,7 @@
*/ */
static void __init asp834x_setup_arch(void) static void __init asp834x_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("asp834x_setup_arch()", 0);
mpc834x_usb_cfg(); mpc834x_usb_cfg();
} }
......
...@@ -130,10 +130,7 @@ static void __init mpc83xx_km_setup_arch(void) ...@@ -130,10 +130,7 @@ static void __init mpc83xx_km_setup_arch(void)
struct device_node *np; struct device_node *np;
#endif #endif
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("kmpbec83xx_setup_arch()", 0);
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
np = of_find_node_by_name(NULL, "par_io"); np = of_find_node_by_name(NULL, "par_io");
......
...@@ -142,3 +142,11 @@ void __init mpc83xx_setup_pci(void) ...@@ -142,3 +142,11 @@ void __init mpc83xx_setup_pci(void)
mpc83xx_add_bridge(np); mpc83xx_add_bridge(np);
} }
#endif #endif
void __init mpc83xx_setup_arch(void)
{
if (ppc_md.progress)
ppc_md.progress("mpc83xx_setup_arch()", 0);
mpc83xx_setup_pci();
}
...@@ -27,10 +27,7 @@ ...@@ -27,10 +27,7 @@
*/ */
static void __init mpc830x_rdb_setup_arch(void) static void __init mpc830x_rdb_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc830x_rdb_setup_arch()", 0);
mpc83xx_setup_pci();
mpc831x_usb_cfg(); mpc831x_usb_cfg();
} }
......
...@@ -28,10 +28,7 @@ ...@@ -28,10 +28,7 @@
*/ */
static void __init mpc831x_rdb_setup_arch(void) static void __init mpc831x_rdb_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc831x_rdb_setup_arch()", 0);
mpc83xx_setup_pci();
mpc831x_usb_cfg(); mpc831x_usb_cfg();
} }
......
...@@ -58,8 +58,7 @@ static void __init mpc832x_sys_setup_arch(void) ...@@ -58,8 +58,7 @@ static void __init mpc832x_sys_setup_arch(void)
struct device_node *np; struct device_node *np;
u8 __iomem *bcsr_regs = NULL; u8 __iomem *bcsr_regs = NULL;
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc832x_sys_setup_arch()", 0);
/* Map BCSR area */ /* Map BCSR area */
np = of_find_node_by_name(NULL, "bcsr"); np = of_find_node_by_name(NULL, "bcsr");
...@@ -71,8 +70,6 @@ static void __init mpc832x_sys_setup_arch(void) ...@@ -71,8 +70,6 @@ static void __init mpc832x_sys_setup_arch(void)
of_node_put(np); of_node_put(np);
} }
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
par_io_init(np); par_io_init(np);
......
...@@ -197,10 +197,7 @@ static void __init mpc832x_rdb_setup_arch(void) ...@@ -197,10 +197,7 @@ static void __init mpc832x_rdb_setup_arch(void)
struct device_node *np; struct device_node *np;
#endif #endif
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc832x_rdb_setup_arch()", 0);
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
......
...@@ -57,10 +57,7 @@ machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); ...@@ -57,10 +57,7 @@ machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices);
*/ */
static void __init mpc834x_itx_setup_arch(void) static void __init mpc834x_itx_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc834x_itx_setup_arch()", 0);
mpc83xx_setup_pci();
mpc834x_usb_cfg(); mpc834x_usb_cfg();
} }
......
...@@ -76,10 +76,7 @@ static int mpc834xemds_usb_cfg(void) ...@@ -76,10 +76,7 @@ static int mpc834xemds_usb_cfg(void)
*/ */
static void __init mpc834x_mds_setup_arch(void) static void __init mpc834x_mds_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc834x_mds_setup_arch()", 0);
mpc83xx_setup_pci();
mpc834xemds_usb_cfg(); mpc834xemds_usb_cfg();
} }
......
...@@ -66,8 +66,7 @@ static void __init mpc836x_mds_setup_arch(void) ...@@ -66,8 +66,7 @@ static void __init mpc836x_mds_setup_arch(void)
struct device_node *np; struct device_node *np;
u8 __iomem *bcsr_regs = NULL; u8 __iomem *bcsr_regs = NULL;
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc836x_mds_setup_arch()", 0);
/* Map BCSR area */ /* Map BCSR area */
np = of_find_node_by_name(NULL, "bcsr"); np = of_find_node_by_name(NULL, "bcsr");
...@@ -79,8 +78,6 @@ static void __init mpc836x_mds_setup_arch(void) ...@@ -79,8 +78,6 @@ static void __init mpc836x_mds_setup_arch(void)
of_node_put(np); of_node_put(np);
} }
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
par_io_init(np); par_io_init(np);
......
...@@ -31,10 +31,7 @@ machine_device_initcall(mpc836x_rdk, mpc83xx_declare_of_platform_devices); ...@@ -31,10 +31,7 @@ machine_device_initcall(mpc836x_rdk, mpc83xx_declare_of_platform_devices);
static void __init mpc836x_rdk_setup_arch(void) static void __init mpc836x_rdk_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc836x_rdk_setup_arch()", 0);
mpc83xx_setup_pci();
} }
/* /*
......
...@@ -79,10 +79,7 @@ static int mpc837xmds_usb_cfg(void) ...@@ -79,10 +79,7 @@ static int mpc837xmds_usb_cfg(void)
*/ */
static void __init mpc837x_mds_setup_arch(void) static void __init mpc837x_mds_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc837x_mds_setup_arch()", 0);
mpc83xx_setup_pci();
mpc837xmds_usb_cfg(); mpc837xmds_usb_cfg();
} }
......
...@@ -50,10 +50,7 @@ static void mpc837x_rdb_sd_cfg(void) ...@@ -50,10 +50,7 @@ static void mpc837x_rdb_sd_cfg(void)
*/ */
static void __init mpc837x_rdb_setup_arch(void) static void __init mpc837x_rdb_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("mpc837x_rdb_setup_arch()", 0);
mpc83xx_setup_pci();
mpc837x_usb_cfg(); mpc837x_usb_cfg();
mpc837x_rdb_sd_cfg(); mpc837x_rdb_sd_cfg();
} }
......
...@@ -86,5 +86,6 @@ extern void mpc83xx_setup_pci(void); ...@@ -86,5 +86,6 @@ extern void mpc83xx_setup_pci(void);
#endif #endif
extern int mpc83xx_declare_of_platform_devices(void); extern int mpc83xx_declare_of_platform_devices(void);
extern void mpc83xx_setup_arch(void);
#endif /* __MPC83XX_H__ */ #endif /* __MPC83XX_H__ */
...@@ -47,10 +47,7 @@ ...@@ -47,10 +47,7 @@
*/ */
static void __init sbc834x_setup_arch(void) static void __init sbc834x_setup_arch(void)
{ {
if (ppc_md.progress) mpc83xx_setup_arch();
ppc_md.progress("sbc834x_setup_arch()", 0);
mpc83xx_setup_pci();
} }
machine_device_initcall(sbc834x, mpc83xx_declare_of_platform_devices); machine_device_initcall(sbc834x, mpc83xx_declare_of_platform_devices);
......
...@@ -72,7 +72,7 @@ config MPC85xx_CDS ...@@ -72,7 +72,7 @@ config MPC85xx_CDS
config MPC85xx_MDS config MPC85xx_MDS
bool "Freescale MPC85xx MDS" bool "Freescale MPC85xx MDS"
select DEFAULT_UIMAGE select DEFAULT_UIMAGE
select PHYLIB select PHYLIB if NETDEVICES
select HAS_RAPIDIO select HAS_RAPIDIO
select SWIOTLB select SWIOTLB
help help
......
...@@ -72,7 +72,6 @@ define_machine(bsc9132_qds) { ...@@ -72,7 +72,6 @@ define_machine(bsc9132_qds) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -59,7 +59,6 @@ define_machine(bsc9131_rdb) { ...@@ -59,7 +59,6 @@ define_machine(bsc9131_rdb) {
.setup_arch = bsc913x_rdb_setup_arch, .setup_arch = bsc913x_rdb_setup_arch,
.init_IRQ = bsc913x_rdb_pic_init, .init_IRQ = bsc913x_rdb_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -65,7 +65,6 @@ define_machine(c293_pcie) { ...@@ -65,7 +65,6 @@ define_machine(c293_pcie) {
.setup_arch = c293_pcie_setup_arch, .setup_arch = c293_pcie_setup_arch,
.init_IRQ = c293_pcie_pic_init, .init_IRQ = c293_pcie_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -225,7 +225,6 @@ define_machine(corenet_generic) { ...@@ -225,7 +225,6 @@ define_machine(corenet_generic) {
#else #else
.get_irq = mpic_get_coreint_irq, .get_irq = mpic_get_coreint_irq,
#endif #endif
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
......
...@@ -215,7 +215,6 @@ define_machine(ge_imp3a) { ...@@ -215,7 +215,6 @@ define_machine(ge_imp3a) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -77,7 +77,6 @@ define_machine(mpc8536_ds) { ...@@ -77,7 +77,6 @@ define_machine(mpc8536_ds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -170,7 +170,6 @@ define_machine(mpc85xx_ads) { ...@@ -170,7 +170,6 @@ define_machine(mpc85xx_ads) {
.init_IRQ = mpc85xx_ads_pic_init, .init_IRQ = mpc85xx_ads_pic_init,
.show_cpuinfo = mpc85xx_ads_show_cpuinfo, .show_cpuinfo = mpc85xx_ads_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -83,7 +83,8 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, ...@@ -83,7 +83,8 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static void __noreturn mpc85xx_cds_restart(char *cmd) static int mpc85xx_cds_restart(struct notifier_block *this,
unsigned long mode, void *cmd)
{ {
struct pci_dev *dev; struct pci_dev *dev;
u_char tmp; u_char tmp;
...@@ -108,12 +109,25 @@ static void __noreturn mpc85xx_cds_restart(char *cmd) ...@@ -108,12 +109,25 @@ static void __noreturn mpc85xx_cds_restart(char *cmd)
} }
/* /*
* If we can't find the VIA chip (maybe the P2P bridge is disabled) * If we can't find the VIA chip (maybe the P2P bridge is
* or the VIA chip reset didn't work, just use the default reset. * disabled) or the VIA chip reset didn't work, just return
* and let default reset sequence happen.
*/ */
fsl_rstcr_restart(NULL); return NOTIFY_DONE;
} }
static int mpc85xx_cds_restart_register(void)
{
static struct notifier_block restart_handler;
restart_handler.notifier_call = mpc85xx_cds_restart;
restart_handler.priority = 192;
return register_restart_handler(&restart_handler);
}
machine_arch_initcall(mpc85xx_cds, mpc85xx_cds_restart_register);
static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev) static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
{ {
u_char c; u_char c;
...@@ -380,11 +394,8 @@ define_machine(mpc85xx_cds) { ...@@ -380,11 +394,8 @@ define_machine(mpc85xx_cds) {
.show_cpuinfo = mpc85xx_cds_show_cpuinfo, .show_cpuinfo = mpc85xx_cds_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.restart = mpc85xx_cds_restart,
.pcibios_fixup_bus = mpc85xx_cds_fixup_bus, .pcibios_fixup_bus = mpc85xx_cds_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#else
.restart = fsl_rstcr_restart,
#endif #endif
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -204,7 +204,6 @@ define_machine(mpc8544_ds) { ...@@ -204,7 +204,6 @@ define_machine(mpc8544_ds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -219,7 +218,6 @@ define_machine(mpc8572_ds) { ...@@ -219,7 +218,6 @@ define_machine(mpc8572_ds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -234,7 +232,6 @@ define_machine(p2020_ds) { ...@@ -234,7 +232,6 @@ define_machine(p2020_ds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -63,6 +63,8 @@ ...@@ -63,6 +63,8 @@
#define DBG(fmt...) #define DBG(fmt...)
#endif #endif
#if IS_BUILTIN(CONFIG_PHYLIB)
#define MV88E1111_SCR 0x10 #define MV88E1111_SCR 0x10
#define MV88E1111_SCR_125CLK 0x0010 #define MV88E1111_SCR_125CLK 0x0010
static int mpc8568_fixup_125_clock(struct phy_device *phydev) static int mpc8568_fixup_125_clock(struct phy_device *phydev)
...@@ -152,6 +154,8 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) ...@@ -152,6 +154,8 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
return err; return err;
} }
#endif
/* ************************************************************************ /* ************************************************************************
* *
* Setup the architecture * Setup the architecture
...@@ -313,6 +317,7 @@ static void __init mpc85xx_mds_setup_arch(void) ...@@ -313,6 +317,7 @@ static void __init mpc85xx_mds_setup_arch(void)
swiotlb_detect_4g(); swiotlb_detect_4g();
} }
#if IS_BUILTIN(CONFIG_PHYLIB)
static int __init board_fixups(void) static int __init board_fixups(void)
{ {
...@@ -342,9 +347,12 @@ static int __init board_fixups(void) ...@@ -342,9 +347,12 @@ static int __init board_fixups(void)
return 0; return 0;
} }
machine_arch_initcall(mpc8568_mds, board_fixups); machine_arch_initcall(mpc8568_mds, board_fixups);
machine_arch_initcall(mpc8569_mds, board_fixups); machine_arch_initcall(mpc8569_mds, board_fixups);
#endif
static int __init mpc85xx_publish_devices(void) static int __init mpc85xx_publish_devices(void)
{ {
if (machine_is(mpc8568_mds)) if (machine_is(mpc8568_mds))
...@@ -385,7 +393,6 @@ define_machine(mpc8568_mds) { ...@@ -385,7 +393,6 @@ define_machine(mpc8568_mds) {
.setup_arch = mpc85xx_mds_setup_arch, .setup_arch = mpc85xx_mds_setup_arch,
.init_IRQ = mpc85xx_mds_pic_init, .init_IRQ = mpc85xx_mds_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -405,7 +412,6 @@ define_machine(mpc8569_mds) { ...@@ -405,7 +412,6 @@ define_machine(mpc8569_mds) {
.setup_arch = mpc85xx_mds_setup_arch, .setup_arch = mpc85xx_mds_setup_arch,
.init_IRQ = mpc85xx_mds_pic_init, .init_IRQ = mpc85xx_mds_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -426,7 +432,6 @@ define_machine(p1021_mds) { ...@@ -426,7 +432,6 @@ define_machine(p1021_mds) {
.setup_arch = mpc85xx_mds_setup_arch, .setup_arch = mpc85xx_mds_setup_arch,
.init_IRQ = mpc85xx_mds_pic_init, .init_IRQ = mpc85xx_mds_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -434,4 +439,3 @@ define_machine(p1021_mds) { ...@@ -434,4 +439,3 @@ define_machine(p1021_mds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -213,7 +213,6 @@ define_machine(p2020_rdb) { ...@@ -213,7 +213,6 @@ define_machine(p2020_rdb) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -228,7 +227,6 @@ define_machine(p1020_rdb) { ...@@ -228,7 +227,6 @@ define_machine(p1020_rdb) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -243,7 +241,6 @@ define_machine(p1021_rdb_pc) { ...@@ -243,7 +241,6 @@ define_machine(p1021_rdb_pc) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -258,7 +255,6 @@ define_machine(p2020_rdb_pc) { ...@@ -258,7 +255,6 @@ define_machine(p2020_rdb_pc) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -273,7 +269,6 @@ define_machine(p1025_rdb) { ...@@ -273,7 +269,6 @@ define_machine(p1025_rdb) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -288,7 +283,6 @@ define_machine(p1020_mbg_pc) { ...@@ -288,7 +283,6 @@ define_machine(p1020_mbg_pc) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -303,7 +297,6 @@ define_machine(p1020_utm_pc) { ...@@ -303,7 +297,6 @@ define_machine(p1020_utm_pc) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -318,7 +311,6 @@ define_machine(p1020_rdb_pc) { ...@@ -318,7 +311,6 @@ define_machine(p1020_rdb_pc) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -333,7 +325,6 @@ define_machine(p1020_rdb_pd) { ...@@ -333,7 +325,6 @@ define_machine(p1020_rdb_pd) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -348,7 +339,6 @@ define_machine(p1024_rdb) { ...@@ -348,7 +339,6 @@ define_machine(p1024_rdb) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -66,7 +66,6 @@ define_machine(mvme2500) { ...@@ -66,7 +66,6 @@ define_machine(mvme2500) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -79,7 +79,6 @@ define_machine(p1010_rdb) { ...@@ -79,7 +79,6 @@ define_machine(p1010_rdb) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -568,7 +568,6 @@ define_machine(p1022_ds) { ...@@ -568,7 +568,6 @@ define_machine(p1022_ds) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -148,7 +148,6 @@ define_machine(p1022_rdk) { ...@@ -148,7 +148,6 @@ define_machine(p1022_rdk) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -110,7 +110,6 @@ define_machine(p1023_rdb) { ...@@ -110,7 +110,6 @@ define_machine(p1023_rdb) {
.setup_arch = mpc85xx_rdb_setup_arch, .setup_arch = mpc85xx_rdb_setup_arch,
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
......
...@@ -91,7 +91,6 @@ define_machine(ppa8548) { ...@@ -91,7 +91,6 @@ define_machine(ppa8548) {
.init_IRQ = ppa8548_pic_init, .init_IRQ = ppa8548_pic_init,
.show_cpuinfo = ppa8548_show_cpuinfo, .show_cpuinfo = ppa8548_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -77,7 +77,6 @@ define_machine(qemu_e500) { ...@@ -77,7 +77,6 @@ define_machine(qemu_e500) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_coreint_irq, .get_irq = mpic_get_coreint_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -130,7 +130,6 @@ define_machine(sbc8548) { ...@@ -130,7 +130,6 @@ define_machine(sbc8548) {
.init_IRQ = sbc8548_pic_init, .init_IRQ = sbc8548_pic_init,
.show_cpuinfo = sbc8548_show_cpuinfo, .show_cpuinfo = sbc8548_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
......
...@@ -38,18 +38,18 @@ static void gpio_halt_wfn(struct work_struct *work) ...@@ -38,18 +38,18 @@ static void gpio_halt_wfn(struct work_struct *work)
} }
static DECLARE_WORK(gpio_halt_wq, gpio_halt_wfn); static DECLARE_WORK(gpio_halt_wq, gpio_halt_wfn);
static void gpio_halt_cb(void) static void __noreturn gpio_halt_cb(void)
{ {
enum of_gpio_flags flags; enum of_gpio_flags flags;
int trigger, gpio; int trigger, gpio;
if (!halt_node) if (!halt_node)
return; panic("No reset GPIO information was provided in DT\n");
gpio = of_get_gpio_flags(halt_node, 0, &flags); gpio = of_get_gpio_flags(halt_node, 0, &flags);
if (!gpio_is_valid(gpio)) if (!gpio_is_valid(gpio))
return; panic("Provided GPIO is invalid\n");
trigger = (flags == OF_GPIO_ACTIVE_LOW); trigger = (flags == OF_GPIO_ACTIVE_LOW);
...@@ -57,6 +57,8 @@ static void gpio_halt_cb(void) ...@@ -57,6 +57,8 @@ static void gpio_halt_cb(void)
/* Probably wont return */ /* Probably wont return */
gpio_set_value(gpio, trigger); gpio_set_value(gpio, trigger);
panic("Halt failed\n");
} }
/* This IRQ means someone pressed the power button and it is waiting for us /* This IRQ means someone pressed the power button and it is waiting for us
......
...@@ -91,7 +91,6 @@ define_machine(socrates) { ...@@ -91,7 +91,6 @@ define_machine(socrates) {
.setup_arch = socrates_setup_arch, .setup_arch = socrates_setup_arch,
.init_IRQ = socrates_pic_init, .init_IRQ = socrates_pic_init,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -103,7 +103,6 @@ define_machine(stx_gp3) { ...@@ -103,7 +103,6 @@ define_machine(stx_gp3) {
.init_IRQ = stx_gp3_pic_init, .init_IRQ = stx_gp3_pic_init,
.show_cpuinfo = stx_gp3_show_cpuinfo, .show_cpuinfo = stx_gp3_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -132,7 +132,6 @@ define_machine(tqm85xx) { ...@@ -132,7 +132,6 @@ define_machine(tqm85xx) {
.init_IRQ = tqm85xx_pic_init, .init_IRQ = tqm85xx_pic_init,
.show_cpuinfo = tqm85xx_show_cpuinfo, .show_cpuinfo = tqm85xx_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -140,7 +140,6 @@ define_machine(twr_p1025) { ...@@ -140,7 +140,6 @@ define_machine(twr_p1025) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -167,7 +167,6 @@ define_machine(xes_mpc8572) { ...@@ -167,7 +167,6 @@ define_machine(xes_mpc8572) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -182,7 +181,6 @@ define_machine(xes_mpc8548) { ...@@ -182,7 +181,6 @@ define_machine(xes_mpc8548) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -197,7 +195,6 @@ define_machine(xes_mpc8540) { ...@@ -197,7 +195,6 @@ define_machine(xes_mpc8540) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb, .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
}; };
...@@ -204,7 +204,6 @@ define_machine(gef_ppc9a) { ...@@ -204,7 +204,6 @@ define_machine(gef_ppc9a) {
.init_IRQ = gef_ppc9a_init_irq, .init_IRQ = gef_ppc9a_init_irq,
.show_cpuinfo = gef_ppc9a_show_cpuinfo, .show_cpuinfo = gef_ppc9a_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -191,7 +191,6 @@ define_machine(gef_sbc310) { ...@@ -191,7 +191,6 @@ define_machine(gef_sbc310) {
.init_IRQ = gef_sbc310_init_irq, .init_IRQ = gef_sbc310_init_irq,
.show_cpuinfo = gef_sbc310_show_cpuinfo, .show_cpuinfo = gef_sbc310_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -181,7 +181,6 @@ define_machine(gef_sbc610) { ...@@ -181,7 +181,6 @@ define_machine(gef_sbc610) {
.init_IRQ = gef_sbc610_init_irq, .init_IRQ = gef_sbc610_init_irq,
.show_cpuinfo = gef_sbc610_show_cpuinfo, .show_cpuinfo = gef_sbc610_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -331,7 +331,6 @@ define_machine(mpc86xx_hpcd) { ...@@ -331,7 +331,6 @@ define_machine(mpc86xx_hpcd) {
.setup_arch = mpc86xx_hpcd_setup_arch, .setup_arch = mpc86xx_hpcd_setup_arch,
.init_IRQ = mpc86xx_init_irq, .init_IRQ = mpc86xx_init_irq,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -130,7 +130,6 @@ define_machine(mpc86xx_hpcn) { ...@@ -130,7 +130,6 @@ define_machine(mpc86xx_hpcn) {
.init_IRQ = mpc86xx_init_irq, .init_IRQ = mpc86xx_init_irq,
.show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -111,7 +111,6 @@ define_machine(mvme7100) { ...@@ -111,7 +111,6 @@ define_machine(mvme7100) {
.setup_arch = mvme7100_setup_arch, .setup_arch = mvme7100_setup_arch,
.init_IRQ = mpc86xx_init_irq, .init_IRQ = mpc86xx_init_irq,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -82,7 +82,6 @@ define_machine(sbc8641) { ...@@ -82,7 +82,6 @@ define_machine(sbc8641) {
.init_IRQ = mpc86xx_init_irq, .init_IRQ = mpc86xx_init_irq,
.show_cpuinfo = sbc8641_show_cpuinfo, .show_cpuinfo = sbc8641_show_cpuinfo,
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init, .time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -393,7 +393,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot, ...@@ -393,7 +393,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
unsigned long *vpn, int count, unsigned long *vpn, int count,
int psize, int ssize) int psize, int ssize)
{ {
unsigned long param[8]; unsigned long param[PLPAR_HCALL9_BUFSIZE];
int i = 0, pix = 0, rc; int i = 0, pix = 0, rc;
unsigned long flags = 0; unsigned long flags = 0;
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
...@@ -522,7 +522,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) ...@@ -522,7 +522,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
unsigned long flags = 0; unsigned long flags = 0;
struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
unsigned long param[9]; unsigned long param[PLPAR_HCALL9_BUFSIZE];
unsigned long hash, index, shift, hidx, slot; unsigned long hash, index, shift, hidx, slot;
real_pte_t pte; real_pte_t pte;
int psize, ssize; int psize, ssize;
......
...@@ -233,8 +233,6 @@ void __init cpm_reset(void) ...@@ -233,8 +233,6 @@ void __init cpm_reset(void)
else else
out_be32(&siu_conf->sc_sdcr, 1); out_be32(&siu_conf->sc_sdcr, 1);
immr_unmap(siu_conf); immr_unmap(siu_conf);
cpm_muram_init();
} }
static DEFINE_SPINLOCK(cmd_lock); static DEFINE_SPINLOCK(cmd_lock);
......
...@@ -66,10 +66,6 @@ void __init cpm2_reset(void) ...@@ -66,10 +66,6 @@ void __init cpm2_reset(void)
cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE); cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
#endif #endif
/* Reclaim the DP memory for our use.
*/
cpm_muram_init();
/* Tell everyone where the comm processor resides. /* Tell everyone where the comm processor resides.
*/ */
cpmp = &cpm2_immr->im_cpm; cpmp = &cpm2_immr->im_cpm;
......
...@@ -37,6 +37,21 @@ ...@@ -37,6 +37,21 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#endif #endif
static int __init cpm_init(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
if (!np)
np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
if (!np)
return -ENODEV;
cpm_muram_init();
of_node_put(np);
return 0;
}
subsys_initcall(cpm_init);
#ifdef CONFIG_PPC_EARLY_DEBUG_CPM #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
static u32 __iomem *cpm_udbg_txdesc; static u32 __iomem *cpm_udbg_txdesc;
static u8 __iomem *cpm_udbg_txbuf; static u8 __iomem *cpm_udbg_txbuf;
......
...@@ -111,8 +111,7 @@ static struct pci_ops fsl_indirect_pcie_ops = ...@@ -111,8 +111,7 @@ static struct pci_ops fsl_indirect_pcie_ops =
.write = indirect_write_config, .write = indirect_write_config,
}; };
#define MAX_PHYS_ADDR_BITS 40 static u64 pci64_dma_offset;
static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
#ifdef CONFIG_SWIOTLB #ifdef CONFIG_SWIOTLB
static void setup_swiotlb_ops(struct pci_controller *hose) static void setup_swiotlb_ops(struct pci_controller *hose)
...@@ -132,12 +131,10 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask) ...@@ -132,12 +131,10 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
return -EIO; return -EIO;
/* /*
* Fixup PCI devices that are able to DMA to above the physical * Fix up PCI devices that are able to DMA to the large inbound
* address width of the SoC such that we can address any internal * mapping that allows addressing any RAM address from across PCI.
* SoC address from across PCI if needed
*/ */
if ((dev_is_pci(dev)) && if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, &dma_direct_ops); set_dma_ops(dev, &dma_direct_ops);
set_dma_offset(dev, pci64_dma_offset); set_dma_offset(dev, pci64_dma_offset);
} }
...@@ -387,6 +384,7 @@ static void setup_pci_atmu(struct pci_controller *hose) ...@@ -387,6 +384,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log++; mem_log++;
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1); piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
pci64_dma_offset = 1ULL << mem_log;
if (setup_inbound) { if (setup_inbound) {
/* Setup inbound memory window */ /* Setup inbound memory window */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/fsl_devices.h> #include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h> #include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h> #include <linux/fs_uart_pd.h>
#include <linux/reboot.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -180,23 +181,38 @@ EXPORT_SYMBOL(get_baudrate); ...@@ -180,23 +181,38 @@ EXPORT_SYMBOL(get_baudrate);
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static __be32 __iomem *rstcr; static __be32 __iomem *rstcr;
static int fsl_rstcr_restart(struct notifier_block *this,
unsigned long mode, void *cmd)
{
local_irq_disable();
/* set reset control register */
out_be32(rstcr, 0x2); /* HRESET_REQ */
return NOTIFY_DONE;
}
static int __init setup_rstcr(void) static int __init setup_rstcr(void)
{ {
struct device_node *np; struct device_node *np;
static struct notifier_block restart_handler = {
.notifier_call = fsl_rstcr_restart,
.priority = 128,
};
for_each_node_by_name(np, "global-utilities") { for_each_node_by_name(np, "global-utilities") {
if ((of_get_property(np, "fsl,has-rstcr", NULL))) { if ((of_get_property(np, "fsl,has-rstcr", NULL))) {
rstcr = of_iomap(np, 0) + 0xb0; rstcr = of_iomap(np, 0) + 0xb0;
if (!rstcr) if (!rstcr) {
printk (KERN_ERR "Error: reset control " printk (KERN_ERR "Error: reset control "
"register not mapped!\n"); "register not mapped!\n");
} else {
register_restart_handler(&restart_handler);
}
break; break;
} }
} }
if (!rstcr && ppc_md.restart == fsl_rstcr_restart)
printk(KERN_ERR "No RSTCR register, warm reboot won't work\n");
of_node_put(np); of_node_put(np);
return 0; return 0;
...@@ -204,15 +220,6 @@ static int __init setup_rstcr(void) ...@@ -204,15 +220,6 @@ static int __init setup_rstcr(void)
arch_initcall(setup_rstcr); arch_initcall(setup_rstcr);
void __noreturn fsl_rstcr_restart(char *cmd)
{
local_irq_disable();
if (rstcr)
/* set reset control register */
out_be32(rstcr, 0x2); /* HRESET_REQ */
while (1) ;
}
#endif #endif
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
......
...@@ -19,8 +19,6 @@ extern u32 fsl_get_sys_freq(void); ...@@ -19,8 +19,6 @@ extern u32 fsl_get_sys_freq(void);
struct spi_board_info; struct spi_board_info;
struct device_node; struct device_node;
extern void __noreturn fsl_rstcr_restart(char *cmd);
/* The different ports that the DIU can be connected to */ /* The different ports that the DIU can be connected to */
enum fsl_diu_monitor_port { enum fsl_diu_monitor_port {
FSL_DIU_PORT_DVI, /* DVI */ FSL_DIU_PORT_DVI, /* DVI */
......
...@@ -1249,7 +1249,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, ...@@ -1249,7 +1249,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
/* Pick the physical address from the device tree if unspecified */ /* Pick the physical address from the device tree if unspecified */
if (!phys_addr) { if (!phys_addr) {
/* Check if it is DCR-based */ /* Check if it is DCR-based */
if (of_get_property(node, "dcr-reg", NULL)) { if (of_property_read_bool(node, "dcr-reg")) {
flags |= MPIC_USES_DCR; flags |= MPIC_USES_DCR;
} else { } else {
struct resource r; struct resource r;
......
menu "SOC (System On Chip) specific Drivers" menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/bcm/Kconfig" source "drivers/soc/bcm/Kconfig"
source "drivers/soc/fsl/qbman/Kconfig"
source "drivers/soc/fsl/qe/Kconfig" source "drivers/soc/fsl/qe/Kconfig"
source "drivers/soc/mediatek/Kconfig" source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/qcom/Kconfig" source "drivers/soc/qcom/Kconfig"
......
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
# Makefile for the Linux Kernel SOC fsl specific device drivers # Makefile for the Linux Kernel SOC fsl specific device drivers
# #
obj-$(CONFIG_FSL_DPAA) += qbman/
obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_QUICC_ENGINE) += qe/
obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_CPM) += qe/
menuconfig FSL_DPAA
bool "Freescale DPAA 1.x support"
depends on FSL_SOC_BOOKE
select GENERIC_ALLOCATOR
help
The Freescale Data Path Acceleration Architecture (DPAA) is a set of
hardware components on specific QorIQ multicore processors.
This architecture provides the infrastructure to support simplified
sharing of networking interfaces and accelerators by multiple CPUs.
The major h/w blocks composing DPAA are BMan and QMan.
The Buffer Manager (BMan) is a hardware buffer pool management block
that allows software and accelerators on the datapath to acquire and
release buffers in order to build frames.
The Queue Manager (QMan) is a hardware queue management block
that allows software and accelerators on the datapath to enqueue and
dequeue frames in order to communicate.
if FSL_DPAA
config FSL_DPAA_CHECKING
bool "Additional driver checking"
help
Compiles in additional checks, to sanity-check the drivers and
any use of the exported API. Not recommended for performance.
config FSL_BMAN_TEST
tristate "BMan self-tests"
help
Compile the BMan self-test code. These tests will
exercise the BMan APIs to confirm functionality
of both the software drivers and hardware device.
config FSL_BMAN_TEST_API
bool "High-level API self-test"
depends on FSL_BMAN_TEST
default y
help
This requires the presence of cpu-affine portals, and performs
high-level API testing with them (whichever portal(s) are affine
to the cpu(s) the test executes on).
config FSL_QMAN_TEST
tristate "QMan self-tests"
help
Compile self-test code for QMan.
config FSL_QMAN_TEST_API
bool "QMan high-level self-test"
depends on FSL_QMAN_TEST
default y
help
This requires the presence of cpu-affine portals, and performs
high-level API testing with them (whichever portal(s) are affine to
the cpu(s) the test executes on).
config FSL_QMAN_TEST_STASH
bool "QMan 'hot potato' data-stashing self-test"
depends on FSL_QMAN_TEST
default y
help
This performs a "hot potato" style test enqueuing/dequeuing a frame
across a series of FQs scheduled to different portals (and cpus), with
DQRR, data and context stashing always on.
endif # FSL_DPAA
obj-$(CONFIG_FSL_DPAA) += bman_ccsr.o qman_ccsr.o \
bman_portal.o qman_portal.o \
bman.o qman.o
obj-$(CONFIG_FSL_BMAN_TEST) += bman-test.o
bman-test-y = bman_test.o
bman-test-$(CONFIG_FSL_BMAN_TEST_API) += bman_test_api.o
obj-$(CONFIG_FSL_QMAN_TEST) += qman-test.o
qman-test-y = qman_test.o
qman-test-$(CONFIG_FSL_QMAN_TEST_API) += qman_test_api.o
qman-test-$(CONFIG_FSL_QMAN_TEST_STASH) += qman_test_stash.o
This diff is collapsed.
/* Copyright (c) 2009 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bman_priv.h"
u16 bman_ip_rev;
EXPORT_SYMBOL(bman_ip_rev);
/* Register offsets */
#define REG_FBPR_FPC 0x0800
#define REG_ECSR 0x0a00
#define REG_ECIR 0x0a04
#define REG_EADR 0x0a08
#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
#define REG_IP_REV_1 0x0bf8
#define REG_IP_REV_2 0x0bfc
#define REG_FBPR_BARE 0x0c00
#define REG_FBPR_BAR 0x0c04
#define REG_FBPR_AR 0x0c10
#define REG_SRCIDR 0x0d04
#define REG_LIODNR 0x0d08
#define REG_ERR_ISR 0x0e00
#define REG_ERR_IER 0x0e04
#define REG_ERR_ISDR 0x0e08
/* Used by all error interrupt registers except 'inhibit' */
#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
struct bman_hwerr_txt {
u32 mask;
const char *txt;
};
static const struct bman_hwerr_txt bman_hwerr_txts[] = {
{ BM_EIRQ_IVCI, "Invalid Command Verb" },
{ BM_EIRQ_FLWI, "FBPR Low Watermark" },
{ BM_EIRQ_MBEI, "Multi-bit ECC Error" },
{ BM_EIRQ_SBEI, "Single-bit ECC Error" },
{ BM_EIRQ_BSCN, "Pool State Change Notification" },
};
/* Only trigger low water mark interrupt once only */
#define BMAN_ERRS_TO_DISABLE BM_EIRQ_FLWI
/* Pointer to the start of the BMan's CCSR space */
static u32 __iomem *bm_ccsr_start;
static inline u32 bm_ccsr_in(u32 offset)
{
return ioread32be(bm_ccsr_start + offset/4);
}
static inline void bm_ccsr_out(u32 offset, u32 val)
{
iowrite32be(val, bm_ccsr_start + offset/4);
}
static void bm_get_version(u16 *id, u8 *major, u8 *minor)
{
u32 v = bm_ccsr_in(REG_IP_REV_1);
*id = (v >> 16);
*major = (v >> 8) & 0xff;
*minor = v & 0xff;
}
/* signal transactions for FBPRs with higher priority */
#define FBPR_AR_RPRIO_HI BIT(30)
static void bm_set_memory(u64 ba, u32 size)
{
u32 exp = ilog2(size);
/* choke if size isn't within range */
DPAA_ASSERT(size >= 4096 && size <= 1024*1024*1024 &&
is_power_of_2(size));
/* choke if '[e]ba' has lower-alignment than 'size' */
DPAA_ASSERT(!(ba & (size - 1)));
bm_ccsr_out(REG_FBPR_BARE, upper_32_bits(ba));
bm_ccsr_out(REG_FBPR_BAR, lower_32_bits(ba));
bm_ccsr_out(REG_FBPR_AR, exp - 1);
}
/*
* Location and size of BMan private memory
*
* Ideally we would use the DMA API to turn rmem->base into a DMA address
* (especially if iommu translations ever get involved). Unfortunately, the
* DMA API currently does not allow mapping anything that is not backed with
* a struct page.
*/
static dma_addr_t fbpr_a;
static size_t fbpr_sz;
static int bman_fbpr(struct reserved_mem *rmem)
{
fbpr_a = rmem->base;
fbpr_sz = rmem->size;
WARN_ON(!(fbpr_a && fbpr_sz));
return 0;
}
RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
static irqreturn_t bman_isr(int irq, void *ptr)
{
u32 isr_val, ier_val, ecsr_val, isr_mask, i;
struct device *dev = ptr;
ier_val = bm_ccsr_in(REG_ERR_IER);
isr_val = bm_ccsr_in(REG_ERR_ISR);
ecsr_val = bm_ccsr_in(REG_ECSR);
isr_mask = isr_val & ier_val;
if (!isr_mask)
return IRQ_NONE;
for (i = 0; i < ARRAY_SIZE(bman_hwerr_txts); i++) {
if (bman_hwerr_txts[i].mask & isr_mask) {
dev_err_ratelimited(dev, "ErrInt: %s\n",
bman_hwerr_txts[i].txt);
if (bman_hwerr_txts[i].mask & ecsr_val) {
/* Re-arm error capture registers */
bm_ccsr_out(REG_ECSR, ecsr_val);
}
if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_DISABLE) {
dev_dbg(dev, "Disabling error 0x%x\n",
bman_hwerr_txts[i].mask);
ier_val &= ~bman_hwerr_txts[i].mask;
bm_ccsr_out(REG_ERR_IER, ier_val);
}
}
}
bm_ccsr_out(REG_ERR_ISR, isr_val);
return IRQ_HANDLED;
}
static int fsl_bman_probe(struct platform_device *pdev)
{
int ret, err_irq;
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct resource *res;
u16 id, bm_pool_cnt;
u8 major, minor;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
node->full_name);
return -ENXIO;
}
bm_ccsr_start = devm_ioremap(dev, res->start,
res->end - res->start + 1);
if (!bm_ccsr_start)
return -ENXIO;
bm_get_version(&id, &major, &minor);
if (major == 1 && minor == 0) {
bman_ip_rev = BMAN_REV10;
bm_pool_cnt = BM_POOL_MAX;
} else if (major == 2 && minor == 0) {
bman_ip_rev = BMAN_REV20;
bm_pool_cnt = 8;
} else if (major == 2 && minor == 1) {
bman_ip_rev = BMAN_REV21;
bm_pool_cnt = BM_POOL_MAX;
} else {
dev_err(dev, "Unknown Bman version:%04x,%02x,%02x\n",
id, major, minor);
return -ENODEV;
}
bm_set_memory(fbpr_a, fbpr_sz);
err_irq = platform_get_irq(pdev, 0);
if (err_irq <= 0) {
dev_info(dev, "Can't get %s IRQ\n", node->full_name);
return -ENODEV;
}
ret = devm_request_irq(dev, err_irq, bman_isr, IRQF_SHARED, "bman-err",
dev);
if (ret) {
dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
ret, node->full_name);
return ret;
}
/* Disable Buffer Pool State Change */
bm_ccsr_out(REG_ERR_ISDR, BM_EIRQ_BSCN);
/*
* Write-to-clear any stale bits, (eg. starvation being asserted prior
* to resource allocation during driver init).
*/
bm_ccsr_out(REG_ERR_ISR, 0xffffffff);
/* Enable Error Interrupts */
bm_ccsr_out(REG_ERR_IER, 0xffffffff);
bm_bpalloc = devm_gen_pool_create(dev, 0, -1, "bman-bpalloc");
if (IS_ERR(bm_bpalloc)) {
ret = PTR_ERR(bm_bpalloc);
dev_err(dev, "bman-bpalloc pool init failed (%d)\n", ret);
return ret;
}
/* seed BMan resource pool */
ret = gen_pool_add(bm_bpalloc, DPAA_GENALLOC_OFF, bm_pool_cnt, -1);
if (ret) {
dev_err(dev, "Failed to seed BPID range [%d..%d] (%d)\n",
0, bm_pool_cnt - 1, ret);
return ret;
}
return 0;
};
static const struct of_device_id fsl_bman_ids[] = {
{
.compatible = "fsl,bman",
},
{}
};
static struct platform_driver fsl_bman_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = fsl_bman_ids,
.suppress_bind_attrs = true,
},
.probe = fsl_bman_probe,
};
builtin_platform_driver(fsl_bman_driver);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bman_priv.h"
static struct bman_portal *affine_bportals[NR_CPUS];
static struct cpumask portal_cpus;
/* protect bman global registers and global data shared among portals */
static DEFINE_SPINLOCK(bman_lock);
static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
{
struct bman_portal *p = bman_create_affine_portal(pcfg);
if (!p) {
dev_crit(pcfg->dev, "%s: Portal failure on cpu %d\n",
__func__, pcfg->cpu);
return NULL;
}
bman_p_irqsource_add(p, BM_PIRQ_RCRI);
affine_bportals[pcfg->cpu] = p;
dev_info(pcfg->dev, "Portal initialised, cpu %d\n", pcfg->cpu);
return p;
}
static void bman_offline_cpu(unsigned int cpu)
{
struct bman_portal *p = affine_bportals[cpu];
const struct bm_portal_config *pcfg;
if (!p)
return;
pcfg = bman_get_bm_portal_config(p);
if (!pcfg)
return;
irq_set_affinity(pcfg->irq, cpumask_of(0));
}
static void bman_online_cpu(unsigned int cpu)
{
struct bman_portal *p = affine_bportals[cpu];
const struct bm_portal_config *pcfg;
if (!p)
return;
pcfg = bman_get_bm_portal_config(p);
if (!pcfg)
return;
irq_set_affinity(pcfg->irq, cpumask_of(cpu));
}
static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
bman_online_cpu(cpu);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
bman_offline_cpu(cpu);
}
return NOTIFY_OK;
}
static struct notifier_block bman_hotplug_cpu_notifier = {
.notifier_call = bman_hotplug_cpu_callback,
};
static int bman_portal_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct bm_portal_config *pcfg;
struct resource *addr_phys[2];
void __iomem *va;
int irq, cpu;
pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
if (!pcfg)
return -ENOMEM;
pcfg->dev = dev;
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CE);
if (!addr_phys[0]) {
dev_err(dev, "Can't get %s property 'reg::CE'\n",
node->full_name);
return -ENXIO;
}
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CI);
if (!addr_phys[1]) {
dev_err(dev, "Can't get %s property 'reg::CI'\n",
node->full_name);
return -ENXIO;
}
pcfg->cpu = -1;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(dev, "Can't get %s IRQ'\n", node->full_name);
return -ENXIO;
}
pcfg->irq = irq;
va = ioremap_prot(addr_phys[0]->start, resource_size(addr_phys[0]), 0);
if (!va)
goto err_ioremap1;
pcfg->addr_virt[DPAA_PORTAL_CE] = va;
va = ioremap_prot(addr_phys[1]->start, resource_size(addr_phys[1]),
_PAGE_GUARDED | _PAGE_NO_CACHE);
if (!va)
goto err_ioremap2;
pcfg->addr_virt[DPAA_PORTAL_CI] = va;
spin_lock(&bman_lock);
cpu = cpumask_next_zero(-1, &portal_cpus);
if (cpu >= nr_cpu_ids) {
/* unassigned portal, skip init */
spin_unlock(&bman_lock);
return 0;
}
cpumask_set_cpu(cpu, &portal_cpus);
spin_unlock(&bman_lock);
pcfg->cpu = cpu;
if (!init_pcfg(pcfg))
goto err_ioremap2;
/* clear irq affinity if assigned cpu is offline */
if (!cpu_online(cpu))
bman_offline_cpu(cpu);
return 0;
err_ioremap2:
iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]);
err_ioremap1:
dev_err(dev, "ioremap failed\n");
return -ENXIO;
}
static const struct of_device_id bman_portal_ids[] = {
{
.compatible = "fsl,bman-portal",
},
{}
};
MODULE_DEVICE_TABLE(of, bman_portal_ids);
static struct platform_driver bman_portal_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = bman_portal_ids,
},
.probe = bman_portal_probe,
};
static int __init bman_portal_driver_register(struct platform_driver *drv)
{
int ret;
ret = platform_driver_register(drv);
if (ret < 0)
return ret;
register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
return 0;
}
module_driver(bman_portal_driver,
bman_portal_driver_register, platform_driver_unregister);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include "dpaa_sys.h"
#include <soc/fsl/bman.h>
/* Portal processing (interrupt) sources */
#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
/* Revision info (for errata and feature handling) */
#define BMAN_REV10 0x0100
#define BMAN_REV20 0x0200
#define BMAN_REV21 0x0201
extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise BMAN_REVx */
extern struct gen_pool *bm_bpalloc;
struct bm_portal_config {
/*
* Corenet portal addresses;
* [0]==cache-enabled, [1]==cache-inhibited.
*/
void __iomem *addr_virt[2];
/* Allow these to be joined in lists */
struct list_head list;
struct device *dev;
/* User-visible portal configuration settings */
/* portal is affined to this cpu */
int cpu;
/* portal interrupt line */
int irq;
};
struct bman_portal *bman_create_affine_portal(
const struct bm_portal_config *config);
/*
* The below bman_p_***() variant might be called in a situation that the cpu
* which the portal affine to is not online yet.
* @bman_portal specifies which portal the API will use.
*/
int bman_p_irqsource_add(struct bman_portal *p, u32 bits);
/*
* Used by all portal interrupt registers except 'inhibit'
* This mask contains all the "irqsource" bits visible to API users
*/
#define BM_PIRQ_VISIBLE BM_PIRQ_RCRI
const struct bm_portal_config *
bman_get_bm_portal_config(const struct bman_portal *portal);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bman_test.h"
MODULE_AUTHOR("Geoff Thorpe");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("BMan testing");
static int test_init(void)
{
#ifdef CONFIG_FSL_BMAN_TEST_API
int loop = 1;
while (loop--)
bman_test_api();
#endif
return 0;
}
static void test_exit(void)
{
}
module_init(test_init);
module_exit(test_exit);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bman_priv.h"
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
void bman_test_api(void);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bman_test.h"
#define NUM_BUFS 93
#define LOOPS 3
#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
static struct bman_pool *pool;
static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
static int bufs_received;
static void bufs_init(void)
{
int i;
for (i = 0; i < NUM_BUFS; i++)
bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
bufs_received = 0;
}
static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
{
if (bman_ip_rev == BMAN_REV20 || bman_ip_rev == BMAN_REV21) {
/*
* On SoCs with BMan revison 2.0, BMan only respects the 40
* LS-bits of buffer addresses, masking off the upper 8-bits on
* release commands. The API provides for 48-bit addresses
* because some SoCs support all 48-bits. When generating
* garbage addresses for testing, we either need to zero the
* upper 8-bits when releasing to BMan (otherwise we'll be
* disappointed when the buffers we acquire back from BMan
* don't match), or we need to mask the upper 8-bits off when
* comparing. We do the latter.
*/
if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) <
(bm_buffer_get64(b) & BMAN_TOKEN_MASK))
return -1;
if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) >
(bm_buffer_get64(b) & BMAN_TOKEN_MASK))
return 1;
} else {
if (bm_buffer_get64(a) < bm_buffer_get64(b))
return -1;
if (bm_buffer_get64(a) > bm_buffer_get64(b))
return 1;
}
return 0;
}
static void bufs_confirm(void)
{
int i, j;
for (i = 0; i < NUM_BUFS; i++) {
int matches = 0;
for (j = 0; j < NUM_BUFS; j++)
if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
matches++;
WARN_ON(matches != 1);
}
}
/* test */
void bman_test_api(void)
{
int i, loops = LOOPS;
bufs_init();
pr_info("%s(): Starting\n", __func__);
pool = bman_new_pool();
if (!pool) {
pr_crit("bman_new_pool() failed\n");
goto failed;
}
/* Release buffers */
do_loop:
i = 0;
while (i < NUM_BUFS) {
int num = 8;
if (i + num > NUM_BUFS)
num = NUM_BUFS - i;
if (bman_release(pool, bufs_in + i, num)) {
pr_crit("bman_release() failed\n");
goto failed;
}
i += num;
}
/* Acquire buffers */
while (i > 0) {
int tmp, num = 8;
if (num > i)
num = i;
tmp = bman_acquire(pool, bufs_out + i - num, num);
WARN_ON(tmp != num);
i -= num;
}
i = bman_acquire(pool, NULL, 1);
WARN_ON(i > 0);
bufs_confirm();
if (--loops)
goto do_loop;
/* Clean up */
bman_free_pool(pool);
pr_info("%s(): Finished\n", __func__);
return;
failed:
WARN_ON(1);
}
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __DPAA_SYS_H
#define __DPAA_SYS_H
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/platform_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/prefetch.h>
#include <linux/genalloc.h>
#include <asm/cacheflush.h>
/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
#define DPAA_PORTAL_CE 0
#define DPAA_PORTAL_CI 1
#if (L1_CACHE_BYTES != 32) && (L1_CACHE_BYTES != 64)
#error "Unsupported Cacheline Size"
#endif
static inline void dpaa_flush(void *p)
{
#ifdef CONFIG_PPC
flush_dcache_range((unsigned long)p, (unsigned long)p+64);
#elif defined(CONFIG_ARM32)
__cpuc_flush_dcache_area(p, 64);
#elif defined(CONFIG_ARM64)
__flush_dcache_area(p, 64);
#endif
}
#define dpaa_invalidate(p) dpaa_flush(p)
#define dpaa_zero(p) memset(p, 0, 64)
static inline void dpaa_touch_ro(void *p)
{
#if (L1_CACHE_BYTES == 32)
prefetch(p+32);
#endif
prefetch(p);
}
/* Commonly used combo */
static inline void dpaa_invalidate_touch_ro(void *p)
{
dpaa_invalidate(p);
dpaa_touch_ro(p);
}
#ifdef CONFIG_FSL_DPAA_CHECKING
#define DPAA_ASSERT(x) WARN_ON(!(x))
#else
#define DPAA_ASSERT(x)
#endif
/* cyclic helper for rings */
static inline u8 dpaa_cyc_diff(u8 ringsize, u8 first, u8 last)
{
/* 'first' is included, 'last' is excluded */
if (first <= last)
return last - first;
return ringsize + last - first;
}
/* Offset applied to genalloc pools due to zero being an error return */
#define DPAA_GENALLOC_OFF 0x80000000
#endif /* __DPAA_SYS_H */
This diff is collapsed.
This diff is collapsed.
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qman_priv.h"
/* Enable portal interupts (as opposed to polling mode) */
#define CONFIG_FSL_DPA_PIRQ_SLOW 1
#define CONFIG_FSL_DPA_PIRQ_FAST 1
static struct cpumask portal_cpus;
/* protect qman global registers and global data shared among portals */
static DEFINE_SPINLOCK(qman_lock);
static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
{
#ifdef CONFIG_FSL_PAMU
struct device *dev = pcfg->dev;
int window_count = 1;
struct iommu_domain_geometry geom_attr;
struct pamu_stash_attribute stash_attr;
int ret;
pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
if (!pcfg->iommu_domain) {
dev_err(dev, "%s(): iommu_domain_alloc() failed", __func__);
goto no_iommu;
}
geom_attr.aperture_start = 0;
geom_attr.aperture_end =
((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
geom_attr.force_aperture = true;
ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
&geom_attr);
if (ret < 0) {
dev_err(dev, "%s(): iommu_domain_set_attr() = %d", __func__,
ret);
goto out_domain_free;
}
ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
&window_count);
if (ret < 0) {
dev_err(dev, "%s(): iommu_domain_set_attr() = %d", __func__,
ret);
goto out_domain_free;
}
stash_attr.cpu = cpu;
stash_attr.cache = PAMU_ATTR_CACHE_L1;
ret = iommu_domain_set_attr(pcfg->iommu_domain,
DOMAIN_ATTR_FSL_PAMU_STASH,
&stash_attr);
if (ret < 0) {
dev_err(dev, "%s(): iommu_domain_set_attr() = %d",
__func__, ret);
goto out_domain_free;
}
ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
IOMMU_READ | IOMMU_WRITE);
if (ret < 0) {
dev_err(dev, "%s(): iommu_domain_window_enable() = %d",
__func__, ret);
goto out_domain_free;
}
ret = iommu_attach_device(pcfg->iommu_domain, dev);
if (ret < 0) {
dev_err(dev, "%s(): iommu_device_attach() = %d", __func__,
ret);
goto out_domain_free;
}
ret = iommu_domain_set_attr(pcfg->iommu_domain,
DOMAIN_ATTR_FSL_PAMU_ENABLE,
&window_count);
if (ret < 0) {
dev_err(dev, "%s(): iommu_domain_set_attr() = %d", __func__,
ret);
goto out_detach_device;
}
no_iommu:
#endif
qman_set_sdest(pcfg->channel, cpu);
return;
#ifdef CONFIG_FSL_PAMU
out_detach_device:
iommu_detach_device(pcfg->iommu_domain, NULL);
out_domain_free:
iommu_domain_free(pcfg->iommu_domain);
pcfg->iommu_domain = NULL;
#endif
}
static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
{
struct qman_portal *p;
u32 irq_sources = 0;
/* We need the same LIODN offset for all portals */
qman_liodn_fixup(pcfg->channel);
pcfg->iommu_domain = NULL;
portal_set_cpu(pcfg, pcfg->cpu);
p = qman_create_affine_portal(pcfg, NULL);
if (!p) {
dev_crit(pcfg->dev, "%s: Portal failure on cpu %d\n",
__func__, pcfg->cpu);
return NULL;
}
/* Determine what should be interrupt-vs-poll driven */
#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
QM_PIRQ_CSCI;
#endif
#ifdef CONFIG_FSL_DPA_PIRQ_FAST
irq_sources |= QM_PIRQ_DQRI;
#endif
qman_p_irqsource_add(p, irq_sources);
spin_lock(&qman_lock);
if (cpumask_equal(&portal_cpus, cpu_possible_mask)) {
/* all assigned portals are initialized now */
qman_init_cgr_all();
}
spin_unlock(&qman_lock);
dev_info(pcfg->dev, "Portal initialised, cpu %d\n", pcfg->cpu);
return p;
}
static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
unsigned int cpu)
{
#ifdef CONFIG_FSL_PAMU /* TODO */
struct pamu_stash_attribute stash_attr;
int ret;
if (pcfg->iommu_domain) {
stash_attr.cpu = cpu;
stash_attr.cache = PAMU_ATTR_CACHE_L1;
ret = iommu_domain_set_attr(pcfg->iommu_domain,
DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
if (ret < 0) {
dev_err(pcfg->dev,
"Failed to update pamu stash setting\n");
return;
}
}
#endif
qman_set_sdest(pcfg->channel, cpu);
}
static void qman_offline_cpu(unsigned int cpu)
{
struct qman_portal *p;
const struct qm_portal_config *pcfg;
p = affine_portals[cpu];
if (p) {
pcfg = qman_get_qm_portal_config(p);
if (pcfg) {
irq_set_affinity(pcfg->irq, cpumask_of(0));
qman_portal_update_sdest(pcfg, 0);
}
}
}
static void qman_online_cpu(unsigned int cpu)
{
struct qman_portal *p;
const struct qm_portal_config *pcfg;
p = affine_portals[cpu];
if (p) {
pcfg = qman_get_qm_portal_config(p);
if (pcfg) {
irq_set_affinity(pcfg->irq, cpumask_of(cpu));
qman_portal_update_sdest(pcfg, cpu);
}
}
}
static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
qman_online_cpu(cpu);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
qman_offline_cpu(cpu);
default:
break;
}
return NOTIFY_OK;
}
static struct notifier_block qman_hotplug_cpu_notifier = {
.notifier_call = qman_hotplug_cpu_callback,
};
static int qman_portal_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct qm_portal_config *pcfg;
struct resource *addr_phys[2];
const u32 *channel;
void __iomem *va;
int irq, len, cpu;
pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
if (!pcfg)
return -ENOMEM;
pcfg->dev = dev;
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CE);
if (!addr_phys[0]) {
dev_err(dev, "Can't get %s property 'reg::CE'\n",
node->full_name);
return -ENXIO;
}
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CI);
if (!addr_phys[1]) {
dev_err(dev, "Can't get %s property 'reg::CI'\n",
node->full_name);
return -ENXIO;
}
channel = of_get_property(node, "cell-index", &len);
if (!channel || (len != 4)) {
dev_err(dev, "Can't get %s property 'cell-index'\n",
node->full_name);
return -ENXIO;
}
pcfg->channel = *channel;
pcfg->cpu = -1;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(dev, "Can't get %s IRQ\n", node->full_name);
return -ENXIO;
}
pcfg->irq = irq;
va = ioremap_prot(addr_phys[0]->start, resource_size(addr_phys[0]), 0);
if (!va)
goto err_ioremap1;
pcfg->addr_virt[DPAA_PORTAL_CE] = va;
va = ioremap_prot(addr_phys[1]->start, resource_size(addr_phys[1]),
_PAGE_GUARDED | _PAGE_NO_CACHE);
if (!va)
goto err_ioremap2;
pcfg->addr_virt[DPAA_PORTAL_CI] = va;
pcfg->pools = qm_get_pools_sdqcr();
spin_lock(&qman_lock);
cpu = cpumask_next_zero(-1, &portal_cpus);
if (cpu >= nr_cpu_ids) {
/* unassigned portal, skip init */
spin_unlock(&qman_lock);
return 0;
}
cpumask_set_cpu(cpu, &portal_cpus);
spin_unlock(&qman_lock);
pcfg->cpu = cpu;
if (!init_pcfg(pcfg))
goto err_ioremap2;
/* clear irq affinity if assigned cpu is offline */
if (!cpu_online(cpu))
qman_offline_cpu(cpu);
return 0;
err_ioremap2:
iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]);
err_ioremap1:
dev_err(dev, "ioremap failed\n");
return -ENXIO;
}
static const struct of_device_id qman_portal_ids[] = {
{
.compatible = "fsl,qman-portal",
},
{}
};
MODULE_DEVICE_TABLE(of, qman_portal_ids);
static struct platform_driver qman_portal_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = qman_portal_ids,
},
.probe = qman_portal_probe,
};
static int __init qman_portal_driver_register(struct platform_driver *drv)
{
int ret;
ret = platform_driver_register(drv);
if (ret < 0)
return ret;
register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
return 0;
}
module_driver(qman_portal_driver,
qman_portal_driver_register, platform_driver_unregister);
This diff is collapsed.
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qman_test.h"
MODULE_AUTHOR("Geoff Thorpe");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("QMan testing");
static int test_init(void)
{
int loop = 1;
int err = 0;
while (loop--) {
#ifdef CONFIG_FSL_QMAN_TEST_STASH
err = qman_test_stash();
if (err)
break;
#endif
#ifdef CONFIG_FSL_QMAN_TEST_API
err = qman_test_api();
if (err)
break;
#endif
}
return err;
}
static void test_exit(void)
{
}
module_init(test_init);
module_exit(test_exit);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qman_priv.h"
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
int qman_test_stash(void);
int qman_test_api(void);
/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qman_test.h"
#define CGR_ID 27
#define POOL_ID 2
#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
#define NUM_ENQUEUES 10
#define NUM_PARTIAL 4
#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
QM_SDQCR_TYPE_PRIO_QOS | \
QM_SDQCR_TOKEN_SET(0x98) | \
QM_SDQCR_CHANNELS_DEDICATED | \
QM_SDQCR_CHANNELS_POOL(POOL_ID))
#define PORTAL_OPAQUE ((void *)0xf00dbeef)
#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
struct qman_fq *,
const struct qm_dqrr_entry *);
static void cb_ern(struct qman_portal *, struct qman_fq *,
const union qm_mr_entry *);
static void cb_fqs(struct qman_portal *, struct qman_fq *,
const union qm_mr_entry *);
static struct qm_fd fd, fd_dq;
static struct qman_fq fq_base = {
.cb.dqrr = cb_dqrr,
.cb.ern = cb_ern,
.cb.fqs = cb_fqs
};
static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
static int retire_complete, sdqcr_complete;
/* Helpers for initialising and "incrementing" a frame descriptor */
static void fd_init(struct qm_fd *fd)
{
qm_fd_addr_set64(fd, 0xabdeadbeefLLU);
qm_fd_set_contig_big(fd, 0x0000ffff);
fd->cmd = 0xfeedf00d;
}
static void fd_inc(struct qm_fd *fd)
{
u64 t = qm_fd_addr_get64(fd);
int z = t >> 40;
unsigned int len, off;
enum qm_fd_format fmt;
t <<= 1;
if (z)
t |= 1;
qm_fd_addr_set64(fd, t);
fmt = qm_fd_get_format(fd);
off = qm_fd_get_offset(fd);
len = qm_fd_get_length(fd);
len--;
qm_fd_set_param(fd, fmt, off, len);
fd->cmd++;
}
/* The only part of the 'fd' we can't memcmp() is the ppid */
static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
{
int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
if (!r) {
enum qm_fd_format fmt_a, fmt_b;
fmt_a = qm_fd_get_format(a);
fmt_b = qm_fd_get_format(b);
r = fmt_a - fmt_b;
}
if (!r)
r = a->cfg - b->cfg;
if (!r)
r = a->cmd - b->cmd;
return r;
}
/* test */
static int do_enqueues(struct qman_fq *fq)
{
unsigned int loop;
int err = 0;
for (loop = 0; loop < NUM_ENQUEUES; loop++) {
if (qman_enqueue(fq, &fd)) {
pr_crit("qman_enqueue() failed\n");
err = -EIO;
}
fd_inc(&fd);
}
return err;
}
int qman_test_api(void)
{
unsigned int flags, frmcnt;
int err;
struct qman_fq *fq = &fq_base;
pr_info("%s(): Starting\n", __func__);
fd_init(&fd);
fd_init(&fd_dq);
/* Initialise (parked) FQ */
err = qman_create_fq(0, FQ_FLAGS, fq);
if (err) {
pr_crit("qman_create_fq() failed\n");
goto failed;
}
err = qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL);
if (err) {
pr_crit("qman_init_fq() failed\n");
goto failed;
}
/* Do enqueues + VDQCR, twice. (Parked FQ) */
err = do_enqueues(fq);
if (err)
goto failed;
pr_info("VDQCR (till-empty);\n");
frmcnt = QM_VDQCR_NUMFRAMES_TILLEMPTY;
err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
if (err) {
pr_crit("qman_volatile_dequeue() failed\n");
goto failed;
}
err = do_enqueues(fq);
if (err)
goto failed;
pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
frmcnt = QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL);
err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
if (err) {
pr_crit("qman_volatile_dequeue() failed\n");
goto failed;
}
pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
NUM_ENQUEUES);
frmcnt = QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL);
err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
if (err) {
pr_err("qman_volatile_dequeue() failed\n");
goto failed;
}
err = do_enqueues(fq);
if (err)
goto failed;
pr_info("scheduled dequeue (till-empty)\n");
err = qman_schedule_fq(fq);
if (err) {
pr_crit("qman_schedule_fq() failed\n");
goto failed;
}
wait_event(waitqueue, sdqcr_complete);
/* Retire and OOS the FQ */
err = qman_retire_fq(fq, &flags);
if (err < 0) {
pr_crit("qman_retire_fq() failed\n");
goto failed;
}
wait_event(waitqueue, retire_complete);
if (flags & QMAN_FQ_STATE_BLOCKOOS) {
err = -EIO;
pr_crit("leaking frames\n");
goto failed;
}
err = qman_oos_fq(fq);
if (err) {
pr_crit("qman_oos_fq() failed\n");
goto failed;
}
qman_destroy_fq(fq);
pr_info("%s(): Finished\n", __func__);
return 0;
failed:
WARN_ON(1);
return err;
}
static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
struct qman_fq *fq,
const struct qm_dqrr_entry *dq)
{
if (WARN_ON(fd_cmp(&fd_dq, &dq->fd))) {
pr_err("BADNESS: dequeued frame doesn't match;\n");
return qman_cb_dqrr_consume;
}
fd_inc(&fd_dq);
if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
sdqcr_complete = 1;
wake_up(&waitqueue);
}
return qman_cb_dqrr_consume;
}
static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
const union qm_mr_entry *msg)
{
pr_crit("cb_ern() unimplemented");
WARN_ON(1);
}
static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
const union qm_mr_entry *msg)
{
u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI)) {
pr_crit("unexpected FQS message");
WARN_ON(1);
return;
}
pr_info("Retirement message received\n");
retire_complete = 1;
wake_up(&waitqueue);
}
This diff is collapsed.
...@@ -41,7 +41,8 @@ struct qe_gpio_chip { ...@@ -41,7 +41,8 @@ struct qe_gpio_chip {
static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
{ {
struct qe_gpio_chip *qe_gc = gpiochip_get_data(&mm_gc->gc); struct qe_gpio_chip *qe_gc =
container_of(mm_gc, struct qe_gpio_chip, mm_gc);
struct qe_pio_regs __iomem *regs = mm_gc->regs; struct qe_pio_regs __iomem *regs = mm_gc->regs;
qe_gc->cpdata = in_be32(&regs->cpdata); qe_gc->cpdata = in_be32(&regs->cpdata);
......
This diff is collapsed.
This diff is collapsed.
...@@ -99,7 +99,7 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm, ...@@ -99,7 +99,7 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm,
utdm->tdm_port = val; utdm->tdm_port = val;
ut_info->uf_info.tdm_num = utdm->tdm_port; ut_info->uf_info.tdm_num = utdm->tdm_port;
if (of_get_property(np, "fsl,tdm-internal-loopback", NULL)) if (of_property_read_bool(np, "fsl,tdm-internal-loopback"))
utdm->tdm_mode = TDM_INTERNAL_LOOPBACK; utdm->tdm_mode = TDM_INTERNAL_LOOPBACK;
else else
utdm->tdm_mode = TDM_NORMAL; utdm->tdm_mode = TDM_NORMAL;
...@@ -167,7 +167,7 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm, ...@@ -167,7 +167,7 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm,
} }
if (siram_init_flag == 0) { if (siram_init_flag == 0) {
memset_io(utdm->siram, 0, res->end - res->start + 1); memset_io(utdm->siram, 0, resource_size(res));
siram_init_flag = 1; siram_init_flag = 1;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment