Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ata: ftide010: Add a quirk for SQ201

The DMA is broken on this specific device for some unknown
reason (probably badly designed or plain broken interface
electronics) and will only work with PIO. Other users of
the same hardware does not have this problem.

Add a specific quirk so that this Gemini device gets
DMA turned off. Also fix up some code around passing the
port information around in probe while we're at it.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Linus Walleij and committed by
Jens Axboe
46cb52ad b0a84beb

+17 -10
+17 -10
drivers/ata/pata_ftide010.c
··· 256 256 .qc_issue = ftide010_qc_issue, 257 257 }; 258 258 259 - static struct ata_port_info ftide010_port_info[] = { 260 - { 261 - .flags = ATA_FLAG_SLAVE_POSS, 262 - .mwdma_mask = ATA_MWDMA2, 263 - .udma_mask = ATA_UDMA6, 264 - .pio_mask = ATA_PIO4, 265 - .port_ops = &pata_ftide010_port_ops, 266 - }, 259 + static struct ata_port_info ftide010_port_info = { 260 + .flags = ATA_FLAG_SLAVE_POSS, 261 + .mwdma_mask = ATA_MWDMA2, 262 + .udma_mask = ATA_UDMA6, 263 + .pio_mask = ATA_PIO4, 264 + .port_ops = &pata_ftide010_port_ops, 267 265 }; 268 266 269 267 #if IS_ENABLED(CONFIG_SATA_GEMINI) ··· 347 349 } 348 350 349 351 static int pata_ftide010_gemini_init(struct ftide010 *ftide, 352 + struct ata_port_info *pi, 350 353 bool is_ata1) 351 354 { 352 355 struct device *dev = ftide->dev; ··· 372 373 373 374 /* Flag port as SATA-capable */ 374 375 if (gemini_sata_bridge_enabled(sg, is_ata1)) 375 - ftide010_port_info[0].flags |= ATA_FLAG_SATA; 376 + pi->flags |= ATA_FLAG_SATA; 377 + 378 + /* This device has broken DMA, only PIO works */ 379 + if (of_machine_is_compatible("itian,sq201")) { 380 + pi->mwdma_mask = 0; 381 + pi->udma_mask = 0; 382 + } 376 383 377 384 /* 378 385 * We assume that a simple 40-wire cable is used in the PATA mode. ··· 440 435 } 441 436 #else 442 437 static int pata_ftide010_gemini_init(struct ftide010 *ftide, 438 + struct ata_port_info *pi, 443 439 bool is_ata1) 444 440 { 445 441 return -ENOTSUPP; ··· 452 446 { 453 447 struct device *dev = &pdev->dev; 454 448 struct device_node *np = dev->of_node; 455 - const struct ata_port_info pi = ftide010_port_info[0]; 449 + struct ata_port_info pi = ftide010_port_info; 456 450 const struct ata_port_info *ppi[] = { &pi, NULL }; 457 451 struct ftide010 *ftide; 458 452 struct resource *res; ··· 496 490 * are ATA0. This will also set up the cable types. 497 491 */ 498 492 ret = pata_ftide010_gemini_init(ftide, 493 + &pi, 499 494 (res->start == 0x63400000)); 500 495 if (ret) 501 496 goto err_dis_clk;