Commit 36e79dec authored by Viresh Kumar's avatar Viresh Kumar Committed by Greg Kroah-Hartman

greybus: create get_version() routines with the help of a macro

This gets rid of lots of duplication of code.
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 530430b7
...@@ -88,32 +88,8 @@ struct gb_battery_voltage_response { ...@@ -88,32 +88,8 @@ struct gb_battery_voltage_response {
__le32 voltage; __le32 voltage;
}; };
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_battery, BATTERY);
* fills in the major and minor protocol version of the target.
*/
static int get_version(struct gb_battery *gb)
{
struct gb_battery_proto_version_response version_response;
int retval;
retval = gb_operation_sync(gb->connection,
GB_BATTERY_TYPE_PROTOCOL_VERSION,
NULL, 0,
&version_response, sizeof(version_response));
if (retval)
return retval;
if (version_response.major > GB_BATTERY_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
version_response.major, GB_BATTERY_VERSION_MAJOR);
return -ENOTSUPP;
}
gb->version_major = version_response.major;
gb->version_minor = version_response.minor;
return 0;
}
static int get_tech(struct gb_battery *gb) static int get_tech(struct gb_battery *gb)
{ {
......
...@@ -113,29 +113,8 @@ struct gb_gpio_set_debounce_request { ...@@ -113,29 +113,8 @@ struct gb_gpio_set_debounce_request {
/* debounce response has no payload */ /* debounce response has no payload */
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_gpio_controller, GPIO);
* fills in the major and minor protocol version of the target.
*/
static int gb_gpio_proto_version_operation(struct gb_gpio_controller *ggc)
{
struct gb_gpio_proto_version_response response;
int ret;
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_PROTOCOL_VERSION,
NULL, 0, &response, sizeof(response));
if (ret)
return ret;
if (response.major > GB_GPIO_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
response.major, GB_GPIO_VERSION_MAJOR);
return -ENOTSUPP;
}
ggc->version_major = response.major;
ggc->version_minor = response.minor;
return 0;
}
static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc) static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
{ {
...@@ -446,7 +425,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *gb_gpio_controlle ...@@ -446,7 +425,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *gb_gpio_controlle
int ret; int ret;
/* First thing we need to do is check the version */ /* First thing we need to do is check the version */
ret = gb_gpio_proto_version_operation(gb_gpio_controller); ret = get_version(gb_gpio_controller);
if (ret) if (ret)
; /* return ret; */ ; /* return ret; */
......
...@@ -87,30 +87,8 @@ struct gb_i2c_transfer_response { ...@@ -87,30 +87,8 @@ struct gb_i2c_transfer_response {
__u8 data[0]; /* inbound data */ __u8 data[0]; /* inbound data */
}; };
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_i2c_device, I2C);
* fills in the major and minor protocol version of the target.
*/
static int gb_i2c_proto_version_operation(struct gb_i2c_device *gb_i2c_dev)
{
struct gb_i2c_proto_version_response response;
int ret;
ret = gb_operation_sync(gb_i2c_dev->connection,
GB_I2C_TYPE_PROTOCOL_VERSION,
NULL, 0, &response, sizeof(response));
if (ret)
return ret;
if (response.major > GB_I2C_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
response.major, GB_I2C_VERSION_MAJOR);
return -ENOTSUPP;
}
gb_i2c_dev->version_major = response.major;
gb_i2c_dev->version_minor = response.minor;
return 0;
}
/* /*
* Map Greybus i2c functionality bits into Linux ones * Map Greybus i2c functionality bits into Linux ones
...@@ -361,7 +339,7 @@ static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) ...@@ -361,7 +339,7 @@ static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev)
int ret; int ret;
/* First thing we need to do is check the version */ /* First thing we need to do is check the version */
ret = gb_i2c_proto_version_operation(gb_i2c_dev); ret = get_version(gb_i2c_dev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -148,6 +148,32 @@ struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor) ...@@ -148,6 +148,32 @@ struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
return protocol; return protocol;
} }
int gb_protocol_get_version(struct gb_connection *connection, int type,
void *request, int request_size,
struct gb_protocol_version_response *response,
__u8 major)
{
int retval;
retval = gb_operation_sync(connection, type, request, request_size,
response, sizeof(*response));
if (retval)
return retval;
if (response->major > major) {
dev_err(&connection->dev,
"unsupported major version (%hhu > %hhu)\n",
response->major, major);
return -ENOTSUPP;
}
dev_dbg(&connection->dev, "version_major = %u version_minor = %u\n",
response->major, response->minor);
return 0;
}
EXPORT_SYMBOL_GPL(gb_protocol_get_version);
void gb_protocol_put(struct gb_protocol *protocol) void gb_protocol_put(struct gb_protocol *protocol)
{ {
u8 major; u8 major;
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
struct gb_operation; struct gb_operation;
/* version request has no payload */
struct gb_protocol_version_response {
__u8 major;
__u8 minor;
};
typedef int (*gb_connection_init_t)(struct gb_connection *); typedef int (*gb_connection_init_t)(struct gb_connection *);
typedef void (*gb_connection_exit_t)(struct gb_connection *); typedef void (*gb_connection_exit_t)(struct gb_connection *);
typedef void (*gb_request_recv_t)(u8, struct gb_operation *); typedef void (*gb_request_recv_t)(u8, struct gb_operation *);
...@@ -45,6 +51,11 @@ int gb_protocol_deregister(struct gb_protocol *protocol); ...@@ -45,6 +51,11 @@ int gb_protocol_deregister(struct gb_protocol *protocol);
__gb_protocol_register(protocol, THIS_MODULE) __gb_protocol_register(protocol, THIS_MODULE)
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor); struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
int gb_protocol_get_version(struct gb_connection *connection, int type,
void *request, int request_size,
struct gb_protocol_version_response *response,
__u8 major);
void gb_protocol_put(struct gb_protocol *protocol); void gb_protocol_put(struct gb_protocol *protocol);
/* /*
...@@ -82,4 +93,27 @@ static void __exit protocol_exit(void) \ ...@@ -82,4 +93,27 @@ static void __exit protocol_exit(void) \
} \ } \
module_exit(protocol_exit); module_exit(protocol_exit);
/*
* Macro to create get_version() routine for protocols
* @__device: name of the device struct
* @__protocol: name of protocol in CAPITALS
*/
#define define_get_version(__device, __protocol) \
static int get_version(struct __device *dev) \
{ \
struct gb_protocol_version_response response; \
int retval; \
\
retval = gb_protocol_get_version(dev->connection, \
GB_##__protocol##_TYPE_PROTOCOL_VERSION,\
NULL, 0, &response, \
GB_##__protocol##_VERSION_MAJOR); \
if (retval) \
return retval; \
\
dev->version_major = response.major; \
dev->version_minor = response.minor; \
return 0; \
}
#endif /* __PROTOCOL_H */ #endif /* __PROTOCOL_H */
...@@ -79,30 +79,8 @@ struct gb_pwm_disable_request { ...@@ -79,30 +79,8 @@ struct gb_pwm_disable_request {
__u8 which; __u8 which;
}; };
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_pwm_chip, PWM);
* fills in the major and minor protocol version of the target.
*/
static int gb_pwm_proto_version_operation(struct gb_pwm_chip *pwmc)
{
struct gb_pwm_proto_version_response response;
int ret;
ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_PROTOCOL_VERSION,
NULL, 0, &response, sizeof(response));
if (ret)
return ret;
if (response.major > GB_PWM_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
response.major, GB_PWM_VERSION_MAJOR);
return -ENOTSUPP;
}
pwmc->version_major = response.major;
pwmc->version_minor = response.minor;
return 0;
}
static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc) static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
{ {
...@@ -269,7 +247,7 @@ static int gb_pwm_connection_init(struct gb_connection *connection) ...@@ -269,7 +247,7 @@ static int gb_pwm_connection_init(struct gb_connection *connection)
connection->private = pwmc; connection->private = pwmc;
/* Check for compatible protocol version */ /* Check for compatible protocol version */
ret = gb_pwm_proto_version_operation(pwmc); ret = get_version(pwmc);
if (ret) if (ret)
goto out_err; goto out_err;
......
...@@ -131,33 +131,8 @@ static DEFINE_IDR(tty_minors); ...@@ -131,33 +131,8 @@ static DEFINE_IDR(tty_minors);
static DEFINE_MUTEX(table_lock); static DEFINE_MUTEX(table_lock);
static atomic_t reference_count = ATOMIC_INIT(0); static atomic_t reference_count = ATOMIC_INIT(0);
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_tty, UART);
* fills in the major and minor protocol version of the target.
*/
static int get_version(struct gb_tty *tty)
{
struct gb_uart_proto_version_response response;
int ret;
ret = gb_operation_sync(tty->connection,
GB_UART_TYPE_PROTOCOL_VERSION,
NULL, 0, &response, sizeof(response));
if (ret)
return ret;
if (response.major > GB_UART_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
response.major, GB_UART_VERSION_MAJOR);
return -ENOTSUPP;
}
tty->version_major = response.major;
tty->version_minor = response.minor;
pr_debug("%s: version_major = %u version_minor = %u\n",
__func__, tty->version_major, tty->version_minor);
return 0;
}
static int send_data(struct gb_tty *tty, u16 size, const u8 *data) static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
{ {
......
...@@ -93,26 +93,8 @@ struct gb_usb_device { ...@@ -93,26 +93,8 @@ struct gb_usb_device {
#define to_gb_usb_device(d) ((struct gb_usb_device*) d->hcd_priv) #define to_gb_usb_device(d) ((struct gb_usb_device*) d->hcd_priv)
static int get_version(struct gb_usb_device *dev) /* Define get_version() routine */
{ define_get_version(gb_usb_device, USB);
struct gb_usb_proto_version_response response;
int ret;
ret = gb_operation_sync(dev->connection,
GB_USB_TYPE_PROTOCOL_VERSION,
NULL, 0, &response, sizeof(response));
if (ret)
return ret;
if (response.major > GB_USB_VERSION_MAJOR) {
pr_err("unsupported major version (%hhu > %hhu)\n",
response.major, GB_USB_VERSION_MAJOR);
return -ENOTSUPP;
}
dev->version_major = response.major;
dev->version_minor = response.minor;
return 0;
}
static void hcd_stop(struct usb_hcd *hcd) static void hcd_stop(struct usb_hcd *hcd)
{ {
......
...@@ -43,34 +43,8 @@ struct gb_vibrator_on_request { ...@@ -43,34 +43,8 @@ struct gb_vibrator_on_request {
__le16 timeout_ms; __le16 timeout_ms;
}; };
/* /* Define get_version() routine */
* This request only uses the connection field, and if successful, define_get_version(gb_vibrator_device, VIBRATOR);
* fills in the major and minor protocol version of the target.
*/
static int get_version(struct gb_vibrator_device *vib)
{
struct gb_connection *connection = vib->connection;
struct gb_vibrator_proto_version_response version_response;
int retval;
retval = gb_operation_sync(connection,
GB_VIBRATOR_TYPE_PROTOCOL_VERSION,
NULL, 0,
&version_response, sizeof(version_response));
if (retval)
return retval;
if (version_response.major > GB_VIBRATOR_VERSION_MAJOR) {
dev_err(&connection->dev,
"unsupported major version (%hhu > %hhu)\n",
version_response.major, GB_VIBRATOR_VERSION_MAJOR);
return -ENOTSUPP;
}
vib->version_major = version_response.major;
vib->version_minor = version_response.minor;
return 0;
}
static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms) static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment