Path: blob/master/arch/powerpc/platforms/44x/iss4xx.c
10820 views
/*1* PPC476 board specific routines2*3* Copyright 2010 Torez Smith, IBM Corporation.4*5* Based on earlier code:6* Matt Porter <[email protected]>7* Copyright 2002-2005 MontaVista Software Inc.8*9* Eugene Surovegin <[email protected]> or <[email protected]>10* Copyright (c) 2003-2005 Zultys Technologies11*12* Rewritten and ported to the merged powerpc tree:13* Copyright 2007 David Gibson <[email protected]>, IBM Corporation.14*15* This program is free software; you can redistribute it and/or modify it16* under the terms of the GNU General Public License as published by the17* Free Software Foundation; either version 2 of the License, or (at your18* option) any later version.19*/2021#include <linux/init.h>22#include <linux/of_platform.h>23#include <linux/rtc.h>2425#include <asm/machdep.h>26#include <asm/prom.h>27#include <asm/udbg.h>28#include <asm/time.h>29#include <asm/uic.h>30#include <asm/ppc4xx.h>31#include <asm/mpic.h>32#include <asm/mmu.h>3334static __initdata struct of_device_id iss4xx_of_bus[] = {35{ .compatible = "ibm,plb4", },36{ .compatible = "ibm,plb6", },37{ .compatible = "ibm,opb", },38{ .compatible = "ibm,ebc", },39{},40};4142static int __init iss4xx_device_probe(void)43{44of_platform_bus_probe(NULL, iss4xx_of_bus, NULL);45of_instantiate_rtc();4647return 0;48}49machine_device_initcall(iss4xx, iss4xx_device_probe);5051/* We can have either UICs or MPICs */52static void __init iss4xx_init_irq(void)53{54struct device_node *np;5556/* Find top level interrupt controller */57for_each_node_with_property(np, "interrupt-controller") {58if (of_get_property(np, "interrupts", NULL) == NULL)59break;60}61if (np == NULL)62panic("Can't find top level interrupt controller");6364/* Check type and do appropriate initialization */65if (of_device_is_compatible(np, "ibm,uic")) {66uic_init_tree();67ppc_md.get_irq = uic_get_irq;68#ifdef CONFIG_MPIC69} else if (of_device_is_compatible(np, "chrp,open-pic")) {70/* The MPIC driver will get everything it needs from the71* device-tree, just pass 0 to all arguments72*/73struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0,74" MPIC ");75BUG_ON(mpic == NULL);76mpic_init(mpic);77ppc_md.get_irq = mpic_get_irq;78#endif79} else80panic("Unrecognized top level interrupt controller");81}8283#ifdef CONFIG_SMP84static void __cpuinit smp_iss4xx_setup_cpu(int cpu)85{86mpic_setup_this_cpu();87}8889static int __cpuinit smp_iss4xx_kick_cpu(int cpu)90{91struct device_node *cpunode = of_get_cpu_node(cpu, NULL);92const u64 *spin_table_addr_prop;93u32 *spin_table;94extern void start_secondary_47x(void);9596BUG_ON(cpunode == NULL);9798/* Assume spin table. We could test for the enable-method in99* the device-tree but currently there's little point as it's100* our only supported method101*/102spin_table_addr_prop = of_get_property(cpunode, "cpu-release-addr",103NULL);104if (spin_table_addr_prop == NULL) {105pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu);106return -ENOENT;107}108109/* Assume it's mapped as part of the linear mapping. This is a bit110* fishy but will work fine for now111*/112spin_table = (u32 *)__va(*spin_table_addr_prop);113pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);114115spin_table[3] = cpu;116smp_wmb();117spin_table[1] = __pa(start_secondary_47x);118mb();119120return 0;121}122123static struct smp_ops_t iss_smp_ops = {124.probe = smp_mpic_probe,125.message_pass = smp_mpic_message_pass,126.setup_cpu = smp_iss4xx_setup_cpu,127.kick_cpu = smp_iss4xx_kick_cpu,128.give_timebase = smp_generic_give_timebase,129.take_timebase = smp_generic_take_timebase,130};131132static void __init iss4xx_smp_init(void)133{134if (mmu_has_feature(MMU_FTR_TYPE_47x))135smp_ops = &iss_smp_ops;136}137138#else /* CONFIG_SMP */139static void __init iss4xx_smp_init(void) { }140#endif /* CONFIG_SMP */141142static void __init iss4xx_setup_arch(void)143{144iss4xx_smp_init();145}146147/*148* Called very early, MMU is off, device-tree isn't unflattened149*/150static int __init iss4xx_probe(void)151{152unsigned long root = of_get_flat_dt_root();153154if (!of_flat_dt_is_compatible(root, "ibm,iss-4xx"))155return 0;156157return 1;158}159160define_machine(iss4xx) {161.name = "ISS-4xx",162.probe = iss4xx_probe,163.progress = udbg_progress,164.init_IRQ = iss4xx_init_irq,165.setup_arch = iss4xx_setup_arch,166.restart = ppc4xx_reset_system,167.calibrate_decr = generic_calibrate_decr,168};169170171