mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
Merge remote-tracking branch 'jwb/next' into next
This commit is contained in:
commit
4b575f3e8a
12 changed files with 186 additions and 85 deletions
|
@ -3876,7 +3876,7 @@ F: arch/powerpc/platforms/512x/
|
|||
F: arch/powerpc/platforms/52xx/
|
||||
|
||||
LINUX FOR POWERPC EMBEDDED PPC4XX
|
||||
M: Josh Boyer <jwboyer@linux.vnet.ibm.com>
|
||||
M: Josh Boyer <jwboyer@gmail.com>
|
||||
M: Matt Porter <mporter@kernel.crashing.org>
|
||||
W: http://www.penguinppc.org/
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
|
|
|
@ -842,7 +842,7 @@ config LOWMEM_CAM_NUM
|
|||
|
||||
config RELOCATABLE
|
||||
bool "Build a relocatable kernel (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
|
||||
depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && (FSL_BOOKE || PPC_47x)
|
||||
help
|
||||
This builds a kernel image that is capable of running at the
|
||||
location the kernel is loaded at (some alignment restrictions may
|
||||
|
|
|
@ -337,7 +337,7 @@ EMAC2: ethernet@40000c00 {
|
|||
rx-fifo-size = <4096>;
|
||||
tx-fifo-size = <2048>;
|
||||
phy-mode = "rgmii";
|
||||
phy-map = <0x00000001>;
|
||||
phy-address = <1>;
|
||||
rgmii-device = <&RGMII0>;
|
||||
rgmii-channel = <0>;
|
||||
zmii-device = <&ZMII0>;
|
||||
|
@ -361,7 +361,7 @@ EMAC3: ethernet@40000e00 {
|
|||
rx-fifo-size = <4096>;
|
||||
tx-fifo-size = <2048>;
|
||||
phy-mode = "rgmii";
|
||||
phy-map = <0x00000003>;
|
||||
phy-address = <3>;
|
||||
rgmii-device = <&RGMII0>;
|
||||
rgmii-channel = <1>;
|
||||
zmii-device = <&ZMII0>;
|
||||
|
|
|
@ -34,9 +34,29 @@
|
|||
|
||||
BSS_STACK(4096);
|
||||
|
||||
static u32 ibm4xx_memstart;
|
||||
|
||||
static void iss_4xx_fixups(void)
|
||||
{
|
||||
ibm4xx_sdram_fixup_memsize();
|
||||
void *memory;
|
||||
u32 reg[3];
|
||||
|
||||
memory = finddevice("/memory");
|
||||
if (!memory)
|
||||
fatal("Can't find memory node\n");
|
||||
/* This assumes #address-cells = 2, #size-cells =1 and that */
|
||||
getprop(memory, "reg", reg, sizeof(reg));
|
||||
if (reg[2])
|
||||
/* If the device tree specifies the memory range, use it */
|
||||
ibm4xx_memstart = reg[1];
|
||||
else
|
||||
/* othersize, read it from the SDRAM controller */
|
||||
ibm4xx_sdram_fixup_memsize();
|
||||
}
|
||||
|
||||
static void *iss_4xx_vmlinux_alloc(unsigned long size)
|
||||
{
|
||||
return (void *)ibm4xx_memstart;
|
||||
}
|
||||
|
||||
#define SPRN_PIR 0x11E /* Processor Indentification Register */
|
||||
|
@ -48,6 +68,7 @@ void platform_init(void)
|
|||
|
||||
simple_alloc_init(_end, avail_ram, 128, 64);
|
||||
platform_ops.fixups = iss_4xx_fixups;
|
||||
platform_ops.vmlinux_alloc = iss_4xx_vmlinux_alloc;
|
||||
platform_ops.exit = ibm44x_dbcr_reset;
|
||||
pir_reg = mfspr(SPRN_PIR);
|
||||
fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
|
||||
|
|
|
@ -3,8 +3,8 @@ CONFIG_SMP=y
|
|||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_EXPERT=y
|
||||
|
@ -21,10 +21,11 @@ CONFIG_ISS4xx=y
|
|||
CONFIG_HZ_100=y
|
||||
CONFIG_MATH_EMULATION=y
|
||||
CONFIG_IRQ_ALL_CPUS=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
CONFIG_CMDLINE="root=/dev/issblk0"
|
||||
# CONFIG_PCI is not set
|
||||
CONFIG_ADVANCED_OPTIONS=y
|
||||
CONFIG_RELOCATABLE=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
@ -67,7 +68,6 @@ CONFIG_EXT3_FS=y
|
|||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_CRAMFS=y
|
||||
|
|
|
@ -125,9 +125,14 @@ static inline int mmu_has_feature(unsigned long feature)
|
|||
return (cur_cpu_spec->mmu_features & feature);
|
||||
}
|
||||
|
||||
static inline void mmu_clear_feature(unsigned long feature)
|
||||
{
|
||||
cur_cpu_spec->mmu_features &= ~feature;
|
||||
}
|
||||
|
||||
extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
|
||||
|
||||
/* MMU initialization (64-bit only fo now) */
|
||||
/* MMU initialization */
|
||||
extern void early_init_mmu(void);
|
||||
extern void early_init_mmu_secondary(void);
|
||||
|
||||
|
|
|
@ -93,6 +93,30 @@ _ENTRY(_start);
|
|||
|
||||
bl early_init
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
/*
|
||||
* r25 will contain RPN/ERPN for the start address of memory
|
||||
*
|
||||
* Add the difference between KERNELBASE and PAGE_OFFSET to the
|
||||
* start of physical memory to get kernstart_addr.
|
||||
*/
|
||||
lis r3,kernstart_addr@ha
|
||||
la r3,kernstart_addr@l(r3)
|
||||
|
||||
lis r4,KERNELBASE@h
|
||||
ori r4,r4,KERNELBASE@l
|
||||
lis r5,PAGE_OFFSET@h
|
||||
ori r5,r5,PAGE_OFFSET@l
|
||||
subf r4,r5,r4
|
||||
|
||||
rlwinm r6,r25,0,28,31 /* ERPN */
|
||||
rlwinm r7,r25,0,0,3 /* RPN - assuming 256 MB page size */
|
||||
add r7,r7,r4
|
||||
|
||||
stw r6,0(r3)
|
||||
stw r7,4(r3)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decide what sort of machine this is and initialize the MMU.
|
||||
*/
|
||||
|
@ -1001,9 +1025,6 @@ clear_utlb_entry:
|
|||
lis r3,PAGE_OFFSET@h
|
||||
ori r3,r3,PAGE_OFFSET@l
|
||||
|
||||
/* Kernel is at the base of RAM */
|
||||
li r4, 0 /* Load the kernel physical address */
|
||||
|
||||
/* Load the kernel PID = 0 */
|
||||
li r0,0
|
||||
mtspr SPRN_PID,r0
|
||||
|
@ -1013,9 +1034,8 @@ clear_utlb_entry:
|
|||
clrrwi r3,r3,12 /* Mask off the effective page number */
|
||||
ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M
|
||||
|
||||
/* Word 1 */
|
||||
clrrwi r4,r4,12 /* Mask off the real page number */
|
||||
/* ERPN is 0 for first 4GB page */
|
||||
/* Word 1 - use r25. RPN is the same as the original entry */
|
||||
|
||||
/* Word 2 */
|
||||
li r5,0
|
||||
ori r5,r5,PPC47x_TLB2_S_RWX
|
||||
|
@ -1026,7 +1046,7 @@ clear_utlb_entry:
|
|||
/* We write to way 0 and bolted 0 */
|
||||
lis r0,0x8800
|
||||
tlbwe r3,r0,0
|
||||
tlbwe r4,r0,1
|
||||
tlbwe r25,r0,1
|
||||
tlbwe r5,r0,2
|
||||
|
||||
/*
|
||||
|
@ -1124,7 +1144,13 @@ head_start_common:
|
|||
lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
|
||||
mtspr SPRN_IVPR,r4
|
||||
|
||||
addis r22,r22,KERNELBASE@h
|
||||
/*
|
||||
* If the kernel was loaded at a non-zero 256 MB page, we need to
|
||||
* mask off the most significant 4 bits to get the relative address
|
||||
* from the start of physical memory
|
||||
*/
|
||||
rlwinm r22,r22,0,4,31
|
||||
addis r22,r22,PAGE_OFFSET@h
|
||||
mtlr r22
|
||||
isync
|
||||
blr
|
||||
|
|
|
@ -127,6 +127,8 @@ notrace void __init machine_init(unsigned long dt_ptr)
|
|||
/* Do some early initialization based on the flat device tree */
|
||||
early_init_devtree(__va(dt_ptr));
|
||||
|
||||
early_init_mmu();
|
||||
|
||||
probe_machine();
|
||||
|
||||
setup_kdump_trampoline();
|
||||
|
|
|
@ -186,10 +186,11 @@ void __init MMU_init_hw(void)
|
|||
unsigned long __init mmu_mapin_ram(unsigned long top)
|
||||
{
|
||||
unsigned long addr;
|
||||
unsigned long memstart = memstart_addr & ~(PPC_PIN_SIZE - 1);
|
||||
|
||||
/* Pin in enough TLBs to cover any lowmem not covered by the
|
||||
* initial 256M mapping established in head_44x.S */
|
||||
for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr;
|
||||
for (addr = memstart + PPC_PIN_SIZE; addr < lowmem_end_addr;
|
||||
addr += PPC_PIN_SIZE) {
|
||||
if (mmu_has_feature(MMU_FTR_TYPE_47x))
|
||||
ppc47x_pin_tlb(addr + PAGE_OFFSET, addr);
|
||||
|
@ -218,19 +219,25 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
|
|||
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||
phys_addr_t first_memblock_size)
|
||||
{
|
||||
u64 size;
|
||||
|
||||
#ifndef CONFIG_RELOCATABLE
|
||||
/* We don't currently support the first MEMBLOCK not mapping 0
|
||||
* physical on those processors
|
||||
*/
|
||||
BUG_ON(first_memblock_base != 0);
|
||||
#endif
|
||||
|
||||
/* 44x has a 256M TLB entry pinned at boot */
|
||||
memblock_set_current_limit(min_t(u64, first_memblock_size, PPC_PIN_SIZE));
|
||||
size = (min_t(u64, first_memblock_size, PPC_PIN_SIZE));
|
||||
memblock_set_current_limit(first_memblock_base + size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void __cpuinit mmu_init_secondary(int cpu)
|
||||
{
|
||||
unsigned long addr;
|
||||
unsigned long memstart = memstart_addr & ~(PPC_PIN_SIZE - 1);
|
||||
|
||||
/* Pin in enough TLBs to cover any lowmem not covered by the
|
||||
* initial 256M mapping established in head_44x.S
|
||||
|
@ -241,7 +248,7 @@ void __cpuinit mmu_init_secondary(int cpu)
|
|||
* stack. current (r2) isn't initialized, smp_processor_id()
|
||||
* will not work, current thread info isn't accessible, ...
|
||||
*/
|
||||
for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr;
|
||||
for (addr = memstart + PPC_PIN_SIZE; addr < lowmem_end_addr;
|
||||
addr += PPC_PIN_SIZE) {
|
||||
if (mmu_has_feature(MMU_FTR_TYPE_47x))
|
||||
ppc47x_pin_tlb(addr + PAGE_OFFSET, addr);
|
||||
|
|
|
@ -177,3 +177,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
|||
flush_range(vma->vm_mm, start, end);
|
||||
}
|
||||
EXPORT_SYMBOL(flush_tlb_range);
|
||||
|
||||
void __init early_init_mmu(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/preempt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/tlb.h>
|
||||
|
@ -272,6 +273,17 @@ EXPORT_SYMBOL(flush_tlb_page);
|
|||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_PPC_47x
|
||||
void __init early_init_mmu_47x(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
if (of_get_flat_dt_prop(root, "cooperative-partition", NULL))
|
||||
mmu_clear_feature(MMU_FTR_USE_TLBIVAX_BCAST);
|
||||
#endif /* CONFIG_SMP */
|
||||
}
|
||||
#endif /* CONFIG_PPC_47x */
|
||||
|
||||
/*
|
||||
* Flush kernel TLB entries in the given range
|
||||
*/
|
||||
|
@ -599,4 +611,11 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
|||
/* Finally limit subsequent allocations */
|
||||
memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
|
||||
}
|
||||
#else /* ! CONFIG_PPC64 */
|
||||
void __init early_init_mmu(void)
|
||||
{
|
||||
#ifdef CONFIG_PPC_47x
|
||||
early_init_mmu_47x();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
|
|
@ -650,12 +650,74 @@ struct ppc4xx_pciex_hwops
|
|||
int (*core_init)(struct device_node *np);
|
||||
int (*port_init_hw)(struct ppc4xx_pciex_port *port);
|
||||
int (*setup_utl)(struct ppc4xx_pciex_port *port);
|
||||
void (*check_link)(struct ppc4xx_pciex_port *port);
|
||||
};
|
||||
|
||||
static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops;
|
||||
|
||||
#ifdef CONFIG_44x
|
||||
|
||||
static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
|
||||
unsigned int sdr_offset,
|
||||
unsigned int mask,
|
||||
unsigned int value,
|
||||
int timeout_ms)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
while(timeout_ms--) {
|
||||
val = mfdcri(SDR0, port->sdr_base + sdr_offset);
|
||||
if ((val & mask) == value) {
|
||||
pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
|
||||
port->index, sdr_offset, timeout_ms, val);
|
||||
return 0;
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port)
|
||||
{
|
||||
/* Wait for reset to complete */
|
||||
if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
|
||||
printk(KERN_WARNING "PCIE%d: PGRST failed\n",
|
||||
port->index);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port)
|
||||
{
|
||||
printk(KERN_INFO "PCIE%d: Checking link...\n", port->index);
|
||||
|
||||
/* Check for card presence detect if supported, if not, just wait for
|
||||
* link unconditionally.
|
||||
*
|
||||
* note that we don't fail if there is no link, we just filter out
|
||||
* config space accesses. That way, it will be easier to implement
|
||||
* hotplug later on.
|
||||
*/
|
||||
if (!port->has_ibpre ||
|
||||
!ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
|
||||
1 << 28, 1 << 28, 100)) {
|
||||
printk(KERN_INFO
|
||||
"PCIE%d: Device detected, waiting for link...\n",
|
||||
port->index);
|
||||
if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
|
||||
0x1000, 0x1000, 2000))
|
||||
printk(KERN_WARNING
|
||||
"PCIE%d: Link up failed\n", port->index);
|
||||
else {
|
||||
printk(KERN_INFO
|
||||
"PCIE%d: link is up !\n", port->index);
|
||||
port->link = 1;
|
||||
}
|
||||
} else
|
||||
printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
|
||||
}
|
||||
|
||||
/* Check various reset bits of the 440SPe PCIe core */
|
||||
static int __init ppc440spe_pciex_check_reset(struct device_node *np)
|
||||
{
|
||||
|
@ -806,7 +868,7 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
|
|||
dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
|
||||
(1 << 24) | (1 << 16), 1 << 12);
|
||||
|
||||
return 0;
|
||||
return ppc4xx_pciex_port_reset_sdr(port);
|
||||
}
|
||||
|
||||
static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
|
||||
|
@ -856,6 +918,7 @@ static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
|
|||
.core_init = ppc440spe_pciex_core_init,
|
||||
.port_init_hw = ppc440speA_pciex_init_port_hw,
|
||||
.setup_utl = ppc440speA_pciex_init_utl,
|
||||
.check_link = ppc4xx_pciex_check_link_sdr,
|
||||
};
|
||||
|
||||
static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
|
||||
|
@ -863,6 +926,7 @@ static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
|
|||
.core_init = ppc440spe_pciex_core_init,
|
||||
.port_init_hw = ppc440speB_pciex_init_port_hw,
|
||||
.setup_utl = ppc440speB_pciex_init_utl,
|
||||
.check_link = ppc4xx_pciex_check_link_sdr,
|
||||
};
|
||||
|
||||
static int __init ppc460ex_pciex_core_init(struct device_node *np)
|
||||
|
@ -944,7 +1008,7 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
|
|||
|
||||
port->has_ibpre = 1;
|
||||
|
||||
return 0;
|
||||
return ppc4xx_pciex_port_reset_sdr(port);
|
||||
}
|
||||
|
||||
static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
|
||||
|
@ -972,6 +1036,7 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata =
|
|||
.core_init = ppc460ex_pciex_core_init,
|
||||
.port_init_hw = ppc460ex_pciex_init_port_hw,
|
||||
.setup_utl = ppc460ex_pciex_init_utl,
|
||||
.check_link = ppc4xx_pciex_check_link_sdr,
|
||||
};
|
||||
|
||||
static int __init ppc460sx_pciex_core_init(struct device_node *np)
|
||||
|
@ -1075,7 +1140,7 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
|
|||
|
||||
port->has_ibpre = 1;
|
||||
|
||||
return 0;
|
||||
return ppc4xx_pciex_port_reset_sdr(port);
|
||||
}
|
||||
|
||||
static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
|
||||
|
@ -1089,6 +1154,7 @@ static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
|
|||
.core_init = ppc460sx_pciex_core_init,
|
||||
.port_init_hw = ppc460sx_pciex_init_port_hw,
|
||||
.setup_utl = ppc460sx_pciex_init_utl,
|
||||
.check_link = ppc4xx_pciex_check_link_sdr,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_44x */
|
||||
|
@ -1154,7 +1220,7 @@ static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
|
|||
|
||||
port->has_ibpre = 1;
|
||||
|
||||
return 0;
|
||||
return ppc4xx_pciex_port_reset_sdr(port);
|
||||
}
|
||||
|
||||
static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
|
||||
|
@ -1183,11 +1249,11 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
|
|||
.core_init = ppc405ex_pciex_core_init,
|
||||
.port_init_hw = ppc405ex_pciex_init_port_hw,
|
||||
.setup_utl = ppc405ex_pciex_init_utl,
|
||||
.check_link = ppc4xx_pciex_check_link_sdr,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_40x */
|
||||
|
||||
|
||||
/* Check that the core has been initied and if not, do it */
|
||||
static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
|
||||
{
|
||||
|
@ -1261,26 +1327,6 @@ static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port
|
|||
dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0);
|
||||
}
|
||||
|
||||
static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
|
||||
unsigned int sdr_offset,
|
||||
unsigned int mask,
|
||||
unsigned int value,
|
||||
int timeout_ms)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
while(timeout_ms--) {
|
||||
val = mfdcri(SDR0, port->sdr_base + sdr_offset);
|
||||
if ((val & mask) == value) {
|
||||
pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
|
||||
port->index, sdr_offset, timeout_ms, val);
|
||||
return 0;
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -1291,40 +1337,8 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
|
|||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
printk(KERN_INFO "PCIE%d: Checking link...\n",
|
||||
port->index);
|
||||
|
||||
/* Wait for reset to complete */
|
||||
if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
|
||||
printk(KERN_WARNING "PCIE%d: PGRST failed\n",
|
||||
port->index);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for card presence detect if supported, if not, just wait for
|
||||
* link unconditionally.
|
||||
*
|
||||
* note that we don't fail if there is no link, we just filter out
|
||||
* config space accesses. That way, it will be easier to implement
|
||||
* hotplug later on.
|
||||
*/
|
||||
if (!port->has_ibpre ||
|
||||
!ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
|
||||
1 << 28, 1 << 28, 100)) {
|
||||
printk(KERN_INFO
|
||||
"PCIE%d: Device detected, waiting for link...\n",
|
||||
port->index);
|
||||
if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
|
||||
0x1000, 0x1000, 2000))
|
||||
printk(KERN_WARNING
|
||||
"PCIE%d: Link up failed\n", port->index);
|
||||
else {
|
||||
printk(KERN_INFO
|
||||
"PCIE%d: link is up !\n", port->index);
|
||||
port->link = 1;
|
||||
}
|
||||
} else
|
||||
printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
|
||||
if (ppc4xx_pciex_hwops->check_link)
|
||||
ppc4xx_pciex_hwops->check_link(port);
|
||||
|
||||
/*
|
||||
* Initialize mapping: disable all regions and configure
|
||||
|
@ -1347,14 +1361,17 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
|
|||
/*
|
||||
* Check for VC0 active and assert RDY.
|
||||
*/
|
||||
if (port->link &&
|
||||
ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
|
||||
1 << 16, 1 << 16, 5000)) {
|
||||
printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
|
||||
port->link = 0;
|
||||
if (port->sdr_base) {
|
||||
if (port->link &&
|
||||
ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
|
||||
1 << 16, 1 << 16, 5000)) {
|
||||
printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
|
||||
port->link = 0;
|
||||
}
|
||||
|
||||
dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20);
|
||||
}
|
||||
|
||||
dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20);
|
||||
msleep(100);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue