diff options
Diffstat (limited to 'arch/powerpc/sysdev/mv64x60_dev.c')
| -rw-r--r-- | arch/powerpc/sysdev/mv64x60_dev.c | 99 |
1 files changed, 64 insertions, 35 deletions
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 047b31027fa..c2dba7db71a 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -15,15 +15,18 @@ #include <linux/console.h> #include <linux/mv643xx.h> #include <linux/platform_device.h> +#include <linux/of_platform.h> +#include <linux/of_net.h> +#include <linux/dma-mapping.h> #include <asm/prom.h> -/* - * These functions provide the necessary setup for the mv64x60 drivers. - * These drivers are unusual in that they work on both the MIPS and PowerPC - * architectures. Because of that, the drivers do not support the normal - * PowerPC of_platform_bus_type. They support platform_bus_type instead. - */ +/* These functions provide the necessary setup for the mv64x60 drivers. */ + +static struct of_device_id __initdata of_mv64x60_devices[] = { + { .compatible = "marvell,mv64306-devctrl", }, + {} +}; /* * Create MPSC platform devices @@ -183,6 +186,7 @@ static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id) pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number); if (!pdev) return -ENOMEM; + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); err = platform_device_add_resources(pdev, r, 5); if (err) @@ -210,15 +214,27 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev( struct device_node *np, int id) { struct platform_device *pdev; - struct resource r[1]; + struct resource r[2]; int err; err = of_address_to_resource(np, 0, &r[0]); if (err) return ERR_PTR(err); + /* register an orion mdio bus driver */ + r[1].start = r[0].start + 0x4; + r[1].end = r[0].start + 0x84 - 1; + r[1].flags = IORESOURCE_MEM; + + if (id == 0) { + pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1); + if (IS_ERR(pdev)) + return pdev; + } + pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, - r, 1); + &r[0], 1); + return pdev; } @@ -239,6 +255,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id, memset(&pdata, 0, sizeof(pdata)); + pdata.shared = shared_pdev; + prop = of_get_property(np, "reg", NULL); if (!prop) return -ENODEV; @@ -285,10 +303,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id, return -ENODEV; prop = of_get_property(phy, "reg", NULL); - if (prop) { - pdata.force_phy_addr = 1; - pdata.phy_addr = *prop; - } + if (prop) + pdata.phy_addr = MV643XX_ETH_PHY_ADDR(*prop); of_node_put(phy); @@ -296,6 +312,7 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id, if (!pdev) return -ENOMEM; + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); err = platform_device_add_resources(pdev, r, 1); if (err) goto error; @@ -338,15 +355,13 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id) pdata.freq_m = 8; /* default */ prop = of_get_property(np, "freq_m", NULL); - if (!prop) - return -ENODEV; - pdata.freq_m = *prop; + if (prop) + pdata.freq_m = *prop; - pdata.freq_m = 3; /* default */ + pdata.freq_n = 3; /* default */ prop = of_get_property(np, "freq_n", NULL); - if (!prop) - return -ENODEV; - pdata.freq_n = *prop; + if (prop) + pdata.freq_n = *prop; pdata.timeout = 1000; /* default: 1 second */ @@ -433,9 +448,13 @@ static int __init mv64x60_device_setup(void) int err; id = 0; - for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") - if ((err = mv64x60_mpsc_device_setup(np, id++))) - goto error; + for_each_compatible_node(np, NULL, "marvell,mv64360-mpsc") { + err = mv64x60_mpsc_device_setup(np, id++); + if (err) + printk(KERN_ERR "Failed to initialize MV64x60 " + "serial device %s: error %d.\n", + np->full_name, err); + } id = 0; id2 = 0; @@ -443,38 +462,48 @@ static int __init mv64x60_device_setup(void) pdev = mv64x60_eth_register_shared_pdev(np, id++); if (IS_ERR(pdev)) { err = PTR_ERR(pdev); - goto error; + printk(KERN_ERR "Failed to initialize MV64x60 " + "network block %s: error %d.\n", + np->full_name, err); + continue; } for_each_child_of_node(np, np2) { if (!of_device_is_compatible(np2, "marvell,mv64360-eth")) continue; err = mv64x60_eth_device_setup(np2, id2++, pdev); - if (err) { - of_node_put(np2); - goto error; - } + if (err) + printk(KERN_ERR "Failed to initialize " + "MV64x60 network device %s: " + "error %d.\n", + np2->full_name, err); } } id = 0; - for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") - if ((err = mv64x60_i2c_device_setup(np, id++))) - goto error; + for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") { + err = mv64x60_i2c_device_setup(np, id++); + if (err) + printk(KERN_ERR "Failed to initialize MV64x60 I2C " + "bus %s: error %d.\n", + np->full_name, err); + } /* support up to one watchdog timer */ np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt"); if (np) { if ((err = mv64x60_wdt_device_setup(np, id))) - goto error; + printk(KERN_ERR "Failed to initialize MV64x60 " + "Watchdog %s: error %d.\n", + np->full_name, err); of_node_put(np); } - return 0; + /* Now add every node that is on the device bus */ + for_each_compatible_node(np, NULL, "marvell,mv64360") + of_platform_bus_probe(np, of_mv64x60_devices, NULL); -error: - of_node_put(np); - return err; + return 0; } arch_initcall(mv64x60_device_setup); |
