mv64x60_dev.c revision a0916bd64a0e6636f0161480e04057c89e90c5da
152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth/*
252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth *
452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * Author: Dale Farnsworth <dale@farnsworth.org>
552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth *
652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * the terms of the GNU General Public License version 2.  This program
852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * is licensed "as is" without any warranty of any kind, whether express
952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * or implied.
1052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth */
1152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
1252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <linux/stddef.h>
1352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <linux/kernel.h>
1452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <linux/init.h>
15542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer#include <linux/console.h>
1652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <linux/mv643xx.h>
1752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <linux/platform_device.h>
1852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
1952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth#include <asm/prom.h>
2052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
2152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth/*
2252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * These functions provide the necessary setup for the mv64x60 drivers.
2352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * These drivers are unusual in that they work on both the MIPS and PowerPC
2452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * architectures.  Because of that, the drivers do not support the normal
2552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * PowerPC of_platform_bus_type.  They support platform_bus_type instead.
2652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth */
2752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
2852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth/*
2952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth * Create MPSC platform devices
3052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth */
3152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworthstatic int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
3252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth{
3352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct platform_device *pdev;
3452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct resource r[2];
3552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct mpsc_shared_pdata pdata;
3652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	const phandle *ph;
3752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct device_node *mpscrouting, *mpscintr;
3852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	int err;
3952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
4052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	ph = of_get_property(np, "mpscrouting", NULL);
4152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	mpscrouting = of_find_node_by_phandle(*ph);
4252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!mpscrouting)
4352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENODEV;
4452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
4552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = of_address_to_resource(mpscrouting, 0, &r[0]);
4652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_node_put(mpscrouting);
4752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
4852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
4952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
5052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	ph = of_get_property(np, "mpscintr", NULL);
5152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	mpscintr = of_find_node_by_phandle(*ph);
5252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!mpscintr)
5352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENODEV;
5452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
5552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = of_address_to_resource(mpscintr, 0, &r[1]);
5652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_node_put(mpscintr);
5752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
5852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
5952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
6052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	memset(&pdata, 0, sizeof(pdata));
6152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
6252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
6352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!pdev)
6452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENOMEM;
6552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
6652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add_resources(pdev, r, 2);
6752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
6852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
6952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
7052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
7152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
7252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
7352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
7452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add(pdev);
7552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
7652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
7752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
7852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return 0;
7952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
8052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnswortherror:
8152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	platform_device_put(pdev);
8252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return err;
8352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth}
8452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
8552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
8652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworthstatic int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
8752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth{
8852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct resource r[5];
8952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct mpsc_pdata pdata;
9052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct platform_device *pdev;
9152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	const unsigned int *prop;
9252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	const phandle *ph;
9352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	struct device_node *sdma, *brg;
9452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	int err;
9552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	int port_number;
9652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
9752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	/* only register the shared platform device the first time through */
9852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
9952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
10052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
10152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	memset(r, 0, sizeof(r));
10252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
10352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = of_address_to_resource(np, 0, &r[0]);
10452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
10552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
10652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
10752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_irq_to_resource(np, 0, &r[4]);
10852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
10952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	ph = of_get_property(np, "sdma", NULL);
11052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	sdma = of_find_node_by_phandle(*ph);
11152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!sdma)
11252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENODEV;
11352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
11452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_irq_to_resource(sdma, 0, &r[3]);
11552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = of_address_to_resource(sdma, 0, &r[1]);
11652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_node_put(sdma);
11752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
11852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
11952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
12052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	ph = of_get_property(np, "brg", NULL);
12152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	brg = of_find_node_by_phandle(*ph);
12252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!brg)
12352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENODEV;
12452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
12552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = of_address_to_resource(brg, 0, &r[2]);
12652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_node_put(brg);
12752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
12852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return err;
12952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
1301791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	prop = of_get_property(np, "cell-index", NULL);
13152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!prop)
13252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENODEV;
13352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	port_number = *(int *)prop;
13452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
13552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	memset(&pdata, 0, sizeof(pdata));
13652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
13752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdata.cache_mgmt = 1; /* All current revs need this set */
13852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
1391791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	pdata.max_idle = 40; /* default */
14052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(np, "max_idle", NULL);
14152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
14252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.max_idle = *prop;
14352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
14452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(brg, "current-speed", NULL);
14552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
14652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.default_baud = *prop;
14752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
14852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	/* Default is 8 bits, no parity, no flow control */
14952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdata.default_bits = 8;
15052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdata.default_parity = 'n';
15152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdata.default_flow = 'n';
15252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
15352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(np, "chr_1", NULL);
15452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
15552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.chr_1_val = *prop;
15652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
15752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(np, "chr_2", NULL);
15852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
15952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.chr_2_val = *prop;
16052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
16152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(np, "chr_10", NULL);
16252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
16352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.chr_10_val = *prop;
16452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
16552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(np, "mpcr", NULL);
16652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
16752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.mpcr_val = *prop;
16852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
16952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(brg, "bcr", NULL);
17052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
17152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.bcr_val = *prop;
17252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
17352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdata.brg_can_tune = 1; /* All current revs need this set */
17452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
17552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(brg, "clock-src", NULL);
17652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
17752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.brg_clk_src = *prop;
17852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
17952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	prop = of_get_property(brg, "clock-frequency", NULL);
18052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (prop)
18152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		pdata.brg_clk_freq = *prop;
18252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
18352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
18452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (!pdev)
18552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		return -ENOMEM;
18652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
18752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add_resources(pdev, r, 5);
18852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
18952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
19052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
19152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
19252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
19352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
19452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
19552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	err = platform_device_add(pdev);
19652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	if (err)
19752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth		goto error;
19852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
19952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return 0;
20052d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
20152d3aff903171af13b56c5a4d6fb828461406c65Dale Farnswortherror:
20252d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	platform_device_put(pdev);
20352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return err;
20452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth}
20552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
206649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth/*
207649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth * Create mv64x60_eth platform devices
208649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth */
209a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworthstatic struct platform_device * __init mv64x60_eth_register_shared_pdev(
210a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth						struct device_node *np, int id)
211649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth{
212649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct platform_device *pdev;
213649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct resource r[1];
214649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	int err;
215649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
216649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	err = of_address_to_resource(np, 0, &r[0]);
217649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (err)
218a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		return ERR_PTR(err);
219649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
220a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
221649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth					       r, 1);
222a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	return pdev;
223649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth}
224649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
225a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworthstatic int __init mv64x60_eth_device_setup(struct device_node *np, int id,
226a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth					   struct platform_device *shared_pdev)
227649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth{
228649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct resource r[1];
229649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct mv643xx_eth_platform_data pdata;
230649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct platform_device *pdev;
231649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	struct device_node *phy;
232649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	const u8 *mac_addr;
233649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	const int *prop;
234649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	const phandle *ph;
235649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	int err;
236649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
237649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	memset(r, 0, sizeof(r));
238649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	of_irq_to_resource(np, 0, &r[0]);
239649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
240649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	memset(&pdata, 0, sizeof(pdata));
241649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
242a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	prop = of_get_property(np, "reg", NULL);
243649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (!prop)
244649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		return -ENODEV;
245649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	pdata.port_number = *prop;
246649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
247649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	mac_addr = of_get_mac_address(np);
248649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (mac_addr)
249649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		memcpy(pdata.mac_addr, mac_addr, 6);
250649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
251649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "speed", NULL);
252649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
253649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.speed = *prop;
254649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
255649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "tx_queue_size", NULL);
256649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
257649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.tx_queue_size = *prop;
258649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
259649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "rx_queue_size", NULL);
260649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
261649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.rx_queue_size = *prop;
262649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
263649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "tx_sram_addr", NULL);
264649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
265649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.tx_sram_addr = *prop;
266649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
267649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "tx_sram_size", NULL);
268649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
269649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.tx_sram_size = *prop;
270649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
271649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "rx_sram_addr", NULL);
272649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
273649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.rx_sram_addr = *prop;
274649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
275649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(np, "rx_sram_size", NULL);
276649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop)
277649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.rx_sram_size = *prop;
278649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
279649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	ph = of_get_property(np, "phy", NULL);
280649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (!ph)
281649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		return -ENODEV;
282649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
283649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	phy = of_find_node_by_phandle(*ph);
284649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (phy == NULL)
285649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		return -ENODEV;
286649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
287649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	prop = of_get_property(phy, "reg", NULL);
288649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (prop) {
289649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.force_phy_addr = 1;
290649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		pdata.phy_addr = *prop;
291649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	}
292649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
293649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	of_node_put(phy);
294649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
295a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	pdev = platform_device_alloc(MV643XX_ETH_NAME, id);
296649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (!pdev)
297649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		return -ENOMEM;
298649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
299649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	err = platform_device_add_resources(pdev, r, 1);
300649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (err)
301649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		goto error;
302649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
303649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
304649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (err)
305649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		goto error;
306649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
307649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	err = platform_device_add(pdev);
308649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	if (err)
309649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth		goto error;
310649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
311649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	return 0;
312649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
313649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnswortherror:
314649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	platform_device_put(pdev);
315649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth	return err;
316649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth}
317649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
31801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth/*
31901f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth * Create mv64x60_i2c platform devices
32001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth */
32101f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworthstatic int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
32201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth{
32301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	struct resource r[2];
32401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	struct platform_device *pdev;
32501f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	struct mv64xxx_i2c_pdata pdata;
32601f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	const unsigned int *prop;
32701f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	int err;
32801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
32901f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	memset(r, 0, sizeof(r));
33001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
33101f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	err = of_address_to_resource(np, 0, &r[0]);
33201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (err)
33301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		return err;
33401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
33501f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	of_irq_to_resource(np, 0, &r[1]);
33601f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
33701f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	memset(&pdata, 0, sizeof(pdata));
33801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
3391791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	pdata.freq_m = 8;	/* default */
34001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	prop = of_get_property(np, "freq_m", NULL);
34101f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (!prop)
34201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		return -ENODEV;
34301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	pdata.freq_m = *prop;
34401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
3451791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	pdata.freq_m = 3;	/* default */
34601f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	prop = of_get_property(np, "freq_n", NULL);
34701f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (!prop)
34801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		return -ENODEV;
34901f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	pdata.freq_n = *prop;
35001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
3511791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	pdata.timeout = 1000;				/* default: 1 second */
35201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
35301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
35401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (!pdev)
35501f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		return -ENOMEM;
35601f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
35701f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	err = platform_device_add_resources(pdev, r, 2);
35801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (err)
35901f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		goto error;
36001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
36101f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
36201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (err)
36301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		goto error;
36401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
36501f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	err = platform_device_add(pdev);
36601f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	if (err)
36701f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth		goto error;
36801f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
36901f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	return 0;
37001f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
37101f0e78e15c52af480c867af5bd406afec80d9ccDale Farnswortherror:
37201f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	platform_device_put(pdev);
37301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth	return err;
37401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth}
37501f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
3767e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth/*
3777e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth * Create mv64x60_wdt platform devices
3787e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth */
3797e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworthstatic int __init mv64x60_wdt_device_setup(struct device_node *np, int id)
3807e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth{
3817e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	struct resource r;
3827e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	struct platform_device *pdev;
3837e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	struct mv64x60_wdt_pdata pdata;
3847e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	const unsigned int *prop;
3857e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	int err;
3867e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
3877e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	err = of_address_to_resource(np, 0, &r);
3887e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (err)
3897e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		return err;
3907e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
3917e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	memset(&pdata, 0, sizeof(pdata));
3927e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
3931791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	pdata.timeout = 10;			/* Default: 10 seconds */
3947e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
3957e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	np = of_get_parent(np);
3967e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (!np)
3977e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		return -ENODEV;
3987e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
3997e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	prop = of_get_property(np, "clock-frequency", NULL);
4007e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	of_node_put(np);
4017e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (!prop)
4027e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		return -ENODEV;
4037e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	pdata.bus_clk = *prop / 1000000; /* wdt driver wants freq in MHz */
4047e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4057e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	pdev = platform_device_alloc(MV64x60_WDT_NAME, id);
4067e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (!pdev)
4077e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		return -ENOMEM;
4087e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4097e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	err = platform_device_add_resources(pdev, &r, 1);
4107e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (err)
4117e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		goto error;
4127e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4137e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
4147e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (err)
4157e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		goto error;
4167e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4177e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	err = platform_device_add(pdev);
4187e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (err)
4197e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		goto error;
4207e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4217e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	return 0;
4227e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
4237e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnswortherror:
4247e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	platform_device_put(pdev);
4257e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	return err;
4267e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth}
4277e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
42852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworthstatic int __init mv64x60_device_setup(void)
42952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth{
430a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	struct device_node *np, *np2;
431a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	struct platform_device *pdev;
432a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	int id, id2;
43352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	int err;
43452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
43526cb7d8bbddc8338904b8810b860ccf052c761faCyrill Gorcunov	id = 0;
436a1810b44c2d52392cd63e17fc208783cf6be6215Mark A. Greer	for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc")
43726cb7d8bbddc8338904b8810b860ccf052c761faCyrill Gorcunov		if ((err = mv64x60_mpsc_device_setup(np, id++)))
43852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth			goto error;
43952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
44026cb7d8bbddc8338904b8810b860ccf052c761faCyrill Gorcunov	id = 0;
441a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	id2 = 0;
442a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	for_each_compatible_node(np, NULL, "marvell,mv64360-eth-group") {
443a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		pdev = mv64x60_eth_register_shared_pdev(np, id++);
444a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		if (IS_ERR(pdev)) {
445a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth			err = PTR_ERR(pdev);
446649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth			goto error;
447a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		}
448a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		for_each_child_of_node(np, np2) {
449a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth			if (!of_device_is_compatible(np2,
450a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth					"marvell,mv64360-eth"))
451a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth				continue;
452a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth			err = mv64x60_eth_device_setup(np2, id2++, pdev);
453a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth			if (err) {
454a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth				of_node_put(np2);
455a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth				goto error;
456a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth			}
457a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth		}
458a0916bd64a0e6636f0161480e04057c89e90c5daDale Farnsworth	}
459649c8e0289eeee2ab3d4c6c6e062df24dd602233Dale Farnsworth
46026cb7d8bbddc8338904b8810b860ccf052c761faCyrill Gorcunov	id = 0;
461a1810b44c2d52392cd63e17fc208783cf6be6215Mark A. Greer	for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c")
46226cb7d8bbddc8338904b8810b860ccf052c761faCyrill Gorcunov		if ((err = mv64x60_i2c_device_setup(np, id++)))
46301f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth			goto error;
46401f0e78e15c52af480c867af5bd406afec80d9ccDale Farnsworth
4657e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	/* support up to one watchdog timer */
466a1810b44c2d52392cd63e17fc208783cf6be6215Mark A. Greer	np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt");
4677e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	if (np) {
4687e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		if ((err = mv64x60_wdt_device_setup(np, id)))
4697e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth			goto error;
4707e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth		of_node_put(np);
4717e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth	}
4727e07a15913e2e1fd99fb77c4c848437bd99a8d5fDale Farnsworth
47352d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return 0;
47452d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth
47552d3aff903171af13b56c5a4d6fb828461406c65Dale Farnswortherror:
47652d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	of_node_put(np);
47752d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth	return err;
47852d3aff903171af13b56c5a4d6fb828461406c65Dale Farnsworth}
47952d3aff903171af13b56c5a4d6fb828461406c65Dale Farnswortharch_initcall(mv64x60_device_setup);
480542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
481542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greerstatic int __init mv64x60_add_mpsc_console(void)
482542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer{
483542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	struct device_node *np = NULL;
484542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	const char *prop;
485542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
486542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	prop = of_get_property(of_chosen, "linux,stdout-path", NULL);
487542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	if (prop == NULL)
488542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer		goto not_mpsc;
489542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
490542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	np = of_find_node_by_path(prop);
491542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	if (!np)
492542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer		goto not_mpsc;
493542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
494a1810b44c2d52392cd63e17fc208783cf6be6215Mark A. Greer	if (!of_device_is_compatible(np, "marvell,mv64360-mpsc"))
495542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer		goto not_mpsc;
496542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
4971791f91bc794b7efc90719268146f582b9f29eadMark A. Greer	prop = of_get_property(np, "cell-index", NULL);
498542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	if (!prop)
499542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer		goto not_mpsc;
500542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
501542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	add_preferred_console("ttyMM", *(int *)prop, NULL);
502542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer
503542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greernot_mpsc:
504542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer	return 0;
505542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greer}
506542c98c06712fdbbbfe6b9e92a8d0023cf45102aMark A. Greerconsole_initcall(mv64x60_add_mpsc_console);
507