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; | 	unsigned int reg_shift = 0; | ||||||
| 	int pio_mode = 0; | 	int pio_mode = 0; | ||||||
| 	int pio_mask; | 	int pio_mask; | ||||||
|  | 	bool use16bit; | ||||||
| 
 | 
 | ||||||
| 	ret = of_address_to_resource(dn, 0, &io_res); | 	ret = of_address_to_resource(dn, 0, &io_res); | ||||||
| 	if (ret) { | 	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"); | 		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; | ||||||
| 	pio_mask |= (1 << pio_mode) - 1; | 	pio_mask |= (1 << pio_mode) - 1; | ||||||
| 
 | 
 | ||||||
| 	return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, irq_res, | 	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[] = { | 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), | 	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, | static void pata_platform_setup_port(struct ata_ioports *ioaddr, | ||||||
| 				     unsigned int shift) | 				     unsigned int shift) | ||||||
| { | { | ||||||
|  | @ -79,6 +72,7 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | ||||||
|  *	@ioport_shift: I/O port shift |  *	@ioport_shift: I/O port shift | ||||||
|  *	@__pio_mask: PIO mask |  *	@__pio_mask: PIO mask | ||||||
|  *	@sht: scsi_host_template to use when registering |  *	@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 |  *	Register a platform bus IDE interface. Such interfaces are PIO and we | ||||||
|  *	assume do not support IRQ sharing. |  *	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, | int __pata_platform_probe(struct device *dev, struct resource *io_res, | ||||||
| 			  struct resource *ctl_res, struct resource *irq_res, | 			  struct resource *ctl_res, struct resource *irq_res, | ||||||
| 			  unsigned int ioport_shift, int __pio_mask, | 			  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_host *host; | ||||||
| 	struct ata_port *ap; | 	struct ata_port *ap; | ||||||
|  | @ -131,7 +125,15 @@ int __pata_platform_probe(struct device *dev, struct resource *io_res, | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 	ap = host->ports[0]; | 	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->pio_mask = __pio_mask; | ||||||
| 	ap->flags |= ATA_FLAG_SLAVE_POSS; | 	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, | 	return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, | ||||||
| 				     pp_info ? pp_info->ioport_shift : 0, | 				     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 = { | static struct platform_driver pata_platform_driver = { | ||||||
|  |  | ||||||
|  | @ -19,7 +19,8 @@ extern int __pata_platform_probe(struct device *dev, | ||||||
| 				 struct resource *irq_res, | 				 struct resource *irq_res, | ||||||
| 				 unsigned int ioport_shift, | 				 unsigned int ioport_shift, | ||||||
| 				 int __pio_mask, | 				 int __pio_mask, | ||||||
| 				 struct scsi_host_template *sht); | 				 struct scsi_host_template *sht, | ||||||
|  | 				 bool use16bit); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Marvell SATA private data |  * Marvell SATA private data | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Alexander Shiyan
						Alexander Shiyan