diff options
Diffstat (limited to 'drivers/fpga/fpga-bridge.c')
-rw-r--r-- | drivers/fpga/fpga-bridge.c | 86 |
1 files changed, 49 insertions, 37 deletions
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 31bd2c59c305..24b8f98b73ec 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,6 +121,7 @@ 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 | * |
@@ -328,28 +318,29 @@ 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 | * Return: struct fpga_bridge or NULL |
338 | */ | 328 | */ |
339 | int fpga_bridge_register(struct device *dev, const char *name, | 329 | struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, |
340 | const struct fpga_bridge_ops *br_ops, void *priv) | 330 | const struct fpga_bridge_ops *br_ops, |
331 | void *priv) | ||
341 | { | 332 | { |
342 | struct fpga_bridge *bridge; | 333 | struct fpga_bridge *bridge; |
343 | int id, ret = 0; | 334 | int id, ret = 0; |
344 | 335 | ||
345 | if (!name || !strlen(name)) { | 336 | if (!name || !strlen(name)) { |
346 | dev_err(dev, "Attempt to register with no name!\n"); | 337 | dev_err(dev, "Attempt to register with no name!\n"); |
347 | return -EINVAL; | 338 | return NULL; |
348 | } | 339 | } |
349 | 340 | ||
350 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | 341 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); |
351 | if (!bridge) | 342 | if (!bridge) |
352 | return -ENOMEM; | 343 | return NULL; |
353 | 344 | ||
354 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); | 345 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); |
355 | if (id < 0) { | 346 | if (id < 0) { |
@@ -370,40 +361,62 @@ int fpga_bridge_register(struct device *dev, const char *name, | |||
370 | bridge->dev.parent = dev; | 361 | bridge->dev.parent = dev; |
371 | bridge->dev.of_node = dev->of_node; | 362 | bridge->dev.of_node = dev->of_node; |
372 | bridge->dev.id = id; | 363 | bridge->dev.id = id; |
373 | dev_set_drvdata(dev, bridge); | ||
374 | 364 | ||
375 | ret = dev_set_name(&bridge->dev, "br%d", id); | 365 | ret = dev_set_name(&bridge->dev, "br%d", id); |
376 | if (ret) | 366 | if (ret) |
377 | goto error_device; | 367 | goto error_device; |
378 | 368 | ||
379 | ret = device_add(&bridge->dev); | 369 | 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 | 370 | ||
390 | error_device: | 371 | error_device: |
391 | ida_simple_remove(&fpga_bridge_ida, id); | 372 | ida_simple_remove(&fpga_bridge_ida, id); |
392 | error_kfree: | 373 | error_kfree: |
393 | kfree(bridge); | 374 | kfree(bridge); |
394 | 375 | ||
395 | return ret; | 376 | return NULL; |
396 | } | 377 | } |
397 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | 378 | EXPORT_SYMBOL_GPL(fpga_bridge_create); |
398 | 379 | ||
399 | /** | 380 | /** |
400 | * fpga_bridge_unregister - unregister a fpga bridge driver | 381 | * fpga_bridge_free - free a fpga bridge and its id |
401 | * @dev: FPGA bridge device from pdev | 382 | * @bridge: FPGA bridge struct created by fpga_bridge_create |
402 | */ | 383 | */ |
403 | void fpga_bridge_unregister(struct device *dev) | 384 | void fpga_bridge_free(struct fpga_bridge *bridge) |
404 | { | 385 | { |
405 | struct fpga_bridge *bridge = dev_get_drvdata(dev); | 386 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); |
387 | kfree(bridge); | ||
388 | } | ||
389 | EXPORT_SYMBOL_GPL(fpga_bridge_free); | ||
406 | 390 | ||
391 | /** | ||
392 | * fpga_bridge_register - register a fpga bridge | ||
393 | * @bridge: FPGA bridge struct created by fpga_bridge_create | ||
394 | * | ||
395 | * Return: 0 for success, error code otherwise. | ||
396 | */ | ||
397 | int fpga_bridge_register(struct fpga_bridge *bridge) | ||
398 | { | ||
399 | struct device *dev = &bridge->dev; | ||
400 | int ret; | ||
401 | |||
402 | ret = device_add(dev); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
406 | of_platform_populate(dev->of_node, NULL, NULL, dev); | ||
407 | |||
408 | dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | ||
413 | |||
414 | /** | ||
415 | * fpga_bridge_unregister - unregister and free a fpga bridge | ||
416 | * @bridge: FPGA bridge struct created by fpga_bridge_create | ||
417 | */ | ||
418 | void fpga_bridge_unregister(struct fpga_bridge *bridge) | ||
419 | { | ||
407 | /* | 420 | /* |
408 | * If the low level driver provides a method for putting bridge into | 421 | * If the low level driver provides a method for putting bridge into |
409 | * a desired state upon unregister, do it. | 422 | * a desired state upon unregister, do it. |
@@ -419,8 +432,7 @@ static void fpga_bridge_dev_release(struct device *dev) | |||
419 | { | 432 | { |
420 | struct fpga_bridge *bridge = to_fpga_bridge(dev); | 433 | struct fpga_bridge *bridge = to_fpga_bridge(dev); |
421 | 434 | ||
422 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); | 435 | fpga_bridge_free(bridge); |
423 | kfree(bridge); | ||
424 | } | 436 | } |
425 | 437 | ||
426 | static int __init fpga_bridge_dev_init(void) | 438 | static int __init fpga_bridge_dev_init(void) |