0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/errno.h>
0008 #include <linux/slab.h>
0009 #include <linux/init.h>
0010 #include <linux/idr.h>
0011 #include <linux/of.h>
0012 #include <linux/of_device.h>
0013 #include <linux/pm_runtime.h>
0014 #include <linux/slimbus.h>
0015 #include "slimbus.h"
0016
0017 static DEFINE_IDA(ctrl_ida);
0018
0019 static const struct slim_device_id *slim_match(const struct slim_device_id *id,
0020 const struct slim_device *sbdev)
0021 {
0022 while (id->manf_id != 0 || id->prod_code != 0) {
0023 if (id->manf_id == sbdev->e_addr.manf_id &&
0024 id->prod_code == sbdev->e_addr.prod_code &&
0025 id->dev_index == sbdev->e_addr.dev_index &&
0026 id->instance == sbdev->e_addr.instance)
0027 return id;
0028 id++;
0029 }
0030 return NULL;
0031 }
0032
0033 static int slim_device_match(struct device *dev, struct device_driver *drv)
0034 {
0035 struct slim_device *sbdev = to_slim_device(dev);
0036 struct slim_driver *sbdrv = to_slim_driver(drv);
0037
0038
0039 if (of_driver_match_device(dev, drv))
0040 return 1;
0041
0042 return !!slim_match(sbdrv->id_table, sbdev);
0043 }
0044
0045 static void slim_device_update_status(struct slim_device *sbdev,
0046 enum slim_device_status status)
0047 {
0048 struct slim_driver *sbdrv;
0049
0050 if (sbdev->status == status)
0051 return;
0052
0053 sbdev->status = status;
0054 if (!sbdev->dev.driver)
0055 return;
0056
0057 sbdrv = to_slim_driver(sbdev->dev.driver);
0058 if (sbdrv->device_status)
0059 sbdrv->device_status(sbdev, sbdev->status);
0060 }
0061
0062 static int slim_device_probe(struct device *dev)
0063 {
0064 struct slim_device *sbdev = to_slim_device(dev);
0065 struct slim_driver *sbdrv = to_slim_driver(dev->driver);
0066 int ret;
0067
0068 ret = sbdrv->probe(sbdev);
0069 if (ret)
0070 return ret;
0071
0072
0073 ret = slim_get_logical_addr(sbdev);
0074 if (!ret) {
0075 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP);
0076 } else {
0077 dev_err(&sbdev->dev, "Failed to get logical address\n");
0078 ret = -EPROBE_DEFER;
0079 }
0080
0081 return ret;
0082 }
0083
0084 static void slim_device_remove(struct device *dev)
0085 {
0086 struct slim_device *sbdev = to_slim_device(dev);
0087 struct slim_driver *sbdrv;
0088
0089 if (dev->driver) {
0090 sbdrv = to_slim_driver(dev->driver);
0091 if (sbdrv->remove)
0092 sbdrv->remove(sbdev);
0093 }
0094 }
0095
0096 static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env)
0097 {
0098 struct slim_device *sbdev = to_slim_device(dev);
0099
0100 return add_uevent_var(env, "MODALIAS=slim:%s", dev_name(&sbdev->dev));
0101 }
0102
0103 struct bus_type slimbus_bus = {
0104 .name = "slimbus",
0105 .match = slim_device_match,
0106 .probe = slim_device_probe,
0107 .remove = slim_device_remove,
0108 .uevent = slim_device_uevent,
0109 };
0110 EXPORT_SYMBOL_GPL(slimbus_bus);
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 int __slim_driver_register(struct slim_driver *drv, struct module *owner)
0122 {
0123
0124 if (!(drv->driver.of_match_table || drv->id_table) || !drv->probe)
0125 return -EINVAL;
0126
0127 drv->driver.bus = &slimbus_bus;
0128 drv->driver.owner = owner;
0129
0130 return driver_register(&drv->driver);
0131 }
0132 EXPORT_SYMBOL_GPL(__slim_driver_register);
0133
0134
0135
0136
0137
0138
0139 void slim_driver_unregister(struct slim_driver *drv)
0140 {
0141 driver_unregister(&drv->driver);
0142 }
0143 EXPORT_SYMBOL_GPL(slim_driver_unregister);
0144
0145 static void slim_dev_release(struct device *dev)
0146 {
0147 struct slim_device *sbdev = to_slim_device(dev);
0148
0149 kfree(sbdev);
0150 }
0151
0152 static int slim_add_device(struct slim_controller *ctrl,
0153 struct slim_device *sbdev,
0154 struct device_node *node)
0155 {
0156 sbdev->dev.bus = &slimbus_bus;
0157 sbdev->dev.parent = ctrl->dev;
0158 sbdev->dev.release = slim_dev_release;
0159 sbdev->dev.driver = NULL;
0160 sbdev->ctrl = ctrl;
0161 INIT_LIST_HEAD(&sbdev->stream_list);
0162 spin_lock_init(&sbdev->stream_list_lock);
0163 sbdev->dev.of_node = of_node_get(node);
0164 sbdev->dev.fwnode = of_fwnode_handle(node);
0165
0166 dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
0167 sbdev->e_addr.manf_id,
0168 sbdev->e_addr.prod_code,
0169 sbdev->e_addr.dev_index,
0170 sbdev->e_addr.instance);
0171
0172 return device_register(&sbdev->dev);
0173 }
0174
0175 static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
0176 struct slim_eaddr *eaddr,
0177 struct device_node *node)
0178 {
0179 struct slim_device *sbdev;
0180 int ret;
0181
0182 sbdev = kzalloc(sizeof(*sbdev), GFP_KERNEL);
0183 if (!sbdev)
0184 return NULL;
0185
0186 sbdev->e_addr = *eaddr;
0187 ret = slim_add_device(ctrl, sbdev, node);
0188 if (ret) {
0189 put_device(&sbdev->dev);
0190 return NULL;
0191 }
0192
0193 return sbdev;
0194 }
0195
0196 static void of_register_slim_devices(struct slim_controller *ctrl)
0197 {
0198 struct device *dev = ctrl->dev;
0199 struct device_node *node;
0200
0201 if (!ctrl->dev->of_node)
0202 return;
0203
0204 for_each_child_of_node(ctrl->dev->of_node, node) {
0205 struct slim_device *sbdev;
0206 struct slim_eaddr e_addr;
0207 const char *compat = NULL;
0208 int reg[2], ret;
0209 int manf_id, prod_code;
0210
0211 compat = of_get_property(node, "compatible", NULL);
0212 if (!compat)
0213 continue;
0214
0215 ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code);
0216 if (ret != 2) {
0217 dev_err(dev, "Manf ID & Product code not found %s\n",
0218 compat);
0219 continue;
0220 }
0221
0222 ret = of_property_read_u32_array(node, "reg", reg, 2);
0223 if (ret) {
0224 dev_err(dev, "Device and Instance id not found:%d\n",
0225 ret);
0226 continue;
0227 }
0228
0229 e_addr.dev_index = reg[0];
0230 e_addr.instance = reg[1];
0231 e_addr.manf_id = manf_id;
0232 e_addr.prod_code = prod_code;
0233
0234 sbdev = slim_alloc_device(ctrl, &e_addr, node);
0235 if (!sbdev)
0236 continue;
0237 }
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 int slim_register_controller(struct slim_controller *ctrl)
0250 {
0251 int id;
0252
0253 id = ida_alloc(&ctrl_ida, GFP_KERNEL);
0254 if (id < 0)
0255 return id;
0256
0257 ctrl->id = id;
0258
0259 if (!ctrl->min_cg)
0260 ctrl->min_cg = SLIM_MIN_CLK_GEAR;
0261 if (!ctrl->max_cg)
0262 ctrl->max_cg = SLIM_MAX_CLK_GEAR;
0263
0264 ida_init(&ctrl->laddr_ida);
0265 idr_init(&ctrl->tid_idr);
0266 mutex_init(&ctrl->lock);
0267 mutex_init(&ctrl->sched.m_reconf);
0268 init_completion(&ctrl->sched.pause_comp);
0269 spin_lock_init(&ctrl->txn_lock);
0270
0271 dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
0272 ctrl->name, ctrl->dev);
0273
0274 of_register_slim_devices(ctrl);
0275
0276 return 0;
0277 }
0278 EXPORT_SYMBOL_GPL(slim_register_controller);
0279
0280
0281 static void slim_remove_device(struct slim_device *sbdev)
0282 {
0283 of_node_put(sbdev->dev.of_node);
0284 device_unregister(&sbdev->dev);
0285 }
0286
0287 static int slim_ctrl_remove_device(struct device *dev, void *null)
0288 {
0289 slim_remove_device(to_slim_device(dev));
0290 return 0;
0291 }
0292
0293
0294
0295
0296
0297
0298 int slim_unregister_controller(struct slim_controller *ctrl)
0299 {
0300
0301 device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device);
0302 ida_free(&ctrl_ida, ctrl->id);
0303
0304 return 0;
0305 }
0306 EXPORT_SYMBOL_GPL(slim_unregister_controller);
0307
0308
0309
0310
0311
0312
0313
0314 void slim_report_absent(struct slim_device *sbdev)
0315 {
0316 struct slim_controller *ctrl = sbdev->ctrl;
0317
0318 if (!ctrl)
0319 return;
0320
0321
0322 mutex_lock(&ctrl->lock);
0323 sbdev->is_laddr_valid = false;
0324 mutex_unlock(&ctrl->lock);
0325 if (!ctrl->get_laddr)
0326 ida_free(&ctrl->laddr_ida, sbdev->laddr);
0327 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
0328 }
0329 EXPORT_SYMBOL_GPL(slim_report_absent);
0330
0331 static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b)
0332 {
0333 return (a->manf_id == b->manf_id &&
0334 a->prod_code == b->prod_code &&
0335 a->dev_index == b->dev_index &&
0336 a->instance == b->instance);
0337 }
0338
0339 static int slim_match_dev(struct device *dev, void *data)
0340 {
0341 struct slim_eaddr *e_addr = data;
0342 struct slim_device *sbdev = to_slim_device(dev);
0343
0344 return slim_eaddr_equal(&sbdev->e_addr, e_addr);
0345 }
0346
0347 static struct slim_device *find_slim_device(struct slim_controller *ctrl,
0348 struct slim_eaddr *eaddr)
0349 {
0350 struct slim_device *sbdev;
0351 struct device *dev;
0352
0353 dev = device_find_child(ctrl->dev, eaddr, slim_match_dev);
0354 if (dev) {
0355 sbdev = to_slim_device(dev);
0356 return sbdev;
0357 }
0358
0359 return NULL;
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 struct slim_device *slim_get_device(struct slim_controller *ctrl,
0372 struct slim_eaddr *e_addr)
0373 {
0374 struct slim_device *sbdev;
0375
0376 sbdev = find_slim_device(ctrl, e_addr);
0377 if (!sbdev) {
0378 sbdev = slim_alloc_device(ctrl, e_addr, NULL);
0379 if (!sbdev)
0380 return ERR_PTR(-ENOMEM);
0381 }
0382
0383 return sbdev;
0384 }
0385 EXPORT_SYMBOL_GPL(slim_get_device);
0386
0387 static int of_slim_match_dev(struct device *dev, void *data)
0388 {
0389 struct device_node *np = data;
0390 struct slim_device *sbdev = to_slim_device(dev);
0391
0392 return (sbdev->dev.of_node == np);
0393 }
0394
0395 static struct slim_device *of_find_slim_device(struct slim_controller *ctrl,
0396 struct device_node *np)
0397 {
0398 struct slim_device *sbdev;
0399 struct device *dev;
0400
0401 dev = device_find_child(ctrl->dev, np, of_slim_match_dev);
0402 if (dev) {
0403 sbdev = to_slim_device(dev);
0404 return sbdev;
0405 }
0406
0407 return NULL;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 struct slim_device *of_slim_get_device(struct slim_controller *ctrl,
0420 struct device_node *np)
0421 {
0422 return of_find_slim_device(ctrl, np);
0423 }
0424 EXPORT_SYMBOL_GPL(of_slim_get_device);
0425
0426 static int slim_device_alloc_laddr(struct slim_device *sbdev,
0427 bool report_present)
0428 {
0429 struct slim_controller *ctrl = sbdev->ctrl;
0430 u8 laddr;
0431 int ret;
0432
0433 mutex_lock(&ctrl->lock);
0434 if (ctrl->get_laddr) {
0435 ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, &laddr);
0436 if (ret < 0)
0437 goto err;
0438 } else if (report_present) {
0439 ret = ida_simple_get(&ctrl->laddr_ida,
0440 0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
0441 if (ret < 0)
0442 goto err;
0443
0444 laddr = ret;
0445 } else {
0446 ret = -EINVAL;
0447 goto err;
0448 }
0449
0450 if (ctrl->set_laddr) {
0451 ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, laddr);
0452 if (ret) {
0453 ret = -EINVAL;
0454 goto err;
0455 }
0456 }
0457
0458 sbdev->laddr = laddr;
0459 sbdev->is_laddr_valid = true;
0460 mutex_unlock(&ctrl->lock);
0461
0462 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP);
0463
0464 dev_dbg(ctrl->dev, "setting slimbus l-addr:%x, ea:%x,%x,%x,%x\n",
0465 laddr, sbdev->e_addr.manf_id, sbdev->e_addr.prod_code,
0466 sbdev->e_addr.dev_index, sbdev->e_addr.instance);
0467
0468 return 0;
0469
0470 err:
0471 mutex_unlock(&ctrl->lock);
0472 return ret;
0473
0474 }
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 int slim_device_report_present(struct slim_controller *ctrl,
0489 struct slim_eaddr *e_addr, u8 *laddr)
0490 {
0491 struct slim_device *sbdev;
0492 int ret;
0493
0494 ret = pm_runtime_get_sync(ctrl->dev);
0495
0496 if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
0497 dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
0498 ctrl->sched.clk_state, ret);
0499 goto slimbus_not_active;
0500 }
0501
0502 sbdev = slim_get_device(ctrl, e_addr);
0503 if (IS_ERR(sbdev))
0504 return -ENODEV;
0505
0506 if (sbdev->is_laddr_valid) {
0507 *laddr = sbdev->laddr;
0508 return 0;
0509 }
0510
0511 ret = slim_device_alloc_laddr(sbdev, true);
0512
0513 slimbus_not_active:
0514 pm_runtime_mark_last_busy(ctrl->dev);
0515 pm_runtime_put_autosuspend(ctrl->dev);
0516 return ret;
0517 }
0518 EXPORT_SYMBOL_GPL(slim_device_report_present);
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528 int slim_get_logical_addr(struct slim_device *sbdev)
0529 {
0530 if (!sbdev->is_laddr_valid)
0531 return slim_device_alloc_laddr(sbdev, false);
0532
0533 return 0;
0534 }
0535 EXPORT_SYMBOL_GPL(slim_get_logical_addr);
0536
0537 static void __exit slimbus_exit(void)
0538 {
0539 bus_unregister(&slimbus_bus);
0540 }
0541 module_exit(slimbus_exit);
0542
0543 static int __init slimbus_init(void)
0544 {
0545 return bus_register(&slimbus_bus);
0546 }
0547 postcore_initcall(slimbus_init);
0548
0549 MODULE_LICENSE("GPL v2");
0550 MODULE_DESCRIPTION("SLIMbus core");