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

Commit 17523680 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/omap100k',...

Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/omap100k', 'spi/topic/omap2', 'spi/topic/orion', 'spi/topic/pl022', 'spi/topic/qup', 'spi/topic/rspi' and 'spi/topic/s3c24xx' into spi-next
Loading
+85 −0
Original line number Diff line number Diff line
Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)

The QUP core is an AHB slave that provides a common data path (an output FIFO
and an input FIFO) for serial peripheral interface (SPI) mini-core.

SPI in master mode supports up to 50MHz, up to four chip selects, programmable
data path from 4 bits to 32 bits and numerous protocol variants.

Required properties:
- compatible:     Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
- reg:            Should contain base register location and length
- interrupts:     Interrupt number used by this controller

- clocks:         Should contain the core clock and the AHB clock.
- clock-names:    Should be "core" for the core clock and "iface" for the
                  AHB clock.

- #address-cells: Number of cells required to define a chip select
                  address on the SPI bus. Should be set to 1.
- #size-cells:    Should be zero.

Optional properties:
- spi-max-frequency: Specifies maximum SPI clock frequency,
                     Units - Hz. Definition as per
                     Documentation/devicetree/bindings/spi/spi-bus.txt

SPI slave nodes must be children of the SPI master node and can contain
properties described in Documentation/devicetree/bindings/spi/spi-bus.txt

Example:

	spi_8: spi@f9964000 { /* BLSP2 QUP2 */

		compatible = "qcom,spi-qup-v2";
		#address-cells = <1>;
		#size-cells = <0>;
		reg = <0xf9964000 0x1000>;
		interrupts = <0 102 0>;
		spi-max-frequency = <19200000>;

		clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
		clock-names = "core", "iface";

		pinctrl-names = "default";
		pinctrl-0 = <&spi8_default>;

		device@0 {
			compatible = "arm,pl022-dummy";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <0>; /* Chip select 0 */
			spi-max-frequency = <19200000>;
			spi-cpol;
		};

		device@1 {
			compatible = "arm,pl022-dummy";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <1>; /* Chip select 1 */
			spi-max-frequency = <9600000>;
			spi-cpha;
		};

		device@2 {
			compatible = "arm,pl022-dummy";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <2>; /* Chip select 2 */
			spi-max-frequency = <19200000>;
			spi-cpol;
			spi-cpha;
		};

		device@3 {
			compatible = "arm,pl022-dummy";
			#address-cells = <1>;
			#size-cells = <1>;
			reg = <3>; /* Chip select 3 */
			spi-max-frequency = <19200000>;
			spi-cpol;
			spi-cpha;
			spi-cs-high;
		};
	};
+61 −0
Original line number Diff line number Diff line
Device tree configuration for Renesas RSPI/QSPI driver

Required properties:
- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
		     For Renesas Serial Peripheral Interface on RZ/A1H:
		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
		     For Quad Serial Peripheral Interface on R-Car Gen2:
		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
		     Examples with soctypes are:
		        - "renesas,rspi-sh7757" (SH)
			- "renesas,rspi-r7s72100" (RZ/A1H)
			- "renesas,qspi-r8a7790" (R-Car H2)
			- "renesas,qspi-r8a7791" (R-Car M2)
- reg              : Address start and address range size of the device
- interrupts       : A list of interrupt-specifiers, one for each entry in
		     interrupt-names.
		     If interrupt-names is not present, an interrupt specifier
		     for a single muxed interrupt.
- interrupt-names  : A list of interrupt names. Should contain (if present):
		       - "error" for SPEI,
		       - "rx" for SPRI,
		       - "tx" to SPTI,
		       - "mux" for a single muxed interrupt.
- interrupt-parent : The phandle for the interrupt controller that
		     services interrupts for this device.
- num-cs	   : Number of chip selects. Some RSPI cores have more than 1.
- #address-cells   : Must be <1>
- #size-cells      : Must be <0>

Optional properties:
- clocks           : Must contain a reference to the functional clock.

Pinctrl properties might be needed, too.  See
Documentation/devicetree/bindings/pinctrl/renesas,*.

