diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pasemi/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/cpufreq.c | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/gpio_mdio.c | 94 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/pasemi.h | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/powersave.S | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/setup.c | 16 |
6 files changed, 105 insertions, 43 deletions
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig index 735e1536cbf..2f4dd6e4aac 100644 --- a/arch/powerpc/platforms/pasemi/Kconfig +++ b/arch/powerpc/platforms/pasemi/Kconfig @@ -17,7 +17,7 @@ config PPC_PASEMI_IOMMU bool "PA Semi IOMMU support" depends on PPC_PASEMI help - IOMMU support for PA6T-1682M + IOMMU support for PA Semi PWRficient config PPC_PASEMI_IOMMU_DMA_FORCE bool "Force DMA engine to use IOMMU" diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index 1cfb8b0c8fe..58556b028a4 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c @@ -32,6 +32,7 @@ #include <asm/io.h> #include <asm/prom.h> #include <asm/time.h> +#include <asm/smp.h> #define SDCASR_REG 0x0100 #define SDCASR_REG_STRIDE 0x1000 @@ -124,6 +125,11 @@ static void set_astate(int cpu, unsigned int astate) local_irq_restore(flags); } +int check_astate(void) +{ + return get_cur_astate(hard_smp_processor_id()); +} + void restore_astate(int cpu) { set_astate(cpu, current_astate); @@ -147,7 +153,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) if (!cpu) goto out; - dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc"); + dn = of_find_compatible_node(NULL, NULL, "1682m-sdc"); + if (!dn) + dn = of_find_compatible_node(NULL, NULL, + "pasemi,pwrficient-sdc"); if (!dn) goto out; err = of_address_to_resource(dn, 0, &res); @@ -160,7 +169,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) goto out; } - dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo"); + dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo"); + if (!dn) + dn = of_find_compatible_node(NULL, NULL, + "pasemi,pwrficient-gizmo"); if (!dn) { err = -ENODEV; goto out_unmap_sdcasr; @@ -292,7 +304,8 @@ static struct cpufreq_driver pas_cpufreq_driver = { static int __init pas_cpufreq_init(void) { - if (!machine_is_compatible("PA6T-1682M")) + if (!machine_is_compatible("PA6T-1682M") && + !machine_is_compatible("pasemi,pwrficient")) return -ENODEV; return cpufreq_register_driver(&pas_cpufreq_driver); diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index dae9f658122..04a8686e608 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -218,45 +218,27 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; - struct device_node *gpio_np; + struct device_node *phy_dn, *np = ofdev->node; struct mii_bus *new_bus; - struct resource res; struct gpio_priv *priv; const unsigned int *prop; - int err = 0; + int err; int i; - gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio"); - - if (!gpio_np) - return -ENODEV; - - err = of_address_to_resource(gpio_np, 0, &res); - of_node_put(gpio_np); - - if (err) - return -EINVAL; - - if (!gpio_regs) - gpio_regs = ioremap(res.start, 0x100); - - if (!gpio_regs) - return -EPERM; - + err = -ENOMEM; priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; + if (!priv) + goto out; new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - if (new_bus == NULL) - return -ENOMEM; + if (!new_bus) + goto out_free_priv; - new_bus->name = "pasemi gpio mdio bus", - new_bus->read = &gpio_mdio_read, - new_bus->write = &gpio_mdio_write, - new_bus->reset = &gpio_mdio_reset, + new_bus->name = "pasemi gpio mdio bus"; + new_bus->read = &gpio_mdio_read; + new_bus->write = &gpio_mdio_write; + new_bus->reset = &gpio_mdio_reset; prop = of_get_property(np, "reg", NULL); new_bus->id = *prop; @@ -265,9 +247,24 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, new_bus->phy_mask = 0; new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); - for(i = 0; i < PHY_MAX_ADDR; ++i) - new_bus->irq[i] = irq_create_mapping(NULL, 10); + if (!new_bus->irq) + goto out_free_bus; + + for (i = 0; i < PHY_MAX_ADDR; i++) + new_bus->irq[i] = NO_IRQ; + + for (phy_dn = of_get_next_child(np, NULL); + phy_dn != NULL; + phy_dn = of_get_next_child(np, phy_dn)) { + const unsigned int *ip, *regp; + + ip = of_get_property(phy_dn, "interrupts", NULL); + regp = of_get_property(phy_dn, "reg", NULL); + if (!ip || !regp || *regp >= PHY_MAX_ADDR) + continue; + new_bus->irq[*regp] = irq_create_mapping(NULL, *ip); + } prop = of_get_property(np, "mdc-pin", NULL); priv->mdc_pin = *prop; @@ -280,17 +277,21 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, err = mdiobus_register(new_bus); - if (0 != err) { + if (err != 0) { printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", new_bus->name, err); - goto bus_register_fail; + goto out_free_irq; } return 0; -bus_register_fail: +out_free_irq: + kfree(new_bus->irq); +out_free_bus: kfree(new_bus); - +out_free_priv: + kfree(priv); +out: return err; } @@ -317,6 +318,7 @@ static struct of_device_id gpio_mdio_match[] = }, {}, }; +MODULE_DEVICE_TABLE(of, gpio_mdio_match); static struct of_platform_driver gpio_mdio_driver = { @@ -330,12 +332,32 @@ static struct of_platform_driver gpio_mdio_driver = int gpio_mdio_init(void) { + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "1682m-gpio"); + if (!np) + np = of_find_compatible_node(NULL, NULL, + "pasemi,pwrficient-gpio"); + if (!np) + return -ENODEV; + gpio_regs = of_iomap(np, 0); + of_node_put(np); + + if (!gpio_regs) + return -ENODEV; + return of_register_platform_driver(&gpio_mdio_driver); } +module_init(gpio_mdio_init); void gpio_mdio_exit(void) { of_unregister_platform_driver(&gpio_mdio_driver); + if (gpio_regs) + iounmap(gpio_regs); } -device_initcall(gpio_mdio_init); +module_exit(gpio_mdio_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Olof Johansson <olof@lixom.net>"); +MODULE_DESCRIPTION("Driver for MDIO over GPIO on PA Semi PWRficient-based boards"); diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index 516acabb4e9..c96127b029b 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -16,8 +16,14 @@ extern void idle_doze(void); /* Restore astate to last set */ #ifdef CONFIG_PPC_PASEMI_CPUFREQ +extern int check_astate(void); extern void restore_astate(int cpu); #else +static inline int check_astate(void) +{ + /* Always return >0 so we never power save */ + return 1; +} static inline void restore_astate(int cpu) { } diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S index 6d0fba6aab1..56f45adcd08 100644 --- a/arch/powerpc/platforms/pasemi/powersave.S +++ b/arch/powerpc/platforms/pasemi/powersave.S @@ -62,7 +62,16 @@ sleep_common: mflr r0 std r0, 16(r1) stdu r1,-64(r1) +#ifdef CONFIG_PPC_PASEMI_CPUFREQ + std r3, 48(r1) + /* Only do power savings when in astate 0 */ + bl .check_astate + cmpwi r3,0 + bne 1f + + ld r3, 48(r1) +#endif LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) mfmsr r4 andc r5,r4,r6 @@ -73,7 +82,7 @@ sleep_common: mtmsrd r4,0 - addi r1,r1,64 +1: addi r1,r1,64 ld r0,16(r1) mtlr r0 blr diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 3d62060498b..2b638659d1e 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -43,6 +43,10 @@ #include "pasemi.h" +#if !defined(CONFIG_SMP) +static void smp_send_stop(void) {} +#endif + /* SDC reset register, must be pre-mapped at reset time */ static void __iomem *reset_reg; @@ -60,6 +64,9 @@ static int num_mce_regs; static void pas_restart(char *cmd) { + /* Need to put others cpu in hold loop so they're not sleeping */ + smp_send_stop(); + udelay(10000); printk("Restarting...\n"); while (1) out_le32(reset_reg, 0x6000000); @@ -362,8 +369,12 @@ static inline void pasemi_pcmcia_init(void) static struct of_device_id pasemi_bus_ids[] = { + /* Unfortunately needed for legacy firmwares */ { .type = "localbus", }, { .type = "sdc", }, + /* These are the proper entries, which newer firmware uses */ + { .compatible = "pasemi,localbus", }, + { .compatible = "pasemi,sdc", }, {}, }; @@ -389,7 +400,8 @@ static int __init pas_probe(void) { unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "PA6T-1682M")) + if (!of_flat_dt_is_compatible(root, "PA6T-1682M") && + !of_flat_dt_is_compatible(root, "pasemi,pwrficient")) return 0; hpte_init_native(); @@ -400,7 +412,7 @@ static int __init pas_probe(void) } define_machine(pasemi) { - .name = "PA Semi PA6T-1682M", + .name = "PA Semi PWRficient", .probe = pas_probe, .setup_arch = pas_setup_arch, .init_early = pas_init_early, |