static int legacy_probe(struct gb_bundle *bundle, const struct greybus_bundle_id *id) { struct greybus_descriptor_cport *cport_desc; struct legacy_data *data; struct legacy_connection *lc; int i; int ret; dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x, num_cports = %zu\n", __func__, bundle->class, bundle->num_cports); data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->num_cports = bundle->num_cports; data->connections = kcalloc(data->num_cports, sizeof(*data->connections), GFP_KERNEL); if (!data->connections) { ret = -ENOMEM; goto err_free_data; } for (i = 0; i < data->num_cports; ++i) { cport_desc = &bundle->cport_desc[i]; lc = &data->connections[i]; ret = legacy_connection_create(lc, bundle, cport_desc); if (ret) goto err_connections_destroy; } greybus_set_drvdata(bundle, data); for (i = 0; i < data->num_cports; ++i) { lc = &data->connections[i]; ret = legacy_connection_init(lc); if (ret) goto err_connections_disable; } return 0; err_connections_disable: for (--i; i >= 0; --i) legacy_connection_exit(&data->connections[i]); err_connections_destroy: for (i = 0; i < data->num_cports; ++i) legacy_connection_destroy(&data->connections[i]); kfree(data->connections); err_free_data: kfree(data); return ret; }
static int gb_vibrator_probe(struct gb_bundle *bundle, const struct greybus_bundle_id *id) { struct greybus_descriptor_cport *cport_desc; struct gb_connection *connection; struct gb_vibrator_device *vib; struct device *dev; int retval; if (bundle->num_cports != 1) return -ENODEV; cport_desc = &bundle->cport_desc[0]; if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR) return -ENODEV; vib = kzalloc(sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), NULL); if (IS_ERR(connection)) { retval = PTR_ERR(connection); goto err_free_vib; } gb_connection_set_data(connection, vib); vib->connection = connection; greybus_set_drvdata(bundle, vib); retval = gb_connection_enable(connection); if (retval) goto err_connection_destroy; /* * For now we create a device in sysfs for the vibrator, but odds are * there is a "real" device somewhere in the kernel for this, but I * can't find it at the moment... */ vib->minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL); if (vib->minor < 0) { retval = vib->minor; goto err_connection_disable; } dev = device_create(&vibrator_class, &bundle->dev, MKDEV(0, 0), vib, "vibrator%d", vib->minor); if (IS_ERR(dev)) { retval = -EINVAL; goto err_ida_remove; } vib->dev = dev; INIT_DELAYED_WORK(&vib->delayed_work, gb_vibrator_worker); gb_pm_runtime_put_autosuspend(bundle); return 0; err_ida_remove: ida_simple_remove(&minors, vib->minor); err_connection_disable: gb_connection_disable(connection); err_connection_destroy: gb_connection_destroy(connection); err_free_vib: kfree(vib); return retval; }
static int gb_firmware_probe(struct gb_bundle *bundle, const struct greybus_bundle_id *id) { struct greybus_descriptor_cport *cport_desc; struct gb_connection *connection; struct gb_firmware *firmware; int ret; if (bundle->num_cports != 1) return -ENODEV; cport_desc = &bundle->cport_desc[0]; if (cport_desc->protocol_id != GREYBUS_PROTOCOL_FIRMWARE) return -ENODEV; firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) return -ENOMEM; connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), gb_firmware_request_handler); if (IS_ERR(connection)) { ret = PTR_ERR(connection); goto err_free_firmware; } gb_connection_set_data(connection, firmware); firmware->connection = connection; greybus_set_drvdata(bundle, firmware); ret = gb_connection_enable_tx(connection); if (ret) goto err_connection_destroy; ret = gb_firmware_get_version(firmware); if (ret) goto err_connection_disable; firmware_es2_fixup_vid_pid(firmware); ret = gb_connection_enable(connection); if (ret) goto err_connection_disable; /* Tell bootrom we're ready. */ ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_AP_READY, NULL, 0, NULL, 0); if (ret) { dev_err(&connection->bundle->dev, "failed to send AP READY: %d\n", ret); goto err_connection_disable; } dev_dbg(&bundle->dev, "AP_READY sent\n"); return 0; err_connection_disable: gb_connection_disable(connection); err_connection_destroy: gb_connection_destroy(connection); err_free_firmware: kfree(firmware); return ret; }
static int gb_bootrom_probe(struct gb_bundle *bundle, const struct greybus_bundle_id *id) { struct greybus_descriptor_cport *cport_desc; struct gb_connection *connection; struct gb_bootrom *bootrom; int ret; if (bundle->num_cports != 1) return -ENODEV; cport_desc = &bundle->cport_desc[0]; if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM) return -ENODEV; bootrom = kzalloc(sizeof(*bootrom), GFP_KERNEL); if (!bootrom) return -ENOMEM; connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), gb_bootrom_request_handler); if (IS_ERR(connection)) { ret = PTR_ERR(connection); goto err_free_bootrom; } gb_connection_set_data(connection, bootrom); bootrom->connection = connection; mutex_init(&bootrom->mutex); INIT_DELAYED_WORK(&bootrom->dwork, gb_bootrom_timedout); greybus_set_drvdata(bundle, bootrom); ret = gb_connection_enable_tx(connection); if (ret) goto err_connection_destroy; ret = gb_bootrom_get_version(bootrom); if (ret) goto err_connection_disable; bootrom_es2_fixup_vid_pid(bootrom); ret = gb_connection_enable(connection); if (ret) goto err_connection_disable; /* Refresh timeout */ gb_bootrom_set_timeout(bootrom, NEXT_REQ_FIRMWARE_SIZE, NEXT_REQ_TIMEOUT_MS); /* Tell bootrom we're ready. */ ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_AP_READY, NULL, 0, NULL, 0); if (ret) { dev_err(&connection->bundle->dev, "failed to send AP READY: %d\n", ret); goto err_cancel_timeout; } dev_dbg(&bundle->dev, "AP_READY sent\n"); return 0; err_cancel_timeout: gb_bootrom_cancel_timeout(bootrom); err_connection_disable: gb_connection_disable(connection); err_connection_destroy: gb_connection_destroy(connection); err_free_bootrom: kfree(bootrom); return ret; }
static int gb_lights_probe(struct gb_bundle *bundle, const struct greybus_bundle_id *id) { struct greybus_descriptor_cport *cport_desc; struct gb_connection *connection; struct gb_lights *glights; int ret; if (bundle->num_cports != 1) return -ENODEV; cport_desc = &bundle->cport_desc[0]; if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS) return -ENODEV; glights = kzalloc(sizeof(*glights), GFP_KERNEL); if (!glights) return -ENOMEM; mutex_init(&glights->lights_lock); connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), gb_lights_request_handler); if (IS_ERR(connection)) { ret = PTR_ERR(connection); goto out; } glights->connection = connection; gb_connection_set_data(connection, glights); greybus_set_drvdata(bundle, glights); /* We aren't ready to receive an incoming request yet */ ret = gb_connection_enable_tx(connection); if (ret) goto error_connection_destroy; /* * Setup all the lights devices over this connection, if anything goes * wrong tear down all lights */ ret = gb_lights_create_all(glights); if (ret < 0) goto error_connection_disable; /* We are ready to receive an incoming request now, enable RX as well */ ret = gb_connection_enable(connection); if (ret) goto error_connection_disable; /* Enable & register lights */ ret = gb_lights_register_all(glights); if (ret < 0) goto error_connection_disable; gb_pm_runtime_put_autosuspend(bundle); return 0; error_connection_disable: gb_connection_disable(connection); error_connection_destroy: gb_connection_destroy(connection); out: gb_lights_release(glights); return ret; }