@@ -131,12 +131,10 @@ struct moxart_host {
131
131
struct dma_async_tx_descriptor * tx_desc ;
132
132
struct mmc_host * mmc ;
133
133
struct mmc_request * mrq ;
134
- struct scatterlist * cur_sg ;
135
134
struct completion dma_complete ;
136
135
struct completion pio_complete ;
137
136
138
- u32 num_sg ;
139
- u32 data_remain ;
137
+ struct sg_mapping_iter sg_miter ;
140
138
u32 data_len ;
141
139
u32 fifo_width ;
142
140
u32 timeout ;
@@ -148,35 +146,6 @@ struct moxart_host {
148
146
bool is_removed ;
149
147
};
150
148
151
- static inline void moxart_init_sg (struct moxart_host * host ,
152
- struct mmc_data * data )
153
- {
154
- host -> cur_sg = data -> sg ;
155
- host -> num_sg = data -> sg_len ;
156
- host -> data_remain = host -> cur_sg -> length ;
157
-
158
- if (host -> data_remain > host -> data_len )
159
- host -> data_remain = host -> data_len ;
160
- }
161
-
162
- static inline int moxart_next_sg (struct moxart_host * host )
163
- {
164
- int remain ;
165
- struct mmc_data * data = host -> mrq -> cmd -> data ;
166
-
167
- host -> cur_sg ++ ;
168
- host -> num_sg -- ;
169
-
170
- if (host -> num_sg > 0 ) {
171
- host -> data_remain = host -> cur_sg -> length ;
172
- remain = host -> data_len - data -> bytes_xfered ;
173
- if (remain > 0 && remain < host -> data_remain )
174
- host -> data_remain = remain ;
175
- }
176
-
177
- return host -> num_sg ;
178
- }
179
-
180
149
static int moxart_wait_for_status (struct moxart_host * host ,
181
150
u32 mask , u32 * status )
182
151
{
@@ -309,14 +278,28 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
309
278
310
279
static void moxart_transfer_pio (struct moxart_host * host )
311
280
{
281
+ struct sg_mapping_iter * sgm = & host -> sg_miter ;
312
282
struct mmc_data * data = host -> mrq -> cmd -> data ;
313
283
u32 * sgp , len = 0 , remain , status ;
314
284
315
285
if (host -> data_len == data -> bytes_xfered )
316
286
return ;
317
287
318
- sgp = sg_virt (host -> cur_sg );
319
- remain = host -> data_remain ;
288
+ /*
289
+ * By updating sgm->consumes this will get a proper pointer into the
290
+ * buffer at any time.
291
+ */
292
+ if (!sg_miter_next (sgm )) {
293
+ /* This shold not happen */
294
+ dev_err (mmc_dev (host -> mmc ), "ran out of scatterlist prematurely\n" );
295
+ data -> error = - EINVAL ;
296
+ complete (& host -> pio_complete );
297
+ return ;
298
+ }
299
+ sgp = sgm -> addr ;
300
+ remain = sgm -> length ;
301
+ if (remain > host -> data_len )
302
+ remain = host -> data_len ;
320
303
321
304
if (data -> flags & MMC_DATA_WRITE ) {
322
305
while (remain > 0 ) {
@@ -331,6 +314,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
331
314
sgp ++ ;
332
315
len += 4 ;
333
316
}
317
+ sgm -> consumed += len ;
334
318
remain -= len ;
335
319
}
336
320
@@ -347,22 +331,22 @@ static void moxart_transfer_pio(struct moxart_host *host)
347
331
sgp ++ ;
348
332
len += 4 ;
349
333
}
334
+ sgm -> consumed += len ;
350
335
remain -= len ;
351
336
}
352
337
}
353
338
354
- data -> bytes_xfered += host -> data_remain - remain ;
355
- host -> data_remain = remain ;
356
-
357
- if (host -> data_len != data -> bytes_xfered )
358
- moxart_next_sg (host );
359
- else
339
+ data -> bytes_xfered += sgm -> consumed ;
340
+ if (host -> data_len == data -> bytes_xfered ) {
360
341
complete (& host -> pio_complete );
342
+ return ;
343
+ }
361
344
}
362
345
363
346
static void moxart_prepare_data (struct moxart_host * host )
364
347
{
365
348
struct mmc_data * data = host -> mrq -> cmd -> data ;
349
+ unsigned int flags = SG_MITER_ATOMIC ; /* Used from IRQ */
366
350
u32 datactrl ;
367
351
int blksz_bits ;
368
352
@@ -373,15 +357,19 @@ static void moxart_prepare_data(struct moxart_host *host)
373
357
blksz_bits = ffs (data -> blksz ) - 1 ;
374
358
BUG_ON (1 << blksz_bits != data -> blksz );
375
359
376
- moxart_init_sg (host , data );
377
-
378
360
datactrl = DCR_DATA_EN | (blksz_bits & DCR_BLK_SIZE );
379
361
380
- if (data -> flags & MMC_DATA_WRITE )
362
+ if (data -> flags & MMC_DATA_WRITE ) {
363
+ flags |= SG_MITER_FROM_SG ;
381
364
datactrl |= DCR_DATA_WRITE ;
365
+ } else {
366
+ flags |= SG_MITER_TO_SG ;
367
+ }
382
368
383
369
if (moxart_use_dma (host ))
384
370
datactrl |= DCR_DMA_EN ;
371
+ else
372
+ sg_miter_start (& host -> sg_miter , data -> sg , data -> sg_len , flags );
385
373
386
374
writel (DCR_DATA_FIFO_RESET , host -> base + REG_DATA_CONTROL );
387
375
writel (MASK_DATA | FIFO_URUN | FIFO_ORUN , host -> base + REG_CLEAR );
@@ -454,6 +442,9 @@ static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
454
442
}
455
443
456
444
request_done :
445
+ if (!moxart_use_dma (host ))
446
+ sg_miter_stop (& host -> sg_miter );
447
+
457
448
spin_unlock_irqrestore (& host -> lock , flags );
458
449
mmc_request_done (host -> mmc , mrq );
459
450
}
0 commit comments