@@ -194,6 +194,91 @@ static int fun_chip_init(struct fsl_upm_nand *fun,
194
194
return ret ;
195
195
}
196
196
197
+ static int func_exec_instr (struct nand_chip * chip ,
198
+ const struct nand_op_instr * instr )
199
+ {
200
+ struct fsl_upm_nand * fun = to_fsl_upm_nand (nand_to_mtd (chip ));
201
+ u32 mar , reg_offs = fun -> mchip_offsets [fun -> mchip_number ];
202
+ unsigned int i ;
203
+ const u8 * out ;
204
+ u8 * in ;
205
+
206
+ switch (instr -> type ) {
207
+ case NAND_OP_CMD_INSTR :
208
+ fsl_upm_start_pattern (& fun -> upm , fun -> upm_cmd_offset );
209
+ mar = (instr -> ctx .cmd .opcode << (32 - fun -> upm .width )) |
210
+ reg_offs ;
211
+ fsl_upm_run_pattern (& fun -> upm , fun -> io_base + reg_offs , mar );
212
+ fsl_upm_end_pattern (& fun -> upm );
213
+ return 0 ;
214
+
215
+ case NAND_OP_ADDR_INSTR :
216
+ fsl_upm_start_pattern (& fun -> upm , fun -> upm_addr_offset );
217
+ for (i = 0 ; i < instr -> ctx .addr .naddrs ; i ++ ) {
218
+ mar = (instr -> ctx .addr .addrs [i ] << (32 - fun -> upm .width )) |
219
+ reg_offs ;
220
+ fsl_upm_run_pattern (& fun -> upm , fun -> io_base + reg_offs , mar );
221
+ }
222
+ fsl_upm_end_pattern (& fun -> upm );
223
+ return 0 ;
224
+
225
+ case NAND_OP_DATA_IN_INSTR :
226
+ in = instr -> ctx .data .buf .in ;
227
+ for (i = 0 ; i < instr -> ctx .data .len ; i ++ )
228
+ in [i ] = in_8 (fun -> io_base + reg_offs );
229
+ return 0 ;
230
+
231
+ case NAND_OP_DATA_OUT_INSTR :
232
+ out = instr -> ctx .data .buf .out ;
233
+ for (i = 0 ; i < instr -> ctx .data .len ; i ++ )
234
+ out_8 (fun -> io_base + reg_offs , out [i ]);
235
+ return 0 ;
236
+
237
+ case NAND_OP_WAITRDY_INSTR :
238
+ if (!fun -> rnb_gpio [fun -> mchip_number ])
239
+ return nand_soft_waitrdy (chip , instr -> ctx .waitrdy .timeout_ms );
240
+
241
+ return nand_gpio_waitrdy (chip , fun -> rnb_gpio [fun -> mchip_number ],
242
+ instr -> ctx .waitrdy .timeout_ms );
243
+
244
+ default :
245
+ return - EINVAL ;
246
+ }
247
+
248
+ return 0 ;
249
+ }
250
+
251
+ static int fun_exec_op (struct nand_chip * chip , const struct nand_operation * op ,
252
+ bool check_only )
253
+ {
254
+ struct fsl_upm_nand * fun = to_fsl_upm_nand (nand_to_mtd (chip ));
255
+ unsigned int i ;
256
+ int ret ;
257
+
258
+ if (op -> cs > NAND_MAX_CHIPS )
259
+ return - EINVAL ;
260
+
261
+ if (check_only )
262
+ return 0 ;
263
+
264
+ fun -> mchip_number = op -> cs ;
265
+
266
+ for (i = 0 ; i < op -> ninstrs ; i ++ ) {
267
+ ret = func_exec_instr (chip , & op -> instrs [i ]);
268
+ if (ret )
269
+ return ret ;
270
+
271
+ if (op -> instrs [i ].delay_ns )
272
+ ndelay (op -> instrs [i ].delay_ns );
273
+ }
274
+
275
+ return 0 ;
276
+ }
277
+
278
+ static const struct nand_controller_ops fun_ops = {
279
+ .exec_op = fun_exec_op ,
280
+ };
281
+
197
282
static int fun_probe (struct platform_device * ofdev )
198
283
{
199
284
struct fsl_upm_nand * fun ;
@@ -271,6 +356,7 @@ static int fun_probe(struct platform_device *ofdev)
271
356
FSL_UPM_WAIT_WRITE_BYTE ;
272
357
273
358
nand_controller_init (& fun -> base );
359
+ fun -> base .ops = & fun_ops ;
274
360
fun -> dev = & ofdev -> dev ;
275
361
fun -> last_ctrl = NAND_CLE ;
276
362
0 commit comments