aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 21:34:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 21:34:04 -0400
commit29b88e23a9212136d39b0161a39afe587d0170a5 (patch)
tree48d9f857b137222e35f853004973e12a515314f5 /drivers/base/platform.c
parent2521129a6d2fd8a81f99cf95055eddea3df914ff (diff)
parent4e3a25b0274b8474f5ad46215a270785dd18265e (diff)
Merge tag 'driver-core-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here's the big driver-core pull request for 3.17-rc1. Largest thing in here is the dma-buf rework and fence code, that touched many different subsystems so it was agreed it should go through this tree to handle merge issues. There's also some firmware loading updates, as well as tests added, and a few other tiny changes, the changelog has the details. All have been in linux-next for a long time" * tag 'driver-core-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (32 commits) ARM: imx: Remove references to platform_bus in mxc code firmware loader: Fix _request_firmware_load() return val for fw load abort platform: Remove most references to platform_bus device test: add firmware_class loader test doc: fix minor typos in firmware_class README staging: android: Cleanup style issues Documentation: devres: Sort managed interfaces Documentation: devres: Add devm_kmalloc() et al fs: debugfs: remove trailing whitespace kernfs: kernel-doc warning fix debugfs: Fix corrupted loop in debugfs_remove_recursive stable_kernel_rules: Add pointer to netdev-FAQ for network patches driver core: platform: add device binding path 'driver_override' driver core/platform: remove unused implicit padding in platform_object firmware loader: inform direct failure when udev loader is disabled firmware: replace ALIGN(PAGE_SIZE) by PAGE_ALIGN firmware: read firmware size using i_size_read() firmware loader: allow disabling of udev as firmware loader reservation: add suppport for read-only access using rcu reservation: update api and add some helpers ... Conflicts: drivers/base/platform.c
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 00f2208949d1..ab4f4ce02722 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -24,6 +24,7 @@
24#include <linux/idr.h> 24#include <linux/idr.h>
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/clk/clk-conf.h> 26#include <linux/clk/clk-conf.h>
27#include <linux/limits.h>
27 28
28#include "base.h" 29#include "base.h"
29#include "power/power.h" 30#include "power/power.h"
@@ -176,7 +177,7 @@ EXPORT_SYMBOL_GPL(platform_add_devices);
176 177
177struct platform_object { 178struct platform_object {
178 struct platform_device pdev; 179 struct platform_device pdev;
179 char name[1]; 180 char name[];
180}; 181};
181 182
182/** 183/**
@@ -202,6 +203,7 @@ static void platform_device_release(struct device *dev)
202 kfree(pa->pdev.dev.platform_data); 203 kfree(pa->pdev.dev.platform_data);
203 kfree(pa->pdev.mfd_cell); 204 kfree(pa->pdev.mfd_cell);
204 kfree(pa->pdev.resource); 205 kfree(pa->pdev.resource);
206 kfree(pa->pdev.driver_override);
205 kfree(pa); 207 kfree(pa);
206} 208}
207 209
@@ -217,7 +219,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)
217{ 219{
218 struct platform_object *pa; 220 struct platform_object *pa;
219 221
220 pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL); 222 pa = kzalloc(sizeof(*pa) + strlen(name) + 1, GFP_KERNEL);
221 if (pa) { 223 if (pa) {
222 strcpy(pa->name, name); 224 strcpy(pa->name, name);
223 pa->pdev.name = pa->name; 225 pa->pdev.name = pa->name;
@@ -713,8 +715,49 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
713} 715}
714static DEVICE_ATTR_RO(modalias); 716static DEVICE_ATTR_RO(modalias);
715 717
718static ssize_t driver_override_store(struct device *dev,
719 struct device_attribute *attr,
720 const char *buf, size_t count)
721{
722 struct platform_device *pdev = to_platform_device(dev);
723 char *driver_override, *old = pdev->driver_override, *cp;
724
725 if (count > PATH_MAX)
726 return -EINVAL;
727
728 driver_override = kstrndup(buf, count, GFP_KERNEL);
729 if (!driver_override)
730 return -ENOMEM;
731
732 cp = strchr(driver_override, '\n');
733 if (cp)
734 *cp = '\0';
735
736 if (strlen(driver_override)) {
737 pdev->driver_override = driver_override;
738 } else {
739 kfree(driver_override);
740 pdev->driver_override = NULL;
741 }
742
743 kfree(old);
744
745 return count;
746}
747
748static ssize_t driver_override_show(struct device *dev,
749 struct device_attribute *attr, char *buf)
750{
751 struct platform_device *pdev = to_platform_device(dev);
752
753 return sprintf(buf, "%s\n", pdev->driver_override);
754}
755static DEVICE_ATTR_RW(driver_override);
756
757
716static struct attribute *platform_dev_attrs[] = { 758static struct attribute *platform_dev_attrs[] = {
717 &dev_attr_modalias.attr, 759 &dev_attr_modalias.attr,
760 &dev_attr_driver_override.attr,
718 NULL, 761 NULL,
719}; 762};
720ATTRIBUTE_GROUPS(platform_dev); 763ATTRIBUTE_GROUPS(platform_dev);
@@ -770,6 +813,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)
770 struct platform_device *pdev = to_platform_device(dev); 813 struct platform_device *pdev = to_platform_device(dev);
771 struct platform_driver *pdrv = to_platform_driver(drv); 814 struct platform_driver *pdrv = to_platform_driver(drv);
772 815
816 /* When driver_override is set, only bind to the matching driver */
817 if (pdev->driver_override)
818 return !strcmp(pdev->driver_override, drv->name);
819
773 /* Attempt an OF style match first */ 820 /* Attempt an OF style match first */
774 if (of_driver_match_device(dev, drv)) 821 if (of_driver_match_device(dev, drv))
775 return 1; 822 return 1;