Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9978ec5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libata updates from Jeff Garzik:

1) apply, and then revert, the sysfs export of ATA host controller
   number.  Discussion was continuing after patch application, trying to
   figure out how to best mesh exported data with the installers,
   boot-time agents and other parties that want this info.

2) Merge Zero-Power Optical Device Driver (ZPODD) support, bringing the
   wonderfulness of sane power management to your CD/DVD device.

   Includes one SCSI-subsystem patch (with appropriate ACKs), adding
   runtime PM support to 'sr' driver.  That is the ZPODD interaction
   bits.

   Patchset went through some 13 revisions before it got here; kudos to
   Intel for persistence.

3) pata_samsung_cf: use devm_clk_get()

4) more ata_piix, ahci PCI IDs

5) Add SATA driver for R-Car SoC

6) Convert libata to use devm_ioremap_resource (Note: I think Greg sent
   this to you, also)

7) Set proper Sense Key (SK) in the SCSI simulator when ATA passthrough
   indicates check condition.  Google and specification hawks everywhere
   shall rejoice.

* tag 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (22 commits)
  [libata] fix smatch warning for zpodd_wake_dev
  [libata] Set proper SK when CK_COND is set.
  [libata] Convert to devm_ioremap_resource()
  libata: add R-Car SATA driver
  ahci: Add Device IDs for Intel Wellsburg PCH
  ata_piix: Add Device IDs for Intel Wellsburg PCH
  [SCSI] remove can_power_off flag from scsi_device
  [libata] scsi: no poll when ODD is powered off
  [SCSI] sr: support runtime pm
  ahci: AHCI-mode SATA patch for Intel Avoton DeviceIDs
  ata_piix: IDE-mode SATA patch for Intel Avoton DeviceIDs
  [libata] PM code cleanup for ata port
  [libata] pm: differentiate system and runtime pm for ata port
  Revert "libata: export host controller number thru /sys"
  libata: do not suspend port if normal ODD is attached
  libata: expose pm qos flags for ata device
  libata: handle power transition of ODD
  libata: check zero power ready status for ZPODD
  libata: move acpi notification code to zpodd
  libata: identify and init ZPODD devices
  ...
parents a883b70d 53637e07
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -58,6 +58,19 @@ config ATA_ACPI
	  You can disable this at kernel boot time by using the
	  option libata.noacpi=1

config SATA_ZPODD
	bool "SATA Zero Power ODD Support"
	depends on ATA_ACPI
	default n
	help
	  This option adds support for SATA ZPODD. It requires both
	  ODD and the platform support, and if enabled, will automatically
	  power on/off the ODD when certain condition is satisfied. This
	  does not impact user's experience of the ODD, only power is saved
	  when ODD is not in use(i.e. no disc inside).

	  If unsure, say N.

config SATA_PMP
	bool "SATA Port Multiplier support"
	default y
@@ -247,6 +260,14 @@ config SATA_PROMISE

	  If unsure, say N.

config SATA_RCAR
	tristate "Renesas R-Car SATA support"
	depends on ARCH_SHMOBILE && ARCH_R8A7779
	help
	  This option enables support for Renesas R-Car Serial ATA.

	  If unsure, say N.

