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 <johan@hovoldconsulting.com> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
3e136cc9e0
commit
e420721b47
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue