diff options
Diffstat (limited to 'arch/arm/mach-omap2/display.c')
| -rw-r--r-- | arch/arm/mach-omap2/display.c | 101 | 
1 files changed, 87 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 07232fd7ab1..5369bf13652 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -185,13 +185,71 @@ static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)  	return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput);  } +static struct platform_device *create_dss_pdev(const char *pdev_name, +		int pdev_id, const char *oh_name, void *pdata, int pdata_len, +		struct platform_device *parent) +{ +	struct platform_device *pdev; +	struct omap_device *od; +	struct omap_hwmod *ohs[1]; +	struct omap_hwmod *oh; +	int r; + +	oh = omap_hwmod_lookup(oh_name); +	if (!oh) { +		pr_err("Could not look up %s\n", oh_name); +		r = -ENODEV; +		goto err; +	} + +	pdev = platform_device_alloc(pdev_name, pdev_id); +	if (!pdev) { +		pr_err("Could not create pdev for %s\n", pdev_name); +		r = -ENOMEM; +		goto err; +	} + +	if (parent != NULL) +		pdev->dev.parent = &parent->dev; + +	if (pdev->id != -1) +		dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); +	else +		dev_set_name(&pdev->dev, "%s", pdev->name); + +	ohs[0] = oh; +	od = omap_device_alloc(pdev, ohs, 1, NULL, 0); +	if (!od) { +		pr_err("Could not alloc omap_device for %s\n", pdev_name); +		r = -ENOMEM; +		goto err; +	} + +	r = platform_device_add_data(pdev, pdata, pdata_len); +	if (r) { +		pr_err("Could not set pdata for %s\n", pdev_name); +		goto err; +	} + +	r = omap_device_register(pdev); +	if (r) { +		pr_err("Could not register omap_device for %s\n", pdev_name); +		goto err; +	} + +	return pdev; + +err: +	return ERR_PTR(r); +} +  int __init omap_display_init(struct omap_dss_board_info *board_data)  {  	int r = 0; -	struct omap_hwmod *oh;  	struct platform_device *pdev;  	int i, oh_count;  	const struct omap_dss_hwmod_data *curr_dss_hwmod; +	struct platform_device *dss_pdev;  	/* create omapdss device */ @@ -221,22 +279,37 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)  		oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);  	} -	for (i = 0; i < oh_count; i++) { -		oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); -		if (!oh) { -			pr_err("Could not look up %s\n", -				curr_dss_hwmod[i].oh_name); -			return -ENODEV; -		} +	/* +	 * First create the pdev for dss_core, which is used as a parent device +	 * by the other dss pdevs. Note: dss_core has to be the first item in +	 * the hwmod list. +	 */ +	dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, +			curr_dss_hwmod[0].id, +			curr_dss_hwmod[0].oh_name, +			NULL, 0, +			NULL); -		pdev = omap_device_build(curr_dss_hwmod[i].dev_name, -				curr_dss_hwmod[i].id, oh, +	if (IS_ERR(dss_pdev)) { +		pr_err("Could not build omap_device for %s\n", +				curr_dss_hwmod[0].oh_name); + +		return PTR_ERR(dss_pdev); +	} + +	for (i = 1; i < oh_count; i++) { +		pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, +				curr_dss_hwmod[i].id, +				curr_dss_hwmod[i].oh_name,  				NULL, 0, -				NULL, 0, 0); +				dss_pdev); + +		if (IS_ERR(pdev)) { +			pr_err("Could not build omap_device for %s\n", +					curr_dss_hwmod[i].oh_name); -		if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", -				curr_dss_hwmod[i].oh_name)) -			return -ENODEV; +			return PTR_ERR(pdev); +		}  	}  	return 0;  |