diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2018-02-16 09:47:26 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-02-16 09:47:26 -0500 |
commit | 6dee6ae9d62642e81def4d461d71f13a6496ab59 (patch) | |
tree | 6c75d416c427a59f190e197ad83fe59b7bebf656 /drivers/fpga/fpga-bridge.c | |
parent | 1beaeacdc88b537703d04d5536235d0bbb36db93 (diff) | |
parent | 0b24a0bbe2147815d982d9335c41bb10c04f40bc (diff) |
Merge tag 'irqchip-4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent
Pull irqchip updates for 4.16-rc2 from Marc Zyngier
- A MIPS GIC fix for spurious, masked interrupts
- A fix for a subtle IPI bug in GICv3
- Do not probe GICv3 ITSs that are marked as disabled
- Multi-MSI support for GICv2m
- Various cleanups
Diffstat (limited to 'drivers/fpga/fpga-bridge.c')
-rw-r--r-- | drivers/fpga/fpga-bridge.c | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 9651aa56244a..31bd2c59c305 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * FPGA Bridge Framework Driver | 2 | * FPGA Bridge Framework Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. | 4 | * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. |
5 | * Copyright (C) 2017 Intel Corporation | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 8 | * under the terms and conditions of the GNU General Public License, |
@@ -70,32 +71,13 @@ int fpga_bridge_disable(struct fpga_bridge *bridge) | |||
70 | } | 71 | } |
71 | EXPORT_SYMBOL_GPL(fpga_bridge_disable); | 72 | EXPORT_SYMBOL_GPL(fpga_bridge_disable); |
72 | 73 | ||
73 | /** | 74 | static struct fpga_bridge *__fpga_bridge_get(struct device *dev, |
74 | * of_fpga_bridge_get - get an exclusive reference to a fpga bridge | 75 | struct fpga_image_info *info) |
75 | * | ||
76 | * @np: node pointer of a FPGA bridge | ||
77 | * @info: fpga image specific information | ||
78 | * | ||
79 | * Return fpga_bridge struct if successful. | ||
80 | * Return -EBUSY if someone already has a reference to the bridge. | ||
81 | * Return -ENODEV if @np is not a FPGA Bridge. | ||
82 | */ | ||
83 | struct fpga_bridge *of_fpga_bridge_get(struct device_node *np, | ||
84 | struct fpga_image_info *info) | ||
85 | |||
86 | { | 76 | { |
87 | struct device *dev; | ||
88 | struct fpga_bridge *bridge; | 77 | struct fpga_bridge *bridge; |
89 | int ret = -ENODEV; | 78 | int ret = -ENODEV; |
90 | 79 | ||
91 | dev = class_find_device(fpga_bridge_class, NULL, np, | ||
92 | fpga_bridge_of_node_match); | ||
93 | if (!dev) | ||
94 | goto err_dev; | ||
95 | |||
96 | bridge = to_fpga_bridge(dev); | 80 | bridge = to_fpga_bridge(dev); |
97 | if (!bridge) | ||
98 | goto err_dev; | ||
99 | 81 | ||
100 | bridge->info = info; | 82 | bridge->info = info; |
101 | 83 | ||
@@ -117,8 +99,58 @@ err_dev: | |||
117 | put_device(dev); | 99 | put_device(dev); |
118 | return ERR_PTR(ret); | 100 | return ERR_PTR(ret); |
119 | } | 101 | } |
102 | |||
103 | /** | ||
104 | * of_fpga_bridge_get - get an exclusive reference to a fpga bridge | ||
105 | * | ||
106 | * @np: node pointer of a FPGA bridge | ||
107 | * @info: fpga image specific information | ||
108 | * | ||
109 | * Return fpga_bridge struct if successful. | ||
110 | * Return -EBUSY if someone already has a reference to the bridge. | ||
111 | * Return -ENODEV if @np is not a FPGA Bridge. | ||
112 | */ | ||
113 | struct fpga_bridge *of_fpga_bridge_get(struct device_node *np, | ||
114 | struct fpga_image_info *info) | ||
115 | { | ||
116 | struct device *dev; | ||
117 | |||
118 | dev = class_find_device(fpga_bridge_class, NULL, np, | ||
119 | fpga_bridge_of_node_match); | ||
120 | if (!dev) | ||
121 | return ERR_PTR(-ENODEV); | ||
122 | |||
123 | return __fpga_bridge_get(dev, info); | ||
124 | } | ||
120 | EXPORT_SYMBOL_GPL(of_fpga_bridge_get); | 125 | EXPORT_SYMBOL_GPL(of_fpga_bridge_get); |
121 | 126 | ||
127 | static int fpga_bridge_dev_match(struct device *dev, const void *data) | ||
128 | { | ||
129 | return dev->parent == data; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * fpga_bridge_get - get an exclusive reference to a fpga bridge | ||
134 | * @dev: parent device that fpga bridge was registered with | ||
135 | * | ||
136 | * Given a device, get an exclusive reference to a fpga bridge. | ||
137 | * | ||
138 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
139 | */ | ||
140 | struct fpga_bridge *fpga_bridge_get(struct device *dev, | ||
141 | struct fpga_image_info *info) | ||
142 | { | ||
143 | struct device *bridge_dev; | ||
144 | |||
145 | bridge_dev = class_find_device(fpga_bridge_class, NULL, dev, | ||
146 | fpga_bridge_dev_match); | ||
147 | if (!bridge_dev) | ||
148 | return ERR_PTR(-ENODEV); | ||
149 | |||
150 | return __fpga_bridge_get(bridge_dev, info); | ||
151 | } | ||
152 | EXPORT_SYMBOL_GPL(fpga_bridge_get); | ||
153 | |||
122 | /** | 154 | /** |
123 | * fpga_bridge_put - release a reference to a bridge | 155 | * fpga_bridge_put - release a reference to a bridge |
124 | * | 156 | * |
@@ -206,7 +238,7 @@ void fpga_bridges_put(struct list_head *bridge_list) | |||
206 | EXPORT_SYMBOL_GPL(fpga_bridges_put); | 238 | EXPORT_SYMBOL_GPL(fpga_bridges_put); |
207 | 239 | ||
208 | /** | 240 | /** |
209 | * fpga_bridges_get_to_list - get a bridge, add it to a list | 241 | * of_fpga_bridge_get_to_list - get a bridge, add it to a list |
210 | * | 242 | * |
211 | * @np: node pointer of a FPGA bridge | 243 | * @np: node pointer of a FPGA bridge |
212 | * @info: fpga image specific information | 244 | * @info: fpga image specific information |
@@ -216,14 +248,44 @@ EXPORT_SYMBOL_GPL(fpga_bridges_put); | |||
216 | * | 248 | * |
217 | * Return 0 for success, error code from of_fpga_bridge_get() othewise. | 249 | * Return 0 for success, error code from of_fpga_bridge_get() othewise. |
218 | */ | 250 | */ |
219 | int fpga_bridge_get_to_list(struct device_node *np, | 251 | int of_fpga_bridge_get_to_list(struct device_node *np, |
252 | struct fpga_image_info *info, | ||
253 | struct list_head *bridge_list) | ||
254 | { | ||
255 | struct fpga_bridge *bridge; | ||
256 | unsigned long flags; | ||
257 | |||
258 | bridge = of_fpga_bridge_get(np, info); | ||
259 | if (IS_ERR(bridge)) | ||
260 | return PTR_ERR(bridge); | ||
261 | |||
262 | spin_lock_irqsave(&bridge_list_lock, flags); | ||
263 | list_add(&bridge->node, bridge_list); | ||
264 | spin_unlock_irqrestore(&bridge_list_lock, flags); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | EXPORT_SYMBOL_GPL(of_fpga_bridge_get_to_list); | ||
269 | |||
270 | /** | ||
271 | * fpga_bridge_get_to_list - given device, get a bridge, add it to a list | ||
272 | * | ||
273 | * @dev: FPGA bridge device | ||
274 | * @info: fpga image specific information | ||
275 | * @bridge_list: list of FPGA bridges | ||
276 | * | ||
277 | * Get an exclusive reference to the bridge and and it to the list. | ||
278 | * | ||
279 | * Return 0 for success, error code from fpga_bridge_get() othewise. | ||
280 | */ | ||
281 | int fpga_bridge_get_to_list(struct device *dev, | ||
220 | struct fpga_image_info *info, | 282 | struct fpga_image_info *info, |
221 | struct list_head *bridge_list) | 283 | struct list_head *bridge_list) |
222 | { | 284 | { |
223 | struct fpga_bridge *bridge; | 285 | struct fpga_bridge *bridge; |
224 | unsigned long flags; | 286 | unsigned long flags; |
225 | 287 | ||
226 | bridge = of_fpga_bridge_get(np, info); | 288 | bridge = fpga_bridge_get(dev, info); |
227 | if (IS_ERR(bridge)) | 289 | if (IS_ERR(bridge)) |
228 | return PTR_ERR(bridge); | 290 | return PTR_ERR(bridge); |
229 | 291 | ||
@@ -303,6 +365,7 @@ int fpga_bridge_register(struct device *dev, const char *name, | |||
303 | bridge->priv = priv; | 365 | bridge->priv = priv; |
304 | 366 | ||
305 | device_initialize(&bridge->dev); | 367 | device_initialize(&bridge->dev); |
368 | bridge->dev.groups = br_ops->groups; | ||
306 | bridge->dev.class = fpga_bridge_class; | 369 | bridge->dev.class = fpga_bridge_class; |
307 | bridge->dev.parent = dev; | 370 | bridge->dev.parent = dev; |
308 | bridge->dev.of_node = dev->of_node; | 371 | bridge->dev.of_node = dev->of_node; |
@@ -381,7 +444,7 @@ static void __exit fpga_bridge_dev_exit(void) | |||
381 | } | 444 | } |
382 | 445 | ||
383 | MODULE_DESCRIPTION("FPGA Bridge Driver"); | 446 | MODULE_DESCRIPTION("FPGA Bridge Driver"); |
384 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | 447 | MODULE_AUTHOR("Alan Tull <atull@kernel.org>"); |
385 | MODULE_LICENSE("GPL v2"); | 448 | MODULE_LICENSE("GPL v2"); |
386 | 449 | ||
387 | subsys_initcall(fpga_bridge_dev_init); | 450 | subsys_initcall(fpga_bridge_dev_init); |