Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2011-2017, The Linux Foundation
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     /* Attempt an OF style match first */
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     /* try getting the logical address after probe */
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  * __slim_driver_register() - Client driver registration with SLIMbus
0114  *
0115  * @drv:Client driver to be associated with client-device.
0116  * @owner: owning module/driver
0117  *
0118  * This API will register the client driver with the SLIMbus
0119  * It is called from the driver's module-init function.
0120  */
0121 int __slim_driver_register(struct slim_driver *drv, struct module *owner)
0122 {
0123     /* ID table and probe are mandatory */
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  * slim_driver_unregister() - Undo effect of slim_driver_register
0136  *
0137  * @drv: Client driver to be unregistered
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  * slim_register_controller() - Controller bring-up and registration.
0242  *
0243  * @ctrl: Controller to be registered.
0244  *
0245  * A controller is registered with the framework using this API.
0246  * If devices on a controller were registered before controller,
0247  * this will make sure that they get probed when controller is up
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 /* slim_remove_device: Remove the effect of slim_add_device() */
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  * slim_unregister_controller() - Controller tear-down.
0295  *
0296  * @ctrl: Controller to tear-down.
0297  */
0298 int slim_unregister_controller(struct slim_controller *ctrl)
0299 {
0300     /* Remove all clients */
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  * slim_report_absent() - Controller calls this function when a device
0310  *  reports absent, OR when the device cannot be communicated with
0311  *
0312  * @sbdev: Device that cannot be reached, or sent report absent
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     /* invalidate logical addresses */
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  * slim_get_device() - get handle to a device.
0364  *
0365  * @ctrl: Controller on which this device will be added/queried
0366  * @e_addr: Enumeration address of the device to be queried
0367  *
0368  * Return: pointer to a device if it has already reported. Creates a new
0369  * device and returns pointer to it if the device has not yet enumerated.
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  * of_slim_get_device() - get handle to a device using dt node.
0412  *
0413  * @ctrl: Controller on which this device will be added/queried
0414  * @np: node pointer to device
0415  *
0416  * Return: pointer to a device if it has already reported. Creates a new
0417  * device and returns pointer to it if the device has not yet enumerated.
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  * slim_device_report_present() - Report enumerated device.
0478  *
0479  * @ctrl: Controller with which device is enumerated.
0480  * @e_addr: Enumeration address of the device.
0481  * @laddr: Return logical address (if valid flag is false)
0482  *
0483  * Called by controller in response to REPORT_PRESENT. Framework will assign
0484  * a logical address to this enumeration address.
0485  * Function returns -EXFULL to indicate that all logical addresses are already
0486  * taken.
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  * slim_get_logical_addr() - get/allocate logical address of a SLIMbus device.
0522  *
0523  * @sbdev: client handle requesting the address.
0524  *
0525  * Return: zero if a logical address is valid or a new logical address
0526  * has been assigned. error code in case of error.
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");