Examples:

	spi0: spi@e800c800 {
		compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
		reg = <0xe800c800 0x24>;
		interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
			     <0 239 IRQ_TYPE_LEVEL_HIGH>,
			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-names = "error", "rx", "tx";
		interrupt-parent = <&gic>;
		num-cs = <1>;
		#address-cells = <1>;
		#size-cells = <0>;
	};

	spi: spi@e6b10000 {
		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
		reg = <0 0xe6b10000 0 0x2c>;
		interrupt-parent = <&gic>;
		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
		num-cs = <1>;
		#address-cells = <1>;
		#size-cells = <0>;
	};
+1 −2
Original line number Diff line number Diff line
obj-$(CONFIG_PM)	+= sysfs.o generic_ops.o common.o qos.o
obj-$(CONFIG_PM)	+= sysfs.o generic_ops.o common.o qos.o runtime.o
obj-$(CONFIG_PM_SLEEP)	+= main.o wakeup.o
obj-$(CONFIG_PM_RUNTIME)	+= runtime.o
obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
obj-$(CONFIG_PM_OPP)	+= opp.o
obj-$(CONFIG_PM_GENERIC_DOMAINS)	+=  domain.o domain_governor.o
+123 −39
Original line number Diff line number Diff line
@@ -13,6 +13,43 @@
#include <trace/events/rpm.h>
#include "power.h"

#define RPM_GET_CALLBACK(dev, cb)				\
({								\
	int (*__rpm_cb)(struct device *__d);			\
								\
	if (dev->pm_domain)					\
		__rpm_cb = dev->pm_domain->ops.cb;		\
	else if (dev->type && dev->type->pm)			\
		__rpm_cb = dev->type->pm->cb;			\
	else if (dev->class && dev->class->pm)			\
		__rpm_cb = dev->class->pm->cb;			\
	else if (dev->bus && dev->bus->pm)			\
		__rpm_cb = dev->bus->pm->cb;			\
	else							\
		__rpm_cb = NULL;				\
								\
	if (!__rpm_cb && dev->driver && dev->driver->pm)	\
		__rpm_cb = dev->driver->pm->cb;			\
								\
	__rpm_cb;						\
})

static int (*rpm_get_suspend_cb(struct device *dev))(struct device *)
{
	return RPM_GET_CALLBACK(dev, runtime_suspend);
}

static int (*rpm_get_resume_cb(struct device *dev))(struct device *)
{
	return RPM_GET_CALLBACK(dev, runtime_resume);
}

#ifdef CONFIG_PM_RUNTIME
static int (*rpm_get_idle_cb(struct device *dev))(struct device *)
{
	return RPM_GET_CALLBACK(dev, runtime_idle);
}

static int rpm_resume(struct device *dev, int rpmflags);
static int rpm_suspend(struct device *dev, int rpmflags);

@@ -310,19 +347,7 @@ static int rpm_idle(struct device *dev, int rpmflags)

	dev->power.idle_notification = true;

	if (dev->pm_domain)
		callback = dev->pm_domain->ops.runtime_idle;
	else if (dev->type && dev->type->pm)
		callback = dev->type->pm->runtime_idle;
	else if (dev->class && dev->class->pm)
		callback = dev->class->pm->runtime_idle;
	else if (dev->bus && dev->bus->pm)
		callback = dev->bus->pm->runtime_idle;
	else
		callback = NULL;

	if (!callback && dev->driver && dev->driver->pm)
		callback = dev->driver->pm->runtime_idle;
	callback = rpm_get_idle_cb(dev);

	if (callback)
		retval = __rpm_callback(callback, dev);
@@ -492,19 +517,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)

	__update_runtime_status(dev, RPM_SUSPENDING);

	if (dev->pm_domain)
		callback = dev->pm_domain->ops.runtime_suspend;
	else if (dev->type && dev->type->pm)
		callback = dev->type->pm->runtime_suspend;
	else if (dev->class && dev->class->pm)
		callback = dev->class->pm->runtime_suspend;
	else if (dev->bus && dev->bus->pm)
		callback = dev->bus->pm->runtime_suspend;
	else
		callback = NULL;

	if (!callback && dev->driver && dev->driver->pm)
		callback = dev->driver->pm->runtime_suspend;
	callback = rpm_get_suspend_cb(dev);

	retval = rpm_callback(callback, dev);
	if (retval)
