diff options
-rw-r--r-- | drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c | 1 | ||||
-rw-r--r-- | drivers/vfio/platform/vfio_platform_common.c | 52 | ||||
-rw-r--r-- | drivers/vfio/platform/vfio_platform_private.h | 7 |
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 | } |
79 | EXPORT_SYMBOL_GPL(vfio_platform_calxedaxgmac_reset); | ||
80 | 79 | ||
81 | module_vfio_reset_handler("calxeda,hb-xgmac", vfio_platform_calxedaxgmac_reset); | 80 | module_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 @@ | |||
30 | static LIST_HEAD(reset_list); | 30 | static LIST_HEAD(reset_list); |
31 | static DEFINE_MUTEX(driver_lock); | 31 | static DEFINE_MUTEX(driver_lock); |
32 | 32 | ||
33 | static const struct vfio_platform_reset_combo reset_lookup_table[] = { | 33 | static 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 | |||
41 | static 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 | |||
52 | static 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 | ||
60 | static void vfio_platform_put_reset(struct vfio_platform_device *vdev) | 66 | static 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 | ||
66 | static int vfio_platform_regions_init(struct vfio_platform_device *vdev) | 72 | static 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 | ||
84 | struct vfio_platform_reset_combo { | ||
85 | const char *compat; | ||
86 | const char *reset_function_name; | ||
87 | const char *module_name; | ||
88 | }; | ||
89 | |||
90 | extern int vfio_platform_probe_common(struct vfio_platform_device *vdev, | 85 | extern int vfio_platform_probe_common(struct vfio_platform_device *vdev, |
91 | struct device *dev); | 86 | struct device *dev); |
92 | extern struct vfio_platform_device *vfio_platform_remove_common | 87 | extern struct vfio_platform_device *vfio_platform_remove_common |