Skip to content

Commit

Permalink
Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/oma…
Browse files Browse the repository at this point in the history
…p100k', 'spi/topic/omap2', 'spi/topic/orion', 'spi/topic/pl022', 'spi/topic/qup', 'spi/topic/rspi' and 'spi/topic/s3c24xx' into spi-next
  • Loading branch information
Mark Brown committed Mar 30, 2014
9 parents 6e07b91 + cbab804 + d1c18ca + aca0924 + cd2ac0c + 84a5dc4 + 00cce74 + 490c977 + 3806037 commit 1752368
Show file tree
Hide file tree
Showing 15 changed files with 1,735 additions and 528 deletions.
85 changes: 85 additions & 0 deletions Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
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 changes: 61 additions & 0 deletions Documentation/devicetree/bindings/spi/spi-rspi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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>;
};
3 changes: 1 addition & 2 deletions drivers/base/power/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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
Expand Down
162 changes: 123 additions & 39 deletions drivers/base/power/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
15 changes: 14 additions & 1 deletion drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/spi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_PXADMA) += spi-pxa2xx-pxadma.o
spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_QUP) += spi-qup.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
spi-s3c24xx-hw-y := spi-s3c24xx.o
Expand Down
Loading

0 comments on commit 1752368

Please sign in to comment.