aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio/platform
diff options
context:
space:
mode:
authorEric Auger <eric.auger@linaro.org>2015-11-03 13:12:17 -0500
committerAlex Williamson <alex.williamson@redhat.com>2015-11-03 14:55:03 -0500
commite9e0506ee60dd79714c59457f4301c602786defc (patch)
tree2f155d28505742ce7af5bd843d4e71c7ca9e4eba /drivers/vfio/platform
parent0628c4dfd3a781c09aed983cc79b3c43c5c568bd (diff)
vfio: platform: use list of registered reset function
Remove the static lookup table and use the dynamic list of registered reset functions instead. Also load the reset module through its alias. The reset struct module pointer is stored in vfio_platform_device. We also remove the useless struct device pointer parameter in vfio_platform_get_reset. This patch fixes the issue related to the usage of __symbol_get, which besides from being moot, prevented compilation with CONFIG_MODULES disabled. Also usage of MODULE_ALIAS makes possible to add a new reset module without needing to update the framework. This was suggested by Arnd. Signed-off-by: Eric Auger <eric.auger@linaro.org> Reported-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/platform')
-rw-r--r--drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c1
-rw-r--r--drivers/vfio/platform/vfio_platform_common.c52
-rw-r--r--drivers/vfio/platform/vfio_platform_private.h7
3 files changed, 30 insertions, 30 deletions
diff --git a/drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c b/drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
index 80718f20d5d3..640f5d87d422 100644
--- a/drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
+++ b/drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
@@ -76,7 +76,6 @@ int vfio_platform_calxedaxgmac_reset(struct vfio_platform_device *vdev)
76 76
77 return 0; 77 return 0;
78} 78}
79EXPORT_SYMBOL_GPL(vfio_platform_calxedaxgmac_reset);
80 79
81module_vfio_reset_handler("calxeda,hb-xgmac", vfio_platform_calxedaxgmac_reset); 80module_vfio_reset_handler("calxeda,hb-xgmac", vfio_platform_calxedaxgmac_reset);
82 81
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index d8df8a4318da..ac0229622c1f 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -30,37 +30,43 @@
30static LIST_HEAD(reset_list); 30static LIST_HEAD(reset_list);
31static DEFINE_MUTEX(driver_lock); 31static DEFINE_MUTEX(driver_lock);
32 32
33static const struct vfio_platform_reset_combo reset_lookup_table[] = { 33static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char *compat,
34 { 34 struct module **module)
35 .compat = "calxeda,hb-xgmac",
36 .reset_function_name = "vfio_platform_calxedaxgmac_reset",
37 .module_name = "vfio-platform-calxedaxgmac",
38 },
39};
40
41static void vfio_platform_get_reset(struct vfio_platform_device *vdev,
42 struct device *dev)
43{ 35{
44 int (*reset)(struct vfio_platform_device *); 36 struct vfio_platform_reset_node *iter;
45 int i; 37 vfio_platform_reset_fn_t reset_fn = NULL;
46 38
47 for (i = 0 ; i < ARRAY_SIZE(reset_lookup_table); i++) { 39 mutex_lock(&driver_lock);
48 if (!strcmp(reset_lookup_table[i].compat, vdev->compat)) { 40 list_for_each_entry(iter, &reset_list, link) {
49 request_module(reset_lookup_table[i].module_name); 41 if (!strcmp(iter->compat, compat) &&
50 reset = __symbol_get( 42 try_module_get(iter->owner)) {
51 reset_lookup_table[i].reset_function_name); 43 *module = iter->owner;
52 if (reset) { 44 reset_fn = iter->reset;
53 vdev->reset = reset; 45 break;
54 return;
55 }
56 } 46 }
57 } 47 }
48 mutex_unlock(&driver_lock);
49 return reset_fn;
50}
51
52static void vfio_platform_get_reset(struct vfio_platform_device *vdev)
53{
54 char modname[256];
55
56 vdev->reset = vfio_platform_lookup_reset(vdev->compat,
57 &vdev->reset_module);
58 if (!vdev->reset) {
59 snprintf(modname, 256, "vfio-reset:%s", vdev->compat);
60 request_module(modname);
61 vdev->reset = vfio_platform_lookup_reset(vdev->compat,
62 &vdev->reset_module);
63 }
58} 64}
59 65
60static void vfio_platform_put_reset(struct vfio_platform_device *vdev) 66static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
61{ 67{
62 if (vdev->reset) 68 if (vdev->reset)
63 symbol_put_addr(vdev->reset); 69 module_put(vdev->reset_module);
64} 70}
65 71
66static int vfio_platform_regions_init(struct vfio_platform_device *vdev) 72static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
@@ -557,7 +563,7 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev,
557 return ret; 563 return ret;
558 } 564 }
559 565
560 vfio_platform_get_reset(vdev, dev); 566 vfio_platform_get_reset(vdev);
561 567
562 mutex_init(&vdev->igate); 568 mutex_init(&vdev->igate);
563 569
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 415310f62b06..d1b0668fe394 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -58,6 +58,7 @@ struct vfio_platform_device {
58 struct mutex igate; 58 struct mutex igate;
59 struct module *parent_module; 59 struct module *parent_module;
60 const char *compat; 60 const char *compat;
61 struct module *reset_module;
61 62
62 /* 63 /*
63 * These fields should be filled by the bus specific binder 64 * These fields should be filled by the bus specific binder
@@ -81,12 +82,6 @@ struct vfio_platform_reset_node {
81 vfio_platform_reset_fn_t reset; 82 vfio_platform_reset_fn_t reset;
82}; 83};
83 84
84struct vfio_platform_reset_combo {
85 const char *compat;
86 const char *reset_function_name;
87 const char *module_name;
88};
89
90extern int vfio_platform_probe_common(struct vfio_platform_device *vdev, 85extern int vfio_platform_probe_common(struct vfio_platform_device *vdev,
91 struct device *dev); 86 struct device *dev);
92extern struct vfio_platform_device *vfio_platform_remove_common 87extern struct vfio_platform_device *vfio_platform_remove_common