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

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>

authored by

Alan Tull and committed by
Greg Kroah-Hartman
371cd1b1 7085e2a9

+123 -45
+16 -5
drivers/fpga/altera-fpga2sdram.c
··· 106 106 { 107 107 struct device *dev = &pdev->dev; 108 108 struct alt_fpga2sdram_data *priv; 109 + struct fpga_bridge *br; 109 110 u32 enable; 110 111 struct regmap *sysmgr; 111 112 int ret = 0; ··· 132 131 /* Get f2s bridge configuration saved in handoff register */ 133 132 regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask); 134 133 135 - ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME, 136 - &altera_fpga2sdram_br_ops, priv); 137 - if (ret) 134 + br = fpga_bridge_create(dev, F2S_BRIDGE_NAME, 135 + &altera_fpga2sdram_br_ops, priv); 136 + if (!br) 137 + return -ENOMEM; 138 + 139 + platform_set_drvdata(pdev, br); 140 + 141 + ret = fpga_bridge_register(br); 142 + if (ret) { 143 + fpga_bridge_free(br); 138 144 return ret; 145 + } 139 146 140 147 dev_info(dev, "driver initialized with handoff %08x\n", priv->mask); 141 148 ··· 155 146 (enable ? "enabling" : "disabling")); 156 147 ret = _alt_fpga2sdram_enable_set(priv, enable); 157 148 if (ret) { 158 - fpga_bridge_unregister(&pdev->dev); 149 + fpga_bridge_unregister(br); 159 150 return ret; 160 151 } 161 152 } ··· 166 157 167 158 static int alt_fpga_bridge_remove(struct platform_device *pdev) 168 159 { 169 - fpga_bridge_unregister(&pdev->dev); 160 + struct fpga_bridge *br = platform_get_drvdata(pdev); 161 + 162 + fpga_bridge_unregister(br); 170 163 171 164 return 0; 172 165 }
+19 -3
drivers/fpga/altera-freeze-bridge.c
··· 221 221 struct device_node *np = pdev->dev.of_node; 222 222 void __iomem *base_addr; 223 223 struct altera_freeze_br_data *priv; 224 + struct fpga_bridge *br; 224 225 struct resource *res; 225 226 u32 status, revision; 227 + int ret; 226 228 227 229 if (!np) 228 230 return -ENODEV; ··· 256 254 257 255 priv->base_addr = base_addr; 258 256 259 - return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME, 260 - &altera_freeze_br_br_ops, priv); 257 + br = fpga_bridge_create(dev, FREEZE_BRIDGE_NAME, 258 + &altera_freeze_br_br_ops, priv); 259 + if (!br) 260 + return -ENOMEM; 261 + 262 + platform_set_drvdata(pdev, br); 263 + 264 + ret = fpga_bridge_register(br); 265 + if (ret) { 266 + fpga_bridge_free(br); 267 + return ret; 268 + } 269 + 270 + return 0; 261 271 } 262 272 263 273 static int altera_freeze_br_remove(struct platform_device *pdev) 264 274 { 265 - fpga_bridge_unregister(&pdev->dev); 275 + struct fpga_bridge *br = platform_get_drvdata(pdev); 276 + 277 + fpga_bridge_unregister(br); 266 278 267 279 return 0; 268 280 }
+19 -5
drivers/fpga/altera-hps2fpga.c
··· 139 139 struct device *dev = &pdev->dev; 140 140 struct altera_hps2fpga_data *priv; 141 141 const struct of_device_id *of_id; 142 + struct fpga_bridge *br; 142 143 u32 enable; 143 144 int ret; 144 145 ··· 191 190 } 192 191 } 193 192 194 - ret = fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops, 195 - priv); 196 - err: 193 + br = fpga_bridge_create(dev, priv->name, &altera_hps2fpga_br_ops, priv); 194 + if (!br) { 195 + ret = -ENOMEM; 196 + goto err; 197 + } 198 + 199 + platform_set_drvdata(pdev, br); 200 + 201 + ret = fpga_bridge_register(br); 197 202 if (ret) 198 - clk_disable_unprepare(priv->clk); 203 + goto err_free; 204 + 205 + return 0; 206 + 207 + err_free: 208 + fpga_bridge_free(br); 209 + err: 210 + clk_disable_unprepare(priv->clk); 199 211 200 212 return ret; 201 213 } ··· 218 204 struct fpga_bridge *bridge = platform_get_drvdata(pdev); 219 205 struct altera_hps2fpga_data *priv = bridge->priv; 220 206 221 - fpga_bridge_unregister(&pdev->dev); 207 + fpga_bridge_unregister(bridge); 222 208 223 209 clk_disable_unprepare(priv->clk); 224 210
+46 -24
drivers/fpga/fpga-bridge.c
··· 328 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 332 * @dev: FPGA bridge device from pdev 333 333 * @name: FPGA bridge name 334 334 * @br_ops: pointer to structure of fpga bridge ops 335 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, 340 - const struct fpga_bridge_ops *br_ops, void *priv) 339 + struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, 340 + const struct fpga_bridge_ops *br_ops, 341 + void *priv) 341 342 { 342 343 struct fpga_bridge *bridge; 343 344 int id, ret = 0; 344 345 345 346 if (!name || !strlen(name)) { 346 347 dev_err(dev, "Attempt to register with no name!\n"); 347 - return -EINVAL; 348 + return NULL; 348 349 } 349 350 350 351 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 351 352 if (!bridge) 352 - return -ENOMEM; 353 + return NULL; 353 354 354 355 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); 355 356 if (id < 0) { ··· 371 370 bridge->dev.parent = dev; 372 371 bridge->dev.of_node = dev->of_node; 373 372 bridge->dev.id = id; 374 - dev_set_drvdata(dev, bridge); 375 373 376 374 ret = dev_set_name(&bridge->dev, "br%d", id); 377 375 if (ret) 378 376 goto error_device; 379 377 380 - ret = device_add(&bridge->dev); 381 - if (ret) 382 - goto error_device; 383 - 384 - of_platform_populate(dev->of_node, NULL, NULL, dev); 385 - 386 - dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n", 387 - bridge->name); 388 - 389 - return 0; 378 + return bridge; 390 379 391 380 error_device: 392 381 ida_simple_remove(&fpga_bridge_ida, id); 393 382 error_kfree: 394 383 kfree(bridge); 395 384 396 - return ret; 385 + return NULL; 386 + } 387 + EXPORT_SYMBOL_GPL(fpga_bridge_create); 388 + 389 + /** 390 + * fpga_bridge_free - free a fpga bridge and its id 391 + * @bridge: FPGA bridge struct created by fpga_bridge_create 392 + */ 393 + void fpga_bridge_free(struct fpga_bridge *bridge) 394 + { 395 + ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 396 + kfree(bridge); 397 + } 398 + EXPORT_SYMBOL_GPL(fpga_bridge_free); 399 + 400 + /** 401 + * fpga_bridge_register - register a fpga bridge 402 + * @bridge: FPGA bridge struct created by fpga_bridge_create 403 + * 404 + * Return: 0 for success, error code otherwise. 405 + */ 406 + int fpga_bridge_register(struct fpga_bridge *bridge) 407 + { 408 + struct device *dev = &bridge->dev; 409 + int ret; 410 + 411 + ret = device_add(dev); 412 + if (ret) 413 + return ret; 414 + 415 + of_platform_populate(dev->of_node, NULL, NULL, dev); 416 + 417 + dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); 418 + 419 + return 0; 397 420 } 398 421 EXPORT_SYMBOL_GPL(fpga_bridge_register); 399 422 400 423 /** 401 424 * fpga_bridge_unregister - unregister a fpga bridge driver 402 - * @dev: FPGA bridge device from pdev 425 + * @bridge: FPGA bridge struct created by fpga_bridge_create 403 426 */ 404 - void fpga_bridge_unregister(struct device *dev) 427 + void fpga_bridge_unregister(struct fpga_bridge *bridge) 405 428 { 406 - struct fpga_bridge *bridge = dev_get_drvdata(dev); 407 - 408 429 /* 409 430 * If the low level driver provides a method for putting bridge into 410 431 * a desired state upon unregister, do it. ··· 442 419 { 443 420 struct fpga_bridge *bridge = to_fpga_bridge(dev); 444 421 445 - ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 446 - kfree(bridge); 422 + fpga_bridge_free(bridge); 447 423 } 448 424 449 425 static int __init fpga_bridge_dev_init(void)
+17 -5
drivers/fpga/xilinx-pr-decoupler.c
··· 94 94 static int xlnx_pr_decoupler_probe(struct platform_device *pdev) 95 95 { 96 96 struct xlnx_pr_decoupler_data *priv; 97 + struct fpga_bridge *br; 97 98 int err; 98 99 struct resource *res; 99 100 ··· 121 120 122 121 clk_disable(priv->clk); 123 122 124 - err = fpga_bridge_register(&pdev->dev, "Xilinx PR Decoupler", 125 - &xlnx_pr_decoupler_br_ops, priv); 123 + br = fpga_bridge_create(&pdev->dev, "Xilinx PR Decoupler", 124 + &xlnx_pr_decoupler_br_ops, priv); 125 + if (!br) { 126 + err = -ENOMEM; 127 + goto err_clk; 128 + } 126 129 130 + platform_set_drvdata(pdev, br); 131 + 132 + err = fpga_bridge_register(br); 127 133 if (err) { 128 134 dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler"); 129 - clk_unprepare(priv->clk); 130 - return err; 135 + goto err_clk; 131 136 } 132 137 133 138 return 0; 139 + 140 + err_clk: 141 + clk_unprepare(priv->clk); 142 + 143 + return err; 134 144 } 135 145 136 146 static int xlnx_pr_decoupler_remove(struct platform_device *pdev) ··· 149 137 struct fpga_bridge *bridge = platform_get_drvdata(pdev); 150 138 struct xlnx_pr_decoupler_data *p = bridge->priv; 151 139 152 - fpga_bridge_unregister(&pdev->dev); 140 + fpga_bridge_unregister(bridge); 153 141 154 142 clk_unprepare(p->clk); 155 143
+6 -3
include/linux/fpga/fpga-bridge.h
··· 62 62 struct fpga_image_info *info, 63 63 struct list_head *bridge_list); 64 64 65 - int fpga_bridge_register(struct device *dev, const char *name, 66 - const struct fpga_bridge_ops *br_ops, void *priv); 67 - void fpga_bridge_unregister(struct device *dev); 65 + struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, 66 + const struct fpga_bridge_ops *br_ops, 67 + void *priv); 68 + void fpga_bridge_free(struct fpga_bridge *br); 69 + int fpga_bridge_register(struct fpga_bridge *br); 70 + void fpga_bridge_unregister(struct fpga_bridge *br); 68 71 69 72 #endif /* _LINUX_FPGA_BRIDGE_H */