X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=drivers%2Fstaging%2Fgreybus%2Flegacy.c;h=838c70fe74c0a11d223feb5b6ff6b52bfcc7d327;hb=6e304f5963ce2136cf8fda2acfb87cfe942d2e71;hp=340d8b5feba77ca5afb38752346f29e182c27ec6;hpb=63cf52f79b4c9f73657285031427ca748d11ce86;p=cascardo%2Flinux.git diff --git a/drivers/staging/greybus/legacy.c b/drivers/staging/greybus/legacy.c index 340d8b5feba7..838c70fe74c0 100644 --- a/drivers/staging/greybus/legacy.c +++ b/drivers/staging/greybus/legacy.c @@ -15,7 +15,7 @@ struct legacy_connection { struct gb_connection *connection; bool initialized; - u8 protocol_id; + struct gb_protocol *protocol; }; struct legacy_data { @@ -39,42 +39,6 @@ static int legacy_connection_get_version(struct gb_connection *connection) return 0; } -static int legacy_connection_bind_protocol(struct legacy_connection *lc) -{ - struct gb_connection *connection = lc->connection; - struct gb_protocol *protocol; - u8 major, minor; - - /* - * The legacy protocols have always been looked up using a hard-coded - * version of 0.1, despite (or perhaps rather, due to) the fact that - * module version negotiation could not take place until after the - * protocol was bound. - */ - major = 0; - minor = 1; - - protocol = gb_protocol_get(lc->protocol_id, major, minor); - if (!protocol) { - dev_err(&connection->hd->dev, - "protocol 0x%02x version %u.%u not found\n", - lc->protocol_id, major, minor); - return -EPROTONOSUPPORT; - } - connection->protocol = protocol; - - return 0; -} - -static void legacy_connection_unbind_protocol(struct gb_connection *connection) -{ - struct gb_protocol *protocol = connection->protocol; - - gb_protocol_put(protocol); - - connection->protocol = NULL; -} - static int legacy_request_handler(struct gb_operation *operation) { struct gb_protocol *protocol = operation->connection->protocol; @@ -85,25 +49,15 @@ static int legacy_request_handler(struct gb_operation *operation) static int legacy_connection_init(struct legacy_connection *lc) { struct gb_connection *connection = lc->connection; - gb_request_handler_t handler; int ret; dev_dbg(&connection->bundle->dev, "%s - %s\n", __func__, connection->name); - ret = legacy_connection_bind_protocol(lc); + ret = gb_connection_enable(connection); if (ret) return ret; - if (connection->protocol->request_recv) - handler = legacy_request_handler; - else - handler = NULL; - - ret = gb_connection_enable(connection, handler); - if (ret) - goto err_unbind_protocol; - ret = legacy_connection_get_version(connection); if (ret) goto err_disable; @@ -118,8 +72,6 @@ static int legacy_connection_init(struct legacy_connection *lc) err_disable: gb_connection_disable(connection); -err_unbind_protocol: - legacy_connection_unbind_protocol(connection); return ret; } @@ -135,8 +87,6 @@ static void legacy_connection_exit(struct legacy_connection *lc) connection->protocol->connection_exit(connection); - legacy_connection_unbind_protocol(connection); - lc->initialized = false; } @@ -145,20 +95,67 @@ static int legacy_connection_create(struct legacy_connection *lc, struct greybus_descriptor_cport *desc) { struct gb_connection *connection; + struct gb_protocol *protocol; + gb_request_handler_t handler; + u8 major, minor; + int ret; - connection = gb_connection_create(bundle, le16_to_cpu(desc->id)); - if (IS_ERR(connection)) - return PTR_ERR(connection); + /* + * The legacy protocols have always been looked up using a hard-coded + * version of 0.1, despite (or perhaps rather, due to) the fact that + * module version negotiation could not take place until after the + * protocol was bound. + */ + major = 0; + minor = 1; + + protocol = gb_protocol_get(desc->protocol_id, major, minor); + if (!protocol) { + dev_err(&bundle->dev, + "protocol 0x%02x version %u.%u not found\n", + desc->protocol_id, major, minor); + return -EPROTONOSUPPORT; + } + + if (protocol->request_recv) + handler = legacy_request_handler; + else + handler = NULL; + + connection = gb_connection_create(bundle, le16_to_cpu(desc->id), + handler); + if (IS_ERR(connection)) { + ret = PTR_ERR(connection); + goto err_protocol_put; + } + + /* + * NOTE: We need to keep a pointer to the protocol in the actual + * connection structure for now. + */ + connection->protocol = protocol; lc->connection = connection; - lc->protocol_id = desc->protocol_id; + lc->protocol = protocol; return 0; + +err_protocol_put: + gb_protocol_put(protocol); + + return ret; } static void legacy_connection_destroy(struct legacy_connection *lc) { + if (!lc->connection) + return; + + lc->connection->protocol = NULL; + gb_connection_destroy(lc->connection); + + gb_protocol_put(lc->protocol); } static int legacy_probe(struct gb_bundle *bundle, @@ -242,7 +239,6 @@ static const struct greybus_bundle_id legacy_id_table[] = { { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_GPIO) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_I2C) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_UART) }, - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SDIO) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) }, @@ -252,7 +248,6 @@ static const struct greybus_bundle_id legacy_id_table[] = { { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SENSOR) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) }, - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOOPBACK) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_MGMT) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_DATA) },