1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Greybus "Core" 4 * 5 * Copyright 2014-2015 Google Inc. 6 * Copyright 2014-2015 Linaro Ltd. 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #define CREATE_TRACE_POINTS 12 #include <linux/greybus.h> 13 #include "greybus_trace.h" 14 15 #define GB_BUNDLE_AUTOSUSPEND_MS 3000 16 17 /* Allow greybus to be disabled at boot if needed */ 18 static bool nogreybus; 19 #ifdef MODULE 20 module_param(nogreybus, bool, 0444); 21 #else 22 core_param(nogreybus, nogreybus, bool, 0444); 23 #endif 24 int greybus_disabled(void) 25 { 26 return nogreybus; 27 } 28 EXPORT_SYMBOL_GPL(greybus_disabled); 29 30 static int is_gb_host_device(const struct device *dev) 31 { 32 return dev->type == &greybus_hd_type; 33 } 34 35 static int is_gb_module(const struct device *dev) 36 { 37 return dev->type == &greybus_module_type; 38 } 39 40 static int is_gb_interface(const struct device *dev) 41 { 42 return dev->type == &greybus_interface_type; 43 } 44 45 static int is_gb_control(const struct device *dev) 46 { 47 return dev->type == &greybus_control_type; 48 } 49 50 static int is_gb_bundle(const struct device *dev) 51 { 52 return dev->type == &greybus_bundle_type; 53 } 54 55 static int is_gb_svc(const struct device *dev) 56 { 57 return dev->type == &greybus_svc_type; 58 } 59 60 static bool greybus_match_one_id(struct gb_bundle *bundle, 61 const struct greybus_bundle_id *id) 62 { 63 if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) && 64 (id->vendor != bundle->intf->vendor_id)) 65 return false; 66 67 if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) && 68 (id->product != bundle->intf->product_id)) 69 return false; 70 71 if ((id->match_flags & GREYBUS_ID_MATCH_CLASS) && 72 (id->class != bundle->class)) 73 return false; 74 75 return true; 76 } 77 78 static const struct greybus_bundle_id * 79 greybus_match_id(struct gb_bundle *bundle, const struct greybus_bundle_id *id) 80 { 81 if (!id) 82 return NULL; 83 84 for (; id->vendor || id->product || id->class || id->driver_info; 85 id++) { 86 if (greybus_match_one_id(bundle, id)) 87 return id; 88 } 89 90 return NULL; 91 } 92 93 static int greybus_match_device(struct device *dev, struct device_driver *drv) 94 { 95 struct greybus_driver *driver = to_greybus_driver(drv); 96 struct gb_bundle *bundle; 97 const struct greybus_bundle_id *id; 98 99 if (!is_gb_bundle(dev)) 100 return 0; 101 102 bundle = to_gb_bundle(dev); 103 104 id = greybus_match_id(bundle, driver->id_table); 105 if (id) 106 return 1; 107 /* FIXME - Dynamic ids? */ 108 return 0; 109 } 110 111 static int greybus_uevent(const struct device *dev, struct kobj_uevent_env *env) 112 { 113 const struct gb_host_device *hd; 114 const struct gb_module *module = NULL; 115 const struct gb_interface *intf = NULL; 116 const struct gb_control *control = NULL; 117 const struct gb_bundle *bundle = NULL; 118 const struct gb_svc *svc = NULL; 119 120 if (is_gb_host_device(dev)) { 121 hd = to_gb_host_device(dev); 122 } else if (is_gb_module(dev)) { 123 module = to_gb_module(dev); 124 hd = module->hd; 125 } else if (is_gb_interface(dev)) { 126 intf = to_gb_interface(dev); 127 module = intf->module; 128 hd = intf->hd; 129 } else if (is_gb_control(dev)) { 130 control = to_gb_control(dev); 131 intf = control->intf; 132 module = intf->module; 133 hd = intf->hd; 134 } else if (is_gb_bundle(dev)) { 135 bundle = to_gb_bundle(dev); 136 intf = bundle->intf; 137 module = intf->module; 138 hd = intf->hd; 139 } else if (is_gb_svc(dev)) { 140 svc = to_gb_svc(dev); 141 hd = svc->hd; 142 } else { 143 dev_WARN(dev, "uevent for unknown greybus device \"type\"!\n"); 144 return -EINVAL; 145 } 146 147 if (add_uevent_var(env, "BUS=%u", hd->bus_id)) 148 return -ENOMEM; 149 150 if (module) { 151 if (add_uevent_var(env, "MODULE=%u", module->module_id)) 152 return -ENOMEM; 153 } 154 155 if (intf) { 156 if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id)) 157 return -ENOMEM; 158 if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x", 159 intf->vendor_id, intf->product_id)) 160 return -ENOMEM; 161 } 162 163 if (bundle) { 164 // FIXME 165 // add a uevent that can "load" a bundle type 166 // This is what we need to bind a driver to so use the info 167 // in gmod here as well 168 169 if (add_uevent_var(env, "BUNDLE=%u", bundle->id)) 170 return -ENOMEM; 171 if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class)) 172 return -ENOMEM; 173 } 174 175 return 0; 176 } 177 178 static void greybus_shutdown(struct device *dev) 179 { 180 if (is_gb_host_device(dev)) { 181 struct gb_host_device *hd; 182 183 hd = to_gb_host_device(dev); 184 gb_hd_shutdown(hd); 185 } 186 } 187 188 const struct bus_type greybus_bus_type = { 189 .name = "greybus", 190 .match = greybus_match_device, 191 .uevent = greybus_uevent, 192 .shutdown = greybus_shutdown, 193 }; 194 195 static int greybus_probe(struct device *dev) 196 { 197 struct greybus_driver *driver = to_greybus_driver(dev->driver); 198 struct gb_bundle *bundle = to_gb_bundle(dev); 199 const struct greybus_bundle_id *id; 200 int retval; 201 202 /* match id */ 203 id = greybus_match_id(bundle, driver->id_table); 204 if (!id) 205 return -ENODEV; 206 207 retval = pm_runtime_get_sync(&bundle->intf->dev); 208 if (retval < 0) { 209 pm_runtime_put_noidle(&bundle->intf->dev); 210 return retval; 211 } 212 213 retval = gb_control_bundle_activate(bundle->intf->control, bundle->id); 214 if (retval) { 215 pm_runtime_put(&bundle->intf->dev); 216 return retval; 217 } 218 219 /* 220 * Unbound bundle devices are always deactivated. During probe, the 221 * Runtime PM is set to enabled and active and the usage count is 222 * incremented. If the driver supports runtime PM, it should call 223 * pm_runtime_put() in its probe routine and pm_runtime_get_sync() 224 * in remove routine. 225 */ 226 pm_runtime_set_autosuspend_delay(dev, GB_BUNDLE_AUTOSUSPEND_MS); 227 pm_runtime_use_autosuspend(dev); 228 pm_runtime_get_noresume(dev); 229 pm_runtime_set_active(dev); 230 pm_runtime_enable(dev); 231 232 retval = driver->probe(bundle, id); 233 if (retval) { 234 /* 235 * Catch buggy drivers that fail to destroy their connections. 236 */ 237 WARN_ON(!list_empty(&bundle->connections)); 238 239 gb_control_bundle_deactivate(bundle->intf->control, bundle->id); 240 241 pm_runtime_disable(dev); 242 pm_runtime_set_suspended(dev); 243 pm_runtime_put_noidle(dev); 244 pm_runtime_dont_use_autosuspend(dev); 245 pm_runtime_put(&bundle->intf->dev); 246 247 return retval; 248 } 249 250 pm_runtime_put(&bundle->intf->dev); 251 252 return 0; 253 } 254 255 static int greybus_remove(struct device *dev) 256 { 257 struct greybus_driver *driver = to_greybus_driver(dev->driver); 258 struct gb_bundle *bundle = to_gb_bundle(dev); 259 struct gb_connection *connection; 260 int retval; 261 262 retval = pm_runtime_get_sync(dev); 263 if (retval < 0) 264 dev_err(dev, "failed to resume bundle: %d\n", retval); 265 266 /* 267 * Disable (non-offloaded) connections early in case the interface is 268 * already gone to avoid unceccessary operation timeouts during 269 * driver disconnect. Otherwise, only disable incoming requests. 270 */ 271 list_for_each_entry(connection, &bundle->connections, bundle_links) { 272 if (gb_connection_is_offloaded(connection)) 273 continue; 274 275 if (bundle->intf->disconnected) 276 gb_connection_disable_forced(connection); 277 else 278 gb_connection_disable_rx(connection); 279 } 280 281 driver->disconnect(bundle); 282 283 /* Catch buggy drivers that fail to destroy their connections. */ 284 WARN_ON(!list_empty(&bundle->connections)); 285 286 if (!bundle->intf->disconnected) 287 gb_control_bundle_deactivate(bundle->intf->control, bundle->id); 288 289 pm_runtime_put_noidle(dev); 290 pm_runtime_disable(dev); 291 pm_runtime_set_suspended(dev); 292 pm_runtime_dont_use_autosuspend(dev); 293 pm_runtime_put_noidle(dev); 294 295 return 0; 296 } 297 298 int greybus_register_driver(struct greybus_driver *driver, struct module *owner, 299 const char *mod_name) 300 { 301 int retval; 302 303 if (greybus_disabled()) 304 return -ENODEV; 305 306 driver->driver.bus = &greybus_bus_type; 307 driver->driver.name = driver->name; 308 driver->driver.probe = greybus_probe; 309 driver->driver.remove = greybus_remove; 310 driver->driver.owner = owner; 311 driver->driver.mod_name = mod_name; 312 313 retval = driver_register(&driver->driver); 314 if (retval) 315 return retval; 316 317 pr_info("registered new driver %s\n", driver->name); 318 return 0; 319 } 320 EXPORT_SYMBOL_GPL(greybus_register_driver); 321 322 void greybus_deregister_driver(struct greybus_driver *driver) 323 { 324 driver_unregister(&driver->driver); 325 } 326 EXPORT_SYMBOL_GPL(greybus_deregister_driver); 327 328 static int __init gb_init(void) 329 { 330 int retval; 331 332 if (greybus_disabled()) 333 return -ENODEV; 334 335 BUILD_BUG_ON(CPORT_ID_MAX >= (long)CPORT_ID_BAD); 336 337 gb_debugfs_init(); 338 339 retval = bus_register(&greybus_bus_type); 340 if (retval) { 341 pr_err("bus_register failed (%d)\n", retval); 342 goto error_bus; 343 } 344 345 retval = gb_hd_init(); 346 if (retval) { 347 pr_err("gb_hd_init failed (%d)\n", retval); 348 goto error_hd; 349 } 350 351 retval = gb_operation_init(); 352 if (retval) { 353 pr_err("gb_operation_init failed (%d)\n", retval); 354 goto error_operation; 355 } 356 return 0; /* Success */ 357 358 error_operation: 359 gb_hd_exit(); 360 error_hd: 361 bus_unregister(&greybus_bus_type); 362 error_bus: 363 gb_debugfs_cleanup(); 364 365 return retval; 366 } 367 module_init(gb_init); 368 369 static void __exit gb_exit(void) 370 { 371 gb_operation_exit(); 372 gb_hd_exit(); 373 bus_unregister(&greybus_bus_type); 374 gb_debugfs_cleanup(); 375 tracepoint_synchronize_unregister(); 376 } 377 module_exit(gb_exit); 378 MODULE_LICENSE("GPL v2"); 379 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>"); 380