Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fpga: bridge: Use standard dev_release for class driver

The FPGA bridge class driver data structure is being treated as a
managed resource instead of using the standard dev_release call-back
function to release the class data structure. This change removes
the managed resource code and combines the create() and register()
functions into a single register() function.

Signed-off-by: Russ Weight <russell.h.weight@intel.com>
Reviewed-by: Xu Yilun <yilun.xu@intel.com>
Acked-by: Xu Yilun <yilun.xu@intel.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>

authored by

Russ Weight and committed by
Moritz Fischer
0d70af3c 4ba0b2c2

+74 -145
+1 -5
Documentation/driver-api/fpga/fpga-bridge.rst
··· 6 6 7 7 * struct fpga_bridge - The FPGA Bridge structure 8 8 * struct fpga_bridge_ops - Low level Bridge driver ops 9 - * devm_fpga_bridge_create() - Allocate and init a bridge struct 10 - * fpga_bridge_register() - Register a bridge 9 + * fpga_bridge_register() - Create and register a bridge 11 10 * fpga_bridge_unregister() - Unregister a bridge 12 11 13 12 .. kernel-doc:: include/linux/fpga/fpga-bridge.h ··· 14 15 15 16 .. kernel-doc:: include/linux/fpga/fpga-bridge.h 16 17 :functions: fpga_bridge_ops 17 - 18 - .. kernel-doc:: drivers/fpga/fpga-bridge.c 19 - :functions: devm_fpga_bridge_create 20 18 21 19 .. kernel-doc:: drivers/fpga/fpga-bridge.c 22 20 :functions: fpga_bridge_register
+4 -8
drivers/fpga/altera-fpga2sdram.c
··· 121 121 /* Get f2s bridge configuration saved in handoff register */ 122 122 regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask); 123 123 124 - br = devm_fpga_bridge_create(dev, F2S_BRIDGE_NAME, 125 - &altera_fpga2sdram_br_ops, priv); 126 - if (!br) 127 - return -ENOMEM; 124 + br = fpga_bridge_register(dev, F2S_BRIDGE_NAME, 125 + &altera_fpga2sdram_br_ops, priv); 126 + if (IS_ERR(br)) 127 + return PTR_ERR(br); 128 128 129 129 platform_set_drvdata(pdev, br); 130 - 131 - ret = fpga_bridge_register(br); 132 - if (ret) 133 - return ret; 134 130 135 131 dev_info(dev, "driver initialized with handoff %08x\n", priv->mask); 136 132
+5 -5
drivers/fpga/altera-freeze-bridge.c
··· 246 246 247 247 priv->base_addr = base_addr; 248 248 249 - br = devm_fpga_bridge_create(dev, FREEZE_BRIDGE_NAME, 250 - &altera_freeze_br_br_ops, priv); 251 - if (!br) 252 - return -ENOMEM; 249 + br = fpga_bridge_register(dev, FREEZE_BRIDGE_NAME, 250 + &altera_freeze_br_br_ops, priv); 251 + if (IS_ERR(br)) 252 + return PTR_ERR(br); 253 253 254 254 platform_set_drvdata(pdev, br); 255 255 256 - return fpga_bridge_register(br); 256 + return 0; 257 257 } 258 258 259 259 static int altera_freeze_br_remove(struct platform_device *pdev)
+4 -8
drivers/fpga/altera-hps2fpga.c
··· 180 180 } 181 181 } 182 182 183 - br = devm_fpga_bridge_create(dev, priv->name, 184 - &altera_hps2fpga_br_ops, priv); 185 - if (!br) { 186 - ret = -ENOMEM; 183 + br = fpga_bridge_register(dev, priv->name, 184 + &altera_hps2fpga_br_ops, priv); 185 + if (IS_ERR(br)) { 186 + ret = PTR_ERR(br); 187 187 goto err; 188 188 } 189 189 190 190 platform_set_drvdata(pdev, br); 191 - 192 - ret = fpga_bridge_register(br); 193 - if (ret) 194 - goto err; 195 191 196 192 return 0; 197 193
+5 -5
drivers/fpga/dfl-fme-br.c
··· 68 68 69 69 priv->pdata = dev_get_platdata(dev); 70 70 71 - br = devm_fpga_bridge_create(dev, "DFL FPGA FME Bridge", 72 - &fme_bridge_ops, priv); 73 - if (!br) 74 - return -ENOMEM; 71 + br = fpga_bridge_register(dev, "DFL FPGA FME Bridge", 72 + &fme_bridge_ops, priv); 73 + if (IS_ERR(br)) 74 + return PTR_ERR(br); 75 75 76 76 platform_set_drvdata(pdev, br); 77 77 78 - return fpga_bridge_register(br); 78 + return 0; 79 79 } 80 80 81 81 static int fme_br_remove(struct platform_device *pdev)
+28 -94
drivers/fpga/fpga-bridge.c
··· 312 312 ATTRIBUTE_GROUPS(fpga_bridge); 313 313 314 314 /** 315 - * fpga_bridge_create - create and initialize a struct fpga_bridge 315 + * fpga_bridge_register - create and register an FPGA Bridge device 316 316 * @parent: FPGA bridge device from pdev 317 317 * @name: FPGA bridge name 318 318 * @br_ops: pointer to structure of fpga bridge ops 319 319 * @priv: FPGA bridge private data 320 320 * 321 - * The caller of this function is responsible for freeing the bridge with 322 - * fpga_bridge_free(). Using devm_fpga_bridge_create() instead is recommended. 323 - * 324 - * Return: struct fpga_bridge or NULL 321 + * Return: struct fpga_bridge pointer or ERR_PTR() 325 322 */ 326 - struct fpga_bridge *fpga_bridge_create(struct device *parent, const char *name, 327 - const struct fpga_bridge_ops *br_ops, 328 - void *priv) 323 + struct fpga_bridge * 324 + fpga_bridge_register(struct device *parent, const char *name, 325 + const struct fpga_bridge_ops *br_ops, 326 + void *priv) 329 327 { 330 328 struct fpga_bridge *bridge; 331 329 int id, ret; 332 330 331 + if (!br_ops) { 332 + dev_err(parent, "Attempt to register without fpga_bridge_ops\n"); 333 + return ERR_PTR(-EINVAL); 334 + } 335 + 333 336 if (!name || !strlen(name)) { 334 337 dev_err(parent, "Attempt to register with no name!\n"); 335 - return NULL; 338 + return ERR_PTR(-EINVAL); 336 339 } 337 340 338 341 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 339 342 if (!bridge) 340 - return NULL; 343 + return ERR_PTR(-ENOMEM); 341 344 342 345 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); 343 - if (id < 0) 346 + if (id < 0) { 347 + ret = id; 344 348 goto error_kfree; 349 + } 345 350 346 351 mutex_init(&bridge->mutex); 347 352 INIT_LIST_HEAD(&bridge->node); ··· 355 350 bridge->br_ops = br_ops; 356 351 bridge->priv = priv; 357 352 358 - device_initialize(&bridge->dev); 359 353 bridge->dev.groups = br_ops->groups; 360 354 bridge->dev.class = fpga_bridge_class; 361 355 bridge->dev.parent = parent; 362 356 bridge->dev.of_node = parent->of_node; 363 357 bridge->dev.id = id; 358 + of_platform_populate(bridge->dev.of_node, NULL, NULL, &bridge->dev); 364 359 365 360 ret = dev_set_name(&bridge->dev, "br%d", id); 366 361 if (ret) 367 362 goto error_device; 363 + 364 + ret = device_register(&bridge->dev); 365 + if (ret) { 366 + put_device(&bridge->dev); 367 + return ERR_PTR(ret); 368 + } 368 369 369 370 return bridge; 370 371 ··· 379 368 error_kfree: 380 369 kfree(bridge); 381 370 382 - return NULL; 383 - } 384 - EXPORT_SYMBOL_GPL(fpga_bridge_create); 385 - 386 - /** 387 - * fpga_bridge_free - free an fpga bridge created by fpga_bridge_create() 388 - * @bridge: FPGA bridge struct 389 - */ 390 - void fpga_bridge_free(struct fpga_bridge *bridge) 391 - { 392 - ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 393 - kfree(bridge); 394 - } 395 - EXPORT_SYMBOL_GPL(fpga_bridge_free); 396 - 397 - static void devm_fpga_bridge_release(struct device *dev, void *res) 398 - { 399 - struct fpga_bridge *bridge = *(struct fpga_bridge **)res; 400 - 401 - fpga_bridge_free(bridge); 402 - } 403 - 404 - /** 405 - * devm_fpga_bridge_create - create and init a managed struct fpga_bridge 406 - * @parent: FPGA bridge device from pdev 407 - * @name: FPGA bridge name 408 - * @br_ops: pointer to structure of fpga bridge ops 409 - * @priv: FPGA bridge private data 410 - * 411 - * This function is intended for use in an FPGA bridge driver's probe function. 412 - * After the bridge driver creates the struct with devm_fpga_bridge_create(), it 413 - * should register the bridge with fpga_bridge_register(). The bridge driver's 414 - * remove function should call fpga_bridge_unregister(). The bridge struct 415 - * allocated with this function will be freed automatically on driver detach. 416 - * This includes the case of a probe function returning error before calling 417 - * fpga_bridge_register(), the struct will still get cleaned up. 418 - * 419 - * Return: struct fpga_bridge or NULL 420 - */ 421 - struct fpga_bridge 422 - *devm_fpga_bridge_create(struct device *parent, const char *name, 423 - const struct fpga_bridge_ops *br_ops, void *priv) 424 - { 425 - struct fpga_bridge **ptr, *bridge; 426 - 427 - ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL); 428 - if (!ptr) 429 - return NULL; 430 - 431 - bridge = fpga_bridge_create(parent, name, br_ops, priv); 432 - if (!bridge) { 433 - devres_free(ptr); 434 - } else { 435 - *ptr = bridge; 436 - devres_add(parent, ptr); 437 - } 438 - 439 - return bridge; 440 - } 441 - EXPORT_SYMBOL_GPL(devm_fpga_bridge_create); 442 - 443 - /** 444 - * fpga_bridge_register - register an FPGA bridge 445 - * 446 - * @bridge: FPGA bridge struct 447 - * 448 - * Return: 0 for success, error code otherwise. 449 - */ 450 - int fpga_bridge_register(struct fpga_bridge *bridge) 451 - { 452 - struct device *dev = &bridge->dev; 453 - int ret; 454 - 455 - ret = device_add(dev); 456 - if (ret) 457 - return ret; 458 - 459 - of_platform_populate(dev->of_node, NULL, NULL, dev); 460 - 461 - dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); 462 - 463 - return 0; 371 + return ERR_PTR(ret); 464 372 } 465 373 EXPORT_SYMBOL_GPL(fpga_bridge_register); 466 374 ··· 405 475 406 476 static void fpga_bridge_dev_release(struct device *dev) 407 477 { 478 + struct fpga_bridge *bridge = to_fpga_bridge(dev); 479 + 480 + ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 481 + kfree(bridge); 408 482 } 409 483 410 484 static int __init fpga_bridge_dev_init(void)
+6 -11
drivers/fpga/xilinx-pr-decoupler.c
··· 140 140 141 141 clk_disable(priv->clk); 142 142 143 - br = devm_fpga_bridge_create(&pdev->dev, priv->ipconfig->name, 144 - &xlnx_pr_decoupler_br_ops, priv); 145 - if (!br) { 146 - err = -ENOMEM; 147 - goto err_clk; 148 - } 149 - 150 - platform_set_drvdata(pdev, br); 151 - 152 - err = fpga_bridge_register(br); 153 - if (err) { 143 + br = fpga_bridge_register(&pdev->dev, priv->ipconfig->name, 144 + &xlnx_pr_decoupler_br_ops, priv); 145 + if (IS_ERR(br)) { 146 + err = PTR_ERR(br); 154 147 dev_err(&pdev->dev, "unable to register %s", 155 148 priv->ipconfig->name); 156 149 goto err_clk; 157 150 } 151 + 152 + platform_set_drvdata(pdev, br); 158 153 159 154 return 0; 160 155
+21 -9
include/linux/fpga/fpga-bridge.h
··· 23 23 }; 24 24 25 25 /** 26 + * struct fpga_bridge_info - collection of parameters an FPGA Bridge 27 + * @name: fpga bridge name 28 + * @br_ops: pointer to structure of fpga bridge ops 29 + * @priv: fpga bridge private data 30 + * 31 + * fpga_bridge_info contains parameters for the register function. These 32 + * are separated into an info structure because they some are optional 33 + * others could be added to in the future. The info structure facilitates 34 + * maintaining a stable API. 35 + */ 36 + struct fpga_bridge_info { 37 + const char *name; 38 + const struct fpga_bridge_ops *br_ops; 39 + void *priv; 40 + }; 41 + 42 + /** 26 43 * struct fpga_bridge - FPGA bridge structure 27 44 * @name: name of low level FPGA bridge 28 45 * @dev: FPGA bridge device ··· 79 62 struct fpga_image_info *info, 80 63 struct list_head *bridge_list); 81 64 82 - struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, 83 - const struct fpga_bridge_ops *br_ops, 84 - void *priv); 85 - void fpga_bridge_free(struct fpga_bridge *br); 86 - int fpga_bridge_register(struct fpga_bridge *br); 65 + struct fpga_bridge * 66 + fpga_bridge_register(struct device *parent, const char *name, 67 + const struct fpga_bridge_ops *br_ops, 68 + void *priv); 87 69 void fpga_bridge_unregister(struct fpga_bridge *br); 88 - 89 - struct fpga_bridge 90 - *devm_fpga_bridge_create(struct device *dev, const char *name, 91 - const struct fpga_bridge_ops *br_ops, void *priv); 92 70 93 71 #endif /* _LINUX_FPGA_BRIDGE_H */