diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-01-14 18:33:23 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-01-14 18:33:23 -0500 |
commit | 3eb66e91a25497065c5322b1268cbc3953642227 (patch) | |
tree | 69f8e1312323ceeafc1a0fdc24d168e1617ffed4 /drivers/fpga/fpga-bridge.c | |
parent | 4add635b4e00dd7d6aad83a937afdf1957196da6 (diff) | |
parent | 8fe28cb58bcb235034b64cbbb7550a8a43fd88be (diff) |
Merge tag 'v4.20' into for-linus
Sync with mainline to get linux/overflow.h among other things.
Diffstat (limited to 'drivers/fpga/fpga-bridge.c')
-rw-r--r-- | drivers/fpga/fpga-bridge.c | 142 |
1 files changed, 102 insertions, 40 deletions
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 31bd2c59c305..80bd8f1b2aa6 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c | |||
@@ -1,20 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * FPGA Bridge Framework Driver | 3 | * FPGA Bridge Framework Driver |
3 | * | 4 | * |
4 | * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. | 5 | * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. |
5 | * Copyright (C) 2017 Intel Corporation | 6 | * Copyright (C) 2017 Intel Corporation |
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | 7 | */ |
19 | #include <linux/fpga/fpga-bridge.h> | 8 | #include <linux/fpga/fpga-bridge.h> |
20 | #include <linux/idr.h> | 9 | #include <linux/idr.h> |
@@ -132,10 +121,11 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data) | |||
132 | /** | 121 | /** |
133 | * fpga_bridge_get - get an exclusive reference to a fpga bridge | 122 | * fpga_bridge_get - get an exclusive reference to a fpga bridge |
134 | * @dev: parent device that fpga bridge was registered with | 123 | * @dev: parent device that fpga bridge was registered with |
124 | * @info: fpga manager info | ||
135 | * | 125 | * |
136 | * Given a device, get an exclusive reference to a fpga bridge. | 126 | * Given a device, get an exclusive reference to a fpga bridge. |
137 | * | 127 | * |
138 | * Return: fpga manager struct or IS_ERR() condition containing error code. | 128 | * Return: fpga bridge struct or IS_ERR() condition containing error code. |
139 | */ | 129 | */ |
140 | struct fpga_bridge *fpga_bridge_get(struct device *dev, | 130 | struct fpga_bridge *fpga_bridge_get(struct device *dev, |
141 | struct fpga_image_info *info) | 131 | struct fpga_image_info *info) |
@@ -328,28 +318,32 @@ static struct attribute *fpga_bridge_attrs[] = { | |||
328 | ATTRIBUTE_GROUPS(fpga_bridge); | 318 | ATTRIBUTE_GROUPS(fpga_bridge); |
329 | 319 | ||
330 | /** | 320 | /** |
331 | * fpga_bridge_register - register a fpga bridge driver | 321 | * fpga_bridge_create - create and initialize a struct fpga_bridge |
332 | * @dev: FPGA bridge device from pdev | 322 | * @dev: FPGA bridge device from pdev |
333 | * @name: FPGA bridge name | 323 | * @name: FPGA bridge name |
334 | * @br_ops: pointer to structure of fpga bridge ops | 324 | * @br_ops: pointer to structure of fpga bridge ops |
335 | * @priv: FPGA bridge private data | 325 | * @priv: FPGA bridge private data |
336 | * | 326 | * |
337 | * Return: 0 for success, error code otherwise. | 327 | * The caller of this function is responsible for freeing the bridge with |
328 | * fpga_bridge_free(). Using devm_fpga_bridge_create() instead is recommended. | ||
329 | * | ||
330 | * Return: struct fpga_bridge or NULL | ||
338 | */ | 331 | */ |
339 | int fpga_bridge_register(struct device *dev, const char *name, | 332 | struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, |
340 | const struct fpga_bridge_ops *br_ops, void *priv) | 333 | const struct fpga_bridge_ops *br_ops, |
334 | void *priv) | ||
341 | { | 335 | { |
342 | struct fpga_bridge *bridge; | 336 | struct fpga_bridge *bridge; |
343 | int id, ret = 0; | 337 | int id, ret = 0; |
344 | 338 | ||
345 | if (!name || !strlen(name)) { | 339 | if (!name || !strlen(name)) { |
346 | dev_err(dev, "Attempt to register with no name!\n"); | 340 | dev_err(dev, "Attempt to register with no name!\n"); |
347 | return -EINVAL; | 341 | return NULL; |
348 | } | 342 | } |
349 | 343 | ||
350 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | 344 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); |
351 | if (!bridge) | 345 | if (!bridge) |
352 | return -ENOMEM; | 346 | return NULL; |
353 | 347 | ||
354 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); | 348 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); |
355 | if (id < 0) { | 349 | if (id < 0) { |
@@ -370,40 +364,112 @@ int fpga_bridge_register(struct device *dev, const char *name, | |||
370 | bridge->dev.parent = dev; | 364 | bridge->dev.parent = dev; |
371 | bridge->dev.of_node = dev->of_node; | 365 | bridge->dev.of_node = dev->of_node; |
372 | bridge->dev.id = id; | 366 | bridge->dev.id = id; |
373 | dev_set_drvdata(dev, bridge); | ||
374 | 367 | ||
375 | ret = dev_set_name(&bridge->dev, "br%d", id); | 368 | ret = dev_set_name(&bridge->dev, "br%d", id); |
376 | if (ret) | 369 | if (ret) |
377 | goto error_device; | 370 | goto error_device; |
378 | 371 | ||
379 | ret = device_add(&bridge->dev); | 372 | return bridge; |
380 | if (ret) | ||
381 | goto error_device; | ||
382 | |||
383 | of_platform_populate(dev->of_node, NULL, NULL, dev); | ||
384 | |||
385 | dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n", | ||
386 | bridge->name); | ||
387 | |||
388 | return 0; | ||
389 | 373 | ||
390 | error_device: | 374 | error_device: |
391 | ida_simple_remove(&fpga_bridge_ida, id); | 375 | ida_simple_remove(&fpga_bridge_ida, id); |
392 | error_kfree: | 376 | error_kfree: |
393 | kfree(bridge); | 377 | kfree(bridge); |
394 | 378 | ||
395 | return ret; | 379 | return NULL; |
396 | } | 380 | } |
397 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | 381 | EXPORT_SYMBOL_GPL(fpga_bridge_create); |
398 | 382 | ||
399 | /** | 383 | /** |
400 | * fpga_bridge_unregister - unregister a fpga bridge driver | 384 | * fpga_bridge_free - free a fpga bridge created by fpga_bridge_create() |
401 | * @dev: FPGA bridge device from pdev | 385 | * @bridge: FPGA bridge struct |
402 | */ | 386 | */ |
403 | void fpga_bridge_unregister(struct device *dev) | 387 | void fpga_bridge_free(struct fpga_bridge *bridge) |
388 | { | ||
389 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); | ||
390 | kfree(bridge); | ||
391 | } | ||
392 | EXPORT_SYMBOL_GPL(fpga_bridge_free); | ||
393 | |||
394 | static void devm_fpga_bridge_release(struct device *dev, void *res) | ||
404 | { | 395 | { |
405 | struct fpga_bridge *bridge = dev_get_drvdata(dev); | 396 | struct fpga_bridge *bridge = *(struct fpga_bridge **)res; |
406 | 397 | ||
398 | fpga_bridge_free(bridge); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * devm_fpga_bridge_create - create and init a managed struct fpga_bridge | ||
403 | * @dev: FPGA bridge device from pdev | ||
404 | * @name: FPGA bridge name | ||
405 | * @br_ops: pointer to structure of fpga bridge ops | ||
406 | * @priv: FPGA bridge private data | ||
407 | * | ||
408 | * This function is intended for use in a FPGA bridge driver's probe function. | ||
409 | * After the bridge driver creates the struct with devm_fpga_bridge_create(), it | ||
410 | * should register the bridge with fpga_bridge_register(). The bridge driver's | ||
411 | * remove function should call fpga_bridge_unregister(). The bridge struct | ||
412 | * allocated with this function will be freed automatically on driver detach. | ||
413 | * This includes the case of a probe function returning error before calling | ||
414 | * fpga_bridge_register(), the struct will still get cleaned up. | ||
415 | * | ||
416 | * Return: struct fpga_bridge or NULL | ||
417 | */ | ||
418 | struct fpga_bridge | ||
419 | *devm_fpga_bridge_create(struct device *dev, const char *name, | ||
420 | const struct fpga_bridge_ops *br_ops, void *priv) | ||
421 | { | ||
422 | struct fpga_bridge **ptr, *bridge; | ||
423 | |||
424 | ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL); | ||
425 | if (!ptr) | ||
426 | return NULL; | ||
427 | |||
428 | bridge = fpga_bridge_create(dev, name, br_ops, priv); | ||
429 | if (!bridge) { | ||
430 | devres_free(ptr); | ||
431 | } else { | ||
432 | *ptr = bridge; | ||
433 | devres_add(dev, ptr); | ||
434 | } | ||
435 | |||
436 | return bridge; | ||
437 | } | ||
438 | EXPORT_SYMBOL_GPL(devm_fpga_bridge_create); | ||
439 | |||
440 | /** | ||
441 | * fpga_bridge_register - register a FPGA bridge | ||
442 | * | ||
443 | * @bridge: FPGA bridge struct | ||
444 | * | ||
445 | * Return: 0 for success, error code otherwise. | ||
446 | */ | ||
447 | int fpga_bridge_register(struct fpga_bridge *bridge) | ||
448 | { | ||
449 | struct device *dev = &bridge->dev; | ||
450 | int ret; | ||
451 | |||
452 | ret = device_add(dev); | ||
453 | if (ret) | ||
454 | return ret; | ||
455 | |||
456 | of_platform_populate(dev->of_node, NULL, NULL, dev); | ||
457 | |||
458 | dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | ||
463 | |||
464 | /** | ||
465 | * fpga_bridge_unregister - unregister a FPGA bridge | ||
466 | * | ||
467 | * @bridge: FPGA bridge struct | ||
468 | * | ||
469 | * This function is intended for use in a FPGA bridge driver's remove function. | ||
470 | */ | ||
471 | void fpga_bridge_unregister(struct fpga_bridge *bridge) | ||
472 | { | ||
407 | /* | 473 | /* |
408 | * If the low level driver provides a method for putting bridge into | 474 | * If the low level driver provides a method for putting bridge into |
409 | * a desired state upon unregister, do it. | 475 | * a desired state upon unregister, do it. |
@@ -417,10 +483,6 @@ EXPORT_SYMBOL_GPL(fpga_bridge_unregister); | |||
417 | 483 | ||
418 | static void fpga_bridge_dev_release(struct device *dev) | 484 | static void fpga_bridge_dev_release(struct device *dev) |
419 | { | 485 | { |
420 | struct fpga_bridge *bridge = to_fpga_bridge(dev); | ||
421 | |||
422 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); | ||
423 | kfree(bridge); | ||
424 | } | 486 | } |
425 | 487 | ||
426 | static int __init fpga_bridge_dev_init(void) | 488 | static int __init fpga_bridge_dev_init(void) |