@@ -724,19 +737,7 @@ static int rpm_resume(struct device *dev, int rpmflags)

	__update_runtime_status(dev, RPM_RESUMING);

	if (dev->pm_domain)
		callback = dev->pm_domain->ops.runtime_resume;
	else if (dev->type && dev->type->pm)
		callback = dev->type->pm->runtime_resume;
	else if (dev->class && dev->class->pm)
		callback = dev->class->pm->runtime_resume;
	else if (dev->bus && dev->bus->pm)
		callback = dev->bus->pm->runtime_resume;
	else
		callback = NULL;

	if (!callback && dev->driver && dev->driver->pm)
		callback = dev->driver->pm->runtime_resume;
	callback = rpm_get_resume_cb(dev);

	retval = rpm_callback(callback, dev);
	if (retval) {
@@ -1401,3 +1402,86 @@ void pm_runtime_remove(struct device *dev)
	if (dev->power.irq_safe && dev->parent)
		pm_runtime_put(dev->parent);
}
#endif

/**
 * pm_runtime_force_suspend - Force a device into suspend state if needed.
 * @dev: Device to suspend.
 *
 * Disable runtime PM so we safely can check the device's runtime PM status and
 * if it is active, invoke it's .runtime_suspend callback to bring it into
 * suspend state. Keep runtime PM disabled to preserve the state unless we
 * encounter errors.
 *
 * Typically this function may be invoked from a system suspend callback to make
 * sure the device is put into low power state.
 */
int pm_runtime_force_suspend(struct device *dev)
{
	int (*callback)(struct device *);
	int ret = 0;

	pm_runtime_disable(dev);

	/*
	 * Note that pm_runtime_status_suspended() returns false while
	 * !CONFIG_PM_RUNTIME, which means the device will be put into low
	 * power state.
	 */
	if (pm_runtime_status_suspended(dev))
		return 0;

	callback = rpm_get_suspend_cb(dev);

	if (!callback) {
		ret = -ENOSYS;
		goto err;
	}

	ret = callback(dev);
	if (ret)
		goto err;

	pm_runtime_set_suspended(dev);
	return 0;
err:
	pm_runtime_enable(dev);
	return ret;
}
EXPORT_SYMBOL_GPL(pm_runtime_force_suspend);

/**
 * pm_runtime_force_resume - Force a device into resume state.
 * @dev: Device to resume.
 *
 * Prior invoking this function we expect the user to have brought the device
 * into low power state by a call to pm_runtime_force_suspend(). Here we reverse
 * those actions and brings the device into full power. We update the runtime PM
 * status and re-enables runtime PM.
 *
 * Typically this function may be invoked from a system resume callback to make
 * sure the device is put into full power state.
 */
int pm_runtime_force_resume(struct device *dev)
{
	int (*callback)(struct device *);
	int ret = 0;

	callback = rpm_get_resume_cb(dev);

	if (!callback) {
		ret = -ENOSYS;
		goto out;
	}

	ret = callback(dev);
	if (ret)
		goto out;

	pm_runtime_set_active(dev);
	pm_runtime_mark_last_busy(dev);
out:
	pm_runtime_enable(dev);
	return ret;
}
EXPORT_SYMBOL_GPL(pm_runtime_force_resume);
+14 −1
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ config SPI_OMAP_UWIRE

config SPI_OMAP24XX
	tristate "McSPI driver for OMAP"
	depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SH
	depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH
	depends on ARCH_OMAP2PLUS || COMPILE_TEST
	help
	  SPI master controller for OMAP24XX and later Multichannel SPI
@@ -381,6 +381,19 @@ config SPI_RSPI
	help
	  SPI driver for Renesas RSPI and QSPI blocks.

config SPI_QUP
	tristate "Qualcomm SPI controller with QUP interface"
	depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
	help
	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
	  provides a common data path (an output FIFO and an input FIFO)
	  for serial peripheral interface (SPI) mini-core. SPI in master
	  mode supports up to 50MHz, up to four chip selects, programmable
	  data path from 4 bits to 32 bits and numerous protocol variants.

	  This driver can also be built as a module.  If so, the module
	  will be called spi_qup.

config SPI_S3C24XX
	tristate "Samsung S3C24XX series SPI"
	depends on ARCH_S3C24XX
Loading