1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. 3 // Copyright (c) 2018, Linaro Limited 4 5 #include <linux/kernel.h> 6 #include <linux/module.h> 7 #include <linux/device.h> 8 #include <linux/spinlock.h> 9 #include <linux/idr.h> 10 #include <linux/slab.h> 11 #include <linux/of_device.h> 12 #include <linux/soc/qcom/apr.h> 13 #include <linux/rpmsg.h> 14 #include <linux/of.h> 15 16 struct apr { 17 struct rpmsg_endpoint *ch; 18 struct device *dev; 19 spinlock_t svcs_lock; 20 struct idr svcs_idr; 21 int dest_domain_id; 22 }; 23 24 /** 25 * apr_send_pkt() - Send a apr message from apr device 26 * 27 * @adev: Pointer to previously registered apr device. 28 * @pkt: Pointer to apr packet to send 29 * 30 * Return: Will be an negative on packet size on success. 31 */ 32 int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt) 33 { 34 struct apr *apr = dev_get_drvdata(adev->dev.parent); 35 struct apr_hdr *hdr; 36 unsigned long flags; 37 int ret; 38 39 spin_lock_irqsave(&adev->lock, flags); 40 41 hdr = &pkt->hdr; 42 hdr->src_domain = APR_DOMAIN_APPS; 43 hdr->src_svc = adev->svc_id; 44 hdr->dest_domain = adev->domain_id; 45 hdr->dest_svc = adev->svc_id; 46 47 ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size); 48 spin_unlock_irqrestore(&adev->lock, flags); 49 50 return ret ? ret : hdr->pkt_size; 51 } 52 EXPORT_SYMBOL_GPL(apr_send_pkt); 53 54 static void apr_dev_release(struct device *dev) 55 { 56 struct apr_device *adev = to_apr_device(dev); 57 58 kfree(adev); 59 } 60 61 static int apr_callback(struct rpmsg_device *rpdev, void *buf, 62 int len, void *priv, u32 addr) 63 { 64 struct apr *apr = dev_get_drvdata(&rpdev->dev); 65 uint16_t hdr_size, msg_type, ver, svc_id; 66 struct apr_device *svc = NULL; 67 struct apr_driver *adrv = NULL; 68 struct apr_resp_pkt resp; 69 struct apr_hdr *hdr; 70 unsigned long flags; 71 72 if (len <= APR_HDR_SIZE) { 73 dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n", 74 buf, len); 75 return -EINVAL; 76 } 77 78 hdr = buf; 79 ver = APR_HDR_FIELD_VER(hdr->hdr_field); 80 if (ver > APR_PKT_VER + 1) 81 return -EINVAL; 82 83 hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field); 84 if (hdr_size < APR_HDR_SIZE) { 85 dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size); 86 return -EINVAL; 87 } 88 89 if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) { 90 dev_err(apr->dev, "APR: Wrong paket size\n"); 91 return -EINVAL; 92 } 93 94 msg_type = APR_HDR_FIELD_MT(hdr->hdr_field); 95 if (msg_type >= APR_MSG_TYPE_MAX) { 96 dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type); 97 return -EINVAL; 98 } 99 100 if (hdr->src_domain >= APR_DOMAIN_MAX || 101 hdr->dest_domain >= APR_DOMAIN_MAX || 102 hdr->src_svc >= APR_SVC_MAX || 103 hdr->dest_svc >= APR_SVC_MAX) { 104 dev_err(apr->dev, "APR: Wrong APR header\n"); 105 return -EINVAL; 106 } 107 108 svc_id = hdr->dest_svc; 109 spin_lock_irqsave(&apr->svcs_lock, flags); 110 svc = idr_find(&apr->svcs_idr, svc_id); 111 if (svc && svc->dev.driver) 112 adrv = to_apr_driver(svc->dev.driver); 113 spin_unlock_irqrestore(&apr->svcs_lock, flags); 114 115 if (!adrv) { 116 dev_err(apr->dev, "APR: service is not registered\n"); 117 return -EINVAL; 118 } 119 120 resp.hdr = *hdr; 121 resp.payload_size = hdr->pkt_size - hdr_size; 122 123 /* 124 * NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include 125 * optional headers in to apr_hdr which should be ignored 126 */ 127 if (resp.payload_size > 0) 128 resp.payload = buf + hdr_size; 129 130 adrv->callback(svc, &resp); 131 132 return 0; 133 } 134 135 static int apr_device_match(struct device *dev, struct device_driver *drv) 136 { 137 struct apr_device *adev = to_apr_device(dev); 138 struct apr_driver *adrv = to_apr_driver(drv); 139 const struct apr_device_id *id = adrv->id_table; 140 141 /* Attempt an OF style match first */ 142 if (of_driver_match_device(dev, drv)) 143 return 1; 144 145 if (!id) 146 return 0; 147 148 while (id->domain_id != 0 || id->svc_id != 0) { 149 if (id->domain_id == adev->domain_id && 150 id->svc_id == adev->svc_id) 151 return 1; 152 id++; 153 } 154 155 return 0; 156 } 157 158 static int apr_device_probe(struct device *dev) 159 { 160 struct apr_device *adev = to_apr_device(dev); 161 struct apr_driver *adrv = to_apr_driver(dev->driver); 162 163 return adrv->probe(adev); 164 } 165 166 static int apr_device_remove(struct device *dev) 167 { 168 struct apr_device *adev = to_apr_device(dev); 169 struct apr_driver *adrv; 170 struct apr *apr = dev_get_drvdata(adev->dev.parent); 171 172 if (dev->driver) { 173 adrv = to_apr_driver(dev->driver); 174 if (adrv->remove) 175 adrv->remove(adev); 176 spin_lock(&apr->svcs_lock); 177 idr_remove(&apr->svcs_idr, adev->svc_id); 178 spin_unlock(&apr->svcs_lock); 179 } 180 181 return 0; 182 } 183 184 static int apr_uevent(struct device *dev, struct kobj_uevent_env *env) 185 { 186 struct apr_device *adev = to_apr_device(dev); 187 int ret; 188 189 ret = of_device_uevent_modalias(dev, env); 190 if (ret != -ENODEV) 191 return ret; 192 193 return add_uevent_var(env, "MODALIAS=apr:%s", adev->name); 194 } 195 196 struct bus_type aprbus = { 197 .name = "aprbus", 198 .match = apr_device_match, 199 .probe = apr_device_probe, 200 .uevent = apr_uevent, 201 .remove = apr_device_remove, 202 }; 203 EXPORT_SYMBOL_GPL(aprbus); 204 205 static int apr_add_device(struct device *dev, struct device_node *np, 206 const struct apr_device_id *id) 207 { 208 struct apr *apr = dev_get_drvdata(dev); 209 struct apr_device *adev = NULL; 210 int ret; 211 212 adev = kzalloc(sizeof(*adev), GFP_KERNEL); 213 if (!adev) 214 return -ENOMEM; 215 216 spin_lock_init(&adev->lock); 217 218 adev->svc_id = id->svc_id; 219 adev->domain_id = id->domain_id; 220 adev->version = id->svc_version; 221 if (np) 222 strncpy(adev->name, np->name, APR_NAME_SIZE); 223 else 224 strncpy(adev->name, id->name, APR_NAME_SIZE); 225 226 dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, 227 id->domain_id, id->svc_id); 228 229 adev->dev.bus = &aprbus; 230 adev->dev.parent = dev; 231 adev->dev.of_node = np; 232 adev->dev.release = apr_dev_release; 233 adev->dev.driver = NULL; 234 235 spin_lock(&apr->svcs_lock); 236 idr_alloc(&apr->svcs_idr, adev, id->svc_id, 237 id->svc_id + 1, GFP_ATOMIC); 238 spin_unlock(&apr->svcs_lock); 239 240 dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev)); 241 242 ret = device_register(&adev->dev); 243 if (ret) { 244 dev_err(dev, "device_register failed: %d\n", ret); 245 put_device(&adev->dev); 246 } 247 248 return ret; 249 } 250 251 static void of_register_apr_devices(struct device *dev) 252 { 253 struct apr *apr = dev_get_drvdata(dev); 254 struct device_node *node; 255 256 for_each_child_of_node(dev->of_node, node) { 257 struct apr_device_id id = { {0} }; 258 259 if (of_property_read_u32(node, "reg", &id.svc_id)) 260 continue; 261 262 id.domain_id = apr->dest_domain_id; 263 264 if (apr_add_device(dev, node, &id)) 265 dev_err(dev, "Failed to add apr %d svc\n", id.svc_id); 266 } 267 } 268 269 static int apr_probe(struct rpmsg_device *rpdev) 270 { 271 struct device *dev = &rpdev->dev; 272 struct apr *apr; 273 int ret; 274 275 apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL); 276 if (!apr) 277 return -ENOMEM; 278 279 ret = of_property_read_u32(dev->of_node, "reg", &apr->dest_domain_id); 280 if (ret) { 281 dev_err(dev, "APR Domain ID not specified in DT\n"); 282 return ret; 283 } 284 285 dev_set_drvdata(dev, apr); 286 apr->ch = rpdev->ept; 287 apr->dev = dev; 288 spin_lock_init(&apr->svcs_lock); 289 idr_init(&apr->svcs_idr); 290 of_register_apr_devices(dev); 291 292 return 0; 293 } 294 295 static int apr_remove_device(struct device *dev, void *null) 296 { 297 struct apr_device *adev = to_apr_device(dev); 298 299 device_unregister(&adev->dev); 300 301 return 0; 302 } 303 304 static void apr_remove(struct rpmsg_device *rpdev) 305 { 306 device_for_each_child(&rpdev->dev, NULL, apr_remove_device); 307 } 308 309 /* 310 * __apr_driver_register() - Client driver registration with aprbus 311 * 312 * @drv:Client driver to be associated with client-device. 313 * @owner: owning module/driver 314 * 315 * This API will register the client driver with the aprbus 316 * It is called from the driver's module-init function. 317 */ 318 int __apr_driver_register(struct apr_driver *drv, struct module *owner) 319 { 320 drv->driver.bus = &aprbus; 321 drv->driver.owner = owner; 322 323 return driver_register(&drv->driver); 324 } 325 EXPORT_SYMBOL_GPL(__apr_driver_register); 326 327 /* 328 * apr_driver_unregister() - Undo effect of apr_driver_register 329 * 330 * @drv: Client driver to be unregistered 331 */ 332 void apr_driver_unregister(struct apr_driver *drv) 333 { 334 driver_unregister(&drv->driver); 335 } 336 EXPORT_SYMBOL_GPL(apr_driver_unregister); 337 338 static const struct of_device_id apr_of_match[] = { 339 { .compatible = "qcom,apr"}, 340 { .compatible = "qcom,apr-v2"}, 341 {} 342 }; 343 MODULE_DEVICE_TABLE(of, apr_of_match); 344 345 static struct rpmsg_driver apr_driver = { 346 .probe = apr_probe, 347 .remove = apr_remove, 348 .callback = apr_callback, 349 .drv = { 350 .name = "qcom,apr", 351 .of_match_table = apr_of_match, 352 }, 353 }; 354 355 static int __init apr_init(void) 356 { 357 int ret; 358 359 ret = bus_register(&aprbus); 360 if (!ret) 361 ret = register_rpmsg_driver(&apr_driver); 362 else 363 bus_unregister(&aprbus); 364 365 return ret; 366 } 367 368 static void __exit apr_exit(void) 369 { 370 bus_unregister(&aprbus); 371 unregister_rpmsg_driver(&apr_driver); 372 } 373 374 subsys_initcall(apr_init); 375 module_exit(apr_exit); 376 377 MODULE_LICENSE("GPL v2"); 378 MODULE_DESCRIPTION("Qualcomm APR Bus"); 379