[PATCH] Kirkwood: enable PCIe for kexec

Nicolas Pitre nico at fluxnic.net
Wed Feb 2 12:54:30 EST 2011


On Wed, 2 Feb 2011, Eric Cooper wrote:

> PCIe may have been disabled by kirkwood_clock_gate.
> Make sure PCIe is enabled before attempting to access
> the device ID register, otherwise the system will hang.
> 
> Add kexec_reinit hook so that kexec'ing older kernels will work.
> 
> Signed-off-by: Eric Cooper <ecc at cmu.edu>

I'd suggest splitting this into 3 patches, each with their own 
rationals:

1) The kexec machine hook facility, non Kirkwood specific.

2) The clock ungate for the ID reading upon boot.

3) Initializing the kexec hook with the Kirkwood specific part.

Also, kexec_reinit should probably be called early in machine_kexec() 
before the caches are flushed.

> ---
>  arch/arm/kernel/machine_kexec.c |    7 +++++++
>  arch/arm/mach-kirkwood/common.c |    4 ++++
>  arch/arm/mach-kirkwood/common.h |    1 +
>  arch/arm/mach-kirkwood/pcie.c   |    8 ++++++++
>  4 files changed, 20 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
> index 30ead13..7e870ea 100644
> --- a/arch/arm/kernel/machine_kexec.c
> +++ b/arch/arm/kernel/machine_kexec.c
> @@ -75,6 +75,11 @@ void machine_crash_shutdown(struct pt_regs *regs)
>  	printk(KERN_INFO "Loading crashdump kernel...\n");
>  }
>  
> +/*
> + * Function pointer to optional machine-specific reinitialization
> + */
> +void (*kexec_reinit)(void);
> +
>  void machine_kexec(struct kimage *image)
>  {
>  	unsigned long page_list;
> @@ -113,5 +118,7 @@ void machine_kexec(struct kimage *image)
>  	cpu_proc_fin();
>  	outer_inv_all();
>  	flush_cache_all();
> +	if (kexec_reinit)
> +		kexec_reinit();
>  	cpu_reset(reboot_code_buffer_phys);
>  }
> diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
> index 3688123..78eeb63 100644
> --- a/arch/arm/mach-kirkwood/common.c
> +++ b/arch/arm/mach-kirkwood/common.c
> @@ -974,6 +974,8 @@ static void __init kirkwood_l2_init(void)
>  
>  void __init kirkwood_init(void)
>  {
> +	extern void (*kexec_reinit)(void);
> +
>  	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
>  		kirkwood_id(), kirkwood_tclk);
>  	kirkwood_ge00_shared_data.t_clk = kirkwood_tclk;
> @@ -1003,6 +1005,8 @@ void __init kirkwood_init(void)
>  	kirkwood_xor0_init();
>  	kirkwood_xor1_init();
>  	kirkwood_crypto_init();
> +
> +	kexec_reinit = kirkwood_enable_pcie;
>  }
>  
>  static int __init kirkwood_clock_gate(void)
> diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
> index 95bb0a7..a35b862 100644
> --- a/arch/arm/mach-kirkwood/common.h
> +++ b/arch/arm/mach-kirkwood/common.h
> @@ -32,6 +32,7 @@ void kirkwood_init_irq(void);
>  extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
>  void kirkwood_setup_cpu_mbus(void);
>  
> +void kirkwood_enable_pcie(void);
>  void kirkwood_pcie_id(u32 *dev, u32 *rev);
>  
>  void kirkwood_ehci_init(void);
> diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
> index 513ad31..ca294ff 100644
> --- a/arch/arm/mach-kirkwood/pcie.c
> +++ b/arch/arm/mach-kirkwood/pcie.c
> @@ -18,8 +18,16 @@
>  #include <mach/bridge-regs.h>
>  #include "common.h"
>  
> +void kirkwood_enable_pcie(void)
> +{
> +	u32 curr = readl(CLOCK_GATING_CTRL);
> +	if (!(curr & CGC_PEX0))
> +		writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
> +}
> +
>  void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
>  {
> +	kirkwood_enable_pcie();
>  	*dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
>  	*rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
>  }
> -- 
> 1.7.2.3
> 



More information about the linux-arm-kernel mailing list