diff options
author | Alan Tull <atull@kernel.org> | 2018-05-16 19:49:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-25 12:23:55 -0400 |
commit | 371cd1b1fdabb33603340559049e46dfeae45b1e (patch) | |
tree | 0d1f187b9e48378b7f0b2b83b31f322f7435da17 /drivers/fpga/fpga-bridge.c | |
parent | 7085e2a94f7df5f419e3cfb2fe809ce6564e9629 (diff) |
fpga: bridge: change api, don't use drvdata
Change fpga_bridge_register to not set drvdata. This is to support
the case where a PCIe device can have more than one bridge.
Add API functions to create/free the fpga bridge struct. Change
fpga_bridge_register/unregister to take FPGA bridge struct as
the only parameter.
struct fpga_bridge
*fpga_bridge_create(struct device *dev, const char *name,
const struct fpga_bridge_ops *br_ops,
void *priv);
void fpga_bridge_free(struct fpga_bridge *br);
int fpga_bridge_register(struct fpga_bridge *br);
void fpga_bridge_unregister(struct fpga_bridge *br);
Update the drivers that call fpga_bridge_register with the new API.
Signed-off-by: Alan Tull <atull@kernel.org>
Reported-by: Jiuyue Ma <majiuyue@huawei.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga/fpga-bridge.c')
-rw-r--r-- | drivers/fpga/fpga-bridge.c | 70 |
1 files changed, 46 insertions, 24 deletions
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 31bd2c59c305..2db1573507eb 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c | |||
@@ -328,28 +328,29 @@ static struct attribute *fpga_bridge_attrs[] = { | |||
328 | ATTRIBUTE_GROUPS(fpga_bridge); | 328 | ATTRIBUTE_GROUPS(fpga_bridge); |
329 | 329 | ||
330 | /** | 330 | /** |
331 | * fpga_bridge_register - register a fpga bridge driver | 331 | * fpga_bridge_create - create and initialize a struct fpga_bridge |
332 | * @dev: FPGA bridge device from pdev | 332 | * @dev: FPGA bridge device from pdev |
333 | * @name: FPGA bridge name | 333 | * @name: FPGA bridge name |
334 | * @br_ops: pointer to structure of fpga bridge ops | 334 | * @br_ops: pointer to structure of fpga bridge ops |
335 | * @priv: FPGA bridge private data | 335 | * @priv: FPGA bridge private data |
336 | * | 336 | * |
337 | * Return: 0 for success, error code otherwise. | 337 | * Return: struct fpga_bridge or NULL |
338 | */ | 338 | */ |
339 | int fpga_bridge_register(struct device *dev, const char *name, | 339 | struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, |
340 | const struct fpga_bridge_ops *br_ops, void *priv) | 340 | const struct fpga_bridge_ops *br_ops, |
341 | void *priv) | ||
341 | { | 342 | { |
342 | struct fpga_bridge *bridge; | 343 | struct fpga_bridge *bridge; |
343 | int id, ret = 0; | 344 | int id, ret = 0; |
344 | 345 | ||
345 | if (!name || !strlen(name)) { | 346 | if (!name || !strlen(name)) { |
346 | dev_err(dev, "Attempt to register with no name!\n"); | 347 | dev_err(dev, "Attempt to register with no name!\n"); |
347 | return -EINVAL; | 348 | return NULL; |
348 | } | 349 | } |
349 | 350 | ||
350 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | 351 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); |
351 | if (!bridge) | 352 | if (!bridge) |
352 | return -ENOMEM; | 353 | return NULL; |
353 | 354 | ||
354 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); | 355 | id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); |
355 | if (id < 0) { | 356 | if (id < 0) { |
@@ -370,40 +371,62 @@ int fpga_bridge_register(struct device *dev, const char *name, | |||
370 | bridge->dev.parent = dev; | 371 | bridge->dev.parent = dev; |
371 | bridge->dev.of_node = dev->of_node; | 372 | bridge->dev.of_node = dev->of_node; |
372 | bridge->dev.id = id; | 373 | bridge->dev.id = id; |
373 | dev_set_drvdata(dev, bridge); | ||
374 | 374 | ||
375 | ret = dev_set_name(&bridge->dev, "br%d", id); | 375 | ret = dev_set_name(&bridge->dev, "br%d", id); |
376 | if (ret) | 376 | if (ret) |
377 | goto error_device; | 377 | goto error_device; |
378 | 378 | ||
379 | ret = device_add(&bridge->dev); | 379 | 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 | 380 | ||
390 | error_device: | 381 | error_device: |
391 | ida_simple_remove(&fpga_bridge_ida, id); | 382 | ida_simple_remove(&fpga_bridge_ida, id); |
392 | error_kfree: | 383 | error_kfree: |
393 | kfree(bridge); | 384 | kfree(bridge); |
394 | 385 | ||
395 | return ret; | 386 | return NULL; |
387 | } | ||
388 | EXPORT_SYMBOL_GPL(fpga_bridge_create); | ||
389 | |||
390 | /** | ||
391 | * fpga_bridge_free - free a fpga bridge and its id | ||
392 | * @bridge: FPGA bridge struct created by fpga_bridge_create | ||
393 | */ | ||
394 | void fpga_bridge_free(struct fpga_bridge *bridge) | ||
395 | { | ||
396 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); | ||
397 | kfree(bridge); | ||
398 | } | ||
399 | EXPORT_SYMBOL_GPL(fpga_bridge_free); | ||
400 | |||
401 | /** | ||
402 | * fpga_bridge_register - register a fpga bridge | ||
403 | * @bridge: FPGA bridge struct created by fpga_bridge_create | ||
404 | * | ||
405 | * Return: 0 for success, error code otherwise. | ||
406 | */ | ||
407 | int fpga_bridge_register(struct fpga_bridge *bridge) | ||
408 | { | ||
409 | struct device *dev = &bridge->dev; | ||
410 | int ret; | ||
411 | |||
412 | ret = device_add(dev); | ||
413 | if (ret) | ||
414 | return ret; | ||
415 | |||
416 | of_platform_populate(dev->of_node, NULL, NULL, dev); | ||
417 | |||
418 | dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); | ||
419 | |||
420 | return 0; | ||
396 | } | 421 | } |
397 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | 422 | EXPORT_SYMBOL_GPL(fpga_bridge_register); |
398 | 423 | ||
399 | /** | 424 | /** |
400 | * fpga_bridge_unregister - unregister a fpga bridge driver | 425 | * fpga_bridge_unregister - unregister a fpga bridge driver |
401 | * @dev: FPGA bridge device from pdev | 426 | * @bridge: FPGA bridge struct created by fpga_bridge_create |
402 | */ | 427 | */ |
403 | void fpga_bridge_unregister(struct device *dev) | 428 | void fpga_bridge_unregister(struct fpga_bridge *bridge) |
404 | { | 429 | { |
405 | struct fpga_bridge *bridge = dev_get_drvdata(dev); | ||
406 | |||
407 | /* | 430 | /* |
408 | * If the low level driver provides a method for putting bridge into | 431 | * If the low level driver provides a method for putting bridge into |
409 | * a desired state upon unregister, do it. | 432 | * a desired state upon unregister, do it. |
@@ -419,8 +442,7 @@ static void fpga_bridge_dev_release(struct device *dev) | |||
419 | { | 442 | { |
420 | struct fpga_bridge *bridge = to_fpga_bridge(dev); | 443 | struct fpga_bridge *bridge = to_fpga_bridge(dev); |
421 | 444 | ||
422 | ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); | 445 | fpga_bridge_free(bridge); |
423 | kfree(bridge); | ||
424 | } | 446 | } |
425 | 447 | ||
426 | static int __init fpga_bridge_dev_init(void) | 448 | static int __init fpga_bridge_dev_init(void) |