From: Johan Hovold Date: Wed, 1 Jul 2015 10:37:22 +0000 (+0200) Subject: greybus: operation: allow atomic operation allocations X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~1425 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=e420721b47ef5b0d521584d4efc89ff64bd0cd74;p=karo-tx-linux.git greybus: operation: allow atomic operation allocations Add gfp mask argument to gb_operation_create to allow operations to be allocated in atomic context. Signed-off-by: Johan Hovold Reviewed-by: Bryan O'Donoghue Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c index 1214b7a0a631..a367fd5fad70 100644 --- a/drivers/staging/greybus/hid.c +++ b/drivers/staging/greybus/hid.c @@ -128,7 +128,8 @@ static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id, int ret, size = sizeof(*request) + len - 1; operation = gb_operation_create(ghid->connection, - GB_HID_TYPE_SET_REPORT, size, 0); + GB_HID_TYPE_SET_REPORT, size, 0, + GFP_KERNEL); if (!operation) return -ENOMEM; diff --git a/drivers/staging/greybus/i2c.c b/drivers/staging/greybus/i2c.c index 5eb7703599d6..9514e69d0d4b 100644 --- a/drivers/staging/greybus/i2c.c +++ b/drivers/staging/greybus/i2c.c @@ -146,7 +146,7 @@ gb_i2c_operation_create(struct gb_connection *connection, /* Response consists only of incoming data */ operation = gb_operation_create(connection, GB_I2C_TYPE_TRANSFER, - request_size, data_in_size); + request_size, data_in_size, GFP_KERNEL); if (!operation) return NULL; diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index b125bde32249..4019b030e31c 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -409,22 +409,13 @@ EXPORT_SYMBOL_GPL(gb_operation_response_alloc); */ static struct gb_operation * gb_operation_create_common(struct gb_connection *connection, u8 type, - size_t request_size, size_t response_size) + size_t request_size, size_t response_size, + gfp_t gfp_flags) { struct greybus_host_device *hd = connection->hd; struct gb_operation *operation; unsigned long flags; - gfp_t gfp_flags; - /* - * An incoming request will pass an invalid operation type, - * because the header will get overwritten anyway. These - * occur in interrupt context, so we must use GFP_ATOMIC. - */ - if (type == GB_OPERATION_TYPE_INVALID) - gfp_flags = GFP_ATOMIC; - else - gfp_flags = GFP_KERNEL; operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); if (!operation) return NULL; @@ -472,7 +463,8 @@ err_cache: */ struct gb_operation *gb_operation_create(struct gb_connection *connection, u8 type, size_t request_size, - size_t response_size) + size_t response_size, + gfp_t gfp) { if (WARN_ON_ONCE(type == GB_OPERATION_TYPE_INVALID)) return NULL; @@ -480,7 +472,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection, type &= ~GB_MESSAGE_TYPE_RESPONSE; return gb_operation_create_common(connection, type, - request_size, response_size); + request_size, response_size, gfp); } EXPORT_SYMBOL_GPL(gb_operation_create); @@ -504,7 +496,7 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id, operation = gb_operation_create_common(connection, GB_OPERATION_TYPE_INVALID, - request_size, 0); + request_size, 0, GFP_ATOMIC); if (operation) { operation->id = id; operation->type = type; @@ -888,7 +880,8 @@ int gb_operation_sync(struct gb_connection *connection, int type, return -EINVAL; operation = gb_operation_create(connection, type, - request_size, response_size); + request_size, response_size, + GFP_KERNEL); if (!operation) return -ENOMEM; diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index ad4574b4bfdf..395664835eac 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -134,7 +134,8 @@ int gb_operation_result(struct gb_operation *operation); size_t gb_operation_get_payload_size_max(struct gb_connection *connection); struct gb_operation *gb_operation_create(struct gb_connection *connection, u8 type, size_t request_size, - size_t response_size); + size_t response_size, + gfp_t gfp); void gb_operation_get(struct gb_operation *operation); void gb_operation_put(struct gb_operation *operation); static inline void gb_operation_destroy(struct gb_operation *operation) diff --git a/drivers/staging/greybus/spi.c b/drivers/staging/greybus/spi.c index 374361889666..306fb074c183 100644 --- a/drivers/staging/greybus/spi.c +++ b/drivers/staging/greybus/spi.c @@ -90,7 +90,7 @@ gb_spi_operation_create(struct gb_connection *connection, /* Response consists only of incoming data */ operation = gb_operation_create(connection, GB_SPI_TYPE_TRANSFER, - request_size, rx_size); + request_size, rx_size, GFP_KERNEL); if (!operation) return NULL; diff --git a/drivers/staging/greybus/usb.c b/drivers/staging/greybus/usb.c index 888f514921b6..e49fffdca53b 100644 --- a/drivers/staging/greybus/usb.c +++ b/drivers/staging/greybus/usb.c @@ -131,7 +131,8 @@ static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) operation = gb_operation_create(dev->connection, GB_USB_TYPE_URB_ENQUEUE, sizeof(*request) + - urb->transfer_buffer_length, 0); + urb->transfer_buffer_length, 0, + GFP_KERNEL); if (!operation) return -ENODEV;