Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932122AbaKSP3d (ORCPT ); Wed, 19 Nov 2014 10:29:33 -0500 Received: from mga02.intel.com ([134.134.136.20]:1978 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755821AbaKSP2l (ORCPT ); Wed, 19 Nov 2014 10:28:41 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,417,1413270000"; d="scan'208";a="639756217" From: Heikki Krogerus To: Kishon Vijay Abraham I Cc: Vivek Gautam , linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, andrew.kim@intel.com, Greg Kroah-Hartman Subject: [PATCHv5 6/7] base: platform: name the device already during allocation Date: Wed, 19 Nov 2014 17:28:22 +0200 Message-Id: <1416410903-162369-7-git-send-email-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.1.3 In-Reply-To: <1416410903-162369-1-git-send-email-heikki.krogerus@linux.intel.com> References: <1416410903-162369-1-git-send-email-heikki.krogerus@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The device name is usually required when assigning resources like clocks to platform devices. The problem is that the device name is not know before platform_device_add is called and that can be too late as the drivers may have already requested the resources when the function returns. By naming the device already in platform_device_alloc, the resources can be assigned before platform_device_add is called. This change allows different kinds of probe drivers to pass forward their resources to the actual driver. The first place where we need it is dwc3 controllers host glue code (drivers/usb/dwc3/host.c) to pass the phy's to xhci. Signed-off-by: Heikki Krogerus Cc: Greg Kroah-Hartman --- drivers/base/platform.c | 69 +++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cdb6c07..d2217f3 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -195,11 +195,41 @@ void platform_device_put(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(platform_device_put); +static int pdev_set_name(struct platform_device *pdev) +{ + int ret; + + switch (pdev->id) { + default: + return dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + case PLATFORM_DEVID_NONE: + return dev_set_name(&pdev->dev, "%s", pdev->name); + case PLATFORM_DEVID_AUTO: + /* + * Automatically allocated device ID. We mark it as such so + * that we remember it must be freed, and we append a suffix + * to avoid namespace collision with explicit IDs. + */ + ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); + if (ret < 0) + return ret; + pdev->id = ret; + pdev->id_auto = true; + return dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, + pdev->id); + } + + return 0; +} + static void platform_device_release(struct device *dev) { struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); + if (pa->pdev.id_auto) + ida_simple_remove(&platform_devid_ida, pa->pdev.id); + of_device_node_put(&pa->pdev.dev); kfree(pa->pdev.dev.platform_data); kfree(pa->pdev.mfd_cell); @@ -228,6 +258,10 @@ struct platform_device *platform_device_alloc(const char *name, int id) device_initialize(&pa->pdev.dev); pa->pdev.dev.release = platform_device_release; arch_setup_pdev_archdata(&pa->pdev); + if (pdev_set_name(&pa->pdev)) { + kfree(pa); + return NULL; + } } return pa ? &pa->pdev : NULL; @@ -308,28 +342,6 @@ int platform_device_add(struct platform_device *pdev) pdev->dev.bus = &platform_bus_type; - switch (pdev->id) { - default: - dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); - break; - case PLATFORM_DEVID_NONE: - dev_set_name(&pdev->dev, "%s", pdev->name); - break; - case PLATFORM_DEVID_AUTO: - /* - * Automatically allocated device ID. We mark it as such so - * that we remember it must be freed, and we append a suffix - * to avoid namespace collision with explicit IDs. - */ - ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); - if (ret < 0) - goto err_out; - pdev->id = ret; - pdev->id_auto = true; - dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id); - break; - } - for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; @@ -372,7 +384,6 @@ int platform_device_add(struct platform_device *pdev) release_resource(r); } - err_out: return ret; } EXPORT_SYMBOL_GPL(platform_device_add); @@ -392,11 +403,6 @@ void platform_device_del(struct platform_device *pdev) if (pdev) { device_del(&pdev->dev); - if (pdev->id_auto) { - ida_simple_remove(&platform_devid_ida, pdev->id); - pdev->id = PLATFORM_DEVID_AUTO; - } - for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; unsigned long type = resource_type(r); @@ -414,8 +420,15 @@ EXPORT_SYMBOL_GPL(platform_device_del); */ int platform_device_register(struct platform_device *pdev) { + int ret; + device_initialize(&pdev->dev); arch_setup_pdev_archdata(pdev); + + ret = pdev_set_name(pdev); + if (ret) + return ret; + return platform_device_add(pdev); } EXPORT_SYMBOL_GPL(platform_device_register); -- 2.1.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/