config SATA_SIL
	tristate "Silicon Image SATA support"
	depends on PCI
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ obj-$(CONFIG_ATA_PIIX) += ata_piix.o
obj-$(CONFIG_SATA_MV)		+= sata_mv.o
obj-$(CONFIG_SATA_NV)		+= sata_nv.o
obj-$(CONFIG_SATA_PROMISE)	+= sata_promise.o
obj-$(CONFIG_SATA_RCAR)		+= sata_rcar.o
obj-$(CONFIG_SATA_SIL)		+= sata_sil.o
obj-$(CONFIG_SATA_SIS)		+= sata_sis.o
obj-$(CONFIG_SATA_SVW)		+= sata_svw.o
@@ -107,3 +108,4 @@ libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF)	+= libata-sff.o
libata-$(CONFIG_SATA_PMP)	+= libata-pmp.o
libata-$(CONFIG_ATA_ACPI)	+= libata-acpi.o
libata-$(CONFIG_SATA_ZPODD)	+= libata-zpodd.o
+24 −0
Original line number Diff line number Diff line
@@ -265,6 +265,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
	{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
	{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
	{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
	{ PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
	{ PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
	{ PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
	{ PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
	{ PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */

	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+17 −0
Original line number Diff line number Diff line
@@ -317,6 +317,23 @@ static const struct pci_device_id piix_pci_tbl[] = {
	{ 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (DH89xxCC) */
	{ 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (Avoton) */
	{ 0x8086, 0x1f20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
	/* SATA Controller IDE (Avoton) */
	{ 0x8086, 0x1f21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
	/* SATA Controller IDE (Avoton) */
	{ 0x8086, 0x1f30, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (Avoton) */
	{ 0x8086, 0x1f31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (Wellsburg) */
	{ 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
	/* SATA Controller IDE (Wellsburg) */
	{ 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
	/* SATA Controller IDE (Wellsburg) */
	{ 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
	/* SATA Controller IDE (Wellsburg) */
	{ 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },

	{ }	/* terminate list */
};

+77 −100
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pm_qos.h>
#include <scsi/scsi_device.h>
#include "libata.h"

@@ -835,50 +836,95 @@ void ata_acpi_on_resume(struct ata_port *ap)
	}
}

/**
 * ata_acpi_set_state - set the port power state
 * @ap: target ATA port
 * @state: state, on/off
 *
 * This function executes the _PS0/_PS3 ACPI method to set the power state.
 * ACPI spec requires _PS0 when IDE power on and _PS3 when power off
static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
{
	int d_max_in = ACPI_STATE_D3_COLD;
	if (!runtime)
		goto out;

	/*
	 * For ATAPI, runtime D3 cold is only allowed
	 * for ZPODD in zero power ready state
	 */
void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
	if (dev->class == ATA_DEV_ATAPI &&
	    !(zpodd_dev_enabled(dev) && zpodd_zpready(dev)))
		d_max_in = ACPI_STATE_D3_HOT;

out:
	return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev,
					  NULL, d_max_in);
}

static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
{
	bool runtime = PMSG_IS_AUTO(state);
	struct ata_device *dev;
	acpi_handle handle;
	int acpi_state;

	/* channel first and then drives for power on and vica versa
	   for power off */
	handle = ata_ap_acpi_handle(ap);
	if (handle && state.event == PM_EVENT_ON)
		acpi_bus_set_power(handle, ACPI_STATE_D0);

	ata_for_each_dev(dev, &ap->link, ENABLED) {
		handle = ata_dev_acpi_handle(dev);
		if (!handle)
			continue;

		if (state.event != PM_EVENT_ON) {
			acpi_state = acpi_pm_device_sleep_state(
				&dev->sdev->sdev_gendev, NULL, ACPI_STATE_D3);
			if (acpi_state > 0)
		if (!(state.event & PM_EVENT_RESUME)) {
			acpi_state = ata_acpi_choose_suspend_state(dev, runtime);
			if (acpi_state == ACPI_STATE_D0)
				continue;
			if (runtime && zpodd_dev_enabled(dev) &&
			    acpi_state == ACPI_STATE_D3_COLD)
				zpodd_enable_run_wake(dev);
			acpi_bus_set_power(handle, acpi_state);
			/* TBD: need to check if it's runtime pm request */
			acpi_pm_device_run_wake(
				&dev->sdev->sdev_gendev, true);
		} else {
			/* Ditto */
			acpi_pm_device_run_wake(
				&dev->sdev->sdev_gendev, false);
			if (runtime && zpodd_dev_enabled(dev))
				zpodd_disable_run_wake(dev);
			acpi_bus_set_power(handle, ACPI_STATE_D0);
		}
	}
}

/* ACPI spec requires _PS0 when IDE power on and _PS3 when power off */
static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
{
	struct ata_device *dev;
	acpi_handle port_handle;

	port_handle = ata_ap_acpi_handle(ap);
	if (!port_handle)
		return;

	/* channel first and then drives for power on and vica versa
	   for power off */
	if (state.event & PM_EVENT_RESUME)
		acpi_bus_set_power(port_handle, ACPI_STATE_D0);

	ata_for_each_dev(dev, &ap->link, ENABLED) {
		acpi_handle dev_handle = ata_dev_acpi_handle(dev);
		if (!dev_handle)
			continue;

		acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ?
						ACPI_STATE_D0 : ACPI_STATE_D3);
	}

	handle = ata_ap_acpi_handle(ap);
	if (handle && state.event != PM_EVENT_ON)
		acpi_bus_set_power(handle, ACPI_STATE_D3);
	if (!(state.event & PM_EVENT_RESUME))
		acpi_bus_set_power(port_handle, ACPI_STATE_D3);
}

/**
 * ata_acpi_set_state - set the port power state
 * @ap: target ATA port
 * @state: state, on/off
 *
 * This function sets a proper ACPI D state for the device on
 * system and runtime PM operations.
 */
void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
{
	if (ap->flags & ATA_FLAG_ACPI_SATA)
		sata_acpi_set_state(ap, state);
	else
		pata_acpi_set_state(ap, state);
}

/**
@@ -974,57 +1020,6 @@ void ata_acpi_on_disable(struct ata_device *dev)
	ata_acpi_clear_gtf(dev);
}

static void ata_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
{
	struct ata_device *ata_dev = context;

	if (event == ACPI_NOTIFY_DEVICE_WAKE && ata_dev &&
			pm_runtime_suspended(&ata_dev->sdev->sdev_gendev))
		scsi_autopm_get_device(ata_dev->sdev);
}

static void ata_acpi_add_pm_notifier(struct ata_device *dev)
{
	struct acpi_device *acpi_dev;
	acpi_handle handle;
	acpi_status status;

	handle = ata_dev_acpi_handle(dev);
	if (!handle)
		return;

	status = acpi_bus_get_device(handle, &acpi_dev);
	if (ACPI_FAILURE(status))
		return;

	if (dev->sdev->can_power_off) {
		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
			ata_acpi_wake_dev, dev);
		device_set_run_wake(&dev->sdev->sdev_gendev, true);
	}
}

static void ata_acpi_remove_pm_notifier(struct ata_device *dev)
{
	struct acpi_device *acpi_dev;
	acpi_handle handle;
	acpi_status status;

	handle = ata_dev_acpi_handle(dev);
	if (!handle)
		return;

	status = acpi_bus_get_device(handle, &acpi_dev);
	if (ACPI_FAILURE(status))
		return;

	if (dev->sdev->can_power_off) {
		device_set_run_wake(&dev->sdev->sdev_gendev, false);
		acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
			ata_acpi_wake_dev);
	}
}

static void ata_acpi_register_power_resource(struct ata_device *dev)
{
	struct scsi_device *sdev = dev->sdev;
@@ -1047,13 +1042,13 @@ static void ata_acpi_unregister_power_resource(struct ata_device *dev)

void ata_acpi_bind(struct ata_device *dev)
{
	ata_acpi_add_pm_notifier(dev);
	ata_acpi_register_power_resource(dev);
	if (zpodd_dev_enabled(dev))
		dev_pm_qos_expose_flags(&dev->sdev->sdev_gendev, 0);
}

void ata_acpi_unbind(struct ata_device *dev)
{
	ata_acpi_remove_pm_notifier(dev);
	ata_acpi_unregister_power_resource(dev);
}

@@ -1095,9 +1090,6 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
				acpi_handle *handle)
{
	struct ata_device *ata_dev;
	acpi_status status;
	struct acpi_device *acpi_dev;
	struct acpi_device_power_state *states;

	if (ap->flags & ATA_FLAG_ACPI_SATA) {
		if (!sata_pmp_attached(ap))
@@ -1114,21 +1106,6 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
	if (!*handle)
		return -ENODEV;

	status = acpi_bus_get_device(*handle, &acpi_dev);
	if (ACPI_FAILURE(status))
		return 0;

	/*
	 * If firmware has _PS3 or _PR3 for this device,
	 * and this ata ODD device support device attention,
	 * it means this device can be powered off
	 */
	states = acpi_dev->power.states;
	if ((states[ACPI_STATE_D3_HOT].flags.valid ||
			states[ACPI_STATE_D3_COLD].flags.explicit_set) &&
			ata_dev->flags & ATA_DFLAG_DA)
		sdev->can_power_off = 1;

	return 0;
}

Loading