core.c (13221B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2011-2017, The Linux Foundation 4 */ 5 6#include <linux/kernel.h> 7#include <linux/errno.h> 8#include <linux/slab.h> 9#include <linux/init.h> 10#include <linux/idr.h> 11#include <linux/of.h> 12#include <linux/of_device.h> 13#include <linux/pm_runtime.h> 14#include <linux/slimbus.h> 15#include "slimbus.h" 16 17static DEFINE_IDA(ctrl_ida); 18 19static const struct slim_device_id *slim_match(const struct slim_device_id *id, 20 const struct slim_device *sbdev) 21{ 22 while (id->manf_id != 0 || id->prod_code != 0) { 23 if (id->manf_id == sbdev->e_addr.manf_id && 24 id->prod_code == sbdev->e_addr.prod_code && 25 id->dev_index == sbdev->e_addr.dev_index && 26 id->instance == sbdev->e_addr.instance) 27 return id; 28 id++; 29 } 30 return NULL; 31} 32 33static int slim_device_match(struct device *dev, struct device_driver *drv) 34{ 35 struct slim_device *sbdev = to_slim_device(dev); 36 struct slim_driver *sbdrv = to_slim_driver(drv); 37 38 /* Attempt an OF style match first */ 39 if (of_driver_match_device(dev, drv)) 40 return 1; 41 42 return !!slim_match(sbdrv->id_table, sbdev); 43} 44 45static void slim_device_update_status(struct slim_device *sbdev, 46 enum slim_device_status status) 47{ 48 struct slim_driver *sbdrv; 49 50 if (sbdev->status == status) 51 return; 52 53 sbdev->status = status; 54 if (!sbdev->dev.driver) 55 return; 56 57 sbdrv = to_slim_driver(sbdev->dev.driver); 58 if (sbdrv->device_status) 59 sbdrv->device_status(sbdev, sbdev->status); 60} 61 62static int slim_device_probe(struct device *dev) 63{ 64 struct slim_device *sbdev = to_slim_device(dev); 65 struct slim_driver *sbdrv = to_slim_driver(dev->driver); 66 int ret; 67 68 ret = sbdrv->probe(sbdev); 69 if (ret) 70 return ret; 71 72 /* try getting the logical address after probe */ 73 ret = slim_get_logical_addr(sbdev); 74 if (!ret) { 75 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP); 76 } else { 77 dev_err(&sbdev->dev, "Failed to get logical address\n"); 78 ret = -EPROBE_DEFER; 79 } 80 81 return ret; 82} 83 84static void slim_device_remove(struct device *dev) 85{ 86 struct slim_device *sbdev = to_slim_device(dev); 87 struct slim_driver *sbdrv; 88 89 if (dev->driver) { 90 sbdrv = to_slim_driver(dev->driver); 91 if (sbdrv->remove) 92 sbdrv->remove(sbdev); 93 } 94} 95 96static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env) 97{ 98 struct slim_device *sbdev = to_slim_device(dev); 99 100 return add_uevent_var(env, "MODALIAS=slim:%s", dev_name(&sbdev->dev)); 101} 102 103struct bus_type slimbus_bus = { 104 .name = "slimbus", 105 .match = slim_device_match, 106 .probe = slim_device_probe, 107 .remove = slim_device_remove, 108 .uevent = slim_device_uevent, 109}; 110EXPORT_SYMBOL_GPL(slimbus_bus); 111 112/* 113 * __slim_driver_register() - Client driver registration with SLIMbus 114 * 115 * @drv:Client driver to be associated with client-device. 116 * @owner: owning module/driver 117 * 118 * This API will register the client driver with the SLIMbus 119 * It is called from the driver's module-init function. 120 */ 121int __slim_driver_register(struct slim_driver *drv, struct module *owner) 122{ 123 /* ID table and probe are mandatory */ 124 if (!(drv->driver.of_match_table || drv->id_table) || !drv->probe) 125 return -EINVAL; 126 127 drv->driver.bus = &slimbus_bus; 128 drv->driver.owner = owner; 129 130 return driver_register(&drv->driver); 131} 132EXPORT_SYMBOL_GPL(__slim_driver_register); 133 134/* 135 * slim_driver_unregister() - Undo effect of slim_driver_register 136 * 137 * @drv: Client driver to be unregistered 138 */ 139void slim_driver_unregister(struct slim_driver *drv) 140{ 141 driver_unregister(&drv->driver); 142} 143EXPORT_SYMBOL_GPL(slim_driver_unregister); 144 145static void slim_dev_release(struct device *dev) 146{ 147 struct slim_device *sbdev = to_slim_device(dev); 148 149 kfree(sbdev); 150} 151 152static int slim_add_device(struct slim_controller *ctrl, 153 struct slim_device *sbdev, 154 struct device_node *node) 155{ 156 sbdev->dev.bus = &slimbus_bus; 157 sbdev->dev.parent = ctrl->dev; 158 sbdev->dev.release = slim_dev_release; 159 sbdev->dev.driver = NULL; 160 sbdev->ctrl = ctrl; 161 INIT_LIST_HEAD(&sbdev->stream_list); 162 spin_lock_init(&sbdev->stream_list_lock); 163 sbdev->dev.of_node = of_node_get(node); 164 sbdev->dev.fwnode = of_fwnode_handle(node); 165 166 dev_set_name(&sbdev->dev, "%x:%x:%x:%x", 167 sbdev->e_addr.manf_id, 168 sbdev->e_addr.prod_code, 169 sbdev->e_addr.dev_index, 170 sbdev->e_addr.instance); 171 172 return device_register(&sbdev->dev); 173} 174 175static struct slim_device *slim_alloc_device(struct slim_controller *ctrl, 176 struct slim_eaddr *eaddr, 177 struct device_node *node) 178{ 179 struct slim_device *sbdev; 180 int ret; 181 182 sbdev = kzalloc(sizeof(*sbdev), GFP_KERNEL); 183 if (!sbdev) 184 return NULL; 185 186 sbdev->e_addr = *eaddr; 187 ret = slim_add_device(ctrl, sbdev, node); 188 if (ret) { 189 put_device(&sbdev->dev); 190 return NULL; 191 } 192 193 return sbdev; 194} 195 196static void of_register_slim_devices(struct slim_controller *ctrl) 197{ 198 struct device *dev = ctrl->dev; 199 struct device_node *node; 200 201 if (!ctrl->dev->of_node) 202 return; 203 204 for_each_child_of_node(ctrl->dev->of_node, node) { 205 struct slim_device *sbdev; 206 struct slim_eaddr e_addr; 207 const char *compat = NULL; 208 int reg[2], ret; 209 int manf_id, prod_code; 210 211 compat = of_get_property(node, "compatible", NULL); 212 if (!compat) 213 continue; 214 215 ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code); 216 if (ret != 2) { 217 dev_err(dev, "Manf ID & Product code not found %s\n", 218 compat); 219 continue; 220 } 221 222 ret = of_property_read_u32_array(node, "reg", reg, 2); 223 if (ret) { 224 dev_err(dev, "Device and Instance id not found:%d\n", 225 ret); 226 continue; 227 } 228 229 e_addr.dev_index = reg[0]; 230 e_addr.instance = reg[1]; 231 e_addr.manf_id = manf_id; 232 e_addr.prod_code = prod_code; 233 234 sbdev = slim_alloc_device(ctrl, &e_addr, node); 235 if (!sbdev) 236 continue; 237 } 238} 239 240/* 241 * slim_register_controller() - Controller bring-up and registration. 242 * 243 * @ctrl: Controller to be registered. 244 * 245 * A controller is registered with the framework using this API. 246 * If devices on a controller were registered before controller, 247 * this will make sure that they get probed when controller is up 248 */ 249int slim_register_controller(struct slim_controller *ctrl) 250{ 251 int id; 252 253 id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL); 254 if (id < 0) 255 return id; 256 257 ctrl->id = id; 258 259 if (!ctrl->min_cg) 260 ctrl->min_cg = SLIM_MIN_CLK_GEAR; 261 if (!ctrl->max_cg) 262 ctrl->max_cg = SLIM_MAX_CLK_GEAR; 263 264 ida_init(&ctrl->laddr_ida); 265 idr_init(&ctrl->tid_idr); 266 mutex_init(&ctrl->lock); 267 mutex_init(&ctrl->sched.m_reconf); 268 init_completion(&ctrl->sched.pause_comp); 269 spin_lock_init(&ctrl->txn_lock); 270 271 dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n", 272 ctrl->name, ctrl->dev); 273 274 of_register_slim_devices(ctrl); 275 276 return 0; 277} 278EXPORT_SYMBOL_GPL(slim_register_controller); 279 280/* slim_remove_device: Remove the effect of slim_add_device() */ 281static void slim_remove_device(struct slim_device *sbdev) 282{ 283 of_node_put(sbdev->dev.of_node); 284 device_unregister(&sbdev->dev); 285} 286 287static int slim_ctrl_remove_device(struct device *dev, void *null) 288{ 289 slim_remove_device(to_slim_device(dev)); 290 return 0; 291} 292 293/** 294 * slim_unregister_controller() - Controller tear-down. 295 * 296 * @ctrl: Controller to tear-down. 297 */ 298int slim_unregister_controller(struct slim_controller *ctrl) 299{ 300 /* Remove all clients */ 301 device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device); 302 ida_simple_remove(&ctrl_ida, ctrl->id); 303 304 return 0; 305} 306EXPORT_SYMBOL_GPL(slim_unregister_controller); 307 308/** 309 * slim_report_absent() - Controller calls this function when a device 310 * reports absent, OR when the device cannot be communicated with 311 * 312 * @sbdev: Device that cannot be reached, or sent report absent 313 */ 314void slim_report_absent(struct slim_device *sbdev) 315{ 316 struct slim_controller *ctrl = sbdev->ctrl; 317 318 if (!ctrl) 319 return; 320 321 /* invalidate logical addresses */ 322 mutex_lock(&ctrl->lock); 323 sbdev->is_laddr_valid = false; 324 mutex_unlock(&ctrl->lock); 325 if (!ctrl->get_laddr) 326 ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr); 327 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN); 328} 329EXPORT_SYMBOL_GPL(slim_report_absent); 330 331static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b) 332{ 333 return (a->manf_id == b->manf_id && 334 a->prod_code == b->prod_code && 335 a->dev_index == b->dev_index && 336 a->instance == b->instance); 337} 338 339static int slim_match_dev(struct device *dev, void *data) 340{ 341 struct slim_eaddr *e_addr = data; 342 struct slim_device *sbdev = to_slim_device(dev); 343 344 return slim_eaddr_equal(&sbdev->e_addr, e_addr); 345} 346 347static struct slim_device *find_slim_device(struct slim_controller *ctrl, 348 struct slim_eaddr *eaddr) 349{ 350 struct slim_device *sbdev; 351 struct device *dev; 352 353 dev = device_find_child(ctrl->dev, eaddr, slim_match_dev); 354 if (dev) { 355 sbdev = to_slim_device(dev); 356 return sbdev; 357 } 358 359 return NULL; 360} 361 362/** 363 * slim_get_device() - get handle to a device. 364 * 365 * @ctrl: Controller on which this device will be added/queried 366 * @e_addr: Enumeration address of the device to be queried 367 * 368 * Return: pointer to a device if it has already reported. Creates a new 369 * device and returns pointer to it if the device has not yet enumerated. 370 */ 371struct slim_device *slim_get_device(struct slim_controller *ctrl, 372 struct slim_eaddr *e_addr) 373{ 374 struct slim_device *sbdev; 375 376 sbdev = find_slim_device(ctrl, e_addr); 377 if (!sbdev) { 378 sbdev = slim_alloc_device(ctrl, e_addr, NULL); 379 if (!sbdev) 380 return ERR_PTR(-ENOMEM); 381 } 382 383 return sbdev; 384} 385EXPORT_SYMBOL_GPL(slim_get_device); 386 387static int of_slim_match_dev(struct device *dev, void *data) 388{ 389 struct device_node *np = data; 390 struct slim_device *sbdev = to_slim_device(dev); 391 392 return (sbdev->dev.of_node == np); 393} 394 395static struct slim_device *of_find_slim_device(struct slim_controller *ctrl, 396 struct device_node *np) 397{ 398 struct slim_device *sbdev; 399 struct device *dev; 400 401 dev = device_find_child(ctrl->dev, np, of_slim_match_dev); 402 if (dev) { 403 sbdev = to_slim_device(dev); 404 return sbdev; 405 } 406 407 return NULL; 408} 409 410/** 411 * of_slim_get_device() - get handle to a device using dt node. 412 * 413 * @ctrl: Controller on which this device will be added/queried 414 * @np: node pointer to device 415 * 416 * Return: pointer to a device if it has already reported. Creates a new 417 * device and returns pointer to it if the device has not yet enumerated. 418 */ 419struct slim_device *of_slim_get_device(struct slim_controller *ctrl, 420 struct device_node *np) 421{ 422 return of_find_slim_device(ctrl, np); 423} 424EXPORT_SYMBOL_GPL(of_slim_get_device); 425 426static int slim_device_alloc_laddr(struct slim_device *sbdev, 427 bool report_present) 428{ 429 struct slim_controller *ctrl = sbdev->ctrl; 430 u8 laddr; 431 int ret; 432 433 mutex_lock(&ctrl->lock); 434 if (ctrl->get_laddr) { 435 ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, &laddr); 436 if (ret < 0) 437 goto err; 438 } else if (report_present) { 439 ret = ida_simple_get(&ctrl->laddr_ida, 440 0, SLIM_LA_MANAGER - 1, GFP_KERNEL); 441 if (ret < 0) 442 goto err; 443 444 laddr = ret; 445 } else { 446 ret = -EINVAL; 447 goto err; 448 } 449 450 if (ctrl->set_laddr) { 451 ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, laddr); 452 if (ret) { 453 ret = -EINVAL; 454 goto err; 455 } 456 } 457 458 sbdev->laddr = laddr; 459 sbdev->is_laddr_valid = true; 460 mutex_unlock(&ctrl->lock); 461 462 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP); 463 464 dev_dbg(ctrl->dev, "setting slimbus l-addr:%x, ea:%x,%x,%x,%x\n", 465 laddr, sbdev->e_addr.manf_id, sbdev->e_addr.prod_code, 466 sbdev->e_addr.dev_index, sbdev->e_addr.instance); 467 468 return 0; 469 470err: 471 mutex_unlock(&ctrl->lock); 472 return ret; 473 474} 475 476/** 477 * slim_device_report_present() - Report enumerated device. 478 * 479 * @ctrl: Controller with which device is enumerated. 480 * @e_addr: Enumeration address of the device. 481 * @laddr: Return logical address (if valid flag is false) 482 * 483 * Called by controller in response to REPORT_PRESENT. Framework will assign 484 * a logical address to this enumeration address. 485 * Function returns -EXFULL to indicate that all logical addresses are already 486 * taken. 487 */ 488int slim_device_report_present(struct slim_controller *ctrl, 489 struct slim_eaddr *e_addr, u8 *laddr) 490{ 491 struct slim_device *sbdev; 492 int ret; 493 494 ret = pm_runtime_get_sync(ctrl->dev); 495 496 if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) { 497 dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n", 498 ctrl->sched.clk_state, ret); 499 goto slimbus_not_active; 500 } 501 502 sbdev = slim_get_device(ctrl, e_addr); 503 if (IS_ERR(sbdev)) 504 return -ENODEV; 505 506 if (sbdev->is_laddr_valid) { 507 *laddr = sbdev->laddr; 508 return 0; 509 } 510 511 ret = slim_device_alloc_laddr(sbdev, true); 512 513slimbus_not_active: 514 pm_runtime_mark_last_busy(ctrl->dev); 515 pm_runtime_put_autosuspend(ctrl->dev); 516 return ret; 517} 518EXPORT_SYMBOL_GPL(slim_device_report_present); 519 520/** 521 * slim_get_logical_addr() - get/allocate logical address of a SLIMbus device. 522 * 523 * @sbdev: client handle requesting the address. 524 * 525 * Return: zero if a logical address is valid or a new logical address 526 * has been assigned. error code in case of error. 527 */ 528int slim_get_logical_addr(struct slim_device *sbdev) 529{ 530 if (!sbdev->is_laddr_valid) 531 return slim_device_alloc_laddr(sbdev, false); 532 533 return 0; 534} 535EXPORT_SYMBOL_GPL(slim_get_logical_addr); 536 537static void __exit slimbus_exit(void) 538{ 539 bus_unregister(&slimbus_bus); 540} 541module_exit(slimbus_exit); 542 543static int __init slimbus_init(void) 544{ 545 return bus_register(&slimbus_bus); 546} 547postcore_initcall(slimbus_init); 548 549MODULE_LICENSE("GPL v2"); 550MODULE_DESCRIPTION("SLIMbus core");