@@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr)
2106
2106
}
2107
2107
EXPORT_SYMBOL_GPL (spi_get_next_queued_message );
2108
2108
2109
+ /*
2110
+ * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
2111
+ * and spi_maybe_unoptimize_message()
2112
+ * @msg: the message to unoptimize
2113
+ *
2114
+ * Peripheral drivers should use spi_unoptimize_message() and callers inside
2115
+ * core should use spi_maybe_unoptimize_message() rather than calling this
2116
+ * function directly.
2117
+ *
2118
+ * It is not valid to call this on a message that is not currently optimized.
2119
+ */
2120
+ static void __spi_unoptimize_message (struct spi_message * msg )
2121
+ {
2122
+ struct spi_controller * ctlr = msg -> spi -> controller ;
2123
+
2124
+ if (ctlr -> unoptimize_message )
2125
+ ctlr -> unoptimize_message (msg );
2126
+
2127
+ msg -> optimized = false;
2128
+ msg -> opt_state = NULL ;
2129
+ }
2130
+
2131
+ /*
2132
+ * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
2133
+ * @msg: the message to unoptimize
2134
+ *
2135
+ * This function is used to unoptimize a message if and only if it was
2136
+ * optimized by the core (via spi_maybe_optimize_message()).
2137
+ */
2138
+ static void spi_maybe_unoptimize_message (struct spi_message * msg )
2139
+ {
2140
+ if (!msg -> pre_optimized && msg -> optimized )
2141
+ __spi_unoptimize_message (msg );
2142
+ }
2143
+
2109
2144
/**
2110
2145
* spi_finalize_current_message() - the current message is complete
2111
2146
* @ctlr: the controller to return the message to
@@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
2153
2188
2154
2189
mesg -> prepared = false;
2155
2190
2191
+ spi_maybe_unoptimize_message (mesg );
2192
+
2156
2193
WRITE_ONCE (ctlr -> cur_msg_incomplete , false);
2157
2194
smp_mb (); /* See __spi_pump_transfer_message()... */
2158
2195
if (READ_ONCE (ctlr -> cur_msg_need_completion ))
@@ -4194,6 +4231,110 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
4194
4231
return 0 ;
4195
4232
}
4196
4233
4234
+ /*
4235
+ * __spi_optimize_message - shared implementation for spi_optimize_message()
4236
+ * and spi_maybe_optimize_message()
4237
+ * @spi: the device that will be used for the message
4238
+ * @msg: the message to optimize
4239
+ *
4240
+ * Peripheral drivers will call spi_optimize_message() and the spi core will
4241
+ * call spi_maybe_optimize_message() instead of calling this directly.
4242
+ *
4243
+ * It is not valid to call this on a message that has already been optimized.
4244
+ *
4245
+ * Return: zero on success, else a negative error code
4246
+ */
4247
+ static int __spi_optimize_message (struct spi_device * spi ,
4248
+ struct spi_message * msg )
4249
+ {
4250
+ struct spi_controller * ctlr = spi -> controller ;
4251
+ int ret ;
4252
+
4253
+ ret = __spi_validate (spi , msg );
4254
+ if (ret )
4255
+ return ret ;
4256
+
4257
+ if (ctlr -> optimize_message ) {
4258
+ ret = ctlr -> optimize_message (msg );
4259
+ if (ret )
4260
+ return ret ;
4261
+ }
4262
+
4263
+ msg -> optimized = true;
4264
+
4265
+ return 0 ;
4266
+ }
4267
+
4268
+ /*
4269
+ * spi_maybe_optimize_message - optimize message if it isn't already pre-optimized
4270
+ * @spi: the device that will be used for the message
4271
+ * @msg: the message to optimize
4272
+ * Return: zero on success, else a negative error code
4273
+ */
4274
+ static int spi_maybe_optimize_message (struct spi_device * spi ,
4275
+ struct spi_message * msg )
4276
+ {
4277
+ if (msg -> pre_optimized )
4278
+ return 0 ;
4279
+
4280
+ return __spi_optimize_message (spi , msg );
4281
+ }
4282
+
4283
+ /**
4284
+ * spi_optimize_message - do any one-time validation and setup for a SPI message
4285
+ * @spi: the device that will be used for the message
4286
+ * @msg: the message to optimize
4287
+ *
4288
+ * Peripheral drivers that reuse the same message repeatedly may call this to
4289
+ * perform as much message prep as possible once, rather than repeating it each
4290
+ * time a message transfer is performed to improve throughput and reduce CPU
4291
+ * usage.
4292
+ *
4293
+ * Once a message has been optimized, it cannot be modified with the exception
4294
+ * of updating the contents of any xfer->tx_buf (the pointer can't be changed,
4295
+ * only the data in the memory it points to).
4296
+ *
4297
+ * Calls to this function must be balanced with calls to spi_unoptimize_message()
4298
+ * to avoid leaking resources.
4299
+ *
4300
+ * Context: can sleep
4301
+ * Return: zero on success, else a negative error code
4302
+ */
4303
+ int spi_optimize_message (struct spi_device * spi , struct spi_message * msg )
4304
+ {
4305
+ int ret ;
4306
+
4307
+ ret = __spi_optimize_message (spi , msg );
4308
+ if (ret )
4309
+ return ret ;
4310
+
4311
+ /*
4312
+ * This flag indicates that the peripheral driver called spi_optimize_message()
4313
+ * and therefore we shouldn't unoptimize message automatically when finalizing
4314
+ * the message but rather wait until spi_unoptimize_message() is called
4315
+ * by the peripheral driver.
4316
+ */
4317
+ msg -> pre_optimized = true;
4318
+
4319
+ return 0 ;
4320
+ }
4321
+ EXPORT_SYMBOL_GPL (spi_optimize_message );
4322
+
4323
+ /**
4324
+ * spi_unoptimize_message - releases any resources allocated by spi_optimize_message()
4325
+ * @msg: the message to unoptimize
4326
+ *
4327
+ * Calls to this function must be balanced with calls to spi_optimize_message().
4328
+ *
4329
+ * Context: can sleep
4330
+ */
4331
+ void spi_unoptimize_message (struct spi_message * msg )
4332
+ {
4333
+ __spi_unoptimize_message (msg );
4334
+ msg -> pre_optimized = false;
4335
+ }
4336
+ EXPORT_SYMBOL_GPL (spi_unoptimize_message );
4337
+
4197
4338
static int __spi_async (struct spi_device * spi , struct spi_message * message )
4198
4339
{
4199
4340
struct spi_controller * ctlr = spi -> controller ;
@@ -4258,8 +4399,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
4258
4399
int ret ;
4259
4400
unsigned long flags ;
4260
4401
4261
- ret = __spi_validate (spi , message );
4262
- if (ret != 0 )
4402
+ ret = spi_maybe_optimize_message (spi , message );
4403
+ if (ret )
4263
4404
return ret ;
4264
4405
4265
4406
spin_lock_irqsave (& ctlr -> bus_lock_spinlock , flags );
@@ -4271,6 +4412,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
4271
4412
4272
4413
spin_unlock_irqrestore (& ctlr -> bus_lock_spinlock , flags );
4273
4414
4415
+ spi_maybe_unoptimize_message (message );
4416
+
4274
4417
return ret ;
4275
4418
}
4276
4419
EXPORT_SYMBOL_GPL (spi_async );
@@ -4331,8 +4474,8 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
4331
4474
return - ESHUTDOWN ;
4332
4475
}
4333
4476
4334
- status = __spi_validate (spi , message );
4335
- if (status != 0 )
4477
+ status = spi_maybe_optimize_message (spi , message );
4478
+ if (status )
4336
4479
return status ;
4337
4480
4338
4481
SPI_STATISTICS_INCREMENT_FIELD (ctlr -> pcpu_statistics , spi_sync );
0 commit comments