greybus: legacy: remove legacy driver support
This patch removes the greybus legacy driver support Signed-off-by: David Lin <dtwlin@google.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
68b66c2801
commit
428888a2b6
@ -11,8 +11,7 @@ greybus-y := core.o \
|
||||
svc.o \
|
||||
svc_watchdog.o \
|
||||
bootrom.o \
|
||||
operation.o \
|
||||
legacy.o
|
||||
operation.o
|
||||
|
||||
gb-gbphy-y := gbphy.o
|
||||
|
||||
|
@ -43,7 +43,6 @@ struct gb_connection {
|
||||
gb_request_handler_t handler;
|
||||
unsigned long flags;
|
||||
|
||||
struct gb_protocol *protocol;
|
||||
u8 module_major;
|
||||
u8 module_minor;
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "bootrom.h"
|
||||
#include "greybus.h"
|
||||
#include "greybus_trace.h"
|
||||
#include "legacy.h"
|
||||
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_send);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_recv);
|
||||
@ -266,16 +265,8 @@ static int __init gb_init(void)
|
||||
goto error_bootrom;
|
||||
}
|
||||
|
||||
retval = gb_legacy_init();
|
||||
if (retval) {
|
||||
pr_err("gb_legacy_init failed\n");
|
||||
goto error_legacy;
|
||||
}
|
||||
|
||||
return 0; /* Success */
|
||||
|
||||
error_legacy:
|
||||
gb_bootrom_exit();
|
||||
error_bootrom:
|
||||
gb_operation_exit();
|
||||
error_operation:
|
||||
@ -291,7 +282,6 @@ module_init(gb_init);
|
||||
|
||||
static void __exit gb_exit(void)
|
||||
{
|
||||
gb_legacy_exit();
|
||||
gb_bootrom_exit();
|
||||
gb_operation_exit();
|
||||
gb_hd_exit();
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "interface.h"
|
||||
#include "bundle.h"
|
||||
#include "connection.h"
|
||||
#include "protocol.h"
|
||||
#include "operation.h"
|
||||
|
||||
|
||||
|
@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Greybus legacy-protocol driver
|
||||
*
|
||||
* Copyright 2015 Google Inc.
|
||||
* Copyright 2015 Linaro Ltd.
|
||||
*
|
||||
* Released under the GPLv2 only.
|
||||
*/
|
||||
|
||||
#include "greybus.h"
|
||||
#include "legacy.h"
|
||||
#include "protocol.h"
|
||||
|
||||
|
||||
struct legacy_connection {
|
||||
struct gb_connection *connection;
|
||||
bool initialized;
|
||||
struct gb_protocol *protocol;
|
||||
};
|
||||
|
||||
struct legacy_data {
|
||||
size_t num_cports;
|
||||
struct legacy_connection *connections;
|
||||
};
|
||||
|
||||
|
||||
static int legacy_connection_get_version(struct gb_connection *connection)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gb_protocol_get_version(connection);
|
||||
if (ret) {
|
||||
dev_err(&connection->hd->dev,
|
||||
"%s: failed to get protocol version: %d\n",
|
||||
connection->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int legacy_request_handler(struct gb_operation *operation)
|
||||
{
|
||||
struct gb_protocol *protocol = operation->connection->protocol;
|
||||
|
||||
return protocol->request_recv(operation->type, operation);
|
||||
}
|
||||
|
||||
static int legacy_connection_init(struct legacy_connection *lc)
|
||||
{
|
||||
struct gb_connection *connection = lc->connection;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&connection->bundle->dev, "%s - %s\n", __func__,
|
||||
connection->name);
|
||||
|
||||
ret = gb_connection_enable(connection);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = legacy_connection_get_version(connection);
|
||||
if (ret)
|
||||
goto err_disable;
|
||||
|
||||
ret = connection->protocol->connection_init(connection);
|
||||
if (ret)
|
||||
goto err_disable;
|
||||
|
||||
lc->initialized = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
gb_connection_disable(connection);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void legacy_connection_exit(struct legacy_connection *lc)
|
||||
{
|
||||
struct gb_connection *connection = lc->connection;
|
||||
|
||||
if (!lc->initialized)
|
||||
return;
|
||||
|
||||
gb_connection_disable(connection);
|
||||
|
||||
connection->protocol->connection_exit(connection);
|
||||
|
||||
lc->initialized = false;
|
||||
}
|
||||
|
||||
static int legacy_connection_create(struct legacy_connection *lc,
|
||||
struct gb_bundle *bundle,
|
||||
struct greybus_descriptor_cport *desc)
|
||||
{
|
||||
struct gb_connection *connection;
|
||||
struct gb_protocol *protocol;
|
||||
gb_request_handler_t handler;
|
||||
u8 major, minor;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* 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 = 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,
|
||||
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 void legacy_disconnect(struct gb_bundle *bundle)
|
||||
{
|
||||
struct legacy_data *data = greybus_get_drvdata(bundle);
|
||||
int i;
|
||||
|
||||
dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x\n", __func__,
|
||||
bundle->class);
|
||||
|
||||
for (i = 0; i < data->num_cports; ++i) {
|
||||
legacy_connection_exit(&data->connections[i]);
|
||||
legacy_connection_destroy(&data->connections[i]);
|
||||
}
|
||||
|
||||
kfree(data->connections);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static const struct greybus_bundle_id legacy_id_table[] = {
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(greybus, legacy_id_table);
|
||||
|
||||
static struct greybus_driver legacy_driver = {
|
||||
.name = "legacy",
|
||||
.probe = legacy_probe,
|
||||
.disconnect = legacy_disconnect,
|
||||
.id_table = legacy_id_table,
|
||||
};
|
||||
|
||||
int gb_legacy_init(void)
|
||||
{
|
||||
return greybus_register(&legacy_driver);
|
||||
}
|
||||
|
||||
void gb_legacy_exit(void)
|
||||
{
|
||||
greybus_deregister(&legacy_driver);
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Greybus legacy-protocol driver
|
||||
*
|
||||
* Copyright 2015 Google Inc.
|
||||
* Copyright 2015 Linaro Ltd.
|
||||
*
|
||||
* Released under the GPLv2 only.
|
||||
*/
|
||||
|
||||
#ifndef __LEGACY_H
|
||||
#define __LEGACY_H
|
||||
|
||||
int gb_legacy_init(void);
|
||||
void gb_legacy_exit(void);
|
||||
|
||||
#endif /* __LEGACY_H */
|
@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Greybus protocol handling
|
||||
*
|
||||
* Copyright 2014-2015 Google Inc.
|
||||
* Copyright 2014-2015 Linaro Ltd.
|
||||
*
|
||||
* Released under the GPLv2 only.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include "greybus.h"
|
||||
|
||||
/* Global list of registered protocols */
|
||||
static DEFINE_SPINLOCK(gb_protocols_lock);
|
||||
static LIST_HEAD(gb_protocols);
|
||||
|
||||
/* Caller must hold gb_protocols_lock */
|
||||
static struct gb_protocol *gb_protocol_find(u8 id, u8 major, u8 minor)
|
||||
{
|
||||
struct gb_protocol *protocol;
|
||||
|
||||
list_for_each_entry(protocol, &gb_protocols, links) {
|
||||
if (protocol->id < id)
|
||||
continue;
|
||||
if (protocol->id > id)
|
||||
break;
|
||||
|
||||
if (protocol->major > major)
|
||||
continue;
|
||||
if (protocol->major < major)
|
||||
break;
|
||||
|
||||
if (protocol->minor > minor)
|
||||
continue;
|
||||
if (protocol->minor < minor)
|
||||
break;
|
||||
|
||||
return protocol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int __gb_protocol_register(struct gb_protocol *protocol, struct module *module)
|
||||
{
|
||||
struct gb_protocol *existing;
|
||||
u8 id = protocol->id;
|
||||
u8 major = protocol->major;
|
||||
u8 minor = protocol->minor;
|
||||
|
||||
protocol->owner = module;
|
||||
|
||||
/*
|
||||
* The protocols list is sorted first by protocol id (low to
|
||||
* high), then by major version (high to low), and finally
|
||||
* by minor version (high to low). Searching only by
|
||||
* protocol id will produce the newest implemented version
|
||||
* of the protocol.
|
||||
*/
|
||||
spin_lock_irq(&gb_protocols_lock);
|
||||
|
||||
list_for_each_entry(existing, &gb_protocols, links) {
|
||||
if (existing->id < id)
|
||||
continue;
|
||||
if (existing->id > id)
|
||||
break;
|
||||
|
||||
if (existing->major > major)
|
||||
continue;
|
||||
if (existing->major < major)
|
||||
break;
|
||||
|
||||
if (existing->minor > minor)
|
||||
continue;
|
||||
if (existing->minor < minor)
|
||||
break;
|
||||
|
||||
/* A matching protocol has already been registered */
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to insert the protocol here, before the existing one
|
||||
* (or before the head if we searched the whole list)
|
||||
*/
|
||||
list_add_tail(&protocol->links, &existing->links);
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
|
||||
pr_info("Registered %s protocol.\n", protocol->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__gb_protocol_register);
|
||||
|
||||
/*
|
||||
* De-register a previously registered protocol.
|
||||
*/
|
||||
void gb_protocol_deregister(struct gb_protocol *protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
return;
|
||||
|
||||
spin_lock_irq(&gb_protocols_lock);
|
||||
protocol = gb_protocol_find(protocol->id, protocol->major,
|
||||
protocol->minor);
|
||||
if (WARN_ON(!protocol || protocol->count)) {
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
list_del(&protocol->links);
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
|
||||
pr_info("Deregistered %s protocol.\n", protocol->name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_protocol_deregister);
|
||||
|
||||
/* Returns the requested protocol if available, or a null pointer */
|
||||
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
|
||||
{
|
||||
struct gb_protocol *protocol;
|
||||
u8 protocol_count;
|
||||
|
||||
spin_lock_irq(&gb_protocols_lock);
|
||||
protocol = gb_protocol_find(id, major, minor);
|
||||
if (protocol) {
|
||||
if (!try_module_get(protocol->owner)) {
|
||||
protocol = NULL;
|
||||
} else {
|
||||
protocol_count = protocol->count;
|
||||
if (protocol_count != U8_MAX)
|
||||
protocol->count++;
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
|
||||
if (protocol)
|
||||
WARN_ON(protocol_count == U8_MAX);
|
||||
|
||||
return protocol;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_protocol_get);
|
||||
|
||||
int gb_protocol_get_version(struct gb_connection *connection)
|
||||
{
|
||||
struct gb_protocol_version_request request;
|
||||
struct gb_protocol_version_response response;
|
||||
struct gb_protocol *protocol = connection->protocol;
|
||||
int retval;
|
||||
|
||||
request.major = protocol->major;
|
||||
request.minor = protocol->minor;
|
||||
|
||||
retval = gb_operation_sync(connection, GB_REQUEST_TYPE_PROTOCOL_VERSION,
|
||||
&request, sizeof(request), &response,
|
||||
sizeof(response));
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (response.major > connection->protocol->major) {
|
||||
dev_err(&connection->hd->dev,
|
||||
"%s: unsupported major version (%u > %u)\n",
|
||||
connection->name, response.major,
|
||||
connection->protocol->major);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
connection->module_major = response.major;
|
||||
connection->module_minor = response.minor;
|
||||
|
||||
dev_dbg(&connection->hd->dev,
|
||||
"%s: %s (0x%02x) v%u.%u\n", connection->name,
|
||||
protocol->name, protocol->id, response.major, response.minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_protocol_get_version);
|
||||
|
||||
void gb_protocol_put(struct gb_protocol *protocol)
|
||||
{
|
||||
u8 id;
|
||||
u8 major;
|
||||
u8 minor;
|
||||
|
||||
id = protocol->id;
|
||||
major = protocol->major;
|
||||
minor = protocol->minor;
|
||||
|
||||
spin_lock_irq(&gb_protocols_lock);
|
||||
protocol = gb_protocol_find(id, major, minor);
|
||||
if (WARN_ON(!protocol || !protocol->count))
|
||||
goto out;
|
||||
|
||||
protocol->count--;
|
||||
module_put(protocol->owner);
|
||||
out:
|
||||
spin_unlock_irq(&gb_protocols_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_protocol_put);
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Greybus protocol handling
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright 2014 Linaro Ltd.
|
||||
*
|
||||
* Released under the GPLv2 only.
|
||||
*/
|
||||
|
||||
#ifndef __PROTOCOL_H
|
||||
#define __PROTOCOL_H
|
||||
|
||||
struct gb_connection;
|
||||
struct gb_operation;
|
||||
|
||||
typedef int (*gb_connection_init_t)(struct gb_connection *);
|
||||
typedef void (*gb_connection_exit_t)(struct gb_connection *);
|
||||
typedef int (*gb_request_recv_t)(u8, struct gb_operation *);
|
||||
|
||||
/*
|
||||
* Protocols having the same id but different major and/or minor
|
||||
* version numbers are treated as distinct protocols. If it makes
|
||||
* sense someday we could group protocols having the same id.
|
||||
*/
|
||||
struct gb_protocol {
|
||||
u8 id;
|
||||
u8 major;
|
||||
u8 minor;
|
||||
u8 count;
|
||||
|
||||
struct list_head links; /* global list */
|
||||
|
||||
gb_connection_init_t connection_init;
|
||||
gb_connection_exit_t connection_exit;
|
||||
gb_request_recv_t request_recv;
|
||||
struct module *owner;
|
||||
char *name;
|
||||
};
|
||||
|
||||
int __gb_protocol_register(struct gb_protocol *protocol, struct module *module);
|
||||
void gb_protocol_deregister(struct gb_protocol *protocol);
|
||||
|
||||
#define gb_protocol_register(protocol) \
|
||||
__gb_protocol_register(protocol, THIS_MODULE)
|
||||
|
||||
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
|
||||
int gb_protocol_get_version(struct gb_connection *connection);
|
||||
|
||||
void gb_protocol_put(struct gb_protocol *protocol);
|
||||
|
||||
/* __protocol: Pointer to struct gb_protocol */
|
||||
#define gb_protocol_driver(__protocol) \
|
||||
static int __init protocol_init(void) \
|
||||
{ \
|
||||
return gb_protocol_register(__protocol); \
|
||||
} \
|
||||
module_init(protocol_init); \
|
||||
static void __exit protocol_exit(void) \
|
||||
{ \
|
||||
gb_protocol_deregister(__protocol); \
|
||||
} \
|
||||
module_exit(protocol_exit)
|
||||
|
||||
/* __protocol: string matching name of struct gb_protocol */
|
||||
#define gb_builtin_protocol_driver(__protocol) \
|
||||
int __init gb_##__protocol##_init(void) \
|
||||
{ \
|
||||
return gb_protocol_register(&__protocol); \
|
||||
} \
|
||||
void gb_##__protocol##_exit(void) \
|
||||
{ \
|
||||
gb_protocol_deregister(&__protocol); \
|
||||
} \
|
||||
|
||||
#endif /* __PROTOCOL_H */
|
Loading…
x
Reference in New Issue
Block a user