ahci: Turn off DMA engines when there's no device attached
According to section 10.3.1 of the AHCI spec, PxCMD.ST must not be set unless there's a device attached. Following this saves us a measurable quantity of power and does not impair hotplug support. Based on a patch by Kristen Carlson Accardi. Signed-off-by: Matthew Garrett <mjg@redhat.com> Cc: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
		
					parent
					
						
							
								1c2a49f617
							
						
					
				
			
			
				commit
				
					
						96d60303fd
					
				
			
		
					 1 changed files with 18 additions and 0 deletions
				
			
		|  | @ -437,11 +437,29 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) | |||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| static int ahci_is_device_present(void __iomem *port_mmio) | ||||
| { | ||||
| 	u8 status = readl(port_mmio + PORT_TFDATA) & 0xff; | ||||
| 
 | ||||
| 	/* Make sure PxTFD.STS.BSY and PxTFD.STS.DRQ are 0 */ | ||||
| 	if (status & (ATA_BUSY | ATA_DRQ)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Make sure PxSSTS.DET is 3h */ | ||||
| 	status = readl(port_mmio + PORT_SCR_STAT) & 0xf; | ||||
| 	if (status != 3) | ||||
| 		return 0; | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| void ahci_start_engine(struct ata_port *ap) | ||||
| { | ||||
| 	void __iomem *port_mmio = ahci_port_base(ap); | ||||
| 	u32 tmp; | ||||
| 
 | ||||
| 	if (!ahci_is_device_present(port_mmio)) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* start DMA */ | ||||
| 	tmp = readl(port_mmio + PORT_CMD); | ||||
| 	tmp |= PORT_CMD_START; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Matthew Garrett
				Matthew Garrett