forked from mirrors/linux
		
	ata: pata_of_platform: Allow to use 16-bit wide data transfer
In some cases, the system bus can be configured for 16-bit mode, in this case using read/write functions for 32-bit values results in two cycles of 16 bits each, which is wrong. This patch adds the devicetree flag to switch the driver to use 16-bit mode for I/O transfers. Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
		
							parent
							
								
									740c68a0cd
								
							
						
					
					
						commit
						f3d5e4f18d
					
				
					 3 changed files with 19 additions and 12 deletions
				
			
		|  | @ -32,6 +32,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev) | |||
| 	unsigned int reg_shift = 0; | ||||
| 	int pio_mode = 0; | ||||
| 	int pio_mask; | ||||
| 	bool use16bit; | ||||
| 
 | ||||
| 	ret = of_address_to_resource(dn, 0, &io_res); | ||||
| 	if (ret) { | ||||
|  | @ -60,11 +61,14 @@ static int pata_of_platform_probe(struct platform_device *ofdev) | |||
| 		dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	use16bit = of_property_read_bool(dn, "ata-generic,use16bit"); | ||||
| 
 | ||||
| 	pio_mask = 1 << pio_mode; | ||||
| 	pio_mask |= (1 << pio_mode) - 1; | ||||
| 
 | ||||
| 	return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, irq_res, | ||||
| 				     reg_shift, pio_mask, &pata_platform_sht); | ||||
| 				     reg_shift, pio_mask, &pata_platform_sht, | ||||
| 				     use16bit); | ||||
| } | ||||
| 
 | ||||
| static const struct of_device_id pata_of_platform_match[] = { | ||||
|  |  | |||
|  | @ -47,13 +47,6 @@ static struct scsi_host_template pata_platform_sht = { | |||
| 	ATA_PIO_SHT(DRV_NAME), | ||||
| }; | ||||
| 
 | ||||
| static struct ata_port_operations pata_platform_port_ops = { | ||||
| 	.inherits		= &ata_sff_port_ops, | ||||
| 	.sff_data_xfer		= ata_sff_data_xfer32, | ||||
| 	.cable_detect		= ata_cable_unknown, | ||||
| 	.set_mode		= pata_platform_set_mode, | ||||
| }; | ||||
| 
 | ||||
| static void pata_platform_setup_port(struct ata_ioports *ioaddr, | ||||
| 				     unsigned int shift) | ||||
| { | ||||
|  | @ -79,6 +72,7 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
|  *	@ioport_shift: I/O port shift | ||||
|  *	@__pio_mask: PIO mask | ||||
|  *	@sht: scsi_host_template to use when registering | ||||
|  *	@use16bit: Flag to indicate 16-bit IO instead of 32-bit | ||||
|  * | ||||
|  *	Register a platform bus IDE interface. Such interfaces are PIO and we | ||||
|  *	assume do not support IRQ sharing. | ||||
|  | @ -101,7 +95,7 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
| int __pata_platform_probe(struct device *dev, struct resource *io_res, | ||||
| 			  struct resource *ctl_res, struct resource *irq_res, | ||||
| 			  unsigned int ioport_shift, int __pio_mask, | ||||
| 			  struct scsi_host_template *sht) | ||||
| 			  struct scsi_host_template *sht, bool use16bit) | ||||
| { | ||||
| 	struct ata_host *host; | ||||
| 	struct ata_port *ap; | ||||
|  | @ -131,7 +125,15 @@ int __pata_platform_probe(struct device *dev, struct resource *io_res, | |||
| 		return -ENOMEM; | ||||
| 	ap = host->ports[0]; | ||||
| 
 | ||||
| 	ap->ops = &pata_platform_port_ops; | ||||
| 	ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL); | ||||
| 	ap->ops->inherits = &ata_sff_port_ops; | ||||
| 	ap->ops->cable_detect = ata_cable_unknown; | ||||
| 	ap->ops->set_mode = pata_platform_set_mode; | ||||
| 	if (use16bit) | ||||
| 		ap->ops->sff_data_xfer = ata_sff_data_xfer; | ||||
| 	else | ||||
| 		ap->ops->sff_data_xfer = ata_sff_data_xfer32; | ||||
| 
 | ||||
| 	ap->pio_mask = __pio_mask; | ||||
| 	ap->flags |= ATA_FLAG_SLAVE_POSS; | ||||
| 
 | ||||
|  | @ -218,7 +220,7 @@ static int pata_platform_probe(struct platform_device *pdev) | |||
| 
 | ||||
| 	return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, | ||||
| 				     pp_info ? pp_info->ioport_shift : 0, | ||||
| 				     pio_mask, &pata_platform_sht); | ||||
| 				     pio_mask, &pata_platform_sht, false); | ||||
| } | ||||
| 
 | ||||
| static struct platform_driver pata_platform_driver = { | ||||
|  |  | |||
|  | @ -19,7 +19,8 @@ extern int __pata_platform_probe(struct device *dev, | |||
| 				 struct resource *irq_res, | ||||
| 				 unsigned int ioport_shift, | ||||
| 				 int __pio_mask, | ||||
| 				 struct scsi_host_template *sht); | ||||
| 				 struct scsi_host_template *sht, | ||||
| 				 bool use16bit); | ||||
| 
 | ||||
| /*
 | ||||
|  * Marvell SATA private data | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Alexander Shiyan
						Alexander Shiyan