From patchwork Mon Aug 22 18:22:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Cousson X-Patchwork-Id: 1086102 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7MIMglG005437 for ; Mon, 22 Aug 2011 18:23:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752655Ab1HVSXx (ORCPT ); Mon, 22 Aug 2011 14:23:53 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:55436 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751174Ab1HVSXw (ORCPT ); Mon, 22 Aug 2011 14:23:52 -0400 Received: from dlep34.itg.ti.com ([157.170.170.115]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id p7MINmTG025112 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 22 Aug 2011 13:23:48 -0500 Received: from dlep26.itg.ti.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep34.itg.ti.com (8.13.7/8.13.8) with ESMTP id p7MINmYD029003; Mon, 22 Aug 2011 13:23:48 -0500 (CDT) Received: from dlee73.ent.ti.com (localhost [127.0.0.1]) by dlep26.itg.ti.com (8.13.8/8.13.8) with ESMTP id p7MINkq5002115; Mon, 22 Aug 2011 13:23:48 -0500 (CDT) Received: from dlelxv22.itg.ti.com (172.17.1.197) by DLEE73.ent.ti.com (157.170.170.88) with Microsoft SMTP Server id 8.3.106.1; Mon, 22 Aug 2011 13:22:35 -0500 Received: from localhost.localdomain (lncpu04.tif.ti.com [137.167.102.15]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id p7MIMVud016901; Mon, 22 Aug 2011 13:22:33 -0500 From: Benoit Cousson To: CC: , , , , Benoit Cousson Subject: [RFC PATCH 1/3] OMAP: omap_device: Add omap_device_[alloc|delete] for DT integration Date: Mon, 22 Aug 2011 20:22:21 +0200 Message-ID: <1314037343-19783-2-git-send-email-b-cousson@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1314037343-19783-1-git-send-email-b-cousson@ti.com> References: <1314037343-19783-1-git-send-email-b-cousson@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 22 Aug 2011 18:23:53 +0000 (UTC) Split the omap_device_build_ss into two smaller functions that will allow to populate a platform_device already alocated by device-tree. The functionality of the omap_device_build_ss is still the same, but the omap_device_alloc will be usable with devices already built by device-tree. Signed-off-by: Benoit Cousson Cc: Kevin Hilman --- arch/arm/plat-omap/omap_device.c | 168 ++++++++++++++++++++++++++------------ 1 files changed, 114 insertions(+), 54 deletions(-) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f2149be..752d72a 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -96,6 +96,11 @@ static int omap_device_register(struct platform_device *pdev); static int omap_early_device_register(struct platform_device *pdev); +static struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt); + static struct omap_device_pm_latency omap_default_latency[] = { { @@ -397,6 +402,105 @@ static int omap_device_fill_resources(struct omap_device *od, } /** + * omap_device_alloc - allocate an omap_device + * @pdev: platform_device that will be represent this omap_device + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * @pm_lats: pointer to a omap_device_pm_latency array for this device + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats + * + * Convenience function for allocating an omap_device structure and filling + * hwmods, resources and pm_latency attributes. + * + * Returns an struct omap_device pointer or ERR_PTR() on error; + */ +static struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt) +{ + int ret = -ENOMEM; + struct omap_device *od; + struct resource *res = NULL; + int i, res_count; + struct omap_hwmod **hwmods; + + od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); + if (!od) { + ret = -ENOMEM; + goto oda_exit1; + } + od->hwmods_cnt = oh_cnt; + + hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, + GFP_KERNEL); + if (!hwmods) + goto oda_exit2; + + memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt); + od->hwmods = hwmods; + od->pdev = pdev; + + if (pdev->num_resources && pdev->resource) + dev_warn(&pdev->dev, "%s(): ressources already allocated %d\n", + __func__, pdev->num_resources); + /* + * HACK: Idealy the resources from DT should match, and hwmod + * should just add the missing ones. Since the name is not + * properly populated by DT, stick to hwmod resources only. + */ + res_count = omap_device_count_resources(od); + if (res_count > 0) { + dev_dbg(&pdev->dev, "%s(): ressources allocated from hwmod %d\n", + __func__, res_count); + res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); + if (!res) + goto oda_exit3; + + omap_device_fill_resources(od, res); + + ret = platform_device_add_resources(pdev, res, res_count); + kfree(res); + + if (ret) + goto oda_exit3; + } + + if (pm_lats) { + od->pm_lats = pm_lats; + od->pm_lats_cnt = pm_lats_cnt; + } else { + od->pm_lats = omap_default_latency; + od->pm_lats_cnt = ARRAY_SIZE(omap_default_latency); + } + + pdev->archdata.od = od; + + for (i = 0; i < oh_cnt; i++) { + hwmods[i]->od = od; + _add_hwmod_clocks_clkdev(od, hwmods[i]); + } + + return od; + +oda_exit3: + kfree(hwmods); +oda_exit2: + kfree(od); +oda_exit1: + dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); + + return ERR_PTR(ret); +} + +void omap_device_delete(struct omap_device *od) +{ + kfree(od->hwmods); + kfree(od); +} + +/** * omap_device_build - build and register an omap_device with one omap_hwmod * @pdev_name: name of the platform_device driver to use * @pdev_id: this platform_device's connection ID @@ -455,9 +559,6 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, int ret = -ENOMEM; struct platform_device *pdev; struct omap_device *od; - struct resource *res = NULL; - int i, res_count; - struct omap_hwmod **hwmods; if (!ohs || oh_cnt == 0 || !pdev_name) return ERR_PTR(-EINVAL); @@ -471,72 +572,31 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, goto odbs_exit; } - pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name, - oh_cnt); + /* Set the dev_name early to allow dev_xxx in omap_device_alloc */ + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); - od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); - if (!od) { - ret = -ENOMEM; + od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); + if (!od) goto odbs_exit1; - } - od->hwmods_cnt = oh_cnt; - - hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, - GFP_KERNEL); - if (!hwmods) - goto odbs_exit2; - - memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt); - od->hwmods = hwmods; - od->pdev = pdev; - - res_count = omap_device_count_resources(od); - if (res_count > 0) { - res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); - if (!res) - goto odbs_exit3; - - omap_device_fill_resources(od, res); - - ret = platform_device_add_resources(pdev, res, res_count); - kfree(res); - - if (ret) - goto odbs_exit3; - } ret = platform_device_add_data(pdev, pdata, pdata_len); if (ret) - goto odbs_exit3; - - pdev->archdata.od = od; + goto odbs_exit2; if (is_early_device) ret = omap_early_device_register(pdev); else ret = omap_device_register(pdev); if (ret) - goto odbs_exit3; - - if (pm_lats) { - od->pm_lats = pm_lats; - od->pm_lats_cnt = pm_lats_cnt; - } else { - od->pm_lats = omap_default_latency; - od->pm_lats_cnt = ARRAY_SIZE(omap_default_latency); - } - - for (i = 0; i < oh_cnt; i++) { - hwmods[i]->od = od; - _add_hwmod_clocks_clkdev(od, hwmods[i]); - } + goto odbs_exit2; return pdev; -odbs_exit3: - kfree(hwmods); odbs_exit2: - kfree(od); + omap_device_delete(od); odbs_exit1: platform_device_put(pdev); odbs_exit: