aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/fpga-bridge.c
diff options
context:
space:
mode:
authorAlan Tull <atull@kernel.org>2018-05-16 19:49:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-05-25 12:23:55 -0400
commit371cd1b1fdabb33603340559049e46dfeae45b1e (patch)
tree0d1f187b9e48378b7f0b2b83b31f322f7435da17 /drivers/fpga/fpga-bridge.c
parent7085e2a94f7df5f419e3cfb2fe809ce6564e9629 (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.c70
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[] = {
328ATTRIBUTE_GROUPS(fpga_bridge); 328ATTRIBUTE_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 */
339int fpga_bridge_register(struct device *dev, const char *name, 339struct 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
390error_device: 381error_device:
391 ida_simple_remove(&fpga_bridge_ida, id); 382 ida_simple_remove(&fpga_bridge_ida, id);
392error_kfree: 383error_kfree:
393 kfree(bridge); 384 kfree(bridge);
394 385
395 return ret; 386 return NULL;
387}
388EXPORT_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 */
394void fpga_bridge_free(struct fpga_bridge *bridge)
395{
396 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
397 kfree(bridge);
398}
399EXPORT_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 */
407int 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}
397EXPORT_SYMBOL_GPL(fpga_bridge_register); 422EXPORT_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 */
403void fpga_bridge_unregister(struct device *dev) 428void 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
426static int __init fpga_bridge_dev_init(void) 448static int __init fpga_bridge_dev_init(void)