diff options
Diffstat (limited to 'arch/powerpc/platforms/83xx')
21 files changed, 1008 insertions, 531 deletions
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 6159c5d4e5f..2bdc8c862c4 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -1,6 +1,6 @@ menuconfig PPC_83xx bool "83xx-based boards" - depends on 6xx && PPC_MULTIPLATFORM + depends on 6xx select PPC_UDBG_16550 select PPC_PCI_CHOICE select FSL_PCI if PCI @@ -9,6 +9,14 @@ menuconfig PPC_83xx if PPC_83xx +config MPC830x_RDB + bool "Freescale MPC830x RDB and derivatives" + select DEFAULT_UIMAGE + select PPC_MPC831x + select FSL_GTM + help + This option enables support for the MPC8308 RDB and MPC8308 P1M boards. + config MPC831x_RDB bool "Freescale MPC831x RDB" select DEFAULT_UIMAGE @@ -19,7 +27,6 @@ config MPC831x_RDB config MPC832x_MDS bool "Freescale MPC832x MDS" select DEFAULT_UIMAGE - select QUICC_ENGINE select PPC_MPC832x help This option enables support for the MPC832x MDS evaluation board. @@ -27,7 +34,6 @@ config MPC832x_MDS config MPC832x_RDB bool "Freescale MPC832x RDB" select DEFAULT_UIMAGE - select QUICC_ENGINE select PPC_MPC832x help This option enables support for the MPC8323 RDB board. @@ -57,15 +63,12 @@ config MPC834x_ITX config MPC836x_MDS bool "Freescale MPC836x MDS" select DEFAULT_UIMAGE - select QUICC_ENGINE help This option enables support for the MPC836x MDS Processor Board. config MPC836x_RDK bool "Freescale/Logic MPC836x RDK" select DEFAULT_UIMAGE - select QUICC_ENGINE - select QE_GPIO select FSL_GTM select FSL_LBC help @@ -80,11 +83,11 @@ config MPC837x_MDS This option enables support for the MPC837x MDS Processor Board. config MPC837x_RDB - bool "Freescale MPC837x RDB" + bool "Freescale MPC837x RDB/WLAN" select DEFAULT_UIMAGE select PPC_MPC837x help - This option enables support for the MPC837x RDB Board. + This option enables support for the MPC837x RDB and WLAN Boards. config SBC834x bool "Wind River SBC834x" @@ -96,26 +99,35 @@ config SBC834x config ASP834x bool "Analogue & Micro ASP 834x" select PPC_MPC834x - select REDBOOT help This enables support for the Analogue & Micro ASP 83xx board. +config KMETER1 + bool "Keymile KMETER1" + select DEFAULT_UIMAGE + select QUICC_ENGINE + help + This enables support for the Keymile KMETER1 board. + endif -# used for usb +# used for usb & gpio config PPC_MPC831x bool + select ARCH_WANT_OPTIONAL_GPIOLIB # used for math-emu config PPC_MPC832x bool -# used for usb +# used for usb & gpio config PPC_MPC834x bool + select ARCH_WANT_OPTIONAL_GPIOLIB -# used for usb +# used for usb & gpio config PPC_MPC837x bool + select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index ba5028e2989..ed95bfcbcbf 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -3,6 +3,8 @@ # obj-y := misc.o usb.o obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o +obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o +obj-$(CONFIG_MPC830x_RDB) += mpc830x_rdb.o obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o @@ -14,3 +16,4 @@ obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o obj-$(CONFIG_SBC834x) += sbc834x.o obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o obj-$(CONFIG_ASP834x) += asp834x.o +obj-$(CONFIG_KMETER1) += km83xx.o diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index bb30d67ad0a..464ea8e0292 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c @@ -36,37 +36,7 @@ static void __init asp834x_setup_arch(void) mpc834x_usb_cfg(); } -static void __init asp834x_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - of_node_put(np); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} - -static struct __initdata of_device_id asp8347_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - {}, -}; - -static int __init asp8347_declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, asp8347_ids, NULL); - return 0; -} -machine_device_initcall(asp834x, asp8347_declare_of_platform_devices); +machine_device_initcall(asp834x, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -81,7 +51,7 @@ define_machine(asp834x) { .name = "ASP8347E", .probe = asp834x_probe, .setup_arch = asp834x_setup_arch, - .init_IRQ = asp834x_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c new file mode 100644 index 00000000000..bf4c4473abb --- /dev/null +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -0,0 +1,197 @@ +/* + * Copyright 2008-2011 DENX Software Engineering GmbH + * Author: Heiko Schocher <hs@denx.de> + * + * Description: + * Keymile 83xx platform specific routines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/root_dev.h> +#include <linux/initrd.h> +#include <linux/of_platform.h> +#include <linux/of_device.h> + +#include <linux/atomic.h> +#include <linux/time.h> +#include <linux/io.h> +#include <asm/machdep.h> +#include <asm/ipic.h> +#include <asm/irq.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <sysdev/fsl_soc.h> +#include <sysdev/fsl_pci.h> +#include <asm/qe.h> +#include <asm/qe_ic.h> + +#include "mpc83xx.h" + +#define SVR_REV(svr) (((svr) >> 0) & 0xFFFF) /* Revision field */ + +static void quirk_mpc8360e_qe_enet10(void) +{ + /* + * handle mpc8360E Erratum QE_ENET10: + * RGMII AC values do not meet the specification + */ + uint svid = mfspr(SPRN_SVR); + struct device_node *np_par; + struct resource res; + void __iomem *base; + int ret; + + np_par = of_find_node_by_name(NULL, "par_io"); + if (np_par == NULL) { + pr_warn("%s couldn;t find par_io node\n", __func__); + return; + } + /* Map Parallel I/O ports registers */ + ret = of_address_to_resource(np_par, 0, &res); + if (ret) { + pr_warn("%s couldn;t map par_io registers\n", __func__); + return; + } + + base = ioremap(res.start, res.end - res.start + 1); + + /* + * set output delay adjustments to default values according + * table 5 in Errata Rev. 5, 9/2011: + * + * write 0b01 to UCC1 bits 18:19 + * write 0b01 to UCC2 option 1 bits 4:5 + * write 0b01 to UCC2 option 2 bits 16:17 + */ + clrsetbits_be32((base + 0xa8), 0x0c00f000, 0x04005000); + + /* + * set output delay adjustments to default values according + * table 3-13 in Reference Manual Rev.3 05/2010: + * + * write 0b01 to UCC2 option 2 bits 16:17 + * write 0b0101 to UCC1 bits 20:23 + * write 0b0101 to UCC2 option 1 bits 24:27 + */ + clrsetbits_be32((base + 0xac), 0x0000cff0, 0x00004550); + + if (SVR_REV(svid) == 0x0021) { + /* + * UCC2 option 1: write 0b1010 to bits 24:27 + * at address IMMRBAR+0x14AC + */ + clrsetbits_be32((base + 0xac), 0x000000f0, 0x000000a0); + } else if (SVR_REV(svid) == 0x0020) { + /* + * UCC1: write 0b11 to bits 18:19 + * at address IMMRBAR+0x14A8 + */ + setbits32((base + 0xa8), 0x00003000); + + /* + * UCC2 option 1: write 0b11 to bits 4:5 + * at address IMMRBAR+0x14A8 + */ + setbits32((base + 0xa8), 0x0c000000); + + /* + * UCC2 option 2: write 0b11 to bits 16:17 + * at address IMMRBAR+0x14AC + */ + setbits32((base + 0xac), 0x0000c000); + } + iounmap(base); + of_node_put(np_par); +} + +/* ************************************************************************ + * + * Setup the architecture + * + */ +static void __init mpc83xx_km_setup_arch(void) +{ +#ifdef CONFIG_QUICC_ENGINE + struct device_node *np; +#endif + + if (ppc_md.progress) + ppc_md.progress("kmpbec83xx_setup_arch()", 0); + + mpc83xx_setup_pci(); + +#ifdef CONFIG_QUICC_ENGINE + qe_reset(); + + np = of_find_node_by_name(NULL, "par_io"); + if (np != NULL) { + par_io_init(np); + of_node_put(np); + + for_each_node_by_name(np, "spi") + par_io_of_config(np); + + for_each_node_by_name(np, "ucc") + par_io_of_config(np); + + /* Only apply this quirk when par_io is available */ + np = of_find_compatible_node(NULL, "network", "ucc_geth"); + if (np != NULL) { + quirk_mpc8360e_qe_enet10(); + of_node_put(np); + } + } +#endif /* CONFIG_QUICC_ENGINE */ +} + +machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); + +/* list of the supported boards */ +static char *board[] __initdata = { + "Keymile,KMETER1", + "Keymile,kmpbec8321", + NULL +}; + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init mpc83xx_km_probe(void) +{ + unsigned long node = of_get_flat_dt_root(); + int i = 0; + + while (board[i]) { + if (of_flat_dt_is_compatible(node, board[i])) + break; + i++; + } + return (board[i] != NULL); +} + +define_machine(mpc83xx_km) { + .name = "mpc83xx-km-platform", + .probe = mpc83xx_km_probe, + .setup_arch = mpc83xx_km_setup_arch, + .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, + .get_irq = ipic_get_irq, + .restart = mpc83xx_restart, + .time_init = mpc83xx_time_init, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c new file mode 100644 index 00000000000..e238b6a55b1 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -0,0 +1,237 @@ +/* + * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU + * + * Copyright (c) 2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/slab.h> +#include <linux/kthread.h> +#include <linux/reboot.h> +#include <asm/prom.h> +#include <asm/machdep.h> + +/* + * I don't have specifications for the MCU firmware, I found this register + * and bits positions by the trial&error method. + */ +#define MCU_REG_CTRL 0x20 +#define MCU_CTRL_POFF 0x40 +#define MCU_CTRL_BTN 0x80 + +#define MCU_NUM_GPIO 2 + +struct mcu { + struct mutex lock; + struct i2c_client *client; + struct gpio_chip gc; + u8 reg_ctrl; +}; + +static struct mcu *glob_mcu; + +struct task_struct *shutdown_thread; +static int shutdown_thread_fn(void *data) +{ + int ret; + struct mcu *mcu = glob_mcu; + + while (!kthread_should_stop()) { + ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); + if (ret < 0) + pr_err("MCU status reg read failed.\n"); + mcu->reg_ctrl = ret; + + + if (mcu->reg_ctrl & MCU_CTRL_BTN) { + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl & ~MCU_CTRL_BTN); + + ctrl_alt_del(); + } + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } + + return 0; +} + +static ssize_t show_status(struct device *d, + struct device_attribute *attr, char *buf) +{ + int ret; + struct mcu *mcu = glob_mcu; + + ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); + if (ret < 0) + return -ENODEV; + mcu->reg_ctrl = ret; + + return sprintf(buf, "%02x\n", ret); +} +static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); + +static void mcu_power_off(void) +{ + struct mcu *mcu = glob_mcu; + + pr_info("Sending power-off request to the MCU...\n"); + mutex_lock(&mcu->lock); + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl | MCU_CTRL_POFF); + mutex_unlock(&mcu->lock); +} + +static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct mcu *mcu = container_of(gc, struct mcu, gc); + u8 bit = 1 << (4 + gpio); + + mutex_lock(&mcu->lock); + if (val) + mcu->reg_ctrl &= ~bit; + else + mcu->reg_ctrl |= bit; + + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); + mutex_unlock(&mcu->lock); +} + +static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + mcu_gpio_set(gc, gpio, val); + return 0; +} + +static int mcu_gpiochip_add(struct mcu *mcu) +{ + struct device_node *np; + struct gpio_chip *gc = &mcu->gc; + + np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); + if (!np) + return -ENODEV; + + gc->owner = THIS_MODULE; + gc->label = np->full_name; + gc->can_sleep = 1; + gc->ngpio = MCU_NUM_GPIO; + gc->base = -1; + gc->set = mcu_gpio_set; + gc->direction_output = mcu_gpio_dir_out; + gc->of_node = np; + + return gpiochip_add(gc); +} + +static int mcu_gpiochip_remove(struct mcu *mcu) +{ + return gpiochip_remove(&mcu->gc); +} + +static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct mcu *mcu; + int ret; + + mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); + if (!mcu) + return -ENOMEM; + + mutex_init(&mcu->lock); + mcu->client = client; + i2c_set_clientdata(client, mcu); + + ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); + if (ret < 0) + goto err; + mcu->reg_ctrl = ret; + + ret = mcu_gpiochip_add(mcu); + if (ret) + goto err; + + /* XXX: this is potentially racy, but there is no lock for ppc_md */ + if (!ppc_md.power_off) { + glob_mcu = mcu; + ppc_md.power_off = mcu_power_off; + dev_info(&client->dev, "will provide power-off service\n"); + } + + if (device_create_file(&client->dev, &dev_attr_status)) + dev_err(&client->dev, + "couldn't create device file for status\n"); + + shutdown_thread = kthread_run(shutdown_thread_fn, NULL, + "mcu-i2c-shdn"); + + return 0; +err: + kfree(mcu); + return ret; +} + +static int mcu_remove(struct i2c_client *client) +{ + struct mcu *mcu = i2c_get_clientdata(client); + int ret; + + kthread_stop(shutdown_thread); + + device_remove_file(&client->dev, &dev_attr_status); + + if (glob_mcu == mcu) { + ppc_md.power_off = NULL; + glob_mcu = NULL; + } + + ret = mcu_gpiochip_remove(mcu); + if (ret) + return ret; + kfree(mcu); + return 0; +} + +static const struct i2c_device_id mcu_ids[] = { + { "mcu-mpc8349emitx", }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, mcu_ids); + +static struct of_device_id mcu_of_match_table[] = { + { .compatible = "fsl,mcu-mpc8349emitx", }, + { }, +}; + +static struct i2c_driver mcu_driver = { + .driver = { + .name = "mcu-mpc8349emitx", + .owner = THIS_MODULE, + .of_match_table = mcu_of_match_table, + }, + .probe = mcu_probe, + .remove = mcu_remove, + .id_table = mcu_ids, +}; + +module_i2c_driver(mcu_driver); + +MODULE_DESCRIPTION("Power Management and GPIO expander driver for " + "MPC8349E-mITX-compatible MCU"); +MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index f01806c940e..125336f750c 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -11,10 +11,15 @@ #include <linux/stddef.h> #include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/pci.h> #include <asm/io.h> #include <asm/hw_irq.h> +#include <asm/ipic.h> +#include <asm/qe_ic.h> #include <sysdev/fsl_soc.h> +#include <sysdev/fsl_pci.h> #include "mpc83xx.h" @@ -65,3 +70,75 @@ long __init mpc83xx_time_init(void) return 0; } + +void __init mpc83xx_ipic_init_IRQ(void) +{ + struct device_node *np; + + /* looking for fsl,pq2pro-pic which is asl compatible with fsl,ipic */ + np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); + if (!np) + np = of_find_node_by_type(NULL, "ipic"); + if (!np) + return; + + ipic_init(np, 0); + + of_node_put(np); + + /* Initialize the default interrupt mapping priorities, + * in case the boot rom changed something on us. + */ + ipic_set_default_priority(); +} + +#ifdef CONFIG_QUICC_ENGINE +void __init mpc83xx_qe_init_IRQ(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); + if (!np) { + np = of_find_node_by_type(NULL, "qeic"); + if (!np) + return; + } + qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); + of_node_put(np); +} + +void __init mpc83xx_ipic_and_qe_init_IRQ(void) +{ + mpc83xx_ipic_init_IRQ(); + mpc83xx_qe_init_IRQ(); +} +#endif /* CONFIG_QUICC_ENGINE */ + +static struct of_device_id __initdata of_bus_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .compatible = "simple-bus" }, + { .compatible = "gianfar" }, + { .compatible = "gpio-leds", }, + { .type = "qe", }, + { .compatible = "fsl,qe", }, + {}, +}; + +int __init mpc83xx_declare_of_platform_devices(void) +{ + of_platform_bus_probe(NULL, of_bus_ids, NULL); + return 0; +} + +#ifdef CONFIG_PCI +void __init mpc83xx_setup_pci(void) +{ + struct device_node *np; + + for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") + mpc83xx_add_bridge(np); + for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") + mpc83xx_add_bridge(np); +} +#endif diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c new file mode 100644 index 00000000000..4f2d9fea77b --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c @@ -0,0 +1,64 @@ +/* + * arch/powerpc/platforms/83xx/mpc830x_rdb.c + * + * Description: MPC830x RDB board specific routines. + * This file is based on mpc831x_rdb.c + * + * Copyright (C) Freescale Semiconductor, Inc. 2009. All rights reserved. + * Copyright (C) 2010. Ilya Yanok, Emcraft Systems, yanok@emcraft.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/pci.h> +#include <linux/of_platform.h> +#include <asm/time.h> +#include <asm/ipic.h> +#include <asm/udbg.h> +#include <sysdev/fsl_pci.h> +#include <sysdev/fsl_soc.h> +#include "mpc83xx.h" + +/* + * Setup the architecture + */ +static void __init mpc830x_rdb_setup_arch(void) +{ + if (ppc_md.progress) + ppc_md.progress("mpc830x_rdb_setup_arch()", 0); + + mpc83xx_setup_pci(); + mpc831x_usb_cfg(); +} + +static const char *board[] __initdata = { + "MPC8308RDB", + "fsl,mpc8308rdb", + "denx,mpc8308_p1m", + NULL +}; + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init mpc830x_rdb_probe(void) +{ + return of_flat_dt_match(of_get_flat_dt_root(), board); +} + +machine_device_initcall(mpc830x_rdb, mpc83xx_declare_of_platform_devices); + +define_machine(mpc830x_rdb) { + .name = "MPC830x RDB", + .probe = mpc830x_rdb_probe, + .setup_arch = mpc830x_rdb_setup_arch, + .init_IRQ = mpc83xx_ipic_init_IRQ, + .get_irq = ipic_get_irq, + .restart = mpc83xx_restart, + .time_init = mpc83xx_time_init, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index a428f8d1ac8..fa25977c52d 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -28,64 +28,34 @@ */ static void __init mpc831x_rdb_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc831x_rdb_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); mpc831x_usb_cfg(); } -void __init mpc831x_rdb_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} +static const char *board[] __initdata = { + "MPC8313ERDB", + "fsl,mpc8315erdb", + NULL +}; /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init mpc831x_rdb_probe(void) { - unsigned long root = of_get_flat_dt_root(); - - return of_flat_dt_is_compatible(root, "MPC8313ERDB") || - of_flat_dt_is_compatible(root, "fsl,mpc8315erdb"); + return of_flat_dt_match(of_get_flat_dt_root(), board); } -static struct of_device_id __initdata of_bus_ids[] = { - { .compatible = "simple-bus" }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, of_bus_ids, NULL); - return 0; -} -machine_device_initcall(mpc831x_rdb, declare_of_platform_devices); +machine_device_initcall(mpc831x_rdb, mpc83xx_declare_of_platform_devices); define_machine(mpc831x_rdb) { .name = "MPC831x RDB", .probe = mpc831x_rdb_probe, .setup_arch = mpc831x_rdb_setup_arch, - .init_IRQ = mpc831x_rdb_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index ec43477caa6..8d762203eef 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. + * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved. * * Description: * MPC832xE MDS board specific routines. @@ -26,8 +26,7 @@ #include <linux/of_platform.h> #include <linux/of_device.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -49,8 +48,6 @@ #define DBG(fmt...) #endif -static u8 *bcsr_regs = NULL; - /* ************************************************************************ * * Setup the architecture @@ -59,24 +56,22 @@ static u8 *bcsr_regs = NULL; static void __init mpc832x_sys_setup_arch(void) { struct device_node *np; + u8 __iomem *bcsr_regs = NULL; if (ppc_md.progress) ppc_md.progress("mpc832x_sys_setup_arch()", 0); /* Map BCSR area */ np = of_find_node_by_name(NULL, "bcsr"); - if (np != 0) { + if (np) { struct resource res; of_address_to_resource(np, 0, &res); - bcsr_regs = ioremap(res.start, res.end - res.start +1); + bcsr_regs = ioremap(res.start, resource_size(&res)); of_node_put(np); } -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE qe_reset(); @@ -93,60 +88,16 @@ static void __init mpc832x_sys_setup_arch(void) != NULL){ /* Reset the Ethernet PHYs */ #define BCSR8_FETH_RST 0x50 - bcsr_regs[8] &= ~BCSR8_FETH_RST; + clrbits8(&bcsr_regs[8], BCSR8_FETH_RST); udelay(1000); - bcsr_regs[8] |= BCSR8_FETH_RST; + setbits8(&bcsr_regs[8], BCSR8_FETH_RST); iounmap(bcsr_regs); of_node_put(np); } #endif /* CONFIG_QUICC_ENGINE */ } -static struct of_device_id mpc832x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - { .type = "qe", }, - { .compatible = "fsl,qe", }, - {}, -}; - -static int __init mpc832x_declare_of_platform_devices(void) -{ - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc832x_ids, NULL); - - return 0; -} -machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices); - -static void __init mpc832x_sys_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); - of_node_put(np); - -#ifdef CONFIG_QUICC_ENGINE - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (!np) { - np = of_find_node_by_type(NULL, "qeic"); - if (!np) - return; - } - qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); - of_node_put(np); -#endif /* CONFIG_QUICC_ENGINE */ -} +machine_device_initcall(mpc832x_mds, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -162,7 +113,7 @@ define_machine(mpc832x_mds) { .name = "MPC832x MDS", .probe = mpc832x_sys_probe, .setup_arch = mpc832x_sys_setup_arch, - .init_IRQ = mpc832x_sys_init_IRQ, + .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 0300268ce5b..eff5baabc3f 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -20,6 +20,7 @@ #include <linux/spi/mmc_spi.h> #include <linux/mmc/host.h> #include <linux/of_platform.h> +#include <linux/fsl_devices.h> #include <asm/time.h> #include <asm/ipic.h> @@ -38,16 +39,117 @@ #define DBG(fmt...) #endif -static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) +#ifdef CONFIG_QUICC_ENGINE +static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, + struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*cs_control)(struct spi_device *dev, + bool on)) +{ + struct device_node *np; + unsigned int i = 0; + + for_each_compatible_node(np, type, compatible) { + int ret; + unsigned int j; + const void *prop; + struct resource res[2]; + struct platform_device *pdev; + struct fsl_spi_platform_data pdata = { + .cs_control = cs_control, + }; + + memset(res, 0, sizeof(res)); + + pdata.sysclk = sysclk; + + prop = of_get_property(np, "reg", NULL); + if (!prop) + goto err; + pdata.bus_num = *(u32 *)prop; + + prop = of_get_property(np, "cell-index", NULL); + if (prop) + i = *(u32 *)prop; + + prop = of_get_property(np, "mode", NULL); + if (prop && !strcmp(prop, "cpu-qe")) + pdata.flags = SPI_QE_CPU_MODE; + + for (j = 0; j < num_board_infos; j++) { + if (board_infos[j].bus_num == pdata.bus_num) + pdata.max_chipselect++; + } + + if (!pdata.max_chipselect) + continue; + + ret = of_address_to_resource(np, 0, &res[0]); + if (ret) + goto err; + + ret = of_irq_to_resource(np, 0, &res[1]); + if (ret == NO_IRQ) + goto err; + + pdev = platform_device_alloc("mpc83xx_spi", i); + if (!pdev) + goto err; + + ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); + if (ret) + goto unreg; + + ret = platform_device_add_resources(pdev, res, + ARRAY_SIZE(res)); + if (ret) + goto unreg; + + ret = platform_device_add(pdev); + if (ret) + goto unreg; + + goto next; +unreg: + platform_device_del(pdev); +err: + pr_err("%s: registration failed\n", np->full_name); +next: + i++; + } + + return i; +} + +static int __init fsl_spi_init(struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*cs_control)(struct spi_device *spi, + bool on)) { - pr_debug("%s %d %d\n", __func__, cs, polarity); - par_io_data_set(3, 13, polarity); + u32 sysclk = -1; + int ret; + + /* SPI controller is either clocked from QE or SoC clock */ + sysclk = get_brgfreq(); + if (sysclk == -1) { + sysclk = fsl_get_sys_freq(); + if (sysclk == -1) + return -ENODEV; + } + + ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, + num_board_infos, cs_control); + if (!ret) + of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, + num_board_infos, cs_control); + + return spi_register_board_info(board_infos, num_board_infos); } -static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) +static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) { - pr_debug("%s %d %d\n", __func__, cs, polarity); - par_io_data_set(3, 13, !polarity); + pr_debug("%s %d %d\n", __func__, spi->chip_select, on); + par_io_data_set(3, 13, on); } static struct mmc_spi_platform_data mpc832x_mmc_pdata = { @@ -73,12 +175,16 @@ static int __init mpc832x_spi_init(void) par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */ par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */ - return fsl_spi_init(&mpc832x_spi_boardinfo, 1, - mpc83xx_spi_activate_cs, - mpc83xx_spi_deactivate_cs); + /* + * Don't bother with legacy stuff when device tree contains + * mmc-spi-slot node. + */ + if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot")) + return 0; + return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control); } - machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); +#endif /* CONFIG_QUICC_ENGINE */ /* ************************************************************************ * @@ -87,17 +193,14 @@ machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); */ static void __init mpc832x_rdb_setup_arch(void) { -#if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) +#if defined(CONFIG_QUICC_ENGINE) struct device_node *np; #endif if (ppc_md.progress) ppc_md.progress("mpc832x_rdb_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE qe_reset(); @@ -112,52 +215,7 @@ static void __init mpc832x_rdb_setup_arch(void) #endif /* CONFIG_QUICC_ENGINE */ } -static struct of_device_id mpc832x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - { .type = "qe", }, - { .compatible = "fsl,qe", }, - {}, -}; - -static int __init mpc832x_declare_of_platform_devices(void) -{ - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc832x_ids, NULL); - - return 0; -} -machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); - -void __init mpc832x_rdb_init_IRQ(void) -{ - - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); - of_node_put(np); - -#ifdef CONFIG_QUICC_ENGINE - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (!np) { - np = of_find_node_by_type(NULL, "qeic"); - if (!np) - return; - } - qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); - of_node_put(np); -#endif /* CONFIG_QUICC_ENGINE */ -} +machine_device_initcall(mpc832x_rdb, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -173,7 +231,7 @@ define_machine(mpc832x_rdb) { .name = "MPC832x RDB", .probe = mpc832x_rdb_probe, .setup_arch = mpc832x_rdb_setup_arch, - .init_IRQ = mpc832x_rdb_init_IRQ, + .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 76092d37c7d..a494fa57bdf 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -25,8 +25,7 @@ #include <linux/root_dev.h> #include <linux/of_platform.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -41,12 +40,12 @@ static struct of_device_id __initdata mpc834x_itx_ids[] = { { .compatible = "fsl,pq2pro-localbus", }, - { .compatible = "simple-bus", }, {}, }; static int __init mpc834x_itx_declare_of_platform_devices(void) { + mpc83xx_declare_of_platform_devices(); return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); } machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); @@ -58,37 +57,14 @@ machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); */ static void __init mpc834x_itx_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc834x_itx_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); mpc834x_usb_cfg(); } -static void __init mpc834x_itx_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} - /* * Called very early, MMU is off, device-tree isn't unflattened */ @@ -103,7 +79,7 @@ define_machine(mpc834x_itx) { .name = "MPC834x ITX", .probe = mpc834x_itx_probe, .setup_arch = mpc834x_itx_setup_arch, - .init_IRQ = mpc834x_itx_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index fc3f2ed1f3e..553e793a4a9 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -25,8 +25,7 @@ #include <linux/root_dev.h> #include <linux/of_platform.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -53,7 +52,7 @@ static int mpc834xemds_usb_cfg(void) struct resource res; of_address_to_resource(np, 0, &res); - bcsr_regs = ioremap(res.start, res.end - res.start + 1); + bcsr_regs = ioremap(res.start, resource_size(&res)); of_node_put(np); } if (!bcsr_regs) @@ -77,50 +76,15 @@ static int mpc834xemds_usb_cfg(void) */ static void __init mpc834x_mds_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc834x_mds_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); mpc834xemds_usb_cfg(); } -static void __init mpc834x_mds_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} - -static struct of_device_id mpc834x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - {}, -}; - -static int __init mpc834x_declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, mpc834x_ids, NULL); - return 0; -} -machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices); +machine_device_initcall(mpc834x_mds, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -136,7 +100,7 @@ define_machine(mpc834x_mds) { .name = "MPC834x MDS", .probe = mpc834x_mds_probe, .setup_arch = mpc834x_mds_setup_arch, - .init_IRQ = mpc834x_mds_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 9d46e5bdd10..1a26d2f8340 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. + * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved. * * Author: Li Yang <LeoLi@freescale.com> * Yin Olivia <Hong-hua.Yin@freescale.com> @@ -18,6 +18,7 @@ #include <linux/stddef.h> #include <linux/kernel.h> +#include <linux/compiler.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/reboot.h> @@ -32,8 +33,7 @@ #include <linux/of_platform.h> #include <linux/of_device.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -43,6 +43,7 @@ #include <asm/udbg.h> #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +#include <sysdev/simple_gpio.h> #include <asm/qe.h> #include <asm/qe_ic.h> @@ -55,8 +56,6 @@ #define DBG(fmt...) #endif -static u8 *bcsr_regs = NULL; - /* ************************************************************************ * * Setup the architecture @@ -65,24 +64,22 @@ static u8 *bcsr_regs = NULL; static void __init mpc836x_mds_setup_arch(void) { struct device_node *np; + u8 __iomem *bcsr_regs = NULL; if (ppc_md.progress) ppc_md.progress("mpc836x_mds_setup_arch()", 0); /* Map BCSR area */ np = of_find_node_by_name(NULL, "bcsr"); - if (np != 0) { + if (np) { struct resource res; of_address_to_resource(np, 0, &res); - bcsr_regs = ioremap(res.start, res.end - res.start +1); + bcsr_regs = ioremap(res.start, resource_size(&res)); of_node_put(np); } -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); #ifdef CONFIG_QUICC_ENGINE qe_reset(); @@ -93,6 +90,16 @@ static void __init mpc836x_mds_setup_arch(void) for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) par_io_of_config(np); +#ifdef CONFIG_QE_USB + /* Must fixup Par IO before QE GPIO chips are registered. */ + par_io_config_pin(1, 2, 1, 0, 3, 0); /* USBOE */ + par_io_config_pin(1, 3, 1, 0, 3, 0); /* USBTP */ + par_io_config_pin(1, 8, 1, 0, 1, 0); /* USBTN */ + par_io_config_pin(1, 10, 2, 0, 3, 0); /* USBRXD */ + par_io_config_pin(1, 9, 2, 1, 3, 0); /* USBRP */ + par_io_config_pin(1, 11, 2, 1, 3, 0); /* USBRN */ + par_io_config_pin(2, 20, 2, 0, 1, 0); /* CLK21 */ +#endif /* CONFIG_QE_USB */ } if ((np = of_find_compatible_node(NULL, "network", "ucc_geth")) @@ -133,51 +140,71 @@ static void __init mpc836x_mds_setup_arch(void) #endif /* CONFIG_QUICC_ENGINE */ } -static struct of_device_id mpc836x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - { .type = "qe", }, - { .compatible = "fsl,qe", }, - {}, -}; - -static int __init mpc836x_declare_of_platform_devices(void) -{ - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc836x_ids, NULL); - - return 0; -} -machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices); +machine_device_initcall(mpc836x_mds, mpc83xx_declare_of_platform_devices); -static void __init mpc836x_mds_init_IRQ(void) +#ifdef CONFIG_QE_USB +static int __init mpc836x_usb_cfg(void) { + u8 __iomem *bcsr; struct device_node *np; + const char *mode; + int ret = 0; - np = of_find_node_by_type(NULL, "ipic"); + np = of_find_compatible_node(NULL, NULL, "fsl,mpc8360mds-bcsr"); if (!np) - return; - - ipic_init(np, 0); + return -ENODEV; - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); + bcsr = of_iomap(np, 0); of_node_put(np); + if (!bcsr) + return -ENOMEM; -#ifdef CONFIG_QUICC_ENGINE - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); + np = of_find_compatible_node(NULL, NULL, "fsl,mpc8323-qe-usb"); if (!np) { - np = of_find_node_by_type(NULL, "qeic"); - if (!np) - return; + ret = -ENODEV; + goto err; } - qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); + +#define BCSR8_TSEC1M_MASK (0x3 << 6) +#define BCSR8_TSEC1M_RGMII (0x0 << 6) +#define BCSR8_TSEC2M_MASK (0x3 << 4) +#define BCSR8_TSEC2M_RGMII (0x0 << 4) + /* + * Default is GMII (2), but we should set it to RGMII (0) if we use + * USB (Eth PHY is in RGMII mode anyway). + */ + clrsetbits_8(&bcsr[8], BCSR8_TSEC1M_MASK | BCSR8_TSEC2M_MASK, + BCSR8_TSEC1M_RGMII | BCSR8_TSEC2M_RGMII); + +#define BCSR13_USBMASK 0x0f +#define BCSR13_nUSBEN 0x08 /* 1 - Disable, 0 - Enable */ +#define BCSR13_USBSPEED 0x04 /* 1 - Full, 0 - Low */ +#define BCSR13_USBMODE 0x02 /* 1 - Host, 0 - Function */ +#define BCSR13_nUSBVCC 0x01 /* 1 - gets VBUS, 0 - supplies VBUS */ + + clrsetbits_8(&bcsr[13], BCSR13_USBMASK, BCSR13_USBSPEED); + + mode = of_get_property(np, "mode", NULL); + if (mode && !strcmp(mode, "peripheral")) { + setbits8(&bcsr[13], BCSR13_nUSBVCC); + qe_usb_clock_set(QE_CLK21, 48000000); + } else { + setbits8(&bcsr[13], BCSR13_USBMODE); + /* + * The BCSR GPIOs are used to control power and + * speed of the USB transceiver. This is needed for + * the USB Host only. + */ + simple_gpiochip_init("fsl,mpc8360mds-bcsr-gpio"); + } + of_node_put(np); -#endif /* CONFIG_QUICC_ENGINE */ +err: + iounmap(bcsr); + return ret; } +machine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); +#endif /* CONFIG_QE_USB */ /* * Called very early, MMU is off, device-tree isn't unflattened @@ -193,7 +220,7 @@ define_machine(mpc836x_mds) { .name = "MPC836x MDS", .probe = mpc836x_mds_probe, .setup_arch = mpc836x_mds_setup_arch, - .init_IRQ = mpc836x_mds_init_IRQ, + .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index a5273bb28e1..b63b42d11d6 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -1,7 +1,7 @@ /* * MPC8360E-RDK board file. * - * Copyright (c) 2006 Freescale Semicondutor, Inc. + * Copyright (c) 2006 Freescale Semiconductor, Inc. * Copyright (c) 2007-2008 MontaVista Software, Inc. * * Author: Anton Vorontsov <avorontsov@ru.mvista.com> @@ -27,57 +27,17 @@ #include "mpc83xx.h" -static struct of_device_id __initdata mpc836x_rdk_ids[] = { - { .compatible = "simple-bus", }, - {}, -}; - -static int __init mpc836x_rdk_declare_of_platform_devices(void) -{ - return of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL); -} -machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices); +machine_device_initcall(mpc836x_rdk, mpc83xx_declare_of_platform_devices); static void __init mpc836x_rdk_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc836x_rdk_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif - + mpc83xx_setup_pci(); +#ifdef CONFIG_QUICC_ENGINE qe_reset(); -} - -static void __init mpc836x_rdk_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* - * Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); - of_node_put(np); - - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); - if (!np) - return; - - qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); - of_node_put(np); +#endif } /* @@ -94,7 +54,7 @@ define_machine(mpc836x_rdk) { .name = "MPC836x RDK", .probe = mpc836x_rdk_probe, .setup_arch = mpc836x_rdk_setup_arch, - .init_IRQ = mpc836x_rdk_init_IRQ, + .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index be62de23bea..e53a60b6c86 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -26,7 +26,6 @@ #define BCSR12_USB_SER_MASK 0x8a #define BCSR12_USB_SER_PIN 0x80 #define BCSR12_USB_SER_DEVICE 0x02 -extern int mpc837x_usb_cfg(void); static int mpc837xmds_usb_cfg(void) { @@ -49,8 +48,10 @@ static int mpc837xmds_usb_cfg(void) return -1; np = of_find_node_by_name(NULL, "usb"); - if (!np) - return -ENODEV; + if (!np) { + ret = -ENODEV; + goto out; + } phy_type = of_get_property(np, "phy_type", NULL); if (phy_type && !strcmp(phy_type, "ulpi")) { clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); @@ -66,8 +67,9 @@ static int mpc837xmds_usb_cfg(void) } of_node_put(np); +out: iounmap(bcsr_regs); - return 0; + return ret; } /* ************************************************************************ @@ -77,51 +79,14 @@ static int mpc837xmds_usb_cfg(void) */ static void __init mpc837x_mds_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc837x_mds_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); mpc837xmds_usb_cfg(); } -static struct of_device_id mpc837x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - {}, -}; - -static int __init mpc837x_declare_of_platform_devices(void) -{ - /* Publish of_device */ - of_platform_bus_probe(NULL, mpc837x_ids, NULL); - - return 0; -} -machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices); - -static void __init mpc837x_mds_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} +machine_device_initcall(mpc837x_mds, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -137,7 +102,7 @@ define_machine(mpc837x_mds) { .name = "MPC837x MDS", .probe = mpc837x_mds_probe, .setup_arch = mpc837x_mds_setup_arch, - .init_IRQ = mpc837x_mds_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index da030afa2e2..9813c81e8e5 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -1,7 +1,7 @@ /* * arch/powerpc/platforms/83xx/mpc837x_rdb.c * - * Copyright (C) 2007 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. * * MPC837x RDB board specific routines * @@ -17,11 +17,31 @@ #include <asm/time.h> #include <asm/ipic.h> #include <asm/udbg.h> +#include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> #include "mpc83xx.h" -extern int mpc837x_usb_cfg(void); +static void mpc837x_rdb_sd_cfg(void) +{ + void __iomem *im; + + im = ioremap(get_immrbase(), 0x1000); + if (!im) { + WARN_ON(1); + return; + } + + /* + * On RDB boards (in contrast to MDS) USBB pins are used for SD only, + * so we can safely mux them away from the USB block. + */ + clrsetbits_be32(im + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USBB_MASK, + MPC837X_SICRL_SD); + clrsetbits_be32(im + MPC83XX_SICRH_OFFS, MPC837X_SICRH_SPI_MASK, + MPC837X_SICRH_SD); + iounmap(im); +} /* ************************************************************************ * @@ -30,69 +50,37 @@ extern int mpc837x_usb_cfg(void); */ static void __init mpc837x_rdb_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("mpc837x_rdb_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif + mpc83xx_setup_pci(); mpc837x_usb_cfg(); + mpc837x_rdb_sd_cfg(); } -static struct of_device_id mpc837x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - {}, -}; +machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices); -static int __init mpc837x_declare_of_platform_devices(void) -{ - /* Publish of_device */ - of_platform_bus_probe(NULL, mpc837x_ids, NULL); - - return 0; -} -machine_device_initcall(mpc837x_rdb, mpc837x_declare_of_platform_devices); - -static void __init mpc837x_rdb_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} +static const char * const board[] __initconst = { + "fsl,mpc8377rdb", + "fsl,mpc8378rdb", + "fsl,mpc8379rdb", + "fsl,mpc8377wlan", + NULL +}; /* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init mpc837x_rdb_probe(void) { - unsigned long root = of_get_flat_dt_root(); - - return of_flat_dt_is_compatible(root, "fsl,mpc8377rdb") || - of_flat_dt_is_compatible(root, "fsl,mpc8378rdb") || - of_flat_dt_is_compatible(root, "fsl,mpc8379rdb"); + return of_flat_dt_match(of_get_flat_dt_root(), board); } define_machine(mpc837x_rdb) { - .name = "MPC837x RDB", + .name = "MPC837x RDB/WLAN", .probe = mpc837x_rdb_probe, .setup_arch = mpc837x_rdb_setup_arch, - .init_IRQ = mpc837x_rdb_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 2a7cbabb410..0cf74d7ea1c 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h @@ -22,22 +22,28 @@ /* system i/o configuration register low */ #define MPC83XX_SICRL_OFFS 0x114 #define MPC834X_SICRL_USB_MASK 0x60000000 -#define MPC834X_SICRL_USB0 0x40000000 -#define MPC834X_SICRL_USB1 0x20000000 +#define MPC834X_SICRL_USB0 0x20000000 +#define MPC834X_SICRL_USB1 0x40000000 #define MPC831X_SICRL_USB_MASK 0x00000c00 #define MPC831X_SICRL_USB_ULPI 0x00000800 #define MPC8315_SICRL_USB_MASK 0x000000fc #define MPC8315_SICRL_USB_ULPI 0x00000054 #define MPC837X_SICRL_USB_MASK 0xf0000000 #define MPC837X_SICRL_USB_ULPI 0x50000000 +#define MPC837X_SICRL_USBB_MASK 0x30000000 +#define MPC837X_SICRL_SD 0x20000000 /* system i/o configuration register high */ #define MPC83XX_SICRH_OFFS 0x118 +#define MPC8308_SICRH_USB_MASK 0x000c0000 +#define MPC8308_SICRH_USB_ULPI 0x00040000 #define MPC834X_SICRH_USB_UTMI 0x00020000 #define MPC831X_SICRH_USB_MASK 0x000000e0 #define MPC831X_SICRH_USB_ULPI 0x000000a0 #define MPC8315_SICRH_USB_MASK 0x0000ff00 #define MPC8315_SICRH_USB_ULPI 0x00000000 +#define MPC837X_SICRH_SPI_MASK 0x00000003 +#define MPC837X_SICRH_SD 0x00000001 /* USB Control Register */ #define FSL_USB2_CONTROL_OFFS 0x500 @@ -61,7 +67,24 @@ extern void mpc83xx_restart(char *cmd); extern long mpc83xx_time_init(void); +extern int mpc837x_usb_cfg(void); extern int mpc834x_usb_cfg(void); extern int mpc831x_usb_cfg(void); +extern void mpc83xx_ipic_init_IRQ(void); +#ifdef CONFIG_QUICC_ENGINE +extern void mpc83xx_qe_init_IRQ(void); +extern void mpc83xx_ipic_and_qe_init_IRQ(void); +#else +static inline void __init mpc83xx_qe_init_IRQ(void) {} +#define mpc83xx_ipic_and_qe_init_IRQ mpc83xx_ipic_init_IRQ +#endif /* CONFIG_QUICC_ENGINE */ + +#ifdef CONFIG_PCI +extern void mpc83xx_setup_pci(void); +#else +#define mpc83xx_setup_pci() do {} while (0) +#endif + +extern int mpc83xx_declare_of_platform_devices(void); #endif /* __MPC83XX_H__ */ diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index 156c4e21800..26cb3e93472 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c @@ -27,8 +27,7 @@ #include <linux/root_dev.h> #include <linux/of_platform.h> -#include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> @@ -48,51 +47,13 @@ */ static void __init sbc834x_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("sbc834x_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); -#endif - + mpc83xx_setup_pci(); } -static void __init sbc834x_init_IRQ(void) -{ - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; - - ipic_init(np, 0); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); - - of_node_put(np); -} - -static struct __initdata of_device_id sbc834x_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .compatible = "simple-bus", }, - {}, -}; - -static int __init sbc834x_declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, sbc834x_ids, NULL); - return 0; -} -machine_device_initcall(sbc834x, sbc834x_declare_of_platform_devices); +machine_device_initcall(sbc834x, mpc83xx_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened @@ -101,14 +62,14 @@ static int __init sbc834x_probe(void) { unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "SBC834x"); + return of_flat_dt_is_compatible(root, "SBC834xE"); } define_machine(sbc834x) { - .name = "SBC834x", + .name = "SBC834xE", .probe = sbc834x_probe, .setup_arch = sbc834x_setup_arch, - .init_IRQ = sbc834x_init_IRQ, + .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, .time_init = mpc83xx_time_init, diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S index 1930543c98d..3d1ecd21177 100644 --- a/arch/powerpc/platforms/83xx/suspend-asm.S +++ b/arch/powerpc/platforms/83xx/suspend-asm.S @@ -231,7 +231,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) ori r4, r4, 0x002a mtspr SPRN_DBAT0L, r4 lis r8, TMP_VIRT_IMMR@h - ori r4, r8, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r8, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT0U, r4 isync @@ -241,7 +241,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) ori r4, r4, 0x002a mtspr SPRN_DBAT1L, r4 lis r9, (TMP_VIRT_IMMR + 0x01000000)@h - ori r4, r9, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r9, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT1U, r4 isync @@ -253,7 +253,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) li r4, 0x0002 mtspr SPRN_DBAT2L, r4 lis r4, KERNELBASE@h - ori r4, r4, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r4, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT2U, r4 isync diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 08e65fc8b98..4b4c081df94 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -10,7 +10,6 @@ * by the Free Software Foundation. */ -#include <linux/init.h> #include <linux/pm.h> #include <linux/types.h> #include <linux/ioport.h> @@ -20,18 +19,23 @@ #include <linux/freezer.h> #include <linux/suspend.h> #include <linux/fsl_devices.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/export.h> #include <asm/reg.h> #include <asm/io.h> #include <asm/time.h> #include <asm/mpc6xx.h> +#include <asm/switch_to.h> #include <sysdev/fsl_soc.h> #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ #define PMCCR1_NEXT_STATE_SHIFT 2 #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ +#define IMMR_SYSCR_OFFSET 0x100 #define IMMR_RCW_OFFSET 0x900 #define RCW_PCI_HOST 0x80000000 @@ -78,15 +82,33 @@ struct mpc83xx_clock { u32 sccr; }; +struct mpc83xx_syscr { + __be32 sgprl; + __be32 sgprh; + __be32 spridr; + __be32 :32; + __be32 spcr; + __be32 sicrl; + __be32 sicrh; +}; + +struct mpc83xx_saved { + u32 sicrl; + u32 sicrh; + u32 sccr; +}; + struct pmc_type { int has_deep_sleep; }; -static struct of_device *pmc_dev; +static struct platform_device *pmc_dev; static int has_deep_sleep, deep_sleeping; static int pmc_irq; static struct mpc83xx_pmc __iomem *pmc_regs; static struct mpc83xx_clock __iomem *clock_regs; +static struct mpc83xx_syscr __iomem *syscr_regs; +static struct mpc83xx_saved saved_regs; static int is_pci_agent, wake_from_pci; static phys_addr_t immrbase; static int pci_pm_state; @@ -96,6 +118,7 @@ int fsl_deep_sleep(void) { return deep_sleeping; } +EXPORT_SYMBOL(fsl_deep_sleep); static int mpc83xx_change_state(void) { @@ -136,6 +159,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id) return ret; } +static void mpc83xx_suspend_restore_regs(void) +{ + out_be32(&syscr_regs->sicrl, saved_regs.sicrl); + out_be32(&syscr_regs->sicrh, saved_regs.sicrh); + out_be32(&clock_regs->sccr, saved_regs.sccr); +} + +static void mpc83xx_suspend_save_regs(void) +{ + saved_regs.sicrl = in_be32(&syscr_regs->sicrl); + saved_regs.sicrh = in_be32(&syscr_regs->sicrh); + saved_regs.sccr = in_be32(&clock_regs->sccr); +} + static int mpc83xx_suspend_enter(suspend_state_t state) { int ret = -EAGAIN; @@ -165,6 +202,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) */ if (deep_sleeping) { + mpc83xx_suspend_save_regs(); + out_be32(&pmc_regs->mask, PMCER_ALL); out_be32(&pmc_regs->config1, @@ -178,6 +217,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); out_be32(&pmc_regs->mask, PMCER_PMCI); + + mpc83xx_suspend_restore_regs(); } else { out_be32(&pmc_regs->mask, PMCER_PMCI); @@ -193,7 +234,7 @@ out: return ret; } -static void mpc83xx_suspend_finish(void) +static void mpc83xx_suspend_end(void) { deep_sleeping = 0; } @@ -273,21 +314,28 @@ static int mpc83xx_is_pci_agent(void) return ret; } -static struct platform_suspend_ops mpc83xx_suspend_ops = { +static const struct platform_suspend_ops mpc83xx_suspend_ops = { .valid = mpc83xx_suspend_valid, .begin = mpc83xx_suspend_begin, .enter = mpc83xx_suspend_enter, - .finish = mpc83xx_suspend_finish, + .end = mpc83xx_suspend_end, }; -static int pmc_probe(struct of_device *ofdev, - const struct of_device_id *match) +static struct of_device_id pmc_match[]; +static int pmc_probe(struct platform_device *ofdev) { - struct device_node *np = ofdev->node; + const struct of_device_id *match; + struct device_node *np = ofdev->dev.of_node; struct resource res; - struct pmc_type *type = match->data; + const struct pmc_type *type; int ret = 0; + match = of_match_device(pmc_match, &ofdev->dev); + if (!match) + return -EINVAL; + + type = match->data; + if (!of_device_is_available(np)) return -ENODEV; @@ -332,12 +380,23 @@ static int pmc_probe(struct of_device *ofdev, goto out_pmc; } + if (has_deep_sleep) { + syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, + sizeof(*syscr_regs)); + if (!syscr_regs) { + ret = -ENOMEM; + goto out_syscr; + } + } + if (is_pci_agent) mpc83xx_set_agent(); suspend_set_ops(&mpc83xx_suspend_ops); return 0; +out_syscr: + iounmap(clock_regs); out_pmc: iounmap(pmc_regs); out: @@ -347,7 +406,7 @@ out: return ret; } -static int pmc_remove(struct of_device *ofdev) +static int pmc_remove(struct platform_device *ofdev) { return -EPERM; }; @@ -373,16 +432,19 @@ static struct of_device_id pmc_match[] = { {} }; -static struct of_platform_driver pmc_driver = { - .name = "mpc83xx-pmc", - .match_table = pmc_match, +static struct platform_driver pmc_driver = { + .driver = { + .name = "mpc83xx-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, .remove = pmc_remove }; static int pmc_init(void) { - return of_register_platform_driver(&pmc_driver); + return platform_driver_register(&pmc_driver); } module_init(pmc_init); diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c index cc99c280aad..1ad748bb39b 100644 --- a/arch/powerpc/platforms/83xx/usb.c +++ b/arch/powerpc/platforms/83xx/usb.c @@ -14,6 +14,7 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/errno.h> +#include <linux/of.h> #include <asm/io.h> #include <asm/prom.h> @@ -46,25 +47,25 @@ int mpc834x_usb_cfg(void) sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */ prop = of_get_property(np, "phy_type", NULL); + port1_is_dr = 1; if (prop && (!strcmp(prop, "utmi") || !strcmp(prop, "utmi_wide"))) { sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1; sicrh |= MPC834X_SICRH_USB_UTMI; - port1_is_dr = 1; + port0_is_dr = 1; } else if (prop && !strcmp(prop, "serial")) { dr_mode = of_get_property(np, "dr_mode", NULL); if (dr_mode && !strcmp(dr_mode, "otg")) { sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1; - port1_is_dr = 1; + port0_is_dr = 1; } else { - sicrl |= MPC834X_SICRL_USB0; + sicrl |= MPC834X_SICRL_USB1; } } else if (prop && !strcmp(prop, "ulpi")) { - sicrl |= MPC834X_SICRL_USB0; + sicrl |= MPC834X_SICRL_USB1; } else { printk(KERN_WARNING "834x USB PHY type not supported\n"); } - port0_is_dr = 1; of_node_put(np); } np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph"); @@ -126,7 +127,8 @@ int mpc831x_usb_cfg(void) /* Configure clock */ immr_node = of_get_parent(np); - if (immr_node && of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) + if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") || + of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))) clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC8315_SCCR_USB_MASK, MPC8315_SCCR_USB_DRCM_01); @@ -137,7 +139,11 @@ int mpc831x_usb_cfg(void) /* Configure pin mux for ULPI. There is no pin mux for UTMI */ if (prop && !strcmp(prop, "ulpi")) { - if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) { + if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) { + clrsetbits_be32(immap + MPC83XX_SICRH_OFFS, + MPC8308_SICRH_USB_MASK, + MPC8308_SICRH_USB_ULPI); + } else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) { clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC8315_SICRL_USB_MASK, MPC8315_SICRL_USB_ULPI); @@ -165,13 +171,16 @@ int mpc831x_usb_cfg(void) of_node_put(np); return ret; } - usb_regs = ioremap(res.start, res.end - res.start + 1); + usb_regs = ioremap(res.start, resource_size(&res)); /* Using on-chip PHY */ if (prop && (!strcmp(prop, "utmi_wide") || !strcmp(prop, "utmi"))) { u32 refsel; + if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) + goto out; + if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) refsel = CONTROL_REFSEL_24MHZ; else @@ -185,9 +194,11 @@ int mpc831x_usb_cfg(void) temp = CONTROL_PHY_CLK_SEL_ULPI; #ifdef CONFIG_USB_OTG /* Set OTG_PORT */ - dr_mode = of_get_property(np, "dr_mode", NULL); - if (dr_mode && !strcmp(dr_mode, "otg")) - temp |= CONTROL_OTG_PORT; + if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) { + dr_mode = of_get_property(np, "dr_mode", NULL); + if (dr_mode && !strcmp(dr_mode, "otg")) + temp |= CONTROL_OTG_PORT; + } #endif /* CONFIG_USB_OTG */ out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp); } else { @@ -195,6 +206,7 @@ int mpc831x_usb_cfg(void) ret = -EINVAL; } +out: iounmap(usb_regs); of_node_put(np); return ret; @@ -210,7 +222,7 @@ int mpc837x_usb_cfg(void) int ret = 0; np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr"); - if (!np) + if (!np || !of_device_is_available(np)) return -ENODEV; prop = of_get_property(np, "phy_type", NULL); |
