aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Daniel Kachhap <amit.kachhap@arm.com>2018-07-30 14:06:10 +0530
committerAmit Daniel Kachhap <amit.kachhap@arm.com>2018-07-30 14:06:10 +0530
commitc37be6a93733b0b8e32c4a747153c06448758261 (patch)
treedd72504fb921dac3f0864cd70c78d217db5b7332
parentfd271cdb4e4d81f1b8548c129cf6fd5025ef3269 (diff)
parent8a60d0a554b7c854a00ee61c2a899e8351b6509b (diff)
Merge branch 'latest-armlt-scmi' into latest-armlt
-rw-r--r--Documentation/devicetree/bindings/mailbox/arm-mhu.txt39
-rw-r--r--arch/arm/mach-vexpress/Kconfig1
-rw-r--r--arch/arm64/boot/dts/arm/juno-base.dtsi129
-rw-r--r--arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi6
-rw-r--r--arch/arm64/boot/dts/arm/juno-r1.dts12
-rw-r--r--arch/arm64/boot/dts/arm/juno-r2.dts12
-rw-r--r--arch/arm64/boot/dts/arm/juno.dts12
-rw-r--r--arch/arm64/configs/defconfig14
-rw-r--r--drivers/mailbox/arm_mhu.c388
-rw-r--r--drivers/mailbox/mailbox.c11
-rw-r--r--include/linux/mailbox_controller.h11
-rw-r--r--linaro/configs/vexpress64.conf17
12 files changed, 509 insertions, 143 deletions
diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
index 4971f03f0b33..ba659bcc7109 100644
--- a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
+++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
@@ -10,6 +10,15 @@ STAT register and the remote clears it after having read the data.
The last channel is specified to be a 'Secure' resource, hence can't be
used by Linux running NS.
+The MHU drives the interrupt signal using a 32-bit register, with all
+32-bits logically ORed together. It provides a set of registers to
+enable software to set, clear and check the status of each of the bits
+of this register independently. The use of 32 bits per interrupt line
+enables software to provide more information about the source of the
+interrupt. For example, each bit of the register can be associated with
+a type of event that can contribute to raising the interrupt. Each of
+the 32-bits can be used as "doorbell" to alert the remote processor.
+
Mailbox Device Node:
====================
@@ -18,13 +27,21 @@ Required properties:
- compatible: Shall be "arm,mhu" & "arm,primecell"
- reg: Contains the mailbox register address range (base
address and length)
-- #mbox-cells Shall be 1 - the index of the channel needed.
+- #mbox-cells Shall be 1 - the index of the channel needed when
+ not used as set of doorbell bits.
+ Shall be 2 - the index of the channel needed, and
+ the index of the doorbell bit within the channel
+ when used in doorbell mode.
- interrupts: Contains the interrupt information corresponding to
- each of the 3 links of MHU.
+ each of the 3 physical channels of MHU namely low
+ priority non-secure, high priority non-secure and
+ secure channels.
Example:
--------
+1. Controller which doesn't support doorbells
+
mhu: mailbox@2b1f0000 {
#mbox-cells = <1>;
compatible = "arm,mhu", "arm,primecell";
@@ -41,3 +58,21 @@ Example:
reg = <0 0x2e000000 0x4000>;
mboxes = <&mhu 1>; /* HP-NonSecure */
};
+
+2. Controller which supports doorbells
+
+ mhu: mailbox@2b1f0000 {
+ #mbox-cells = <2>;
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>, /* LP-NonSecure */
+ <0 35 4>; /* HP-NonSecure */
+ clocks = <&clock 0 2 1>;
+ clock-names = "apb_pclk";
+ };
+
+ mhu_client: scb@2e000000 {
+ compatible = "arm,scpi";
+ reg = <0 0x2e000000 0x200>;
+ mboxes = <&mhu 1 4>; /* HP-NonSecure 5th doorbell bit */
+ };
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 34fb191bb6e3..f848d0e11b02 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -24,6 +24,7 @@ menuconfig ARCH_VEXPRESS
select VEXPRESS_CONFIG
select VEXPRESS_SYSCFG
select MFD_VEXPRESS_SYSREG
+ select PM_GENERIC_DOMAINS
help
This option enables support for systems using Cortex processor based
ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 4b898164ab74..000b681a1001 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -23,13 +23,14 @@
};
mailbox: mhu@2b1f0000 {
- compatible = "arm,mhu", "arm,primecell";
+ compatible = "arm,mhu-doorbell", "arm,primecell";
reg = <0x0 0x2b1f0000 0x0 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "mhu_lpri_rx",
"mhu_hpri_rx";
- #mbox-cells = <1>;
+ #mbox-cells = <2>;
+ mbox-name = "ARM-MHU";
clocks = <&soc_refclk100mhz>;
clock-names = "apb_pclk";
};
@@ -53,7 +54,7 @@
#iommu-cells = <1>;
#global-interrupts = <1>;
dma-coherent;
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
gic: interrupt-controller@2c010000 {
@@ -113,7 +114,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -142,7 +143,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
tpiu_in_port: endpoint {
slave-mode;
@@ -158,7 +159,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -197,7 +198,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
etr_in_port: endpoint {
slave-mode;
@@ -214,7 +215,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
stm_out_port: endpoint {
};
@@ -227,7 +228,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm0: etm@22040000 {
@@ -236,7 +237,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster0_etm0_out_port: endpoint {
remote-endpoint = <&cluster0_funnel_in_port0>;
@@ -250,7 +251,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -286,7 +287,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm1: etm@22140000 {
@@ -295,7 +296,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster0_etm1_out_port: endpoint {
remote-endpoint = <&cluster0_funnel_in_port1>;
@@ -309,7 +310,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm2: etm@23040000 {
@@ -318,7 +319,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster1_etm0_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port0>;
@@ -332,7 +333,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -382,7 +383,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm3: etm@23140000 {
@@ -391,7 +392,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster1_etm1_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port1>;
@@ -405,7 +406,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm4: etm@23240000 {
@@ -414,7 +415,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster1_etm2_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port2>;
@@ -428,7 +429,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
};
etm5: etm@23340000 {
@@ -437,7 +438,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
port {
cluster1_etm3_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port3>;
@@ -451,7 +452,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
@@ -490,14 +491,24 @@
#size-cells = <1>;
ranges = <0 0x0 0x2e000000 0x8000>;
- cpu_scp_lpri: scp-shmem@0 {
+ cpu_scp_lpri0: scp-shmem@0 {
compatible = "arm,juno-scp-shmem";
- reg = <0x0 0x200>;
+ reg = <0x0 0x80>;
};
- cpu_scp_hpri: scp-shmem@200 {
+ cpu_scp_lpri1: scp-shmem@80 {
compatible = "arm,juno-scp-shmem";
- reg = <0x200 0x200>;
+ reg = <0x80 0x80>;
+ };
+
+ cpu_scp_hpri0: scp-shmem@100 {
+ compatible = "arm,juno-scp-shmem";
+ reg = <0x100 0x80>;
+ };
+
+ cpu_scp_hpri1: scp-shmem@180 {
+ compatible = "arm,juno-scp-shmem";
+ reg = <0x180 0x80>;
};
};
@@ -525,37 +536,37 @@
iommu-map = <0x0 &smmu_pcie 0x0 0x1>;
};
- scpi {
- compatible = "arm,scpi";
- mboxes = <&mailbox 1>;
- shmem = <&cpu_scp_hpri>;
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 0 0 &mailbox 0 1>;
+ shmem = <&cpu_scp_lpri0 &cpu_scp_lpri1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- clocks {
- compatible = "arm,scpi-clocks";
+ scmi_devpd: protocol@11 {
+ reg = <0x11>;
+ #power-domain-cells = <1>;
+ };
- scpi_dvfs: scpi-dvfs {
- compatible = "arm,scpi-dvfs-clocks";
+ scmi_dvfs: protocol@13 {
+ reg = <0x13>;
#clock-cells = <1>;
- clock-indices = <0>, <1>, <2>;
- clock-output-names = "atlclk", "aplclk","clk_mali";
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 1 0 &mailbox 1 1>;
+ shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>;
};
- scpi_clk: scpi-clk {
- compatible = "arm,scpi-variable-clocks";
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
#clock-cells = <1>;
- clock-indices = <3>;
- clock-output-names = "pxlclk";
};
- };
- scpi_devpd: scpi-power-domains {
- compatible = "arm,scpi-power-domains";
- num-domains = <2>;
- #power-domain-cells = <1>;
- };
-
- scpi_sensors0: sensors {
- compatible = "arm,scpi-sensors";
- #thermal-sensor-cells = <1>;
+ scmi_sensors0: protocol@15 {
+ reg = <0x15>;
+ #thermal-sensor-cells = <1>;
+ };
};
};
@@ -563,40 +574,40 @@
pmic {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 0>;
+ thermal-sensors = <&scmi_sensors0 0>;
};
soc {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 3>;
+ thermal-sensors = <&scmi_sensors0 3>;
};
big_cluster_thermal_zone: big_cluster {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 21>;
+ thermal-sensors = <&scmi_sensors0 21>;
status = "disabled";
};
little_cluster_thermal_zone: little_cluster {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 22>;
+ thermal-sensors = <&scmi_sensors0 22>;
status = "disabled";
};
gpu0_thermal_zone: gpu0 {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 23>;
+ thermal-sensors = <&scmi_sensors0 23>;
status = "disabled";
};
gpu1_thermal_zone: gpu1 {
polling-delay = <1000>;
polling-delay-passive = <100>;
- thermal-sensors = <&scpi_sensors0 24>;
+ thermal-sensors = <&scmi_sensors0 24>;
status = "disabled";
};
};
@@ -673,7 +684,7 @@
reg = <0 0x7ff50000 0 0x1000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_hdlcd1 0>;
- clocks = <&scpi_clk 3>;
+ clocks = <&scmi_clk 3>;
clock-names = "pxlclk";
port {
@@ -688,7 +699,7 @@
reg = <0 0x7ff60000 0 0x1000>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_hdlcd0 0>;
- clocks = <&scpi_clk 3>;
+ clocks = <&scmi_clk 3>;
clock-names = "pxlclk";
port {
diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
index 0c43fb3525eb..21287f2d75d3 100644
--- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
@@ -6,7 +6,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -36,7 +36,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -66,7 +66,7 @@
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- power-domains = <&scpi_devpd 0>;
+ power-domains = <&scmi_devpd 8>;
ports {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts
index ffd94be44f1b..8b2501e73cbe 100644
--- a/arch/arm64/boot/dts/arm/juno-r1.dts
+++ b/arch/arm64/boot/dts/arm/juno-r1.dts
@@ -96,7 +96,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A57_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -113,7 +113,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A57_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -130,7 +130,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -147,7 +147,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -164,7 +164,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -181,7 +181,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts
index 64fe406c9aac..dab2e49befef 100644
--- a/arch/arm64/boot/dts/arm/juno-r2.dts
+++ b/arch/arm64/boot/dts/arm/juno-r2.dts
@@ -96,7 +96,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A72_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -113,7 +113,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A72_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -130,7 +130,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
};
@@ -147,7 +147,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
};
@@ -164,7 +164,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
};
@@ -181,7 +181,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
};
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index 1eec71d8eaf4..1d05029687ff 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -95,7 +95,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A57_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -112,7 +112,7 @@
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A57_L2>;
- clocks = <&scpi_dvfs 0>;
+ clocks = <&scmi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
};
@@ -129,7 +129,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -146,7 +146,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -163,7 +163,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
@@ -180,7 +180,7 @@
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
- clocks = <&scpi_dvfs 1>;
+ clocks = <&scmi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <578>;
};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index ecf613761e78..c259a2186307 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -104,15 +104,16 @@ CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ARM_TEGRA186_CPUFREQ=y
CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_NET=y
@@ -337,6 +338,7 @@ CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_BATTERY_BQ27XXX=y
+CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_INA2XX=m
@@ -533,6 +535,7 @@ CONFIG_VIRTIO_MMIO=y
CONFIG_XEN_GNTDEV=y
CONFIG_XEN_GRANT_DEV_ALLOC=y
CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_CS2000_CP=y
CONFIG_COMMON_CLK_S2MPS11=y
@@ -599,6 +602,7 @@ CONFIG_QCOM_QFPROM=y
CONFIG_UNIPHIER_EFUSE=y
CONFIG_TEE=y
CONFIG_OPTEE=y
+CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EFI_CAPSULE_LOADER=y
@@ -637,10 +641,16 @@ CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
+CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
index 99befa76e37c..4ed389d8f3dd 100644
--- a/drivers/mailbox/arm_mhu.c
+++ b/drivers/mailbox/arm_mhu.c
@@ -13,16 +13,16 @@
* GNU General Public License for more details.
*/
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
+#include <linux/amba/bus.h>
+#include <linux/device.h>
#include <linux/err.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/amba/bus.h>
+#include <linux/kernel.h>
#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#define INTR_STAT_OFS 0x0
#define INTR_SET_OFS 0x8
@@ -33,7 +33,8 @@
#define MHU_SEC_OFFSET 0x200
#define TX_REG_OFFSET 0x100
-#define MHU_CHANS 3
+#define MHU_NUM_PCHANS 3 /* Secure, Non-Secure High and Low Priority */
+#define MHU_CHAN_MAX 20 /* Max channels to save on unused RAM */
struct mhu_link {
unsigned irq;
@@ -43,88 +44,341 @@ struct mhu_link {
struct arm_mhu {
void __iomem *base;
- struct mhu_link mlink[MHU_CHANS];
- struct mbox_chan chan[MHU_CHANS];
+ struct mhu_link mlink[MHU_NUM_PCHANS];
struct mbox_controller mbox;
+ struct device *dev;
+ const char *name;
+};
+
+/**
+ * ARM MHU Mailbox platform specific configuration
+ *
+ * @num_pchans: Maximum number of physical channels
+ * @num_doorbells: Maximum number of doorbells per physical channel
+ */
+struct mhu_mbox_pdata {
+ unsigned int num_pchans;
+ unsigned int num_doorbells;
+ bool support_doorbells;
+};
+
+/**
+ * ARM MHU Mailbox allocated channel information
+ *
+ * @mhu: Pointer to parent mailbox device
+ * @pchan: Physical channel within which this doorbell resides in
+ * @doorbell: doorbell number pertaining to this channel
+ */
+struct mhu_channel {
+ struct arm_mhu *mhu;
+ unsigned int pchan;
+ unsigned int doorbell;
};
+static inline struct mbox_chan *
+mhu_mbox_to_channel(struct mbox_controller *mbox,
+ unsigned int pchan, unsigned int doorbell)
+{
+ int i;
+ struct mhu_channel *chan_info;
+
+ for (i = 0; i < mbox->num_chans; i++) {
+ chan_info = mbox->chans[i].con_priv;
+ if (chan_info && chan_info->pchan == pchan &&
+ chan_info->doorbell == doorbell)
+ return &mbox->chans[i];
+ }
+
+ dev_err(mbox->dev,
+ "Channel not registered: physical channel: %d doorbell: %d\n",
+ pchan, doorbell);
+
+ return NULL;
+}
+
+static void mhu_mbox_clear_irq(struct mbox_chan *chan)
+{
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].rx_reg;
+
+ writel_relaxed(BIT(chan_info->doorbell), base + INTR_CLR_OFS);
+}
+
+static unsigned int mhu_mbox_irq_to_pchan_num(struct arm_mhu *mhu, int irq)
+{
+ unsigned int pchan;
+ struct mhu_mbox_pdata *pdata = dev_get_platdata(mhu->dev);
+
+ for (pchan = 0; pchan < pdata->num_pchans; pchan++)
+ if (mhu->mlink[pchan].irq == irq)
+ break;
+ return pchan;
+}
+
+static struct mbox_chan *mhu_mbox_irq_to_channel(struct arm_mhu *mhu,
+ unsigned int pchan)
+{
+ unsigned long bits;
+ unsigned int doorbell;
+ struct mbox_chan *chan = NULL;
+ struct mbox_controller *mbox = &mhu->mbox;
+ void __iomem *base = mhu->mlink[pchan].rx_reg;
+
+ bits = readl_relaxed(base + INTR_STAT_OFS);
+ if (!bits)
+ /* No IRQs fired in specified physical channel */
+ return NULL;
+
+ /* An IRQ has fired, find the associated channel */
+ for (doorbell = 0; bits; doorbell++) {
+ if (!test_and_clear_bit(doorbell, &bits))
+ continue;
+
+ chan = mhu_mbox_to_channel(mbox, pchan, doorbell);
+ if (chan)
+ break;
+ }
+
+ return chan;
+}
+
+static irqreturn_t mhu_mbox_thread_handler(int irq, void *data)
+{
+ struct mbox_chan *chan;
+ struct arm_mhu *mhu = data;
+ unsigned int pchan = mhu_mbox_irq_to_pchan_num(mhu, irq);
+
+ while (NULL != (chan = mhu_mbox_irq_to_channel(mhu, pchan))) {
+ mbox_chan_received_data(chan, NULL);
+ mhu_mbox_clear_irq(chan);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static bool mhu_doorbell_last_tx_done(struct mbox_chan *chan)
+{
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg;
+
+ if (readl_relaxed(base + INTR_STAT_OFS) & BIT(chan_info->doorbell))
+ return false;
+
+ return true;
+}
+
+static int mhu_doorbell_send_data(struct mbox_chan *chan, void *data)
+{
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg;
+
+ /* Send event to co-processor */
+ writel_relaxed(BIT(chan_info->doorbell), base + INTR_SET_OFS);
+
+ return 0;
+}
+
+static int mhu_doorbell_startup(struct mbox_chan *chan)
+{
+ mhu_mbox_clear_irq(chan);
+ return 0;
+}
+
+static void mhu_doorbell_shutdown(struct mbox_chan *chan)
+{
+ struct mhu_channel *chan_info = chan->con_priv;
+ struct mbox_controller *mbox = &chan_info->mhu->mbox;
+ int i;
+
+ for (i = 0; i < mbox->num_chans; i++)
+ if (chan == &mbox->chans[i])
+ break;
+
+ if (mbox->num_chans == i) {
+ dev_warn(mbox->dev, "Request to free non-existent channel\n");
+ return;
+ }
+
+ /* Reset channel */
+ mhu_mbox_clear_irq(chan);
+ chan->con_priv = NULL;
+}
+
+static struct mbox_chan *mhu_mbox_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *spec)
+{
+ struct arm_mhu *mhu = dev_get_drvdata(mbox->dev);
+ struct mhu_mbox_pdata *pdata = dev_get_platdata(mhu->dev);
+ struct mhu_channel *chan_info;
+ struct mbox_chan *chan = NULL;
+ unsigned int pchan = spec->args[0];
+ unsigned int doorbell = pdata->support_doorbells ? spec->args[1] : 0;
+ int i;
+
+ /* Bounds checking */
+ if (pchan >= pdata->num_pchans || doorbell >= pdata->num_doorbells) {
+ dev_err(mbox->dev,
+ "Invalid channel requested pchan: %d doorbell: %d\n",
+ pchan, doorbell);
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (i = 0; i < mbox->num_chans; i++) {
+ chan_info = mbox->chans[i].con_priv;
+
+ /* Is requested channel free? */
+ if (chan_info &&
+ mbox->dev == chan_info->mhu->dev &&
+ pchan == chan_info->pchan &&
+ doorbell == chan_info->doorbell) {
+ dev_err(mbox->dev, "Channel in use\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ /*
+ * Find the first free slot, then continue checking
+ * to see if requested channel is in use
+ */
+ if (!chan && !chan_info)
+ chan = &mbox->chans[i];
+ }
+
+ if (!chan) {
+ dev_err(mbox->dev, "No free channels left\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL);
+ if (!chan_info)
+ return ERR_PTR(-ENOMEM);
+
+ chan_info->mhu = mhu;
+ chan_info->pchan = pchan;
+ chan_info->doorbell = doorbell;
+
+ chan->con_priv = chan_info;
+
+ dev_dbg(mbox->dev, "mbox: %s, created channel phys: %d doorbell: %d\n",
+ mhu->name, pchan, doorbell);
+
+ return chan;
+}
+
static irqreturn_t mhu_rx_interrupt(int irq, void *p)
{
- struct mbox_chan *chan = p;
- struct mhu_link *mlink = chan->con_priv;
+ struct arm_mhu *mhu = p;
+ unsigned int pchan = mhu_mbox_irq_to_pchan_num(mhu, irq);
+ struct mbox_chan *chan = mhu_mbox_to_channel(&mhu->mbox, pchan, 0);
+ void __iomem *base = mhu->mlink[pchan].rx_reg;
u32 val;
- val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS);
+ val = readl_relaxed(base + INTR_STAT_OFS);
if (!val)
return IRQ_NONE;
mbox_chan_received_data(chan, (void *)&val);
- writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS);
+ writel_relaxed(val, base + INTR_CLR_OFS);
return IRQ_HANDLED;
}
static bool mhu_last_tx_done(struct mbox_chan *chan)
{
- struct mhu_link *mlink = chan->con_priv;
- u32 val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg;
+ u32 val = readl_relaxed(base + INTR_STAT_OFS);
return (val == 0);
}
static int mhu_send_data(struct mbox_chan *chan, void *data)
{
- struct mhu_link *mlink = chan->con_priv;
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg;
u32 *arg = data;
- writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
+ writel_relaxed(*arg, base + INTR_SET_OFS);
return 0;
}
static int mhu_startup(struct mbox_chan *chan)
{
- struct mhu_link *mlink = chan->con_priv;
+ struct mhu_channel *chan_info = chan->con_priv;
+ void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg;
u32 val;
- int ret;
-
- val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
- writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS);
- ret = request_irq(mlink->irq, mhu_rx_interrupt,
- IRQF_SHARED, "mhu_link", chan);
- if (ret) {
- dev_err(chan->mbox->dev,
- "Unable to acquire IRQ %d\n", mlink->irq);
- return ret;
- }
+ val = readl_relaxed(base + INTR_STAT_OFS);
+ writel_relaxed(val, base + INTR_CLR_OFS);
return 0;
}
-static void mhu_shutdown(struct mbox_chan *chan)
-{
- struct mhu_link *mlink = chan->con_priv;
-
- free_irq(mlink->irq, chan);
-}
-
static const struct mbox_chan_ops mhu_ops = {
.send_data = mhu_send_data,
.startup = mhu_startup,
- .shutdown = mhu_shutdown,
.last_tx_done = mhu_last_tx_done,
};
+static const struct mbox_chan_ops mhu_doorbell_ops = {
+ .send_data = mhu_doorbell_send_data,
+ .startup = mhu_doorbell_startup,
+ .shutdown = mhu_doorbell_shutdown,
+ .last_tx_done = mhu_doorbell_last_tx_done,
+};
+
+static const struct mhu_mbox_pdata arm_mhu_pdata = {
+ .num_pchans = 3,
+ .num_doorbells = 1,
+ .support_doorbells = false,
+};
+
+static const struct mhu_mbox_pdata arm_mhu_doorbell_pdata = {
+ .num_pchans = 2, /* Secure can't be used */
+ .num_doorbells = 32,
+ .support_doorbells = true,
+};
+
static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
{
- int i, err;
+ u32 cell_count;
+ int i, err, max_chans;
+ irq_handler_t handler;
struct arm_mhu *mhu;
+ struct mbox_chan *chans;
+ struct mhu_mbox_pdata *pdata;
struct device *dev = &adev->dev;
- int mhu_reg[MHU_CHANS] = {MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET};
+ struct device_node *np = dev->of_node;
+ int mhu_reg[MHU_NUM_PCHANS] = {
+ MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET,
+ };
+
+ err = of_property_read_u32(np, "#mbox-cells", &cell_count);
+ if (err) {
+ dev_err(dev, "failed to read #mbox-cells in %s\n",
+ np->full_name);
+ return err;
+ }
+
+ if (cell_count == 1) {
+ max_chans = MHU_NUM_PCHANS;
+ pdata = (struct mhu_mbox_pdata *)&arm_mhu_pdata;
+ } else if (cell_count == 2) {
+ max_chans = MHU_CHAN_MAX;
+ pdata = (struct mhu_mbox_pdata *)&arm_mhu_doorbell_pdata;
+ } else {
+ dev_err(dev, "incorrect value of #mbox-cells in %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ if (pdata->num_pchans > MHU_NUM_PCHANS) {
+ dev_err(dev, "Number of physical channel can't exceed %d\n",
+ MHU_NUM_PCHANS);
+ return -EINVAL;
+ }
- /* Allocate memory for device */
mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
if (!mhu)
return -ENOMEM;
@@ -135,30 +389,62 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
return PTR_ERR(mhu->base);
}
- for (i = 0; i < MHU_CHANS; i++) {
- mhu->chan[i].con_priv = &mhu->mlink[i];
- mhu->mlink[i].irq = adev->irq[i];
- mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
- mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET;
- }
+ err = of_property_read_string(np, "mbox-name", &mhu->name);
+ if (err)
+ mhu->name = np->full_name;
+
+ chans = devm_kcalloc(dev, max_chans, sizeof(*chans), GFP_KERNEL);
+ if (!chans)
+ return -ENOMEM;
+
+ dev->platform_data = pdata;
+ mhu->dev = dev;
mhu->mbox.dev = dev;
- mhu->mbox.chans = &mhu->chan[0];
- mhu->mbox.num_chans = MHU_CHANS;
- mhu->mbox.ops = &mhu_ops;
+ mhu->mbox.chans = chans;
+ mhu->mbox.num_chans = max_chans;
mhu->mbox.txdone_irq = false;
mhu->mbox.txdone_poll = true;
mhu->mbox.txpoll_period = 1;
+ mhu->mbox.of_xlate = mhu_mbox_xlate;
amba_set_drvdata(adev, mhu);
+ if (pdata->support_doorbells) {
+ mhu->mbox.ops = &mhu_doorbell_ops;
+ handler = mhu_mbox_thread_handler;
+ } else {
+ mhu->mbox.ops = &mhu_ops;
+ handler = mhu_rx_interrupt;
+ }
+
err = mbox_controller_register(&mhu->mbox);
if (err) {
dev_err(dev, "Failed to register mailboxes %d\n", err);
return err;
}
- dev_info(dev, "ARM MHU Mailbox registered\n");
+ for (i = 0; i < pdata->num_pchans; i++) {
+ int irq = mhu->mlink[i].irq = adev->irq[i];
+
+ if (irq <= 0) {
+ dev_dbg(dev, "No IRQ found for Channel %d\n", i);
+ continue;
+ }
+
+ mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
+ mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET;
+
+ err = devm_request_threaded_irq(dev, irq, NULL, handler,
+ IRQF_ONESHOT, "mhu_link", mhu);
+ if (err) {
+ dev_err(dev, "Can't claim IRQ %d\n", irq);
+ mbox_controller_unregister(&mhu->mbox);
+ return err;
+ }
+ }
+
+ dev_info(dev, "%s mailbox registered\n", mhu->name);
return 0;
}
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 674b35f402f5..495b4574b954 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -77,7 +77,10 @@ static void msg_submit(struct mbox_chan *chan)
if (chan->cl->tx_prepare)
chan->cl->tx_prepare(chan->cl, data);
/* Try to submit a message to the MBOX controller */
- err = chan->mbox->ops->send_data(chan, data);
+ if (chan->mbox->ops->send_data)
+ err = chan->mbox->ops->send_data(chan, data);
+ else
+ err = chan->mbox->ops->send_signal(chan);
if (!err) {
chan->active_req = data;
chan->msg_count--;
@@ -451,6 +454,12 @@ int mbox_controller_register(struct mbox_controller *mbox)
/* Sanity check */
if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
return -EINVAL;
+ /*
+ * A controller can support either doorbell mode or normal message
+ * transmission mode but not both
+ */
+ if (mbox->ops->send_data && mbox->ops->send_signal)
+ return -EINVAL;
if (mbox->txdone_irq)
txdone = TXDONE_BY_IRQ;
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 74deadb42d76..bdbc5b74097e 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -24,6 +24,16 @@ struct mbox_chan;
* transmission of data is reported by the controller via
* mbox_chan_txdone (if it has some TX ACK irq). It must not
* sleep.
+ * @send_signal: The API asks the MBOX controller driver, in atomic
+ * context try to transmit a signal on the bus. Returns 0 if
+ * data is accepted for transmission, -EBUSY while rejecting
+ * if the remote hasn't yet absorbed the last signal sent. Actual
+ * transmission of data must be handled by the client and is
+ * reported by the controller via mbox_chan_txdone (if it has
+ * some TX ACK irq). It must not sleep. Unlike send_data,
+ * send_signal doesn't handle any messages/data. It just sends
+ * notification signal(doorbell) and client needs to prepare all
+ * the data.
* @startup: Called when a client requests the chan. The controller
* could ask clients for additional parameters of communication
* to be provided via client's chan_data. This call may
@@ -46,6 +56,7 @@ struct mbox_chan;
*/
struct mbox_chan_ops {
int (*send_data)(struct mbox_chan *chan, void *data);
+ int (*send_signal)(struct mbox_chan *chan);
int (*startup)(struct mbox_chan *chan);
void (*shutdown)(struct mbox_chan *chan);
bool (*last_tx_done)(struct mbox_chan *chan);
diff --git a/linaro/configs/vexpress64.conf b/linaro/configs/vexpress64.conf
index 4d766c762acc..53362364d369 100644
--- a/linaro/configs/vexpress64.conf
+++ b/linaro/configs/vexpress64.conf
@@ -48,19 +48,22 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_PM_OPP=y
CONFIG_MAILBOX=y
CONFIG_ARM_MHU=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_SENSORS_ARM_SCPI=y
-CONFIG_COMMON_CLK_SCPI=y
-CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
-CONFIG_ARM_DT_BL_CPUFREQ=y
+CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_REALLOC_ENABLE_AUTO=y