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

This gets rid of lots of duplication of code.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Viresh Kumar 2015-01-21 18:12:36 +05:30 committed by Greg Kroah-Hartman
parent 530430b717
commit 36e79dec96
9 changed files with 77 additions and 175 deletions

View File

@ -88,32 +88,8 @@ struct gb_battery_voltage_response {
__le32 voltage;
};
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_battery, BATTERY);
static int get_tech(struct gb_battery *gb)
{

View File

@ -113,29 +113,8 @@ struct gb_gpio_set_debounce_request {
/* debounce response has no payload */
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_gpio_controller, GPIO);
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
int ret;
/* 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)
; /* return ret; */

View File

@ -87,30 +87,8 @@ struct gb_i2c_transfer_response {
__u8 data[0]; /* inbound data */
};
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_i2c_device, I2C);
/*
* 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)
int ret;
/* 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)
return ret;

View File

@ -148,6 +148,32 @@ struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
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)
{
u8 major;

View File

@ -14,6 +14,12 @@
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 void (*gb_connection_exit_t)(struct gb_connection *);
typedef void (*gb_request_recv_t)(u8, struct gb_operation *);
@ -45,6 +51,11 @@ int gb_protocol_deregister(struct gb_protocol *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, int type,
void *request, int request_size,
struct gb_protocol_version_response *response,
__u8 major);
void gb_protocol_put(struct gb_protocol *protocol);
/*
@ -82,4 +93,27 @@ static void __exit protocol_exit(void) \
} \
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 */

View File

@ -79,30 +79,8 @@ struct gb_pwm_disable_request {
__u8 which;
};
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_pwm_chip, PWM);
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)
connection->private = pwmc;
/* Check for compatible protocol version */
ret = gb_pwm_proto_version_operation(pwmc);
ret = get_version(pwmc);
if (ret)
goto out_err;

View File

@ -131,33 +131,8 @@ static DEFINE_IDR(tty_minors);
static DEFINE_MUTEX(table_lock);
static atomic_t reference_count = ATOMIC_INIT(0);
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_tty, UART);
static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
{

View File

@ -93,26 +93,8 @@ struct gb_usb_device {
#define to_gb_usb_device(d) ((struct gb_usb_device*) d->hcd_priv)
static int get_version(struct gb_usb_device *dev)
{
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;
}
/* Define get_version() routine */
define_get_version(gb_usb_device, USB);
static void hcd_stop(struct usb_hcd *hcd)
{

View File

@ -43,34 +43,8 @@ struct gb_vibrator_on_request {
__le16 timeout_ms;
};
/*
* This request only uses the connection field, and if successful,
* 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;
}
/* Define get_version() routine */
define_get_version(gb_vibrator_device, VIBRATOR);
static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
{