* [PATCH 2/5] can: xilinx_can: Fix FSR register handling in the rx path
From: Appana Durga Kedareswara rao @ 2019-08-12 7:28 UTC (permalink / raw)
To: wg, mkl, davem, michal.simek
Cc: netdev, Appana Durga Kedareswara rao, linux-kernel,
linux-arm-kernel, linux-can
In-Reply-To: <1565594914-18999-1-git-send-email-appana.durga.rao@xilinx.com>
After commit c223da689324 ("can: xilinx_can: Add support for
CANFD FD frames") Driver is updating the FSR IRI index multiple
times(i.e in xcanfd_rx() and xcan_rx_fifo_get_next_frame()),
It should be updated once per rx packet this patch fixes this issue,
also this patch removes the unnecessary fsr register checks in
xcanfd_rx() API.
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com>
Signed-off-by: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
drivers/net/can/xilinx_can.c | 139 ++++++++++++++++++++-----------------------
1 file changed, 63 insertions(+), 76 deletions(-)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index ac175ab..2d3399e 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -819,91 +819,78 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base)
u32 id_xcan, dlc, data[2] = {0, 0}, dwindex = 0, i, fsr, readindex;
fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
- if (fsr & XCAN_FSR_FL_MASK) {
- readindex = fsr & XCAN_FSR_RI_MASK;
- id_xcan = priv->read_reg(priv,
- XCAN_FRAME_ID_OFFSET(frame_base));
- dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base));
- if (dlc & XCAN_DLCR_EDL_MASK)
- skb = alloc_canfd_skb(ndev, &cf);
- else
- skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
+ readindex = fsr & XCAN_FSR_RI_MASK;
+ id_xcan = priv->read_reg(priv, XCAN_FRAME_ID_OFFSET(frame_base));
+ dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base));
+ if (dlc & XCAN_DLCR_EDL_MASK)
+ skb = alloc_canfd_skb(ndev, &cf);
+ else
+ skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
- if (unlikely(!skb)) {
- stats->rx_dropped++;
- return 0;
- }
+ if (unlikely(!skb)) {
+ stats->rx_dropped++;
+ return 0;
+ }
- /* Change Xilinx CANFD data length format to socketCAN data
- * format
- */
- if (dlc & XCAN_DLCR_EDL_MASK)
- cf->len = can_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
+ /* Change Xilinx CANFD data length format to socketCAN data
+ * format
+ */
+ if (dlc & XCAN_DLCR_EDL_MASK)
+ cf->len = can_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
+ XCAN_DLCR_DLC_SHIFT);
+ else
+ cf->len = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
XCAN_DLCR_DLC_SHIFT);
- else
- cf->len = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
- XCAN_DLCR_DLC_SHIFT);
-
- /* Change Xilinx CAN ID format to socketCAN ID format */
- if (id_xcan & XCAN_IDR_IDE_MASK) {
- /* The received frame is an Extended format frame */
- cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
- cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
- XCAN_IDR_ID2_SHIFT;
- cf->can_id |= CAN_EFF_FLAG;
- if (id_xcan & XCAN_IDR_RTR_MASK)
- cf->can_id |= CAN_RTR_FLAG;
- } else {
- /* The received frame is a standard format frame */
- cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
- XCAN_IDR_ID1_SHIFT;
- if (!(dlc & XCAN_DLCR_EDL_MASK) && (id_xcan &
- XCAN_IDR_SRR_MASK))
- cf->can_id |= CAN_RTR_FLAG;
- }
- /* Check the frame received is FD or not*/
- if (dlc & XCAN_DLCR_EDL_MASK) {
- for (i = 0; i < cf->len; i += 4) {
- if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
- data[0] = priv->read_reg(priv,
+ /* Change Xilinx CAN ID format to socketCAN ID format */
+ if (id_xcan & XCAN_IDR_IDE_MASK) {
+ /* The received frame is an Extended format frame */
+ cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
+ cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
+ XCAN_IDR_ID2_SHIFT;
+ cf->can_id |= CAN_EFF_FLAG;
+ if (id_xcan & XCAN_IDR_RTR_MASK)
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ /* The received frame is a standard format frame */
+ cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
+ XCAN_IDR_ID1_SHIFT;
+ if (!(dlc & XCAN_DLCR_EDL_MASK) && (id_xcan &
+ XCAN_IDR_SRR_MASK))
+ cf->can_id |= CAN_RTR_FLAG;
+ }
+
+ /* Check the frame received is FD or not*/
+ if (dlc & XCAN_DLCR_EDL_MASK) {
+ for (i = 0; i < cf->len; i += 4) {
+ if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
+ data[0] = priv->read_reg(priv,
(XCAN_RXMSG_2_FRAME_OFFSET(readindex) +
(dwindex * XCANFD_DW_BYTES)));
- else
- data[0] = priv->read_reg(priv,
+ else
+ data[0] = priv->read_reg(priv,
(XCAN_RXMSG_FRAME_OFFSET(readindex) +
- (dwindex * XCANFD_DW_BYTES)));
- *(__be32 *)(cf->data + i) =
- cpu_to_be32(data[0]);
- dwindex++;
- }
- } else {
- for (i = 0; i < cf->len; i += 4) {
- if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
- data[0] = priv->read_reg(priv,
- XCAN_RXMSG_2_FRAME_OFFSET(readindex) + i);
- else
- data[0] = priv->read_reg(priv,
- XCAN_RXMSG_FRAME_OFFSET(readindex) + i);
- *(__be32 *)(cf->data + i) =
- cpu_to_be32(data[0]);
- }
+ (dwindex * XCANFD_DW_BYTES)));
+ *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
+ dwindex++;
+ }
+ } else {
+ for (i = 0; i < cf->len; i += 4) {
+ if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
+ data[0] = priv->read_reg(priv,
+ XCAN_RXMSG_2_FRAME_OFFSET(readindex) +
+ i);
+ else
+ data[0] = priv->read_reg(priv,
+ XCAN_RXMSG_FRAME_OFFSET(readindex) + i);
+ *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
}
- /* Update FSR Register so that next packet will save to
- * buffer
- */
- fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
- fsr |= XCAN_FSR_IRI_MASK;
- priv->write_reg(priv, XCAN_FSR_OFFSET, fsr);
- fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
- stats->rx_bytes += cf->len;
- stats->rx_packets++;
- netif_receive_skb(skb);
-
- return 1;
}
- /* If FSR Register is not updated with fill level */
- return 0;
+ stats->rx_bytes += cf->len;
+ stats->rx_packets++;
+ netif_receive_skb(skb);
+
+ return 1;
}
/**
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 5/5] can: xilinx_can: Fix the data phase btr1 calculation
From: Appana Durga Kedareswara rao @ 2019-08-12 7:28 UTC (permalink / raw)
To: wg, mkl, davem, michal.simek
Cc: netdev, Srinivas Neeli, linux-kernel, linux-arm-kernel, linux-can
In-Reply-To: <1565594914-18999-1-git-send-email-appana.durga.rao@xilinx.com>
From: Srinivas Neeli <srinivas.neeli@xilinx.com>
While calculating bitrate for the data phase, the driver is using phase
segment 1 of the arbitration phase instead of the data phase.
Signed-off-by: Srinivas Neeli <srinivas.neeli@xilinx.com>
Acked-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
drivers/net/can/xilinx_can.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 4cb8c1c9..ab26691 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -425,7 +425,7 @@ static int xcan_set_bittiming(struct net_device *ndev)
btr0 = dbt->brp - 1;
/* Setting Time Segment 1 in BTR Register */
- btr1 = dbt->prop_seg + bt->phase_seg1 - 1;
+ btr1 = dbt->prop_seg + dbt->phase_seg1 - 1;
/* Setting Time Segment 2 in BTR Register */
btr1 |= (dbt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift;
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [linux-sunxi] [PATCH v8 0/4] Add support for Orange Pi 3
From: Jernej Škrabec @ 2019-08-12 7:44 UTC (permalink / raw)
To: linux-sunxi, megous
Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel, dri-devel,
David Airlie, Chen-Yu Tsai, Rob Herring, Daniel Vetter,
linux-arm-kernel
In-Reply-To: <20190806155744.10263-1-megous@megous.com>
Dne torek, 06. avgust 2019 ob 17:57:39 CEST je megous@megous.com napisal(a):
> From: Ondrej Jirman <megous@megous.com>
>
> This series implements support for Xunlong Orange Pi 3 board. There
> are only a few patches remaining.
>
> - ethernet support - just a DT change (patch 1)
> - HDMI support (patches 2-4)
>
> For some people, ethernet doesn't work after reboot because u-boot doesn't
> support AXP805 PMIC, and will not turn off the etherent PHY regulators.
> So the regulator controlled by gpio will be shut down, but the other one
> controlled by the AXP PMIC will not.
>
> This is a problem only when running with a builtin driver. This needs
> to be fixed in u-boot.
>
>
> Please take a look.
Is there anything missing? It would be nice to get this in 5.4. There is a lot
of H6 boards which needs DDC bus enable mechanism (part of H6 reference
design), including Beelink GS1 which already has HDMI node in mainline kernel
DT, but due to disabled DDC lines works only with 1024x768 (fallback
resolution in DRM core).
Best regards,
Jernej
>
> thank you and regards,
> Ondrej Jirman
>
> Changes in v8:
> - added reviewed-by tags
> - dropped already applied patches
> - added more info about the phy initialization issue after reset
>
> Changes in v7:
> - dropped stored reference to connector_pdev as suggested by Jernej
> - added forgotten dt-bindings reviewed-by tag
>
> Changes in v6:
> - added dt-bindings reviewed-by tag
> - fix wording in stmmac commit (as suggested by Sergei)
>
> Changes in v5:
> - dropped already applied patches (pinctrl patches, mmc1 pinconf patch)
> - rename GMAC-3V3 -> GMAC-3V to match the schematic (Jagan)
> - changed hdmi-connector's ddc-supply property to ddc-en-gpios
> (Rob Herring)
>
> Changes in v4:
> - fix checkpatch warnings/style issues
> - use enum in struct sunxi_desc_function for io_bias_cfg_variant
> - collected acked-by's
> - fix compile error in drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c:156
> caused by missing conversion from has_io_bias_cfg struct member
> (I've kept the acked-by, because it's a trivial change, but feel free
> to object.) (reported by Martin A. on github)
> I did not have A80 pinctrl enabled for some reason, so I did not catch
> this sooner.
> - dropped brcm firmware patch (was already applied)
> - dropped the wifi dts patch (will re-send after H6 RTC gets merged,
> along with bluetooth support, in a separate series)
>
> Changes in v3:
> - dropped already applied patches
> - changed pinctrl I/O bias selection constants to enum and renamed
> - added /omit-if-no-ref/ to mmc1_pins
> - made mmc1_pins default pinconf for mmc1 in H6 dtsi
> - move ddc-supply to HDMI connector node, updated patch descriptions,
> changed dt-bindings docs
>
> Changes in v2:
> - added dt-bindings documentation for the board's compatible string
> (suggested by Clement)
> - addressed checkpatch warnings and code formatting issues (on Maxime's
> suggestions)
> - stmmac: dropped useless parenthesis, reworded description of the patch
> (suggested by Sergei)
> - drop useles dev_info() about the selected io bias voltage
> - docummented io voltage bias selection variant macros
> - wifi: marked WiFi DTS patch and realted mmc1_pins as "DO NOT MERGE",
> because wifi depends on H6 RTC support that's not merged yet (suggested
> by Clement)
> - added missing signed-of-bys
> - changed &usb2otg dr_mode to otg, and added a note about VBUS
> - improved wording of HDMI driver's DDC power supply patch
>
> Ondrej Jirman (4):
> arm64: dts: allwinner: orange-pi-3: Enable ethernet
> dt-bindings: display: hdmi-connector: Support DDC bus enable
> drm: sun4i: Add support for enabling DDC I2C bus to sun8i_dw_hdmi glue
> arm64: dts: allwinner: orange-pi-3: Enable HDMI output
>
> .../display/connector/hdmi-connector.txt | 1 +
> .../dts/allwinner/sun50i-h6-orangepi-3.dts | 70 +++++++++++++++++++
> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 54 ++++++++++++--
> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 +
> 4 files changed, 123 insertions(+), 4 deletions(-)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 03/14] mfd: ab3100-core: convert to i2c_new_dummy_device
From: Lee Jones @ 2019-08-12 7:46 UTC (permalink / raw)
To: Wolfram Sang; +Cc: Linus Walleij, linux-i2c, linux-arm-kernel, linux-kernel
In-Reply-To: <20190722172623.4166-4-wsa+renesas@sang-engineering.com>
On Mon, 22 Jul 2019, Wolfram Sang wrote:
> Move from i2c_new_dummy() to i2c_new_dummy_device(), so we now get an
> ERRPTR which we use in error handling.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> ---
>
> Generated with coccinelle. Build tested by me and buildbot. Not tested on HW.
>
> drivers/mfd/ab3100-core.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Applied, thanks.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2] arm64: dts: meson-g12b-khadas-vim3: add initial device-tree
From: Neil Armstrong @ 2019-08-12 7:48 UTC (permalink / raw)
To: khilman
Cc: linux-amlogic, Christian Hewitt, linux-kernel, linux-arm-kernel,
Neil Armstrong
From: Christian Hewitt <christianshewitt@gmail.com>
The Khadas VIM3 uses the Amlogic S922X or A311S SoC, both based on the
Amlogic G12B SoC family, on a board with the same form factor as the
VIM/VIM2 models. It ships in two variants; basic and
pro which differ in RAM and eMMC size:
- 2GB (basic) or 4GB (pro) LPDDR4 RAM
- 16GB (basic) or 32GB (pro) eMMC 5.1 storage
- 16MB SPI flash
- 10/100/1000 Base-T Ethernet
- AP6398S Wireless (802.11 a/b/g/n/ac, BT5.0)
- HDMI 2.1 video
- 1x USB 2.0 + 1x USB 3.0 ports
- 1x USB-C (power) with USB 2.0 OTG
- 3x LED's (1x red, 1x blue, 1x white)
- 3x buttons (power, function, reset)
- IR receiver
- M2 socket with PCIe, USB, ADC & I2C
- 40pin GPIO Header
- 1x micro SD card slot
A common meson-g12b-khadas-vim3.dtsi is added to support both S922X and
A311D SoCs supported by two variants of the board.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
Changes since v1 at [1]:
- Changed default memory size to 2GiB
- Added "sys" to white led name
- Added ethernet PHY interrupt line (the reset line is unclear for now)
[1] https://patchwork.kernel.org/patch/11067793/
arch/arm64/boot/dts/amlogic/Makefile | 2 +
.../amlogic/meson-g12b-a311d-khadas-vim3.dts | 15 +
.../dts/amlogic/meson-g12b-khadas-vim3.dtsi | 544 ++++++++++++++++++
.../amlogic/meson-g12b-s922x-khadas-vim3.dts | 15 +
4 files changed, 576 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 07b861fe5fa5..ae5e8d0c08da 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -3,6 +3,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
new file mode 100644
index 000000000000..73128ed24361
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-a311d.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+ compatible = "khadas,vim3", "amlogic,a311d", "amlogic,g12b";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
new file mode 100644
index 000000000000..9c3ca2edc725
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ model = "Khadas VIM3";
+
+ aliases {
+ serial0 = &uart_AO;
+ ethernet0 = ðmac;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 2>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1710000>;
+
+ button-function {
+ label = "Function";
+ linux,code = <KEY_FN>;
+ press-threshold-microvolt = <10000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ white {
+ label = "vim3:white:sys";
+ gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ red {
+ label = "vim3:red";
+ gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ power-button {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ dc_in: regulator-dc_in {
+ compatible = "regulator-fixed";
+ regulator-name = "DC_IN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vcc_5v: regulator-vcc_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_in>;
+
+ gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+ enable-active-high;
+ };
+
+ vcc_1v8: regulator-vcc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vsys_3v3>;
+ regulator-always-on;
+ /* FIXME: actually controlled by VDDCPU_B_EN */
+ };
+
+ vddcpu_a: regulator-vddcpu-a {
+ /*
+ * MP8756GD Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_A";
+ regulator-min-microvolt = <690000>;
+ regulator-max-microvolt = <1050000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_ab 0 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddcpu_b: regulator-vddcpu-b {
+ /*
+ * Silergy SY8030DEC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_B";
+ regulator-min-microvolt = <690000>;
+ regulator-max-microvolt = <1050000>;
+
+ vin-supply = <&vsys_3v3>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddao_1v8: regulator-vddao_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vsys_3v3>;
+ regulator-always-on;
+ };
+
+ emmc_1v8: regulator-emmc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "EMMC_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ vsys_3v3: regulator-vsys_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSYS_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_in>;
+ regulator-always-on;
+ };
+
+ usb_pwr: regulator-usb_pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "USB_PWR";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v>;
+
+ gpio = <&gpio GPIOA_6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "G12A-KHADAS-VIM3";
+ audio-aux-devs = <&tdmout_b>;
+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-tx-mask-1 = <1 1>;
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&cec_AO {
+ pinctrl-0 = <&cec_ao_a_h_pins>;
+ pinctrl-names = "default";
+ status = "disabled";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu100 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu101 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu102 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu103 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+ðmac {
+ pinctrl-0 = <ð_pins>, <ð_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-handle = <&external_phy>;
+ amlogic,tx-delay-ns = <2>;
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+ pinctrl-names = "default";
+ hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&i2c_AO {
+ status = "okay";
+ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>;
+ pinctrl-names = "default";
+
+ gpio_expander: gpio-controller@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ vcc-supply = <&vcc_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+ linux,rc-map-name = "rc-khadas";
+};
+
+&pwm_ab {
+ pinctrl-0 = <&pwm_a_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+ status = "okay";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddao_1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vsys_3v3>;
+ vqmmc-supply = <&vddao_1v8>;
+
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_c_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vsys_3v3>;
+ vqmmc-supply = <&vsys_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_1v8>;
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb2_phy0 {
+ phy-supply = <&dc_in>;
+};
+
+&usb2_phy1 {
+ phy-supply = <&usb_pwr>;
+};
+
+&usb3_pcie_phy {
+ phy-supply = <&usb_pwr>;
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
new file mode 100644
index 000000000000..6bcf972b8bfa
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-s922x.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+ compatible = "khadas,vim3", "amlogic,s922x", "amlogic,g12b";
+};
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] arm64: dts: amlogic: g12 CPU timers stop in suspend
From: Neil Armstrong @ 2019-08-12 7:50 UTC (permalink / raw)
To: Kevin Hilman, linux-amlogic; +Cc: Kevin Hilman, linux-arm-kernel
In-Reply-To: <20190808170510.4141-1-khilman@kernel.org>
On 08/08/2019 19:05, Kevin Hilman wrote:
> From: Kevin Hilman <khilman@baylibre.com>
>
> The Arm per-CPU architected timers stop ticking in suspend, when the
> SCP powers down the CPUs. Flag that in the DT.
>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
> ---
> Applies on my v5.4/dt64 branch
>
> arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index 27bb242dc95d..cd3d23d2c6a2 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -2407,6 +2407,7 @@
> (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
> <GIC_PPI 10
> (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
> + arm,no-tick-in-suspend;
> };
>
> xtal: xtal-clk {
>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [linux-sunxi] [PATCH v8 0/4] Add support for Orange Pi 3
From: Chen-Yu Tsai @ 2019-08-12 7:54 UTC (permalink / raw)
To: Jernej Skrabec
Cc: Ondřej Jirman, Mark Rutland, devicetree, Maxime Ripard,
linux-kernel, dri-devel, David Airlie, linux-sunxi, Rob Herring,
Daniel Vetter, linux-arm-kernel
In-Reply-To: <2218280.0sI6yjypBf@jernej-laptop>
On Mon, Aug 12, 2019 at 3:45 PM Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
>
> Dne torek, 06. avgust 2019 ob 17:57:39 CEST je megous@megous.com napisal(a):
> > From: Ondrej Jirman <megous@megous.com>
> >
> > This series implements support for Xunlong Orange Pi 3 board. There
> > are only a few patches remaining.
> >
> > - ethernet support - just a DT change (patch 1)
> > - HDMI support (patches 2-4)
> >
> > For some people, ethernet doesn't work after reboot because u-boot doesn't
> > support AXP805 PMIC, and will not turn off the etherent PHY regulators.
> > So the regulator controlled by gpio will be shut down, but the other one
> > controlled by the AXP PMIC will not.
> >
> > This is a problem only when running with a builtin driver. This needs
> > to be fixed in u-boot.
> >
> >
> > Please take a look.
>
> Is there anything missing? It would be nice to get this in 5.4. There is a lot
> of H6 boards which needs DDC bus enable mechanism (part of H6 reference
> design), including Beelink GS1 which already has HDMI node in mainline kernel
> DT, but due to disabled DDC lines works only with 1024x768 (fallback
> resolution in DRM core).
I have a few minor comments about patch 1.
I think the HDMI bits are good, but I don't have maintainership / commit
permissions for drm-misc, so I'll have to wait until someone applies patches
2 and 3 before I apply patch 4.
ChenYu
> Best regards,
> Jernej
>
> >
> > thank you and regards,
> > Ondrej Jirman
> >
> > Changes in v8:
> > - added reviewed-by tags
> > - dropped already applied patches
> > - added more info about the phy initialization issue after reset
> >
> > Changes in v7:
> > - dropped stored reference to connector_pdev as suggested by Jernej
> > - added forgotten dt-bindings reviewed-by tag
> >
> > Changes in v6:
> > - added dt-bindings reviewed-by tag
> > - fix wording in stmmac commit (as suggested by Sergei)
> >
> > Changes in v5:
> > - dropped already applied patches (pinctrl patches, mmc1 pinconf patch)
> > - rename GMAC-3V3 -> GMAC-3V to match the schematic (Jagan)
> > - changed hdmi-connector's ddc-supply property to ddc-en-gpios
> > (Rob Herring)
> >
> > Changes in v4:
> > - fix checkpatch warnings/style issues
> > - use enum in struct sunxi_desc_function for io_bias_cfg_variant
> > - collected acked-by's
> > - fix compile error in drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c:156
> > caused by missing conversion from has_io_bias_cfg struct member
> > (I've kept the acked-by, because it's a trivial change, but feel free
> > to object.) (reported by Martin A. on github)
> > I did not have A80 pinctrl enabled for some reason, so I did not catch
> > this sooner.
> > - dropped brcm firmware patch (was already applied)
> > - dropped the wifi dts patch (will re-send after H6 RTC gets merged,
> > along with bluetooth support, in a separate series)
> >
> > Changes in v3:
> > - dropped already applied patches
> > - changed pinctrl I/O bias selection constants to enum and renamed
> > - added /omit-if-no-ref/ to mmc1_pins
> > - made mmc1_pins default pinconf for mmc1 in H6 dtsi
> > - move ddc-supply to HDMI connector node, updated patch descriptions,
> > changed dt-bindings docs
> >
> > Changes in v2:
> > - added dt-bindings documentation for the board's compatible string
> > (suggested by Clement)
> > - addressed checkpatch warnings and code formatting issues (on Maxime's
> > suggestions)
> > - stmmac: dropped useless parenthesis, reworded description of the patch
> > (suggested by Sergei)
> > - drop useles dev_info() about the selected io bias voltage
> > - docummented io voltage bias selection variant macros
> > - wifi: marked WiFi DTS patch and realted mmc1_pins as "DO NOT MERGE",
> > because wifi depends on H6 RTC support that's not merged yet (suggested
> > by Clement)
> > - added missing signed-of-bys
> > - changed &usb2otg dr_mode to otg, and added a note about VBUS
> > - improved wording of HDMI driver's DDC power supply patch
> >
> > Ondrej Jirman (4):
> > arm64: dts: allwinner: orange-pi-3: Enable ethernet
> > dt-bindings: display: hdmi-connector: Support DDC bus enable
> > drm: sun4i: Add support for enabling DDC I2C bus to sun8i_dw_hdmi glue
> > arm64: dts: allwinner: orange-pi-3: Enable HDMI output
> >
> > .../display/connector/hdmi-connector.txt | 1 +
> > .../dts/allwinner/sun50i-h6-orangepi-3.dts | 70 +++++++++++++++++++
> > drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 54 ++++++++++++--
> > drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 +
> > 4 files changed, 123 insertions(+), 4 deletions(-)
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/2218280.0sI6yjypBf%40jernej-laptop.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 1/3] media: stm32-dcmi: improve sensor subdev naming
From: Hugues FRUCHET @ 2019-08-12 7:55 UTC (permalink / raw)
To: Sakari Ailus
Cc: Yannick FERTRE, Alexandre TORGUE, Mickael GUENE,
linux-kernel@vger.kernel.org, Philippe CORNU, Hans Verkuil,
Benjamin Gaignard, Mauro Carvalho Chehab,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org
In-Reply-To: <20190809160121.GA6194@paasikivi.fi.intel.com>
Hi Sakari,
Sorry for inconvenience, I will push a V5 with that fixed.
May I put your "Acked-by" also on the 2 other commits ? Or just this one ?
On 8/9/19 6:01 PM, Sakari Ailus wrote:
> Hi Hugues,
>
> Thanks for teh update.
>
> On Wed, Jul 31, 2019 at 02:56:21PM +0200, Hugues Fruchet wrote:
>> Rename "subdev" entity struct field to "source"
>> to prepare for several subdev support.
>> Move asd field on top of entity struct.
>>
>> Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
>> Change-Id: I1545a1a29a8061ee67cc6e4b799e9a69071911e7
>
> No Change-Id tags in the kernel, please. Check the other two as well.
>
> With that fixed,
>
> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
>
Best regards,
Hugues.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: a64: Drop PMU node
From: Maxime Ripard @ 2019-08-12 8:04 UTC (permalink / raw)
To: Vasily Khoruzhick
Cc: Mark Rutland, devicetree, Jared D . McNeill, Chen-Yu Tsai,
Rob Herring, Harald Geyer, Robin Murphy, arm-linux
In-Reply-To: <CA+E=qVeiWoRGn05HpMzx_5yidit4GM18tBrziW5MBo00f_-PKQ@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 3330 bytes --]
On Thu, Aug 08, 2019 at 12:59:07PM -0700, Vasily Khoruzhick wrote:
> On Thu, Aug 8, 2019 at 9:26 AM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> >
> > On Wed, Aug 07, 2019 at 10:36:08AM -0700, Vasily Khoruzhick wrote:
> > > On Wed, Aug 7, 2019 at 4:56 AM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > > >
> > > > On Tue, Aug 06, 2019 at 07:39:26PM -0700, Vasily Khoruzhick wrote:
> > > > > On Tue, Aug 6, 2019 at 2:14 PM Robin Murphy <robin.murphy@arm.com> wrote:
> > > > > >
> > > > > > On 2019-08-06 9:52 pm, Vasily Khoruzhick wrote:
> > > > > > > On Tue, Aug 6, 2019 at 1:19 PM Harald Geyer <harald@ccbib.org> wrote:
> > > > > > >>
> > > > > > >> Vasily Khoruzhick writes:
> > > > > > >>> On Tue, Aug 6, 2019 at 7:35 AM Robin Murphy <robin.murphy@arm.com> wrote:
> > > > > > >>>>
> > > > > > >>>> On 06/08/2019 15:01, Vasily Khoruzhick wrote:
> > > > > > >>>>> Looks like PMU in A64 is broken, it generates no interrupts at all and
> > > > > > >>>>> as result 'perf top' shows no events.
> > > > > > >>>>
> > > > > > >>>> Does something like 'perf stat sleep 1' at least count cycles correctly?
> > > > > > >>>> It could well just be that the interrupt numbers are wrong...
> > > > > > >>>
> > > > > > >>> Looks like it does, at least result looks plausible:
> > > > > > >>
> > > > > > >> I'm using perf stat regularly (cache benchmarks) and it works fine.
> > > > > > >>
> > > > > > >> Unfortunately I wasn't aware that perf stat is a poor test for
> > > > > > >> the interrupts part of the node, when I added it. So I'm not too
> > > > > > >> surprised I got it wrong.
> > > > > > >>
> > > > > > >> However, it would be unfortunate if the node got removed completely,
> > > > > > >> because perf stat would not work anymore. Maybe we can only remove
> > > > > > >> the interrupts or just fix them even if the HW doesn't work?
> > > > > > >
> > > > > > > I'm not familiar with PMU driver. Is it possible to get it working
> > > > > > > without interrupts?
> > > > > >
> > > > > > Yup - you get a grumpy message from the driver, it will refuse sampling
> > > > > > events (the ones which weren't working anyway), and if you measure
> > > > > > anything for long enough that a counter overflows you'll get wonky
> > > > > > results. But for counting hardware events over relatively short periods
> > > > > > it'll still do the job.
> > > > >
> > > > > I tried to drop interrupts completely from the node but 'perf top' is
> > > > > still broken. Though now in different way: it complains "cycles: PMU
> > > > > Hardware doesn't support sampling/overflow-interrupts. Try 'perf
> > > > > stat'"
> > > >
> > > > I have no idea if that's the culprit, but what is the state of the
> > > > 0x09010000 register?
> > >
> > > What register is that and how do I check it?
> >
> > It's in the CPUX Configuration block, and the bits are labelled as CPU
> > Debug Reset.
> >
> > And if you have busybox, you can use devmem.
>
> CPUX configuration block is at 0x01700000 according to A64 user
> manual, and particular register you're interested in is at 0x01700080,
> its value is 0x1110110F.
>
> Bits 16-19 are not defined in user manual and are not set.
Sorry, I somehow thought this was for the H6...
I don't have any idea then :/
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 0/6] Support for Allwinner V3/S3L and Sochip S3
From: Maxime Ripard @ 2019-08-12 8:07 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Linus Walleij, linux-sunxi, linux-kernel, linux-gpio,
Chen-Yu Tsai, Rob Herring, linux-clk, linux-arm-kernel
In-Reply-To: <20190728031227.49140-1-icenowy@aosc.io>
[-- Attachment #1.1: Type: text/plain, Size: 1356 bytes --]
On Sun, Jul 28, 2019 at 11:12:21AM +0800, Icenowy Zheng wrote:
> This patchset tries to add support for Allwinner V3/S3L and Sochip S3.
>
> Allwinner V3/V3s/S3L and Sochip S3 share the same die, but with
> different package. V3 is BGA w/o co-packaged DDR, V3s is QFP w/ DDR2,
> S3L is BGA w/ DDR2 and S3 is BGA w/ DDR3. (S3 and S3L is compatible
> for pinout, but because of different DDR, DDR voltage is different
> between the two variants). Because of the pin count of V3s is
> restricted due to the package, some pins are not bound on V3s, but
> they're bound on V3/S3/S3L.
>
> Currently the kernel is only prepared for the features available on V3s.
> This patchset adds the features missing on V3s for using them on
> V3/S3/S3L, and add bindings for V3/S3/S3L. It also adds a S3 SoM by
> Sipeed, called Lichee Zero Plus.
>
> Icenowy Zheng (6):
> pinctrl: sunxi: v3s: introduce support for V3
> clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks
> clk: sunxi-ng: v3s: add Allwinner V3 support
> ARM: sunxi: dts: s3/s3l/v3: add DTSI files for S3/S3L/V3 SoCs
> dt-bindings: arm: sunxi: add binding for Lichee Zero Plus core board
> ARM: dts: sun8i: s3: add devicetree for Lichee zero plus w/ S3
Applied the patches 2 to 6, thanks!
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [linux-sunxi] [PATCH v8 0/4] Add support for Orange Pi 3
From: Maxime Ripard @ 2019-08-12 8:14 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Ondřej Jirman, Mark Rutland, devicetree, David Airlie,
linux-kernel, Jernej Skrabec, linux-sunxi, Rob Herring, dri-devel,
Daniel Vetter, linux-arm-kernel
In-Reply-To: <CAGb2v67JVG2rhOdUwBmfsO0+RYb4DNOPmUo=Q_UhL3N+niLiEg@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 1681 bytes --]
On Mon, Aug 12, 2019 at 03:54:03PM +0800, Chen-Yu Tsai wrote:
> On Mon, Aug 12, 2019 at 3:45 PM Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
> >
> > Dne torek, 06. avgust 2019 ob 17:57:39 CEST je megous@megous.com napisal(a):
> > > From: Ondrej Jirman <megous@megous.com>
> > >
> > > This series implements support for Xunlong Orange Pi 3 board. There
> > > are only a few patches remaining.
> > >
> > > - ethernet support - just a DT change (patch 1)
> > > - HDMI support (patches 2-4)
> > >
> > > For some people, ethernet doesn't work after reboot because u-boot doesn't
> > > support AXP805 PMIC, and will not turn off the etherent PHY regulators.
> > > So the regulator controlled by gpio will be shut down, but the other one
> > > controlled by the AXP PMIC will not.
> > >
> > > This is a problem only when running with a builtin driver. This needs
> > > to be fixed in u-boot.
> > >
> > >
> > > Please take a look.
> >
> > Is there anything missing? It would be nice to get this in 5.4. There is a lot
> > of H6 boards which needs DDC bus enable mechanism (part of H6 reference
> > design), including Beelink GS1 which already has HDMI node in mainline kernel
> > DT, but due to disabled DDC lines works only with 1024x768 (fallback
> > resolution in DRM core).
>
> I have a few minor comments about patch 1.
>
> I think the HDMI bits are good, but I don't have maintainership / commit
> permissions for drm-misc, so I'll have to wait until someone applies patches
> 2 and 3 before I apply patch 4.
I've applied 2,3 and 4
Thanks!
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/6] irqchip: Add Realtek RTD129x intc driver
From: Aleix Roca Nonell @ 2019-08-12 8:26 UTC (permalink / raw)
To: Marc Zyngier
Cc: Mark Rutland, devicetree, Jason Cooper, linux-kernel, Rob Herring,
Matthias Brugger, Thomas Gleixner, Andreas Färber,
linux-arm-kernel
In-Reply-To: <5efa2ccb-9659-443c-7986-8ceb01aa64b9@arm.com>
Hi Mark and everyone! Sorry for the large delay, I'm doing this in my
free time, which is not that abundant. In this mail, I'm focusing only
on the largest change mentioned by Mark. I will answer the rest later.
On Mon, Jul 08, 2019 at 10:36:14AM +0100, Marc Zyngier wrote:
> On 07/07/2019 14:22, Aleix Roca Nonell wrote:
> > This driver adds support for the RTD1296 and RTD1295 interrupt
> > controller (intc). It is based on both the BPI-SINOVOIP project and
> > Andreas Färber's previous attempt to submit a similar driver.
> >
> > There is currently no publicly available datasheet on this SoC and the
> > exact behaviour of the registers controlling the intc remain uncertain.
> >
> > This driver controls two intcs: "iso" and "misc". Each intc has its own
> > Interrupt Enable Register (IER) and Interrupt Status Resgister (ISR).
>
> Register
>
> > However, not all "misc" intc irqs have the same offsets for both ISR and
> > IER. For this reason an ISR to IER offsets table is defined.
> >
> > The driver catches the IER value to reduce accesses to the table inside the
> > interrupt handler. Actually, the driver stores the ISR offsets of currently
> > enabled interrupts in a variable.
> >
> > Signed-off-by: Aleix Roca Nonell <kernelrocks@gmail.com>
>
> I expect Andreas and you to sort the attribution issue. I'm certainly
> not going to take this in if things are unclear.
>
> > ---
> > drivers/irqchip/Makefile | 1 +
> > drivers/irqchip/irq-rtd129x.c | 371 ++++++++++++++++++++++++++++++++++
> > 2 files changed, 372 insertions(+)
> > create mode 100644 drivers/irqchip/irq-rtd129x.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index 606a003a0000..0689c3956250 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -100,3 +100,4 @@ obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
> > obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o
> > obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o
> > obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o
> > +obj-$(CONFIG_ARCH_REALTEK) += irq-rtd129x.o
> > diff --git a/drivers/irqchip/irq-rtd129x.c b/drivers/irqchip/irq-rtd129x.c
> > new file mode 100644
> > index 000000000000..76358ca50f10
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-rtd129x.c
> > @@ -0,0 +1,371 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/irqchip.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/io.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/bits.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +
> > +#define RTD129X_INTC_NR_IRQS 32
> > +#define DEV_NAME "RTD1296_INTC"
> > +
> > +/*
> > + * This interrupt controller (hereinafter intc) driver controls two intcs: "iso"
> > + * and "misc". Each intc has its own Interrupt Enable Register (IER) and
> > + * Interrupt Status Resgister (ISR). However, not all "misc" intc irqs have the
> > + * same offsets for both ISR and IER. For this reason an ISR to IER offsets
> > + * table is defined. Also, to reduce accesses to this table in the interrupt
> > + * handler, the driver stores the ISR offsets of currently enabled interrupts in
> > + * a variable.
> > + */
> > +
> > +enum misc_int_en {
> > + MISC_INT_FAIL = 0xFF,
> > + MISC_INT_RVD = 0xFE,
> > + MISC_INT_EN_FAN = 29,
> > + MISC_INT_EN_I2C3 = 28,
> > + MISC_INT_EN_GSPI = 27,
> > + MISC_INT_EN_I2C2 = 26,
> > + MISC_INT_EN_SC0 = 24,
> > + MISC_INT_EN_LSADC1 = 22,
> > + MISC_INT_EN_LSADC0 = 21,
> > + MISC_INT_EN_GPIODA = 20,
> > + MISC_INT_EN_GPIOA = 19,
> > + MISC_INT_EN_I2C4 = 15,
> > + MISC_INT_EN_I2C5 = 14,
> > + MISC_INT_EN_RTC_DATA = 12,
> > + MISC_INT_EN_RTC_HOUR = 11,
> > + MISC_INT_EN_RTC_MIN = 10,
> > + MISC_INT_EN_UR2 = 7,
> > + MISC_INT_EN_UR2_TO = 6,
> > + MISC_INT_EN_UR1_TO = 5,
> > + MISC_INT_EN_UR1 = 3,
> > +};
> > +
> > +enum iso_int_en {
> > + ISO_INT_FAIL = 0xFF,
> > + ISO_INT_RVD = 0xFE,
> > + ISO_INT_EN_I2C1_REQ = 31,
> > + ISO_INT_EN_GPHY_AV = 30,
> > + ISO_INT_EN_GPHY_DV = 29,
> > + ISO_INT_EN_GPIODA = 20,
> > + ISO_INT_EN_GPIOA = 19,
> > + ISO_INT_EN_RTC_ALARM = 13,
> > + ISO_INT_EN_RTC_HSEC = 12,
> > + ISO_INT_EN_I2C1 = 11,
> > + ISO_INT_EN_I2C0 = 8,
> > + ISO_INT_EN_IRDA = 5,
> > + ISO_INT_EN_UR0 = 2,
> > +};
> > +
> > +unsigned char rtd129x_intc_enable_map_misc[RTD129X_INTC_NR_IRQS] = {
> > + MISC_INT_FAIL, /* Bit0 */
> > + MISC_INT_FAIL, /* Bit1 */
> > + MISC_INT_RVD, /* Bit2 */
> > + MISC_INT_EN_UR1, /* Bit3 */
> > + MISC_INT_FAIL, /* Bit4 */
> > + MISC_INT_EN_UR1_TO, /* Bit5 */
> > + MISC_INT_RVD, /* Bit6 */
> > + MISC_INT_RVD, /* Bit7 */
> > + MISC_INT_EN_UR2, /* Bit8 */
> > + MISC_INT_RVD, /* Bit9 */
> > + MISC_INT_EN_RTC_MIN, /* Bit10 */
> > + MISC_INT_EN_RTC_HOUR, /* Bit11 */
> > + MISC_INT_EN_RTC_DATA, /* Bit12 */
> > + MISC_INT_EN_UR2_TO, /* Bit13 */
> > + MISC_INT_EN_I2C5, /* Bit14 */
> > + MISC_INT_EN_I2C4, /* Bit15 */
> > + MISC_INT_FAIL, /* Bit16 */
> > + MISC_INT_FAIL, /* Bit17 */
> > + MISC_INT_FAIL, /* Bit18 */
> > + MISC_INT_EN_GPIOA, /* Bit19 */
> > + MISC_INT_EN_GPIODA, /* Bit20 */
> > + MISC_INT_EN_LSADC0, /* Bit21 */
> > + MISC_INT_EN_LSADC1, /* Bit22 */
> > + MISC_INT_EN_I2C3, /* Bit23 */
> > + MISC_INT_EN_SC0, /* Bit24 */
> > + MISC_INT_FAIL, /* Bit25 */
> > + MISC_INT_EN_I2C2, /* Bit26 */
> > + MISC_INT_EN_GSPI, /* Bit27 */
> > + MISC_INT_FAIL, /* Bit28 */
> > + MISC_INT_EN_FAN, /* Bit29 */
> > + MISC_INT_FAIL, /* Bit30 */
> > + MISC_INT_FAIL /* Bit31 */
> > +};
> > +
> > +unsigned char rtd129x_intc_enable_map_iso[RTD129X_INTC_NR_IRQS] = {
> > + ISO_INT_FAIL, /* Bit0 */
> > + ISO_INT_RVD, /* Bit1 */
> > + ISO_INT_EN_UR0, /* Bit2 */
> > + ISO_INT_FAIL, /* Bit3 */
> > + ISO_INT_FAIL, /* Bit4 */
> > + ISO_INT_EN_IRDA, /* Bit5 */
> > + ISO_INT_FAIL, /* Bit6 */
> > + ISO_INT_RVD, /* Bit7 */
> > + ISO_INT_EN_I2C0, /* Bit8 */
> > + ISO_INT_RVD, /* Bit9 */
> > + ISO_INT_FAIL, /* Bit10 */
> > + ISO_INT_EN_I2C1, /* Bit11 */
> > + ISO_INT_EN_RTC_HSEC, /* Bit12 */
> > + ISO_INT_EN_RTC_ALARM, /* Bit13 */
> > + ISO_INT_FAIL, /* Bit14 */
> > + ISO_INT_FAIL, /* Bit15 */
> > + ISO_INT_FAIL, /* Bit16 */
> > + ISO_INT_FAIL, /* Bit17 */
> > + ISO_INT_FAIL, /* Bit18 */
> > + ISO_INT_EN_GPIOA, /* Bit19 */
> > + ISO_INT_EN_GPIODA, /* Bit20 */
> > + ISO_INT_RVD, /* Bit21 */
> > + ISO_INT_RVD, /* Bit22 */
> > + ISO_INT_RVD, /* Bit23 */
> > + ISO_INT_RVD, /* Bit24 */
> > + ISO_INT_FAIL, /* Bit25 */
> > + ISO_INT_FAIL, /* Bit26 */
> > + ISO_INT_FAIL, /* Bit27 */
> > + ISO_INT_FAIL, /* Bit28 */
> > + ISO_INT_EN_GPHY_DV, /* Bit29 */
> > + ISO_INT_EN_GPHY_AV, /* Bit30 */
> > + ISO_INT_EN_I2C1_REQ /* Bit31 */
> > +};
> > +
> > +struct rtd129x_intc_data {
> > + void __iomem *unmask;
> > + void __iomem *isr;
> > + void __iomem *ier;
> > + u32 ier_cached;
> > + u32 isr_en;
> > + raw_spinlock_t lock;
> > + unsigned int parent_irq;
> > + const unsigned char *en_map;
> > +};
> > +
> > +static struct irq_domain *rtd129x_intc_domain;
> > +
> > +static void rtd129x_intc_irq_handle(struct irq_desc *desc)
> > +{
> > + struct rtd129x_intc_data *priv = irq_desc_get_handler_data(desc);
> > + struct irq_chip *chip = irq_desc_get_chip(desc);
> > + unsigned int local_irq;
> > + u32 status;
> > + int i;
> > +
> > + chained_irq_enter(chip, desc);
> > +
> > + raw_spin_lock(&priv->lock);
> > + status = readl_relaxed(priv->isr);
> > + status &= priv->isr_en;
> > + raw_spin_unlock(&priv->lock);
>
> What is this lock protecting? isr_en?
>
> > +
> > + while (status) {
> > + i = __ffs(status);
> > + status &= ~BIT(i);
> > +
> > + local_irq = irq_find_mapping(rtd129x_intc_domain, i);
> > + if (likely(local_irq)) {
> > + if (!generic_handle_irq(local_irq))
> > + writel_relaxed(BIT(i), priv->isr);
>
> What are the write semantics of the ISR register? Hot bit clear? How
> does it work since mask() does the same thing? Clearly, something is
> wrong here.
Sorry but I have not been able to found the definition of "hot bit
clear", could you explain it? Anyways, you were right, apparently the
mask/unmask code were doing nothing useful. More on this below.
>
> > + } else {
> > + handle_bad_irq(desc);
> > + }
> > + }
> > +
> > + chained_irq_exit(chip, desc);
> > +}
> > +
> > +static void rtd129x_intc_mask(struct irq_data *data)
> > +{
> > + struct rtd129x_intc_data *priv = irq_data_get_irq_chip_data(data);
> > +
> > + writel_relaxed(BIT(data->hwirq), priv->isr);
> > +}
> > +
> > +static void rtd129x_intc_unmask(struct irq_data *data)
> > +{
> > + struct rtd129x_intc_data *priv = irq_data_get_irq_chip_data(data);
> > +
> > + writel_relaxed(BIT(data->hwirq), priv->unmask);
>
> What effect does this have on the isr register? The whole mask/unmask
> thing seems to be pretty dodgy...
>
> > +}
> > +
> > +static void rtd129x_intc_enable(struct irq_data *data)
> > +{
> > + struct rtd129x_intc_data *priv = irq_data_get_irq_chip_data(data);
> > + unsigned long flags;
> > + u8 en_offset;
> > +
> > + en_offset = priv->en_map[data->hwirq];
> > +
> > + if ((en_offset != MISC_INT_RVD) && (en_offset != MISC_INT_FAIL)) {
> > + raw_spin_lock_irqsave(&priv->lock, flags);
> > +
> > + priv->isr_en |= BIT(data->hwirq);
> > + priv->ier_cached |= BIT(en_offset);
> > + writel_relaxed(priv->ier_cached, priv->ier);
> > +
> > + raw_spin_unlock_irqrestore(&priv->lock, flags);
> > + } else if (en_offset == MISC_INT_FAIL) {
> > + pr_err("[%s] Enable irq(%lu) failed\n", DEV_NAME, data->hwirq);
> > + }
> > +}
> > +
> > +static void rtd129x_intc_disable(struct irq_data *data)
> > +{
> > + struct rtd129x_intc_data *priv = irq_data_get_irq_chip_data(data);
> > + unsigned long flags;
> > + u8 en_offset;
> > +
> > + en_offset = priv->en_map[data->hwirq];
> > +
> > + if ((en_offset != MISC_INT_RVD) && (en_offset != MISC_INT_FAIL)) {
> > + raw_spin_lock_irqsave(&priv->lock, flags);
> > +
> > + priv->isr_en &= ~BIT(data->hwirq);
> > + priv->ier_cached &= ~BIT(en_offset);
> > + writel_relaxed(priv->ier_cached, priv->ier);
> > +
> > + raw_spin_unlock_irqrestore(&priv->lock, flags);
> > + } else if (en_offset == MISC_INT_FAIL) {
> > + pr_err("[%s] Disable irq(%lu) failed\n", DEV_NAME, data->hwirq);
> > + }
> > +}
>
> So here's a thought: Why do we need all of this? If mask/unmask do their
> job correctly, we could just enable all interrupts in one go (just a
> 32bit write) at probe time, and leave all interrupts masked until they
> are in use. You could then drop all these silly tables that don't bring
> much...
The idea of dropping all those tables look really good to me, that
would greatly simplify the code! I have been trying to mask all
interrupts on the probe function using the ISR register but while
doing so, I realized that it does not work. Writing to ISR does not
mask interrupts, apparently it only acknowledges them once they have
been triggered. On the scarse available documentation of this Soc I
cannot find a mask-like register. It seems interrupts are managed with
an ISR and an IER register. So it should be posible to use the enable
register to maks/unmask instead. These do work. However, that would
mean that we have to keep those ugly tables.
Nonetheless we might still be able to do something else. Please,
correct me if I'm wrong, but do we really need to mask/unamsk in this
scenario? This is the devised board layout:
+------+ +----------+ +---------+
| | | | | |
| UART |-------|2 INTC |-------|c GIC |
| | +----|1 | +----|b |
+------+ | +--|0 | | +--|a |
| | | | | | | |
| | +----------+ | | +---------+
| |
Once the UART generates an interrupt it passes through the line 2 of
the custom realtek interrupt contoller before reaching the GIC's line
"c". On the INTC interrupt handler, we call chained_irq_enter/exit
to mask/unmask the GIC's "c" line. Because all of this realtek INTC
interrupt lines (2,1,0,...) are muxed on the GIC's line "c", this
means that while on the INTC interrupt handler it is not possible to
send further interrupts on the CPU. Given that interrupts are masked
on the GIC, it seems safe to just remove INTC's mask/unmask functions.
Therefore, the only work that this INTC handler would needs to do is
to acknowledge the interrupt by writing to the ISR, which it could be
done in the respective irq_ack callback of struct irq_chip instead of
in the handler body.
I have implemented this solution and it seems to work. What do you
think? I'm missing something crucial?
>
> > +
> > +static struct irq_chip rtd129x_intc_chip = {
> > + .name = DEV_NAME,
> > + .irq_mask = rtd129x_intc_mask,
> > + .irq_unmask = rtd129x_intc_unmask,
> > + .irq_enable = rtd129x_intc_enable,
> > + .irq_disable = rtd129x_intc_disable,
> > +};
> > +
> > +static int rtd129x_intc_map(struct irq_domain *d, unsigned int virq,
> > + irq_hw_number_t hw_irq)
> > +{
> > + struct rtd129x_intc_data *priv = d->host_data;
> > +
> > + irq_set_chip_and_handler(virq, &rtd129x_intc_chip, handle_level_irq);
> > + irq_set_chip_data(virq, priv);
> > + irq_set_probe(virq);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct irq_domain_ops rtd129x_intc_domain_ops = {
> > + .xlate = irq_domain_xlate_onecell,
> > + .map = rtd129x_intc_map,
> > +};
> > +
> > +static const struct of_device_id rtd129x_intc_matches[] = {
> > + { .compatible = "realtek,rtd129x-intc-misc",
> > + .data = rtd129x_intc_enable_map_misc
> > + },
> > + { .compatible = "realtek,rtd129x-intc-iso",
> > + .data = rtd129x_intc_enable_map_iso
> > + },
> > + { }
> > +};
> > +
> > +static int rtd129x_intc_of_init(struct device_node *node,
> > + struct device_node *parent)
> > +{
> > + struct rtd129x_intc_data *priv;
> > + const struct of_device_id *match;
> > + u32 isr_tmp, ier_tmp, ier_bit;
> > + int ret, i;
> > +
> > + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> > + if (!priv) {
> > + ret = -ENOMEM;
> > + goto err;
> > + }
> > +
> > + raw_spin_lock_init(&priv->lock);
> > +
> > + priv->isr = of_iomap(node, 0);
> > + if (!priv->isr) {
> > + pr_err("unable to obtain status reg iomap address\n");
> > + ret = -ENOMEM;
> > + goto free_priv;
> > + }
> > +
> > + priv->ier = of_iomap(node, 1);
> > + if (!priv->ier) {
> > + pr_err("unable to obtain enable reg iomap address\n");
> > + ret = -ENOMEM;
> > + goto iounmap_status;
> > + }
> > +
> > + priv->unmask = of_iomap(node, 2);
> > + if (!priv->unmask) {
> > + pr_err("unable to obtain unmask reg iomap address\n");
> > + ret = -ENOMEM;
> > + goto iounmap_enable;
> > + }
> > +
> > + priv->parent_irq = irq_of_parse_and_map(node, 0);
> > + if (!priv->parent_irq) {
> > + pr_err("failed to map parent interrupt %d\n", priv->parent_irq);
> > + ret = -EINVAL;
> > + goto iounmap_all;
> > + }
> > +
> > + match = of_match_node(rtd129x_intc_matches, node);
> > + if (!match) {
> > + pr_err("failed to find matching node\n");
> > + ret = -ENODEV;
> > + goto iounmap_all;
> > + }
> > + priv->en_map = match->data;
> > +
> > + // initialize enabled irq's map to its matching status bit in isr by
> > + // inverse walking the enable to status offsets map. Only needed for
> > + // misc
>
> Why do we need any of this? The kernel is supposed to start from a clean
> slate, not to inherit whatever has been set before, unless there is a
> very compelling reason.
>
> > + priv->ier_cached = readl_relaxed(priv->ier);
> > + if (priv->en_map == rtd129x_intc_enable_map_misc) {
> > + ier_tmp = priv->ier_cached;
> > + isr_tmp = 0;
> > + while (ier_tmp) {
> > + ier_bit = __ffs(ier_tmp);
> > + ier_tmp &= ~BIT(ier_bit);
> > + for (i = 0; i < RTD129X_INTC_NR_IRQS; i++)
> > + if (priv->en_map[i] == ier_bit)
> > + isr_tmp |= BIT(i);
> > + }
> > + priv->isr_en = isr_tmp;
> > + } else {
> > + priv->isr_en = priv->ier_cached;
> > + }
> > +
> > + rtd129x_intc_domain = irq_domain_add_linear(node, RTD129X_INTC_NR_IRQS,
> > + &rtd129x_intc_domain_ops,
> > + priv);
> > + if (!rtd129x_intc_domain) {
> > + pr_err("failed to create irq domain\n");
> > + ret = -ENOMEM;
> > + goto iounmap_all;
> > + }
> > +
> > + irq_set_chained_handler_and_data(priv->parent_irq,
> > + rtd129x_intc_irq_handle, priv);
> > +
> > + return 0;
> > +
> > +iounmap_all:
> > + iounmap(priv->unmask);
> > +iounmap_enable:
> > + iounmap(priv->ier);
> > +iounmap_status:
> > + iounmap(priv->isr);
> > +free_priv:
> > + kfree(priv);
> > +err:
> > + return ret;
> > +}
> > +
> > +IRQCHIP_DECLARE(rtd129x_intc_misc, "realtek,rtd129x-intc-misc",
> > + rtd129x_intc_of_init);
> > +IRQCHIP_DECLARE(rtd129x_intc_iso, "realtek,rtd129x-intc-iso",
> > + rtd129x_intc_of_init);
> >
>
> Thanks,
Thank you very much for your time!
>
> M.
> --
> Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 2/7] drm/mediatek: fixes CMDQ reg address of mt8173 is different with mt2701
From: CK Hu @ 2019-08-12 8:40 UTC (permalink / raw)
To: Jitao Shi
Cc: Mark Rutland, devicetree, David Airlie, stonea168, dri-devel,
yingjoe.chen, Ajay Kumar, Vincent Palatin, cawa.cheng,
bibby.hsieh, Russell King, Thierry Reding, linux-pwm,
Sascha Hauer, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
linux-mediatek, Andy Yan, Matthias Brugger, eddie.huang,
linux-arm-kernel, Rahul Sharma, srv_heupstream, linux-kernel,
Philipp Zabel, Sean Paul
In-Reply-To: <20190811104008.53372-3-jitao.shi@mediatek.com>
Hi, Jitao:
On Sun, 2019-08-11 at 18:40 +0800, Jitao Shi wrote:
> Config the different CMDQ reg address in driver data.
>
> Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> ---
> drivers/gpu/drm/mediatek/mtk_dsi.c | 29 ++++++++++++++++++++++++-----
> 1 file changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 52b49daeed9f..ac8e80e379f7 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -123,7 +123,6 @@
> #define VM_CMD_EN BIT(0)
> #define TS_VFP_EN BIT(5)
>
> -#define DSI_CMDQ0 0x180
> #define CONFIG (0xff << 0)
> #define SHORT_PACKET 0
> #define LONG_PACKET 2
> @@ -148,6 +147,10 @@
>
> struct phy;
>
> +struct mtk_dsi_driver_data {
> + const u32 reg_cmdq_off;
> +};
> +
> struct mtk_dsi {
> struct mtk_ddp_comp ddp_comp;
> struct device *dev;
> @@ -174,6 +177,7 @@ struct mtk_dsi {
> bool enabled;
> u32 irq_data;
> wait_queue_head_t irq_wait_queue;
> + const struct mtk_dsi_driver_data *driver_data;
> };
>
> static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
> @@ -936,6 +940,7 @@ static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
> const char *tx_buf = msg->tx_buf;
> u8 config, cmdq_size, cmdq_off, type = msg->type;
> u32 reg_val, cmdq_mask, i;
> + u32 reg_cmdq_off = dsi->driver_data->reg_cmdq_off;
>
> if (MTK_DSI_HOST_IS_READ(type))
> config = BTA;
> @@ -955,9 +960,11 @@ static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
> }
>
> for (i = 0; i < msg->tx_len; i++)
> - writeb(tx_buf[i], dsi->regs + DSI_CMDQ0 + cmdq_off + i);
> + mtk_dsi_mask(dsi, (reg_cmdq_off + cmdq_off + i) & (~0x3U),
> + (0xffUL << (((i + cmdq_off) & 3U) * 8U)),
> + tx_buf[i] << (((i + cmdq_off) & 3U) * 8U));
If writeb() has the same problem in MT2701, I think we need a patch that
just change writeb() to mtk_dsi_mask(), and then a patch to fix CMDQ reg
address of MT8173. So break this patch into two patches.
Regards,
CK
>
> - mtk_dsi_mask(dsi, DSI_CMDQ0, cmdq_mask, reg_val);
> + mtk_dsi_mask(dsi, reg_cmdq_off, cmdq_mask, reg_val);
> mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size);
> }
>
> @@ -1101,6 +1108,8 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> if (ret)
> goto err_unregister_host;
>
> + dsi->driver_data = of_device_get_match_data(dev);
> +
> dsi->engine_clk = devm_clk_get(dev, "engine");
> if (IS_ERR(dsi->engine_clk)) {
> ret = PTR_ERR(dsi->engine_clk);
> @@ -1194,9 +1203,19 @@ static int mtk_dsi_remove(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
> + .reg_cmdq_off = 0x200,
> +};
> +
> +static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = {
> + .reg_cmdq_off = 0x180,
> +};
> +
> static const struct of_device_id mtk_dsi_of_match[] = {
> - { .compatible = "mediatek,mt2701-dsi" },
> - { .compatible = "mediatek,mt8173-dsi" },
> + { .compatible = "mediatek,mt2701-dsi",
> + .data = &mt2701_dsi_driver_data },
> + { .compatible = "mediatek,mt8173-dsi",
> + .data = &mt8173_dsi_driver_data },
> { },
> };
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v7 1/4] arm64: defconfig: Enable CONFIG_ENERGY_MODEL
From: Quentin Perret @ 2019-08-12 8:42 UTC (permalink / raw)
To: edubezval, rui.zhang, javi.merino, viresh.kumar, amit.kachhap,
rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, quentin.perret, mka, ionela.voinescu,
dietmar.eggemann, linux-arm-kernel
In-Reply-To: <20190812084235.21440-1-quentin.perret@arm.com>
The recently introduced Energy Model (EM) framework manages power cost
tables for the CPUs of the system. Its only user right now is the
scheduler, in the context of Energy Aware Scheduling (EAS).
However, the EM framework also offers a generic infrastructure that
could replace subsystem-specific implementations of the same concepts,
as this is the case in the thermal framework.
So, in order to prepare the migration of the thermal subsystem to use
the EM framework, enable it in the default arm64 defconfig, which is the
most commonly used architecture for IPA. This will also compile-in all
of the EAS code, although it won't be enabled by default -- EAS requires
to use the 'schedutil' CPUFreq governor while arm64 defaults to
'performance'.
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Quentin Perret <quentin.perret@arm.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0e58ef02880c..ad0e4944a71f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -71,6 +71,7 @@ CONFIG_COMPAT=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_HIBERNATION=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v7 0/4] Make IPA use PM_EM
From: Quentin Perret @ 2019-08-12 8:42 UTC (permalink / raw)
To: edubezval, rui.zhang, javi.merino, viresh.kumar, amit.kachhap,
rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, quentin.perret, mka, ionela.voinescu,
dietmar.eggemann, linux-arm-kernel
Changes in v7
*************
- Added patch 02/04 to fix the build error reported by the kbuild bot
Changes in v6
*************
- Added Daniel's and Viresh's Acked-by to all patches
Changes in v5:
**************
- Changed patch 02 to guard IPA-specific code in cpu_cooling.c with
appropriate ifdefery (Daniel)
- Rebased on 5.2-rc2
Changes in v4:
**************
- Added Viresh's Acked-by to all 3 patches
- Improved commit message of patch 3/3 to explain how it has no
functional impact on existing users (Eduardo)
Changes in v3:
**************
- Changed warning message for unordered tables to something more
explicit (Viresh)
- Changed WARN() into a pr_err() for consistency
Changes in v2:
**************
- Fixed patch 01/03 to actually enable CONFIG_ENERGY_MODEL
- Added "depends on ENERGY_MODEL" to IPA (Daniel)
- Added check to bail out if the freq table is unsorted (Viresh)
Cover letter:
*************
The Intelligent Power Allocator (IPA) thermal governor uses an Energy
Model (or EM) of the CPUs to re-distribute the power budget. To do so,
it builds a table of <frequency, power> tuples where the power values
are computed using the 'dynamic-power-coefficient' DT property. All of
this is done in and only for the thermal subsystem, and more
specifically for CPUs -- the power of other types of devices is obtained
differently.
Recently, the CPU scheduler has seen the introduction of Energy Aware
Scheduling (EAS) patches, which also rely on an EM of the CPUs. This EM,
however, is managed by an independent framework, called PM_EM, aimed to
be used by all kernel subsystems interested in the power consumed by
CPUs, and not only the scheduler.
This patch series follows this logic and removes the (now redundant)
thermal-specific EM computation code to migrate IPA to use PM_EM
instead.
Doing so should have no visible functional impact for existing users of
IPA since:
- during the 5.1 development cycle, a series of patches [1] introduced
in PM_OPP some infrastructure (dev_pm_opp_of_register_em()) enabling
the registration of EMs in PM_EM using the DT property used by IPA;
- the existing upstream cpufreq drivers marked with the
'CPUFREQ_IS_COOLING_DEV' flag all call dev_pm_opp_of_register_em(),
which means they all support PM_EM (the only two exceptions are
qoriq-cpufreq which doesn't in fact use an EM and scmi-cpufreq which
already supports PM_EM without using the PM_OPP infrastructurei
because it read power costs directly from firmware);
So, migrating IPA to using PM_EM should effectively be just plumbing
since for the existing IPA users the PM_EM tables will contain the
exact same power values that IPA used to compute on its own until now.
The only new dependency is to compile in CONFIG_ENERGY_MODEL.
Why is this migration still a good thing ? For three main reasons.
1. it removes redundant code;
2. it introduces an abstraction layer between IPA and the EM
computation. PM_EM offers to EAS and IPA (and potentially other
clients) standardized EM tables and hides 'how' these tables have
been obtained. PM_EM as of now supports power values either coming
from the 'dynamic-power-coefficient' DT property or obtained
directly from firmware using SCMI. The latter is a new feature for
IPA and that comes 'for free' with the migration. This will also be
true in the future every time PM_EM gets support for other ways of
loading the EM. Moreover, PM_EM is documented and has a debugfs
interface which should help adding support for new platforms.
3. it builds a consistent view of the EM of CPUs across kernel
subsystems, which is a pre-requisite for any kind of future work
aiming at a smarter power allocation using scheduler knowledge about
the system for example.
[1] https://lore.kernel.org/lkml/20190204110952.16025-1-quentin.perret@arm.com/
Quentin Perret (4):
arm64: defconfig: Enable CONFIG_ENERGY_MODEL
PM / EM: Declare EM data types unconditionally
thermal: cpu_cooling: Make the power-related code depend on IPA
thermal: cpu_cooling: Migrate to using the EM framework
arch/arm64/configs/defconfig | 1 +
drivers/thermal/Kconfig | 1 +
drivers/thermal/cpu_cooling.c | 428 ++++++++++++++--------------------
include/linux/energy_model.h | 3 +-
4 files changed, 179 insertions(+), 254 deletions(-)
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v7 2/4] PM / EM: Declare EM data types unconditionally
From: Quentin Perret @ 2019-08-12 8:42 UTC (permalink / raw)
To: edubezval, rui.zhang, javi.merino, viresh.kumar, amit.kachhap,
rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, quentin.perret, mka, ionela.voinescu,
dietmar.eggemann, linux-arm-kernel
In-Reply-To: <20190812084235.21440-1-quentin.perret@arm.com>
The structs representing capacity states and performance domains of an
Energy Model are currently only defined for CONFIG_ENERGY_MODEL=y. That
makes it hard for code outside PM_EM to manipulate those structures
without a lot of ifdefery or stubbed accessors.
So, move the declaration of the two structs outside of the
CONFIG_ENERGY_MODEL ifdef. The client code (e.g. EAS or thermal) always
checks the return of em_cpu_get() before using it, so the exising code
is still safe to use as-is.
Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Quentin Perret <quentin.perret@arm.com>
---
include/linux/energy_model.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 73f8c3cb9588..d249b88a4d5a 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -9,7 +9,6 @@
#include <linux/sched/topology.h>
#include <linux/types.h>
-#ifdef CONFIG_ENERGY_MODEL
/**
* em_cap_state - Capacity state of a performance domain
* @frequency: The CPU frequency in KHz, for consistency with CPUFreq
@@ -40,6 +39,7 @@ struct em_perf_domain {
unsigned long cpus[0];
};
+#ifdef CONFIG_ENERGY_MODEL
#define EM_CPU_MAX_POWER 0xFFFF
struct em_data_callback {
@@ -160,7 +160,6 @@ static inline int em_pd_nr_cap_states(struct em_perf_domain *pd)
}
#else
-struct em_perf_domain {};
struct em_data_callback {};
#define EM_DATA_CB(_active_power_cb) { }
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v7 3/4] thermal: cpu_cooling: Make the power-related code depend on IPA
From: Quentin Perret @ 2019-08-12 8:42 UTC (permalink / raw)
To: edubezval, rui.zhang, javi.merino, viresh.kumar, amit.kachhap,
rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, quentin.perret, mka, ionela.voinescu,
dietmar.eggemann, linux-arm-kernel
In-Reply-To: <20190812084235.21440-1-quentin.perret@arm.com>
The core CPU cooling infrastructure has power-related functions
that have only one client: IPA. Since there can be no user of those
functions if IPA is not compiled in, make sure to guard them with
checks on CONFIG_THERMAL_GOV_POWER_ALLOCATOR to not waste space
unnecessarily.
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Suggested-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Quentin Perret <quentin.perret@arm.com>
---
drivers/thermal/cpu_cooling.c | 214 +++++++++++++++++-----------------
1 file changed, 104 insertions(+), 110 deletions(-)
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 4c5db59a619b..498f59ab64b2 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -46,7 +46,9 @@
*/
struct freq_table {
u32 frequency;
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
u32 power;
+#endif
};
/**
@@ -96,28 +98,6 @@ static DEFINE_IDA(cpufreq_ida);
static DEFINE_MUTEX(cooling_list_lock);
static LIST_HEAD(cpufreq_cdev_list);
-/* Below code defines functions to be used for cpufreq as cooling device */
-
-/**
- * get_level: Find the level for a particular frequency
- * @cpufreq_cdev: cpufreq_cdev for which the property is required
- * @freq: Frequency
- *
- * Return: level corresponding to the frequency.
- */
-static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
- unsigned int freq)
-{
- struct freq_table *freq_table = cpufreq_cdev->freq_table;
- unsigned long level;
-
- for (level = 1; level <= cpufreq_cdev->max_level; level++)
- if (freq > freq_table[level].frequency)
- break;
-
- return level - 1;
-}
-
/**
* cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
* @nb: struct notifier_block * with callback info.
@@ -171,6 +151,27 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
return NOTIFY_OK;
}
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
+/**
+ * get_level: Find the level for a particular frequency
+ * @cpufreq_cdev: cpufreq_cdev for which the property is required
+ * @freq: Frequency
+ *
+ * Return: level corresponding to the frequency.
+ */
+static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
+ unsigned int freq)
+{
+ struct freq_table *freq_table = cpufreq_cdev->freq_table;
+ unsigned long level;
+
+ for (level = 1; level <= cpufreq_cdev->max_level; level++)
+ if (freq > freq_table[level].frequency)
+ break;
+
+ return level - 1;
+}
+
/**
* update_freq_table() - Update the freq table with power numbers
* @cpufreq_cdev: the cpufreq cooling device in which to update the table
@@ -319,80 +320,6 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_cdev,
return (raw_cpu_power * cpufreq_cdev->last_load) / 100;
}
-/* cpufreq cooling device callback functions are defined below */
-
-/**
- * cpufreq_get_max_state - callback function to get the max cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: fill this variable with the max cooling state.
- *
- * Callback for the thermal cooling device to return the cpufreq
- * max cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
- unsigned long *state)
-{
- struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-
- *state = cpufreq_cdev->max_level;
- return 0;
-}
-
-/**
- * cpufreq_get_cur_state - callback function to get the current cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: fill this variable with the current cooling state.
- *
- * Callback for the thermal cooling device to return the cpufreq
- * current cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
- unsigned long *state)
-{
- struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-
- *state = cpufreq_cdev->cpufreq_state;
-
- return 0;
-}
-
-/**
- * cpufreq_set_cur_state - callback function to set the current cooling state.
- * @cdev: thermal cooling device pointer.
- * @state: set this variable to the current cooling state.
- *
- * Callback for the thermal cooling device to change the cpufreq
- * current cooling state.
- *
- * Return: 0 on success, an error code otherwise.
- */
-static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
- unsigned long state)
-{
- struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
- unsigned int clip_freq;
-
- /* Request state should be less than max_level */
- if (WARN_ON(state > cpufreq_cdev->max_level))
- return -EINVAL;
-
- /* Check if the old cooling action is same as new cooling action */
- if (cpufreq_cdev->cpufreq_state == state)
- return 0;
-
- clip_freq = cpufreq_cdev->freq_table[state].frequency;
- cpufreq_cdev->cpufreq_state = state;
- cpufreq_cdev->clipped_freq = clip_freq;
-
- cpufreq_update_policy(cpufreq_cdev->policy->cpu);
-
- return 0;
-}
-
/**
* cpufreq_get_requested_power() - get the current power
* @cdev: &thermal_cooling_device pointer
@@ -536,22 +463,88 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
power);
return 0;
}
+#endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
+
+/* cpufreq cooling device callback functions are defined below */
+
+/**
+ * cpufreq_get_max_state - callback function to get the max cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the max cooling state.
+ *
+ * Callback for the thermal cooling device to return the cpufreq
+ * max cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+
+ *state = cpufreq_cdev->max_level;
+ return 0;
+}
+
+/**
+ * cpufreq_get_cur_state - callback function to get the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the current cooling state.
+ *
+ * Callback for the thermal cooling device to return the cpufreq
+ * current cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+
+ *state = cpufreq_cdev->cpufreq_state;
+
+ return 0;
+}
+
+/**
+ * cpufreq_set_cur_state - callback function to set the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: set this variable to the current cooling state.
+ *
+ * Callback for the thermal cooling device to change the cpufreq
+ * current cooling state.
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+ unsigned int clip_freq;
+
+ /* Request state should be less than max_level */
+ if (WARN_ON(state > cpufreq_cdev->max_level))
+ return -EINVAL;
+
+ /* Check if the old cooling action is same as new cooling action */
+ if (cpufreq_cdev->cpufreq_state == state)
+ return 0;
+
+ clip_freq = cpufreq_cdev->freq_table[state].frequency;
+ cpufreq_cdev->cpufreq_state = state;
+ cpufreq_cdev->clipped_freq = clip_freq;
+
+ cpufreq_update_policy(cpufreq_cdev->policy->cpu);
+
+ return 0;
+}
/* Bind cpufreq callbacks to thermal cooling device ops */
static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
- .get_max_state = cpufreq_get_max_state,
- .get_cur_state = cpufreq_get_cur_state,
- .set_cur_state = cpufreq_set_cur_state,
-};
-
-static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
.get_max_state = cpufreq_get_max_state,
.get_cur_state = cpufreq_get_cur_state,
.set_cur_state = cpufreq_set_cur_state,
- .get_requested_power = cpufreq_get_requested_power,
- .state2power = cpufreq_state2power,
- .power2state = cpufreq_power2state,
};
/* Notifier for cpufreq policy change */
@@ -659,18 +652,19 @@ __cpufreq_cooling_register(struct device_node *np,
pr_debug("%s: freq:%u KHz\n", __func__, freq);
}
+ cooling_ops = &cpufreq_cooling_ops;
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
if (capacitance) {
ret = update_freq_table(cpufreq_cdev, capacitance);
if (ret) {
cdev = ERR_PTR(ret);
goto remove_ida;
}
-
- cooling_ops = &cpufreq_power_cooling_ops;
- } else {
- cooling_ops = &cpufreq_cooling_ops;
+ cooling_ops->get_requested_power = cpufreq_get_requested_power;
+ cooling_ops->state2power = cpufreq_state2power;
+ cooling_ops->power2state = cpufreq_power2state;
}
-
+#endif
cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
cooling_ops);
if (IS_ERR(cdev))
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v7 4/4] thermal: cpu_cooling: Migrate to using the EM framework
From: Quentin Perret @ 2019-08-12 8:42 UTC (permalink / raw)
To: edubezval, rui.zhang, javi.merino, viresh.kumar, amit.kachhap,
rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, quentin.perret, mka, ionela.voinescu,
dietmar.eggemann, linux-arm-kernel
In-Reply-To: <20190812084235.21440-1-quentin.perret@arm.com>
The newly introduced Energy Model framework manages power cost tables in
a generic way. Moreover, it supports several types of models since the
tables can come from DT or firmware (through SCMI) for example. On the
other hand, the cpu_cooling subsystem manages its own power cost tables
using only DT data.
In order to avoid the duplication of data in the kernel, and in order to
enable IPA with EMs coming from more than just DT, remove the private
tables from cpu_cooling.c and migrate it to using the centralized EM
framework. Doing so should have no visible functional impact for
existing users of IPA since:
- recent extenstions to the the PM_OPP infrastructure enable the
registration of EMs in PM_EM using the DT property used by IPA;
- the existing upstream cpufreq drivers marked with the
'CPUFREQ_IS_COOLING_DEV' flag all use the aforementioned PM_OPP
infrastructure, which means they all support PM_EM. The only two
exceptions are qoriq-cpufreq which doesn't in fact use an EM and
scmi-cpufreq which doesn't use DT for power costs.
For existing users of cpu_cooling, PM_EM tables will contain the exact
same power values that IPA used to compute on its own until now. The
only new dependency for them is to compile in CONFIG_ENERGY_MODEL.
The case where the thermal subsystem is used without an Energy Model
(cpufreq_cooling_ops) is handled by looking directly at CPUFreq's
frequency table which is already a dependency for cpu_cooling.c anyway.
Since the thermal framework expects the cooling states in a particular
order, bail out whenever the CPUFreq table is unsorted, since that is
fairly uncommon in general, and there are currently no users of
cpu_cooling for this use-case.
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Quentin Perret <quentin.perret@arm.com>
---
drivers/thermal/Kconfig | 1 +
drivers/thermal/cpu_cooling.c | 250 ++++++++++++----------------------
2 files changed, 91 insertions(+), 160 deletions(-)
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9966364a6deb..340853a3ca48 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -144,6 +144,7 @@ config THERMAL_GOV_USER_SPACE
config THERMAL_GOV_POWER_ALLOCATOR
bool "Power allocator thermal governor"
+ depends on ENERGY_MODEL
help
Enable this to manage platform thermals by dynamically
allocating and limiting power to devices.
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 498f59ab64b2..83486775e593 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/cpu_cooling.h>
+#include <linux/energy_model.h>
#include <trace/events/thermal.h>
@@ -36,21 +37,6 @@
* ...
*/
-/**
- * struct freq_table - frequency table along with power entries
- * @frequency: frequency in KHz
- * @power: power in mW
- *
- * This structure is built when the cooling device registers and helps
- * in translating frequency to power and vice versa.
- */
-struct freq_table {
- u32 frequency;
-#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
- u32 power;
-#endif
-};
-
/**
* struct time_in_idle - Idle time stats
* @time: previous reading of the absolute time that this cpu was idle
@@ -72,7 +58,7 @@ struct time_in_idle {
* frequency.
* @max_level: maximum cooling level. One less than total number of valid
* cpufreq frequencies.
- * @freq_table: Freq table in descending order of frequencies
+ * @em: Reference on the Energy Model of the device
* @cdev: thermal_cooling_device pointer to keep track of the
* registered cooling device.
* @policy: cpufreq policy.
@@ -88,7 +74,7 @@ struct cpufreq_cooling_device {
unsigned int cpufreq_state;
unsigned int clipped_freq;
unsigned int max_level;
- struct freq_table *freq_table; /* In descending order */
+ struct em_perf_domain *em;
struct cpufreq_policy *policy;
struct list_head node;
struct time_in_idle *idle_time;
@@ -162,114 +148,40 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
unsigned int freq)
{
- struct freq_table *freq_table = cpufreq_cdev->freq_table;
- unsigned long level;
+ int i;
- for (level = 1; level <= cpufreq_cdev->max_level; level++)
- if (freq > freq_table[level].frequency)
+ for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+ if (freq > cpufreq_cdev->em->table[i].frequency)
break;
-
- return level - 1;
-}
-
-/**
- * update_freq_table() - Update the freq table with power numbers
- * @cpufreq_cdev: the cpufreq cooling device in which to update the table
- * @capacitance: dynamic power coefficient for these cpus
- *
- * Update the freq table with power numbers. This table will be used in
- * cpu_power_to_freq() and cpu_freq_to_power() to convert between power and
- * frequency efficiently. Power is stored in mW, frequency in KHz. The
- * resulting table is in descending order.
- *
- * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
- * or -ENOMEM if we run out of memory.
- */
-static int update_freq_table(struct cpufreq_cooling_device *cpufreq_cdev,
- u32 capacitance)
-{
- struct freq_table *freq_table = cpufreq_cdev->freq_table;
- struct dev_pm_opp *opp;
- struct device *dev = NULL;
- int num_opps = 0, cpu = cpufreq_cdev->policy->cpu, i;
-
- dev = get_cpu_device(cpu);
- if (unlikely(!dev)) {
- pr_warn("No cpu device for cpu %d\n", cpu);
- return -ENODEV;
- }
-
- num_opps = dev_pm_opp_get_opp_count(dev);
- if (num_opps < 0)
- return num_opps;
-
- /*
- * The cpufreq table is also built from the OPP table and so the count
- * should match.
- */
- if (num_opps != cpufreq_cdev->max_level + 1) {
- dev_warn(dev, "Number of OPPs not matching with max_levels\n");
- return -EINVAL;
- }
-
- for (i = 0; i <= cpufreq_cdev->max_level; i++) {
- unsigned long freq = freq_table[i].frequency * 1000;
- u32 freq_mhz = freq_table[i].frequency / 1000;
- u64 power;
- u32 voltage_mv;
-
- /*
- * Find ceil frequency as 'freq' may be slightly lower than OPP
- * freq due to truncation while converting to kHz.
- */
- opp = dev_pm_opp_find_freq_ceil(dev, &freq);
- if (IS_ERR(opp)) {
- dev_err(dev, "failed to get opp for %lu frequency\n",
- freq);
- return -EINVAL;
- }
-
- voltage_mv = dev_pm_opp_get_voltage(opp) / 1000;
- dev_pm_opp_put(opp);
-
- /*
- * Do the multiplication with MHz and millivolt so as
- * to not overflow.
- */
- power = (u64)capacitance * freq_mhz * voltage_mv * voltage_mv;
- do_div(power, 1000000000);
-
- /* power is stored in mW */
- freq_table[i].power = power;
}
- return 0;
+ return cpufreq_cdev->max_level - i - 1;
}
static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev,
u32 freq)
{
int i;
- struct freq_table *freq_table = cpufreq_cdev->freq_table;
- for (i = 1; i <= cpufreq_cdev->max_level; i++)
- if (freq > freq_table[i].frequency)
+ for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+ if (freq > cpufreq_cdev->em->table[i].frequency)
break;
+ }
- return freq_table[i - 1].power;
+ return cpufreq_cdev->em->table[i + 1].power;
}
static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
u32 power)
{
int i;
- struct freq_table *freq_table = cpufreq_cdev->freq_table;
- for (i = 1; i <= cpufreq_cdev->max_level; i++)
- if (power > freq_table[i].power)
+ for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
+ if (power > cpufreq_cdev->em->table[i].power)
break;
+ }
- return freq_table[i - 1].frequency;
+ return cpufreq_cdev->em->table[i + 1].frequency;
}
/**
@@ -410,7 +322,7 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz,
unsigned long state, u32 *power)
{
- unsigned int freq, num_cpus;
+ unsigned int freq, num_cpus, idx;
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
/* Request state should be less than max_level */
@@ -419,7 +331,8 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);
- freq = cpufreq_cdev->freq_table[state].frequency;
+ idx = cpufreq_cdev->max_level - state;
+ freq = cpufreq_cdev->em->table[idx].frequency;
*power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;
return 0;
@@ -463,8 +376,60 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
power);
return 0;
}
+
+static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev,
+ struct em_perf_domain *em) {
+ struct cpufreq_policy *policy;
+ unsigned int nr_levels;
+
+ if (!em)
+ return false;
+
+ policy = cpufreq_cdev->policy;
+ if (!cpumask_equal(policy->related_cpus, to_cpumask(em->cpus))) {
+ pr_err("The span of pd %*pbl is misaligned with cpufreq policy %*pbl\n",
+ cpumask_pr_args(to_cpumask(em->cpus)),
+ cpumask_pr_args(policy->related_cpus));
+ return false;
+ }
+
+ nr_levels = cpufreq_cdev->max_level + 1;
+ if (em->nr_cap_states != nr_levels) {
+ pr_err("The number of cap states in pd %*pbl (%u) doesn't match the number of cooling levels (%u)\n",
+ cpumask_pr_args(to_cpumask(em->cpus)),
+ em->nr_cap_states, nr_levels);
+ return false;
+ }
+
+ return true;
+}
#endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
+static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
+ unsigned long state)
+{
+ struct cpufreq_policy *policy;
+ unsigned long idx;
+
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
+ /* Use the Energy Model table if available */
+ if (cpufreq_cdev->em) {
+ idx = cpufreq_cdev->max_level - state;
+ return cpufreq_cdev->em->table[idx].frequency;
+ }
+#endif
+
+ /* Otherwise, fallback on the CPUFreq table */
+ policy = cpufreq_cdev->policy;
+ if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
+ idx = cpufreq_cdev->max_level - state;
+ else
+ idx = state;
+
+ return policy->freq_table[idx].frequency;
+}
+
+
/* cpufreq cooling device callback functions are defined below */
/**
@@ -530,7 +495,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
if (cpufreq_cdev->cpufreq_state == state)
return 0;
- clip_freq = cpufreq_cdev->freq_table[state].frequency;
+ clip_freq = get_state_freq(cpufreq_cdev, state);
cpufreq_cdev->cpufreq_state = state;
cpufreq_cdev->clipped_freq = clip_freq;
@@ -552,26 +517,12 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
.notifier_call = cpufreq_thermal_notifier,
};
-static unsigned int find_next_max(struct cpufreq_frequency_table *table,
- unsigned int prev_max)
-{
- struct cpufreq_frequency_table *pos;
- unsigned int max = 0;
-
- cpufreq_for_each_valid_entry(pos, table) {
- if (pos->frequency > max && pos->frequency < prev_max)
- max = pos->frequency;
- }
-
- return max;
-}
-
/**
* __cpufreq_cooling_register - helper function to create cpufreq cooling device
* @np: a valid struct device_node to the cooling device device tree node
* @policy: cpufreq policy
* Normally this should be same as cpufreq policy->related_cpus.
- * @capacitance: dynamic power coefficient for these cpus
+ * @em: Energy Model of the cpufreq policy
*
* This interface function registers the cpufreq cooling device with the name
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -583,12 +534,13 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
*/
static struct thermal_cooling_device *
__cpufreq_cooling_register(struct device_node *np,
- struct cpufreq_policy *policy, u32 capacitance)
+ struct cpufreq_policy *policy,
+ struct em_perf_domain *em)
{
struct thermal_cooling_device *cdev;
struct cpufreq_cooling_device *cpufreq_cdev;
char dev_name[THERMAL_NAME_LENGTH];
- unsigned int freq, i, num_cpus;
+ unsigned int i, num_cpus;
int ret;
struct thermal_cooling_device_ops *cooling_ops;
bool first;
@@ -622,55 +574,38 @@ __cpufreq_cooling_register(struct device_node *np,
/* max_level is an index, not a counter */
cpufreq_cdev->max_level = i - 1;
- cpufreq_cdev->freq_table = kmalloc_array(i,
- sizeof(*cpufreq_cdev->freq_table),
- GFP_KERNEL);
- if (!cpufreq_cdev->freq_table) {
- cdev = ERR_PTR(-ENOMEM);
- goto free_idle_time;
- }
-
ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
if (ret < 0) {
cdev = ERR_PTR(ret);
- goto free_table;
+ goto free_idle_time;
}
cpufreq_cdev->id = ret;
snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
cpufreq_cdev->id);
- /* Fill freq-table in descending order of frequencies */
- for (i = 0, freq = -1; i <= cpufreq_cdev->max_level; i++) {
- freq = find_next_max(policy->freq_table, freq);
- cpufreq_cdev->freq_table[i].frequency = freq;
-
- /* Warn for duplicate entries */
- if (!freq)
- pr_warn("%s: table has duplicate entries\n", __func__);
- else
- pr_debug("%s: freq:%u KHz\n", __func__, freq);
- }
-
cooling_ops = &cpufreq_cooling_ops;
#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
- if (capacitance) {
- ret = update_freq_table(cpufreq_cdev, capacitance);
- if (ret) {
- cdev = ERR_PTR(ret);
- goto remove_ida;
- }
+ if (em_is_sane(cpufreq_cdev, em)) {
+ cpufreq_cdev->em = em;
cooling_ops->get_requested_power = cpufreq_get_requested_power;
cooling_ops->state2power = cpufreq_state2power;
cooling_ops->power2state = cpufreq_power2state;
- }
+ } else
#endif
+ if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
+ pr_err("%s: unsorted frequency tables are not supported\n",
+ __func__);
+ cdev = ERR_PTR(-EINVAL);
+ goto remove_ida;
+ }
+
cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
cooling_ops);
if (IS_ERR(cdev))
goto remove_ida;
- cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
+ cpufreq_cdev->clipped_freq = get_state_freq(cpufreq_cdev, 0);
mutex_lock(&cooling_list_lock);
/* Register the notifier for first cpufreq cooling device */
@@ -686,8 +621,6 @@ __cpufreq_cooling_register(struct device_node *np,
remove_ida:
ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
-free_table:
- kfree(cpufreq_cdev->freq_table);
free_idle_time:
kfree(cpufreq_cdev->idle_time);
free_cdev:
@@ -709,7 +642,7 @@ __cpufreq_cooling_register(struct device_node *np,
struct thermal_cooling_device *
cpufreq_cooling_register(struct cpufreq_policy *policy)
{
- return __cpufreq_cooling_register(NULL, policy, 0);
+ return __cpufreq_cooling_register(NULL, policy, NULL);
}
EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
@@ -737,7 +670,6 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy)
{
struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
struct thermal_cooling_device *cdev = NULL;
- u32 capacitance = 0;
if (!np) {
pr_err("cpu_cooling: OF node not available for cpu%d\n",
@@ -746,10 +678,9 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy)
}
if (of_find_property(np, "#cooling-cells", NULL)) {
- of_property_read_u32(np, "dynamic-power-coefficient",
- &capacitance);
+ struct em_perf_domain *em = em_cpu_get(policy->cpu);
- cdev = __cpufreq_cooling_register(np, policy, capacitance);
+ cdev = __cpufreq_cooling_register(np, policy, em);
if (IS_ERR(cdev)) {
pr_err("cpu_cooling: cpu%d failed to register as cooling device: %ld\n",
policy->cpu, PTR_ERR(cdev));
@@ -791,7 +722,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
thermal_cooling_device_unregister(cdev);
ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
kfree(cpufreq_cdev->idle_time);
- kfree(cpufreq_cdev->freq_table);
kfree(cpufreq_cdev);
}
EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v5 15/18] thermal: sun8i: allow to use custom temperature calculation function
From: Maxime Ripard @ 2019-08-12 8:49 UTC (permalink / raw)
To: Yangtao Li
Cc: mark.rutland, devicetree, linux-pm, gregkh, daniel.lezcano,
linux-kernel, edubezval, wens, robh+dt, Jonathan.Cameron,
mchehab+samsung, rui.zhang, davem, linux-arm-kernel,
Icenowy Zheng
In-Reply-To: <20190810052829.6032-16-tiny.windzz@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 2076 bytes --]
Hi,
On Sat, Aug 10, 2019 at 05:28:26AM +0000, Yangtao Li wrote:
> From: Icenowy Zheng <icenowy@aosc.io>
>
> The H5 temperature calculation function is strange. Firstly, it's
> segmented. Secondly, the formula of two sensors are different in the
> second segment.
>
> Allow to use a custom temperature calculation function, in case of
> the function is complex.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
When you send a patch on someone else's behalf, you need to put your
Signed-off-by as well.
> ---
> drivers/thermal/sun8i_thermal.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index 3259081da841..a761e2afda08 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -76,6 +76,7 @@ struct ths_thermal_chip {
> u16 *caldata, int callen);
> int (*init)(struct ths_device *tmdev);
> int (*irq_ack)(struct ths_device *tmdev);
> + int (*calc_temp)(int id, int reg);
> };
>
> struct ths_device {
> @@ -90,9 +91,12 @@ struct ths_device {
>
> /* Temp Unit: millidegree Celsius */
> static int sun8i_ths_reg2temp(struct ths_device *tmdev,
> - int reg)
> + int id, int reg)
> {
> - return (reg + tmdev->chip->offset) * tmdev->chip->scale;
> + if (tmdev->chip->calc_temp)
> + return tmdev->chip->calc_temp(id, reg);
> + else
> + return (reg + tmdev->chip->offset) * tmdev->chip->scale;
You're not consistent here compared to the other callbacks you have
introduced: calibrate, init and irq_ack all need to be set and will
fail (hard) if you don't set them, yet this one will have a different
behaviour (that behaviour being to use the H6 formula, which is the
latest SoC, which is a bit odd in itself).
I guess we should either make it mandatory as the rest of the
callbacks, or document which callbacks are mandatory and which are
optional (and the behaviour when it's optional).
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] ARM: dts: imx7d: sbc-iot-imx7: add recovery for i2c3/4
From: Philippe Schenker @ 2019-08-12 8:50 UTC (permalink / raw)
To: git@andred.net
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
Max Krummenacher, Marcel Ziswiler, festevam@gmail.com,
s.hauer@pengutronix.de, linux-kernel@vger.kernel.org,
Oleksandr Suvorov, robh+dt@kernel.org, linux-imx@nxp.com,
kernel@pengutronix.de, shawnguo@kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190810215817.5118-1-git@andred.net>
On Sat, 2019-08-10 at 22:58 +0100, André Draszik wrote:
> On Wed, 07 Aug 2019 08:26:15 +0000, Philippe Schenker wrote:
> > From: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
> >
> > - add recovery mode for applicable i2c buses for
> > Colibri iMX7 module.
> >
> > Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
> > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
> > ---
> >
> > Changes in v3: None
> > Changes in v2: None
> >
> > arch/arm/boot/dts/imx7-colibri.dtsi | 25 +++++++++++++++++++++++--
> > 1 file changed, 23 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi
> > b/arch/arm/boot/dts/imx7-colibri.dtsi
> > index a8d992f3e897..2480623c92ff 100644
> > --- a/arch/arm/boot/dts/imx7-colibri.dtsi
> > +++ b/arch/arm/boot/dts/imx7-colibri.dtsi
> > @@ -140,8 +140,12 @@
> >
> > &i2c1 {
> > clock-frequency = <100000>;
> > - pinctrl-names = "default";
> > + pinctrl-names = "default", "gpio";
> > pinctrl-0 = <&pinctrl_i2c1 &pinctrl_i2c1_int>;
> > + pinctrl-1 = <&pinctrl_i2c1_recovery &pinctrl_i2c1_int>;
> > + scl-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
>
> scl-gpios should be (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN) since
> commit d2d0ad2aec4a ("i2c: imx: use open drain for recovery GPIO")
>
> Otherwise you'll get a boot-time warning:
> enforced open drain please flag it properly in DT/ACPI DSDT/board
> file
Thanks for pointing this out, I added this for v4.
Philippe
>
> > + sda-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
> > +
> > status = "okay";
> >
> > codec: sgtl5000@a {
> > @@ -242,8 +246,11 @@
> >
> > &i2c4 {
> > clock-frequency = <100000>;
> > - pinctrl-names = "default";
> > + pinctrl-names = "default", "gpio";
> > pinctrl-0 = <&pinctrl_i2c4>;
> > + pinctrl-1 = <&pinctrl_i2c4_recovery>;
> > + scl-gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>;
>
> and here, too.
>
> Cheers,
> André
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] watchdog: imx_sc: Remove unnecessary error log
From: Anson.Huang @ 2019-08-12 8:44 UTC (permalink / raw)
To: wim, linux, shawnguo, s.hauer, kernel, festevam, linux-watchdog,
linux-arm-kernel, linux-kernel
Cc: Linux-imx
From: Anson Huang <Anson.Huang@nxp.com>
An error message is already displayed by watchdog_register_device()
when failed, so no need to have error log again for failure of
calling devm_watchdog_register_device().
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
drivers/watchdog/imx_sc_wdt.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c
index 78eaaf7..9260475 100644
--- a/drivers/watchdog/imx_sc_wdt.c
+++ b/drivers/watchdog/imx_sc_wdt.c
@@ -175,11 +175,8 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(wdog);
ret = devm_watchdog_register_device(dev, wdog);
-
- if (ret) {
- dev_err(dev, "Failed to register watchdog device\n");
+ if (ret)
return ret;
- }
ret = imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
SC_IRQ_WDOG,
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v3 17/21] ARM: dts: imx6ull: improve can templates
From: Philippe Schenker @ 2019-08-12 8:54 UTC (permalink / raw)
To: stefan@agner.ch, Marcel Ziswiler, festevam@gmail.com,
devicetree@vger.kernel.org, mark.rutland@arm.com,
Max Krummenacher, shawnguo@kernel.org, michal.vokac@ysoft.com,
robh+dt@kernel.org
Cc: linux-imx@nxp.com, s.hauer@pengutronix.de, kernel@pengutronix.de,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <8ae5742f29f17e61fd9fc39a8dbd1b7c3a2f45b0.camel@toradex.com>
On Fri, 2019-08-09 at 15:47 +0000, Marcel Ziswiler wrote:
> Hi Philippe
>
> On Wed, 2019-08-07 at 08:26 +0000, Philippe Schenker wrote:
> > From: Max Krummenacher <max.krummenacher@toradex.com>
> >
> > Add the pinmuxing and a inactive node for flexcan1 on SODIMM 55/63
> > and move the inactive flexcan nodes to imx6ull-colibri-eval-v3.dtsi
> > where they belong.
> >
> > Note that this commit does not enable flexcan functionality, but
> > rather
> > eases the effort needed to do so.
> >
> > Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
> > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
> > ---
> >
> > Changes in v3: None
> > Changes in v2: None
> >
> > arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi | 12 ++++++++++++
> > arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi | 2 +-
> > arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi | 2 +-
> > arch/arm/boot/dts/imx6ull-colibri.dtsi | 16 ++++++++++++++-
> > -
> > 4 files changed, 28 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
> > b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
> > index b6147c76d159..3bee37c75aa6 100644
> > --- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
> > +++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
> > @@ -83,6 +83,18 @@
> > };
> > };
> >
> > +&can1 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_flexcan1>;
> > + status = "disabled";
> > +};
> > +
> > +&can2 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_flexcan2>;
> > + status = "disabled";
> > +};
>
> As those don't really have anything to do with the eval board
> directly,
> wouldn't it make more sense to rather move them into the module's dtsi
> just like the pin muxing further below?
I agree, moved for v4.
Thanks, Philippe
>
> > &i2c1 {
> > status = "okay";
> >
> > diff --git a/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
> > b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
> > index fb213bec4654..95a11b8bcbdb 100644
> > --- a/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
> > +++ b/arch/arm/boot/dts/imx6ull-colibri-nonwifi.dtsi
> > @@ -15,7 +15,7 @@
> > &iomuxc {
> > pinctrl-names = "default";
> > pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
> > - &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6>;
> > + &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio6
> > &pinctrl_gpio7>;
> > };
> >
> > &iomuxc_snvs {
> > diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
> > b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
> > index 038d8c90f6df..a0545431b3dc 100644
> > --- a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
> > +++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
> > @@ -26,7 +26,7 @@
> > &iomuxc {
> > pinctrl-names = "default";
> > pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
> > - &pinctrl_gpio4 &pinctrl_gpio5>;
> > + &pinctrl_gpio4 &pinctrl_gpio5 &pinctrl_gpio7>;
> >
> > };
> >
> > diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi
> > b/arch/arm/boot/dts/imx6ull-colibri.dtsi
> > index e3220298dd6f..553d4c1f80e9 100644
> > --- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
> > +++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
> > @@ -256,6 +256,13 @@
> > >;
> > };
> >
> > + pinctrl_flexcan1: flexcan1-grp {
> > + fsl,pins = <
> > + MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x1b
> > 0
> > 20
> > + MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x1b
> > 0
> > 20
> > + >;
> > + };
> > +
> > pinctrl_flexcan2: flexcan2-grp {
> > fsl,pins = <
> > MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x1b
> > 0
> > 20
> > @@ -271,8 +278,6 @@
> >
> > pinctrl_gpio1: gpio1-grp {
> > fsl,pins = <
> > - MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x74
> > /* SODIMM 55 */
> > - MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x74
> > /* SODIMM 63 */
> > MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0X14
> > /* SODIMM 77 */
> > MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x14
> > /* SODIMM 99 */
> > MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x14 /*
> > SODIMM 133 */
> > @@ -325,6 +330,13 @@
> > >;
> > };
> >
> > + pinctrl_gpio7: gpio7-grp { /* CAN1 */
> > + fsl,pins = <
> > + MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x74
> > /* SODIMM 55 */
> > + MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x74
> > /* SODIMM 63 */
> > + >;
> > + };
> > +
> > pinctrl_gpmi_nand: gpmi-nand-grp {
> > fsl,pins = <
> > MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x10
> > 0
> > a9
>
> Cheers
>
> Marcel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 02/18] dt-bindings: thermal: add binding document for h6 thermal controller
From: Maxime Ripard @ 2019-08-12 8:56 UTC (permalink / raw)
To: Yangtao Li
Cc: mark.rutland, devicetree, linux-pm, gregkh, daniel.lezcano,
linux-kernel, edubezval, wens, robh+dt, Jonathan.Cameron,
mchehab+samsung, rui.zhang, davem, linux-arm-kernel
In-Reply-To: <20190810052829.6032-3-tiny.windzz@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 2562 bytes --]
On Sat, Aug 10, 2019 at 05:28:13AM +0000, Yangtao Li wrote:
> This patch adds binding document for allwinner h6 thermal controller.
>
> Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
> ---
> .../bindings/thermal/sun8i-thermal.yaml | 79 +++++++++++++++++++
> 1 file changed, 79 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-thermal.yaml
>
> diff --git a/Documentation/devicetree/bindings/thermal/sun8i-thermal.yaml b/Documentation/devicetree/bindings/thermal/sun8i-thermal.yaml
> new file mode 100644
> index 000000000000..e0973199ba3c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/sun8i-thermal.yaml
We've used so far for the schemas the first compatible to introduce
that controller as the filename, we should be consistent here. In that
case that would be allwinner,sun8i-a23-ths.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/sun8i-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Allwinner SUN8I Thermal Controller Device Tree Bindings
> +
> +maintainers:
> + - Yangtao Li <tiny.windzz@gmail.com>
> +
> +description: |-
> + This describes the device tree binding for the Allwinner thermal
> + controller which measures the on-SoC temperatures.
> +
> +properties:
> + compatible:
> + enum:
> + - allwinner,sun50i-h6-ths
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + resets:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + clock-names:
> + const: bus
> +
> + "#thermal-sensor-cells":
> + const: 1
> +
> + nvmem-cells:
You need a maxItems here too
> + description: ths calibrate data
What about something like this:
Calibration data for the thermal sensor
> +
> + nvmem-cell-names:
> + const: calib
I'm not sure we need a abbreviation here, calibration would be more
explicit
> +
> +required:
> + - compatible
> + - reg
> + - reset
> + - clocks
> + - clock-names
> + - interrupts
> + - "#thermal-sensor-cells"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + ths: ths@5070400 {
> + compatible = "allwinner,sun50i-h6-ths";
> + reg = <0x05070400 0x100>;
> + clocks = <&ccu CLK_BUS_THS>;
> + clock-names = "bus";
> + resets = <&ccu RST_BUS_THS>;
> + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
Those examples won't compile.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 03/11] clocksource: sun4i: Add missing compatibles
From: Maxime Ripard @ 2019-08-12 8:58 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: Mark Rutland, devicetree, Chen-Yu Tsai, Rob Herring, Frank Rowand,
linux-arm-kernel
In-Reply-To: <20190722081229.22422-3-maxime.ripard@bootlin.com>
[-- Attachment #1.1: Type: text/plain, Size: 382 bytes --]
Hi Daniel, Thomas,
On Mon, Jul 22, 2019 at 10:12:21AM +0200, Maxime Ripard wrote:
> Newer Allwinner SoCs have different number of interrupts, let's add
> different compatibles for all of them to deal with this properly.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Ping?
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 03/11] clocksource: sun4i: Add missing compatibles
From: Daniel Lezcano @ 2019-08-12 8:59 UTC (permalink / raw)
To: Maxime Ripard, Mark Rutland, Rob Herring, Frank Rowand,
Chen-Yu Tsai, tglx
Cc: devicetree, linux-arm-kernel
In-Reply-To: <20190722081229.22422-3-maxime.ripard@bootlin.com>
On 22/07/2019 10:12, Maxime Ripard wrote:
> Newer Allwinner SoCs have different number of interrupts, let's add
> different compatibles for all of them to deal with this properly.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---
> drivers/clocksource/timer-sun4i.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/clocksource/timer-sun4i.c b/drivers/clocksource/timer-sun4i.c
> index 65f38f6ca714..0ba8155b8287 100644
> --- a/drivers/clocksource/timer-sun4i.c
> +++ b/drivers/clocksource/timer-sun4i.c
> @@ -219,5 +219,9 @@ static int __init sun4i_timer_init(struct device_node *node)
> }
> TIMER_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer",
> sun4i_timer_init);
> +TIMER_OF_DECLARE(sun8i_a23, "allwinner,sun8i-a23-timer",
> + sun4i_timer_init);
> +TIMER_OF_DECLARE(sun8i_v3s, "allwinner,sun8i-v3s-timer",
> + sun4i_timer_init);
> TIMER_OF_DECLARE(suniv, "allwinner,suniv-f1c100s-timer",
> sun4i_timer_init);
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox